00001 #include <lightmediascanner_db.h> 00002 #include "lightmediascanner_db_private.h" 00003 #include <stdlib.h> 00004 #include <stdio.h> 00005 00006 struct lms_db_video { 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_videos_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 videos (" 00023 "id INTEGER PRIMARY KEY, " 00024 "title TEXT, " 00025 "artist TEXT" 00026 ")", 00027 NULL, NULL, &errmsg); 00028 if (r != SQLITE_OK) { 00029 fprintf(stderr, "ERROR: could not create 'videos' table: %s\n", errmsg); 00030 sqlite3_free(errmsg); 00031 return -1; 00032 } 00033 00034 r = sqlite3_exec(db, 00035 "CREATE INDEX IF NOT EXISTS videos_title_idx ON videos (" 00036 "title" 00037 ")", 00038 NULL, NULL, &errmsg); 00039 if (r != SQLITE_OK) { 00040 fprintf(stderr, 00041 "ERROR: could not create 'videos_title_idx' index: %s\n", 00042 errmsg); 00043 sqlite3_free(errmsg); 00044 return -2; 00045 } 00046 00047 r = sqlite3_exec(db, 00048 "CREATE INDEX IF NOT EXISTS videos_artist_idx ON videos (" 00049 "artist" 00050 ")", 00051 NULL, NULL, &errmsg); 00052 if (r != SQLITE_OK) { 00053 fprintf(stderr, 00054 "ERROR: could not create 'videos_artist_idx' index: %s\n", 00055 errmsg); 00056 sqlite3_free(errmsg); 00057 return -3; 00058 } 00059 00060 ret = lms_db_create_trigger_if_not_exists(db, 00061 "delete_videos_on_files_deleted " 00062 "DELETE ON files FOR EACH ROW BEGIN " 00063 " DELETE FROM videos WHERE id = OLD.id; END;"); 00064 if (ret != 0) 00065 goto done; 00066 00067 ret = lms_db_create_trigger_if_not_exists(db, 00068 "delete_files_on_videos_deleted " 00069 "DELETE ON videos FOR EACH ROW BEGIN " 00070 " DELETE FROM files WHERE id = OLD.id; END;"); 00071 00072 done: 00073 return ret; 00074 } 00075 00076 static lms_db_table_updater_t _db_table_updater_videos[] = { 00077 _db_table_updater_videos_0 00078 }; 00079 00080 00081 static int 00082 _db_create_table_if_required(sqlite3 *db) 00083 { 00084 return lms_db_table_update_if_required(db, "videos", 00085 LMS_ARRAY_SIZE(_db_table_updater_videos), 00086 _db_table_updater_videos); 00087 } 00088 00103 lms_db_video_t * 00104 lms_db_video_new(sqlite3 *db) 00105 { 00106 lms_db_video_t *ldv; 00107 void *p; 00108 00109 if (lms_db_cache_get(&_cache, db, &p) == 0) { 00110 ldv = p; 00111 ldv->_references++; 00112 return ldv; 00113 } 00114 00115 if (!db) 00116 return NULL; 00117 00118 if (_db_create_table_if_required(db) != 0) { 00119 fprintf(stderr, "ERROR: could not create table.\n"); 00120 return NULL; 00121 } 00122 00123 ldv = calloc(1, sizeof(lms_db_video_t)); 00124 ldv->_references = 1; 00125 ldv->db = db; 00126 00127 if (lms_db_cache_add(&_cache, db, ldv) != 0) { 00128 lms_db_video_free(ldv); 00129 return NULL; 00130 } 00131 00132 return ldv; 00133 } 00134 00147 int 00148 lms_db_video_start(lms_db_video_t *ldv) 00149 { 00150 if (!ldv) 00151 return -1; 00152 if (ldv->_is_started) 00153 return 0; 00154 00155 ldv->insert = lms_db_compile_stmt(ldv->db, 00156 "INSERT OR REPLACE INTO videos (id, title, artist) VALUES (?, ?, ?)"); 00157 if (!ldv->insert) 00158 return -2; 00159 00160 ldv->_is_started = 1; 00161 return 0; 00162 } 00163 00176 int 00177 lms_db_video_free(lms_db_video_t *ldv) 00178 { 00179 int r; 00180 00181 if (!ldv) 00182 return -1; 00183 if (ldv->_references == 0) { 00184 fprintf(stderr, "ERROR: over-called lms_db_video_free(%p)\n", ldv); 00185 return -1; 00186 } 00187 00188 ldv->_references--; 00189 if (ldv->_references > 0) 00190 return 0; 00191 00192 if (ldv->insert) 00193 lms_db_finalize_stmt(ldv->insert, "insert"); 00194 00195 r = lms_db_cache_del(&_cache, ldv->db, ldv); 00196 free(ldv); 00197 00198 return r; 00199 } 00200 00201 static int 00202 _db_insert(lms_db_video_t *ldv, const struct lms_video_info *info) 00203 { 00204 sqlite3_stmt *stmt; 00205 int r, ret; 00206 00207 stmt = ldv->insert; 00208 00209 ret = lms_db_bind_int64(stmt, 1, info->id); 00210 if (ret != 0) 00211 goto done; 00212 00213 ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len); 00214 if (ret != 0) 00215 goto done; 00216 00217 ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len); 00218 if (ret != 0) 00219 goto done; 00220 00221 r = sqlite3_step(stmt); 00222 if (r != SQLITE_DONE) { 00223 fprintf(stderr, "ERROR: could not insert video info: %s\n", 00224 sqlite3_errmsg(ldv->db)); 00225 ret = -4; 00226 goto done; 00227 } 00228 00229 ret = 0; 00230 00231 done: 00232 lms_db_reset_stmt(stmt); 00233 00234 return ret; 00235 } 00236 00248 int 00249 lms_db_video_add(lms_db_video_t *ldv, struct lms_video_info *info) 00250 { 00251 if (!ldv) 00252 return -1; 00253 if (!info) 00254 return -2; 00255 if (info->id < 1) 00256 return -3; 00257 00258 return _db_insert(ldv, info); 00259 }