2 * Copyright (C) 2008-2011 by ProFUSION embedded systems
3 * Copyright (C) 2007 by INdT
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * @author Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
23 #include <lightmediascanner_db.h>
24 #include "lightmediascanner_db_private.h"
25 #include <lightmediascanner_dlna.h>
32 unsigned int _references;
33 unsigned int _is_started:1;
36 static struct lms_db_cache _cache = { };
39 _db_table_updater_images_0(sqlite3 *db, const char *table, unsigned int current_version, int is_last_run) {
45 "CREATE TABLE IF NOT EXISTS images ("
46 "id INTEGER PRIMARY KEY, "
49 "date INTEGER NOT NULL, "
50 "width INTEGER NOT NULL, "
51 "height INTEGER NOT NULL, "
52 "orientation INTEGER NOT NULL, "
53 "gps_lat REAL DEFAULT 0.0, "
54 "gps_long REAL DEFAULT 0.0, "
55 "gps_alt REAL DEFAULT 0.0"
59 fprintf(stderr, "ERROR: could not create 'images' table: %s\n", errmsg);
65 "CREATE INDEX IF NOT EXISTS images_date_idx ON images ("
70 fprintf(stderr, "ERROR: could not create 'images_date_idx' index: %s\n",
76 ret = lms_db_create_trigger_if_not_exists(db,
77 "delete_images_on_files_deleted "
78 "DELETE ON files FOR EACH ROW BEGIN "
79 " DELETE FROM images WHERE id = OLD.id; END;");
83 ret = lms_db_create_trigger_if_not_exists(db,
84 "delete_files_on_images_deleted "
85 "DELETE ON images FOR EACH ROW BEGIN "
86 " DELETE FROM files WHERE id = OLD.id; END;");
93 _db_table_updater_images_1(sqlite3 *db, const char *table, unsigned int current_version, int is_last_run)
99 db, "BEGIN TRANSACTION;"
100 "ALTER TABLE images ADD COLUMN dlna_profile TEXT DEFAULT NULL;"
101 "ALTER TABLE images ADD COLUMN dlna_mime TEXT DEFAULT NULL;"
104 if (ret != SQLITE_OK) {
105 fprintf(stderr, "ERROR: could add columns to images table: %s\n", err);
113 _db_table_updater_images_2(sqlite3 *db, const char *table, unsigned int current_version, int is_last_run)
119 db, "BEGIN TRANSACTION;"
120 "ALTER TABLE images ADD COLUMN container TEXT DEFAULT NULL;"
123 if (ret != SQLITE_OK) {
124 fprintf(stderr, "ERROR: could add columns to images table: %s\n", err);
131 static lms_db_table_updater_t _db_table_updater_images[] = {
132 _db_table_updater_images_0,
133 _db_table_updater_images_1,
134 _db_table_updater_images_2
139 _db_create_table_if_required(sqlite3 *db)
141 return lms_db_table_update_if_required(db, "images",
142 LMS_ARRAY_SIZE(_db_table_updater_images),
143 _db_table_updater_images);
147 * Create image DB access tool.
149 * Creates or get a reference to tools to access 'images' table in an
150 * optimized and easy way.
152 * This is usually called from plugin's @b setup() callback with the @p db
155 * @param db database connection.
157 * @return DB access tool handle.
158 * @ingroup LMS_Plugins
161 lms_db_image_new(sqlite3 *db)
166 if (lms_db_cache_get(&_cache, db, &p) == 0) {
175 if (_db_create_table_if_required(db) != 0) {
176 fprintf(stderr, "ERROR: could not create table.\n");
180 ldi = calloc(1, sizeof(lms_db_image_t));
181 ldi->_references = 1;
184 if (lms_db_cache_add(&_cache, db, ldi) != 0) {
185 lms_db_image_free(ldi);
193 * Start image DB access tool.
195 * Compile SQL statements and other initialization functions.
197 * This is usually called from plugin's @b start() callback.
199 * @param ldi handle returned by lms_db_image_new().
201 * @return On success 0 is returned.
202 * @ingroup LMS_Plugins
205 lms_db_image_start(lms_db_image_t *ldi)
209 if (ldi->_is_started)
212 ldi->insert = lms_db_compile_stmt(ldi->db,
213 "INSERT OR REPLACE INTO images ("
214 "id, title, artist, date, width, height, orientation, "
215 "gps_lat, gps_long, gps_alt, dlna_profile, dlna_mime, container) "
216 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
220 ldi->_is_started = 1;
225 * Free image DB access tool.
227 * Unreference and possible free resources allocated to access tool.
229 * This is usually called from plugin's @b finish() callback.
231 * @param ldi handle returned by lms_db_image_new().
233 * @return On success 0 is returned.
234 * @ingroup LMS_Plugins
237 lms_db_image_free(lms_db_image_t *ldi)
243 if (ldi->_references == 0) {
244 fprintf(stderr, "ERROR: over-called lms_db_image_free(%p)\n", ldi);
249 if (ldi->_references > 0)
253 lms_db_finalize_stmt(ldi->insert, "insert");
255 r = lms_db_cache_del(&_cache, ldi->db, ldi);
262 _db_insert(lms_db_image_t *ldi, const struct lms_image_info *info)
269 ret = lms_db_bind_int64(stmt, 1, info->id);
273 ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len);
277 ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len);
281 ret = lms_db_bind_int(stmt, 4, info->date);
285 ret = lms_db_bind_int(stmt, 5, info->width);
289 ret = lms_db_bind_int(stmt, 6, info->height);
293 ret = lms_db_bind_int(stmt, 7, info->orientation);
297 ret = lms_db_bind_double(stmt, 8, info->gps.latitude);
301 ret = lms_db_bind_double(stmt, 9, info->gps.longitude);
305 ret = lms_db_bind_double(stmt, 10, info->gps.altitude);
309 ret = lms_db_bind_text(stmt, 11, info->dlna_profile.str,
310 info->dlna_profile.len);
314 ret = lms_db_bind_text(stmt, 12, info->dlna_mime.str, info->dlna_mime.len);
318 ret = lms_db_bind_text(stmt, 13, info->container.str, info->container.len);
322 r = sqlite3_step(stmt);
323 if (r != SQLITE_DONE) {
324 fprintf(stderr, "ERROR: could not insert image info: %s\n",
325 sqlite3_errmsg(ldi->db));
333 lms_db_reset_stmt(stmt);
339 * Add image file to DB.
341 * This is usually called from plugin's @b parse() callback.
343 * @param ldi handle returned by lms_db_image_new().
344 * @param info image information to store.
346 * @return On success 0 is returned.
347 * @ingroup LMS_Plugins
350 lms_db_image_add(lms_db_image_t *ldi, struct lms_image_info *info)
352 const struct lms_dlna_image_profile *dlna;
361 if (info->dlna_mime.len == 0 && info->dlna_profile.len == 0) {
362 dlna = lms_dlna_get_image_profile(info);
364 info->dlna_mime = *dlna->dlna_mime;
365 info->dlna_profile = *dlna->dlna_profile;
369 return _db_insert(ldi, info);