src/lib/lightmediascanner_db_image.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_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 }

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