00001 #include <lightmediascanner_db.h> 00002 #include "lightmediascanner_db_private.h" 00003 #include <stdlib.h> 00004 #include <stdio.h> 00005 00006 struct lms_db_image { 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_images_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 images (" 00023 "id INTEGER PRIMARY KEY, " 00024 "title TEXT, " 00025 "artist TEXT, " 00026 "date INTEGER NOT NULL, " 00027 "width INTEGER NOT NULL, " 00028 "height INTEGER NOT NULL, " 00029 "orientation INTEGER NOT NULL, " 00030 "gps_lat REAL DEFAULT 0.0, " 00031 "gps_long REAL DEFAULT 0.0, " 00032 "gps_alt REAL DEFAULT 0.0" 00033 ")", 00034 NULL, NULL, &errmsg); 00035 if (r != SQLITE_OK) { 00036 fprintf(stderr, "ERROR: could not create 'images' table: %s\n", errmsg); 00037 sqlite3_free(errmsg); 00038 return -1; 00039 } 00040 00041 r = sqlite3_exec(db, 00042 "CREATE INDEX IF NOT EXISTS images_date_idx ON images (" 00043 "date" 00044 ")", 00045 NULL, NULL, &errmsg); 00046 if (r != SQLITE_OK) { 00047 fprintf(stderr, "ERROR: could not create 'images_date_idx' index: %s\n", 00048 errmsg); 00049 sqlite3_free(errmsg); 00050 return -2; 00051 } 00052 00053 ret = lms_db_create_trigger_if_not_exists(db, 00054 "delete_images_on_files_deleted " 00055 "DELETE ON files FOR EACH ROW BEGIN " 00056 " DELETE FROM images WHERE id = OLD.id; END;"); 00057 if (ret != 0) 00058 goto done; 00059 00060 ret = lms_db_create_trigger_if_not_exists(db, 00061 "delete_files_on_images_deleted " 00062 "DELETE ON images FOR EACH ROW BEGIN " 00063 " DELETE FROM files WHERE id = OLD.id; END;"); 00064 00065 done: 00066 return ret; 00067 } 00068 00069 static lms_db_table_updater_t _db_table_updater_images[] = { 00070 _db_table_updater_images_0 00071 }; 00072 00073 00074 static int 00075 _db_create_table_if_required(sqlite3 *db) 00076 { 00077 return lms_db_table_update_if_required(db, "images", 00078 LMS_ARRAY_SIZE(_db_table_updater_images), 00079 _db_table_updater_images); 00080 } 00081 00096 lms_db_image_t * 00097 lms_db_image_new(sqlite3 *db) 00098 { 00099 lms_db_image_t *ldi; 00100 void *p; 00101 00102 if (lms_db_cache_get(&_cache, db, &p) == 0) { 00103 ldi = p; 00104 ldi->_references++; 00105 return ldi; 00106 } 00107 00108 if (!db) 00109 return NULL; 00110 00111 if (_db_create_table_if_required(db) != 0) { 00112 fprintf(stderr, "ERROR: could not create table.\n"); 00113 return NULL; 00114 } 00115 00116 ldi = calloc(1, sizeof(lms_db_image_t)); 00117 ldi->_references = 1; 00118 ldi->db = db; 00119 00120 if (lms_db_cache_add(&_cache, db, ldi) != 0) { 00121 lms_db_image_free(ldi); 00122 return NULL; 00123 } 00124 00125 return ldi; 00126 } 00127 00140 int 00141 lms_db_image_start(lms_db_image_t *ldi) 00142 { 00143 if (!ldi) 00144 return -1; 00145 if (ldi->_is_started) 00146 return 0; 00147 00148 ldi->insert = lms_db_compile_stmt(ldi->db, 00149 "INSERT OR REPLACE INTO images (" 00150 "id, title, artist, date, width, height, orientation, " 00151 "gps_lat, gps_long, gps_alt) VALUES (" 00152 "?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); 00153 if (!ldi->insert) 00154 return -2; 00155 00156 ldi->_is_started = 1; 00157 return 0; 00158 } 00159 00172 int 00173 lms_db_image_free(lms_db_image_t *ldi) 00174 { 00175 int r; 00176 00177 if (!ldi) 00178 return -1; 00179 if (ldi->_references == 0) { 00180 fprintf(stderr, "ERROR: over-called lms_db_image_free(%p)\n", ldi); 00181 return -1; 00182 } 00183 00184 ldi->_references--; 00185 if (ldi->_references > 0) 00186 return 0; 00187 00188 if (ldi->insert) 00189 lms_db_finalize_stmt(ldi->insert, "insert"); 00190 00191 r = lms_db_cache_del(&_cache, ldi->db, ldi); 00192 free(ldi); 00193 00194 return r; 00195 } 00196 00197 static int 00198 _db_insert(lms_db_image_t *ldi, const struct lms_image_info *info) 00199 { 00200 sqlite3_stmt *stmt; 00201 int r, ret; 00202 00203 stmt = ldi->insert; 00204 00205 ret = lms_db_bind_int64(stmt, 1, info->id); 00206 if (ret != 0) 00207 goto done; 00208 00209 ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len); 00210 if (ret != 0) 00211 goto done; 00212 00213 ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len); 00214 if (ret != 0) 00215 goto done; 00216 00217 ret = lms_db_bind_int(stmt, 4, info->date); 00218 if (ret != 0) 00219 goto done; 00220 00221 ret = lms_db_bind_int(stmt, 5, info->width); 00222 if (ret != 0) 00223 goto done; 00224 00225 ret = lms_db_bind_int(stmt, 6, info->height); 00226 if (ret != 0) 00227 goto done; 00228 00229 ret = lms_db_bind_int(stmt, 7, info->orientation); 00230 if (ret != 0) 00231 goto done; 00232 00233 ret = lms_db_bind_double(stmt, 8, info->gps.latitude); 00234 if (ret != 0) 00235 goto done; 00236 00237 ret = lms_db_bind_double(stmt, 9, info->gps.longitude); 00238 if (ret != 0) 00239 goto done; 00240 00241 ret = lms_db_bind_double(stmt, 10, info->gps.altitude); 00242 if (ret != 0) 00243 goto done; 00244 00245 r = sqlite3_step(stmt); 00246 if (r != SQLITE_DONE) { 00247 fprintf(stderr, "ERROR: could not insert image info: %s\n", 00248 sqlite3_errmsg(ldi->db)); 00249 ret = -11; 00250 goto done; 00251 } 00252 00253 ret = 0; 00254 00255 done: 00256 lms_db_reset_stmt(stmt); 00257 00258 return ret; 00259 } 00260 00272 int 00273 lms_db_image_add(lms_db_image_t *ldi, struct lms_image_info *info) 00274 { 00275 if (!ldi) 00276 return -1; 00277 if (!info) 00278 return -2; 00279 if (info->id < 1) 00280 return -3; 00281 00282 return _db_insert(ldi, info); 00283 }