00001 00021 #include <lightmediascanner_db.h> 00022 #include "lightmediascanner_db_private.h" 00023 #include <stdlib.h> 00024 #include <stdio.h> 00025 00026 struct lms_db_video { 00027 sqlite3 *db; 00028 sqlite3_stmt *insert; 00029 unsigned int _references; 00030 unsigned int _is_started:1; 00031 }; 00032 00033 static struct lms_db_cache _cache = {0, NULL}; 00034 00035 static int 00036 _db_table_updater_videos_0(sqlite3 *db, const char *table, unsigned int current_version, int is_last_run) { 00037 char *errmsg; 00038 int r, ret; 00039 00040 errmsg = NULL; 00041 r = sqlite3_exec(db, 00042 "CREATE TABLE IF NOT EXISTS videos (" 00043 "id INTEGER PRIMARY KEY, " 00044 "title TEXT, " 00045 "artist TEXT" 00046 ")", 00047 NULL, NULL, &errmsg); 00048 if (r != SQLITE_OK) { 00049 fprintf(stderr, "ERROR: could not create 'videos' table: %s\n", errmsg); 00050 sqlite3_free(errmsg); 00051 return -1; 00052 } 00053 00054 r = sqlite3_exec(db, 00055 "CREATE INDEX IF NOT EXISTS videos_title_idx ON videos (" 00056 "title" 00057 ")", 00058 NULL, NULL, &errmsg); 00059 if (r != SQLITE_OK) { 00060 fprintf(stderr, 00061 "ERROR: could not create 'videos_title_idx' index: %s\n", 00062 errmsg); 00063 sqlite3_free(errmsg); 00064 return -2; 00065 } 00066 00067 r = sqlite3_exec(db, 00068 "CREATE INDEX IF NOT EXISTS videos_artist_idx ON videos (" 00069 "artist" 00070 ")", 00071 NULL, NULL, &errmsg); 00072 if (r != SQLITE_OK) { 00073 fprintf(stderr, 00074 "ERROR: could not create 'videos_artist_idx' index: %s\n", 00075 errmsg); 00076 sqlite3_free(errmsg); 00077 return -3; 00078 } 00079 00080 ret = lms_db_create_trigger_if_not_exists(db, 00081 "delete_videos_on_files_deleted " 00082 "DELETE ON files FOR EACH ROW BEGIN " 00083 " DELETE FROM videos WHERE id = OLD.id; END;"); 00084 if (ret != 0) 00085 goto done; 00086 00087 ret = lms_db_create_trigger_if_not_exists(db, 00088 "delete_files_on_videos_deleted " 00089 "DELETE ON videos FOR EACH ROW BEGIN " 00090 " DELETE FROM files WHERE id = OLD.id; END;"); 00091 00092 done: 00093 return ret; 00094 } 00095 00096 static lms_db_table_updater_t _db_table_updater_videos[] = { 00097 _db_table_updater_videos_0 00098 }; 00099 00100 00101 static int 00102 _db_create_table_if_required(sqlite3 *db) 00103 { 00104 return lms_db_table_update_if_required(db, "videos", 00105 LMS_ARRAY_SIZE(_db_table_updater_videos), 00106 _db_table_updater_videos); 00107 } 00108 00123 lms_db_video_t * 00124 lms_db_video_new(sqlite3 *db) 00125 { 00126 lms_db_video_t *ldv; 00127 void *p; 00128 00129 if (lms_db_cache_get(&_cache, db, &p) == 0) { 00130 ldv = p; 00131 ldv->_references++; 00132 return ldv; 00133 } 00134 00135 if (!db) 00136 return NULL; 00137 00138 if (_db_create_table_if_required(db) != 0) { 00139 fprintf(stderr, "ERROR: could not create table.\n"); 00140 return NULL; 00141 } 00142 00143 ldv = calloc(1, sizeof(lms_db_video_t)); 00144 ldv->_references = 1; 00145 ldv->db = db; 00146 00147 if (lms_db_cache_add(&_cache, db, ldv) != 0) { 00148 lms_db_video_free(ldv); 00149 return NULL; 00150 } 00151 00152 return ldv; 00153 } 00154 00167 int 00168 lms_db_video_start(lms_db_video_t *ldv) 00169 { 00170 if (!ldv) 00171 return -1; 00172 if (ldv->_is_started) 00173 return 0; 00174 00175 ldv->insert = lms_db_compile_stmt(ldv->db, 00176 "INSERT OR REPLACE INTO videos (id, title, artist) VALUES (?, ?, ?)"); 00177 if (!ldv->insert) 00178 return -2; 00179 00180 ldv->_is_started = 1; 00181 return 0; 00182 } 00183 00196 int 00197 lms_db_video_free(lms_db_video_t *ldv) 00198 { 00199 int r; 00200 00201 if (!ldv) 00202 return -1; 00203 if (ldv->_references == 0) { 00204 fprintf(stderr, "ERROR: over-called lms_db_video_free(%p)\n", ldv); 00205 return -1; 00206 } 00207 00208 ldv->_references--; 00209 if (ldv->_references > 0) 00210 return 0; 00211 00212 if (ldv->insert) 00213 lms_db_finalize_stmt(ldv->insert, "insert"); 00214 00215 r = lms_db_cache_del(&_cache, ldv->db, ldv); 00216 free(ldv); 00217 00218 return r; 00219 } 00220 00221 static int 00222 _db_insert(lms_db_video_t *ldv, const struct lms_video_info *info) 00223 { 00224 sqlite3_stmt *stmt; 00225 int r, ret; 00226 00227 stmt = ldv->insert; 00228 00229 ret = lms_db_bind_int64(stmt, 1, info->id); 00230 if (ret != 0) 00231 goto done; 00232 00233 ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len); 00234 if (ret != 0) 00235 goto done; 00236 00237 ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len); 00238 if (ret != 0) 00239 goto done; 00240 00241 r = sqlite3_step(stmt); 00242 if (r != SQLITE_DONE) { 00243 fprintf(stderr, "ERROR: could not insert video info: %s\n", 00244 sqlite3_errmsg(ldv->db)); 00245 ret = -4; 00246 goto done; 00247 } 00248 00249 ret = 0; 00250 00251 done: 00252 lms_db_reset_stmt(stmt); 00253 00254 return ret; 00255 } 00256 00268 int 00269 lms_db_video_add(lms_db_video_t *ldv, struct lms_video_info *info) 00270 { 00271 if (!ldv) 00272 return -1; 00273 if (!info) 00274 return -2; 00275 if (info->id < 1) 00276 return -3; 00277 00278 return _db_insert(ldv, info); 00279 }