src/lib/lightmediascanner_db_playlist.c

Go to the documentation of this file.
00001 #include <lightmediascanner_db.h>
00002 #include "lightmediascanner_db_private.h"
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 
00006 struct lms_db_playlist {
00007     sqlite3 *db;
00008     sqlite3_stmt *insert;
00009     unsigned int _references;
00010     unsigned int _is_started:1;
00011 };
00012 
00013 static struct lms_db_cache _cache = {0, NULL};
00014 
00015 static int
00016 _db_table_updater_playlists_0(sqlite3 *db, const char *table, unsigned int current_version, int is_last_run) {
00017     char *errmsg;
00018     int r, ret;
00019 
00020     errmsg = NULL;
00021     r = sqlite3_exec(db,
00022                      "CREATE TABLE IF NOT EXISTS playlists ("
00023                      "id INTEGER PRIMARY KEY, "
00024                      "title TEXT, "
00025                      "n_entries INTEGER NOT NULL"
00026                      ")",
00027                      NULL, NULL, &errmsg);
00028     if (r != SQLITE_OK) {
00029         fprintf(stderr, "ERROR: could not create 'playlists' table: %s\n",
00030                 errmsg);
00031         sqlite3_free(errmsg);
00032         return -1;
00033     }
00034 
00035     r = sqlite3_exec(db,
00036                      "CREATE INDEX IF NOT EXISTS playlists_title_idx ON "
00037                      "playlists (title)",
00038                      NULL, NULL, &errmsg);
00039     if (r != SQLITE_OK) {
00040         fprintf(stderr,
00041                 "ERROR: could not create 'playlists_title_idx' index: %s\n",
00042                 errmsg);
00043         sqlite3_free(errmsg);
00044         return -2;
00045     }
00046 
00047     ret = lms_db_create_trigger_if_not_exists(db,
00048         "delete_playlists_on_files_deleted "
00049         "DELETE ON files FOR EACH ROW BEGIN "
00050         " DELETE FROM playlists WHERE id = OLD.id; END;");
00051     if (ret != 0)
00052         goto done;
00053 
00054     ret = lms_db_create_trigger_if_not_exists(db,
00055         "delete_files_on_playlists_deleted "
00056         "DELETE ON playlists FOR EACH ROW BEGIN "
00057         " DELETE FROM files WHERE id = OLD.id; END;");
00058 
00059   done:
00060     return ret;
00061 }
00062 
00063 static lms_db_table_updater_t _db_table_updater_playlists[] = {
00064     _db_table_updater_playlists_0
00065 };
00066 
00067 
00068 static int
00069 _db_create_table_if_required(sqlite3 *db)
00070 {
00071     return lms_db_table_update_if_required(db, "playlists",
00072          LMS_ARRAY_SIZE(_db_table_updater_playlists),
00073          _db_table_updater_playlists);
00074 }
00075 
00090 lms_db_playlist_t *
00091 lms_db_playlist_new(sqlite3 *db)
00092 {
00093     lms_db_playlist_t *ldp;
00094     void *p;
00095 
00096     if (lms_db_cache_get(&_cache, db, &p) == 0) {
00097         ldp = p;
00098         ldp->_references++;
00099         return ldp;
00100     }
00101 
00102     if (!db)
00103         return NULL;
00104 
00105     if (_db_create_table_if_required(db) != 0) {
00106         fprintf(stderr, "ERROR: could not create table.\n");
00107         return NULL;
00108     }
00109 
00110     ldp = calloc(1, sizeof(lms_db_playlist_t));
00111     ldp->_references = 1;
00112     ldp->db = db;
00113 
00114     if (lms_db_cache_add(&_cache, db, ldp) != 0) {
00115         lms_db_playlist_free(ldp);
00116         return NULL;
00117     }
00118 
00119     return ldp;
00120 }
00121 
00134 int
00135 lms_db_playlist_start(lms_db_playlist_t *ldp)
00136 {
00137     if (!ldp)
00138         return -1;
00139     if (ldp->_is_started)
00140         return 0;
00141 
00142     ldp->insert = lms_db_compile_stmt(ldp->db,
00143         "INSERT OR REPLACE INTO playlists (id, title, n_entries) "
00144         "VALUES (?, ?, ?)");
00145     if (!ldp->insert)
00146         return -2;
00147 
00148     ldp->_is_started = 1;
00149     return 0;
00150 }
00151 
00164 int
00165 lms_db_playlist_free(lms_db_playlist_t *ldp)
00166 {
00167     int r;
00168 
00169     if (!ldp)
00170         return -1;
00171     if (ldp->_references == 0) {
00172         fprintf(stderr, "ERROR: over-called lms_db_playlist_free(%p)\n", ldp);
00173         return -1;
00174     }
00175 
00176     ldp->_references--;
00177     if (ldp->_references > 0)
00178         return 0;
00179 
00180     if (ldp->insert)
00181         lms_db_finalize_stmt(ldp->insert, "insert");
00182 
00183     r = lms_db_cache_del(&_cache, ldp->db, ldp);
00184     free(ldp);
00185 
00186     return r;
00187 }
00188 
00189 static int
00190 _db_insert(lms_db_playlist_t *ldp, const struct lms_playlist_info *info)
00191 {
00192     sqlite3_stmt *stmt;
00193     int r, ret;
00194 
00195     stmt = ldp->insert;
00196 
00197     ret = lms_db_bind_int64(stmt, 1, info->id);
00198     if (ret != 0)
00199         goto done;
00200 
00201     ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len);
00202     if (ret != 0)
00203         goto done;
00204 
00205     ret = lms_db_bind_int(stmt, 3, info->n_entries);
00206     if (ret != 0)
00207         goto done;
00208 
00209     r = sqlite3_step(stmt);
00210     if (r != SQLITE_DONE) {
00211         fprintf(stderr, "ERROR: could not insert playlist info: %s\n",
00212                 sqlite3_errmsg(ldp->db));
00213         ret = -4;
00214         goto done;
00215     }
00216 
00217     ret = 0;
00218 
00219   done:
00220     lms_db_reset_stmt(stmt);
00221 
00222     return ret;
00223 }
00224 
00236 int
00237 lms_db_playlist_add(lms_db_playlist_t *ldp, struct lms_playlist_info *info)
00238 {
00239     if (!ldp)
00240         return -1;
00241     if (!info)
00242         return -2;
00243     if (info->id < 1)
00244         return -3;
00245 
00246     return _db_insert(ldp, info);
00247 }

Generated on Thu Dec 13 02:04:03 2007 for Light Media Scanner by  doxygen 1.5.2