Split out db utilities from core and add image db functions.
authorGustavo Sverzut Barbieri <barbieri@gmail.com>
Mon, 19 Nov 2007 23:09:20 +0000 (20:09 -0300)
committerGustavo Sverzut Barbieri <barbieri@gmail.com>
Tue, 20 Nov 2007 00:35:38 +0000 (21:35 -0300)
Refactor lightmediascanner.c, move utilities to
lightmediascanner_db_common, add lightmediascanner_db_image with
functions to be used by image parsers.

src/lib/Makefile.am
src/lib/lightmediascanner.c
src/lib/lightmediascanner_db.h [new file with mode: 0644]
src/lib/lightmediascanner_db_common.c [new file with mode: 0644]
src/lib/lightmediascanner_db_image.c [new file with mode: 0644]
src/lib/lightmediascanner_db_private.h [new file with mode: 0644]

index 4ca6845..def33ab 100644 (file)
@@ -5,12 +5,17 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib
 include_HEADERS = \
        lightmediascanner.h \
        lightmediascanner_plugin.h \
-       lightmediascanner_utils.h
+       lightmediascanner_utils.h \
+       lightmediascanner_db.h
+noinst_HEADERS = lightmediascanner_db_private.h
 
 lib_LTLIBRARIES = liblightmediascanner.la
 
 liblightmediascanner_la_SOURCES = \
        lightmediascanner.c \
-       lightmediascanner_utils.c
+       lightmediascanner_utils.c \
+       lightmediascanner_db_common.c \
+       lightmediascanner_db_image.c
+
 liblightmediascanner_la_LIBADD = -ldl @SQLITE3_LIBS@
 liblightmediascanner_la_LDFLAGS = -version-info @version_info@
index 32f1eeb..fc7cad3 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "lightmediascanner.h"
 #include "lightmediascanner_plugin.h"
+#include "lightmediascanner_db_private.h"
 
 #define PATH_SIZE PATH_MAX
 #define DEFAULT_SLAVE_TIMEOUT 1000
@@ -224,47 +225,35 @@ _db_create_tables_if_required(sqlite3 *db)
     return 0;
 }
 
-static sqlite3_stmt *
-_db_compile_stmt(sqlite3 *db, const char *sql)
-{
-    sqlite3_stmt *stmt;
-
-    if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
-        fprintf(stderr, "ERROR: could not prepare \"%s\": %s\n", sql,
-                sqlite3_errmsg(db));
-
-    return stmt;
-}
-
 static int
 _db_compile_all_stmts(struct db *db)
 {
-    db->transaction_begin = _db_compile_stmt(db->handle,
+    db->transaction_begin = lms_db_compile_stmt(db->handle,
         "BEGIN TRANSACTION");
     if (!db->transaction_begin)
         return -1;
 
-    db->transaction_commit = _db_compile_stmt(db->handle,
+    db->transaction_commit = lms_db_compile_stmt(db->handle,
         "COMMIT");
     if (!db->transaction_commit)
         return -2;
 
-    db->transaction_rollback = _db_compile_stmt(db->handle,
+    db->transaction_rollback = lms_db_compile_stmt(db->handle,
         "ROLLBACK");
     if (!db->transaction_rollback)
         return -3;
 
-    db->get_file_info = _db_compile_stmt(db->handle,
+    db->get_file_info = lms_db_compile_stmt(db->handle,
         "SELECT id, mtime, valid FROM files WHERE path = ?");
     if (!db->get_file_info)
         return -4;
 
-    db->insert_file_info = _db_compile_stmt(db->handle,
+    db->insert_file_info = lms_db_compile_stmt(db->handle,
         "INSERT INTO files (path, mtime, valid) VALUES(?, ?, ?)");
     if (!db->insert_file_info)
         return -5;
 
-    db->update_file_info = _db_compile_stmt(db->handle,
+    db->update_file_info = lms_db_compile_stmt(db->handle,
         "UPDATE files SET mtime = ?, valid = ? WHERE id = ?");
     if (!db->update_file_info)
         return -6;
@@ -308,40 +297,25 @@ _db_open(const char *db_path)
 }
 
 static int
-_db_finalize_stmt(sqlite3_stmt *stmt, const char *name)
-{
-    int r;
-
-    r = sqlite3_finalize(stmt);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not finalize %s statement: #%d\n",
-                name, r);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int
 _db_close(struct db *db)
 {
     if (db->transaction_begin)
-        _db_finalize_stmt(db->transaction_begin, "transaction_begin");
+        lms_db_finalize_stmt(db->transaction_begin, "transaction_begin");
 
     if (db->transaction_commit)
-        _db_finalize_stmt(db->transaction_commit, "transaction_commit");
+        lms_db_finalize_stmt(db->transaction_commit, "transaction_commit");
 
     if (db->transaction_rollback)
-        _db_finalize_stmt(db->transaction_rollback, "transaction_rollback");
+        lms_db_finalize_stmt(db->transaction_rollback, "transaction_rollback");
 
     if (db->get_file_info)
-        _db_finalize_stmt(db->get_file_info, "get_file_info");
+        lms_db_finalize_stmt(db->get_file_info, "get_file_info");
 
     if (db->insert_file_info)
-        _db_finalize_stmt(db->insert_file_info, "insert_file_info");
+        lms_db_finalize_stmt(db->insert_file_info, "insert_file_info");
 
     if (db->update_file_info)
-        _db_finalize_stmt(db->update_file_info, "update_file_info");
+        lms_db_finalize_stmt(db->update_file_info, "update_file_info");
 
     if (sqlite3_close(db->handle) != SQLITE_OK) {
         fprintf(stderr, "ERROR: clould not close DB: %s\n",
@@ -402,23 +376,6 @@ _db_end_transaction(struct db *db)
 }
 
 static int
-_db_reset_stmt(sqlite3_stmt *stmt)
-{
-    int r, ret;
-
-    ret = r = sqlite3_reset(stmt);
-    if (r != SQLITE_OK)
-        fprintf(stderr, "ERROR: could not reset SQL statement: #%d\n", r);
-
-    r = sqlite3_clear_bindings(stmt);
-    ret += r;
-    if (r != SQLITE_OK)
-        fprintf(stderr, "ERROR: could not clear SQL: #%d\n", r);
-
-    return ret;
-}
-
-static int
 _db_get_file_info(struct db *db, struct lms_file_info *finfo)
 {
     sqlite3_stmt *stmt;
@@ -426,13 +383,9 @@ _db_get_file_info(struct db *db, struct lms_file_info *finfo)
 
     stmt = db->get_file_info;
 
-    r = sqlite3_bind_text(stmt, 1, finfo->path, finfo->path_len, SQLITE_STATIC);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 1: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -1;
+    ret = lms_db_bind_text(stmt, 1, finfo->path, finfo->path_len);
+    if (ret != 0)
         goto done;
-    }
 
     r = sqlite3_step(stmt);
     if (r == SQLITE_DONE) {
@@ -454,7 +407,7 @@ _db_get_file_info(struct db *db, struct lms_file_info *finfo)
     ret = 0;
 
   done:
-    _db_reset_stmt(stmt);
+    lms_db_reset_stmt(stmt);
 
     return ret;
 }
@@ -467,29 +420,17 @@ _db_update_file_info(struct db *db, struct lms_file_info *finfo)
 
     stmt = db->update_file_info;
 
-    r = sqlite3_bind_int(stmt, 1, finfo->mtime);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 1: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -1;
+    ret = lms_db_bind_int(stmt, 1, finfo->mtime);
+    if (ret != 0)
         goto done;
-    }
 
-    r = sqlite3_bind_int(stmt, 2, finfo->is_valid);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 2: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -2;
+    ret = lms_db_bind_int(stmt, 2, finfo->is_valid);
+    if (ret != 0)
         goto done;
-    }
 
-    r = sqlite3_bind_int64(stmt, 3, finfo->id);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 3: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -3;
+    ret = lms_db_bind_int(stmt, 3, finfo->id);
+    if (ret != 0)
         goto done;
-    }
 
     r = sqlite3_step(stmt);
     if (r != SQLITE_DONE) {
@@ -502,7 +443,7 @@ _db_update_file_info(struct db *db, struct lms_file_info *finfo)
     ret = 0;
 
   done:
-    _db_reset_stmt(stmt);
+    lms_db_reset_stmt(stmt);
 
     return ret;
 }
@@ -515,29 +456,17 @@ _db_insert_file_info(struct db *db, struct lms_file_info *finfo)
 
     stmt = db->insert_file_info;
 
-    r = sqlite3_bind_text(stmt, 1, finfo->path, finfo->path_len, SQLITE_STATIC);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 1: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -1;
+    ret = lms_db_bind_text(stmt, 1, finfo->path, finfo->path_len);
+    if (ret != 0)
         goto done;
-    }
 
-    r = sqlite3_bind_int(stmt, 2, finfo->mtime);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 2: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -2;
+    ret = lms_db_bind_int(stmt, 2, finfo->mtime);
+    if (ret != 0)
         goto done;
-    }
 
-    r = sqlite3_bind_int(stmt, 3, finfo->is_valid);
-    if (r != SQLITE_OK) {
-        fprintf(stderr, "ERROR: could not bind SQL value 3: %s\n",
-                sqlite3_errmsg(db->handle));
-        ret = -3;
+    ret = lms_db_bind_int(stmt, 3, finfo->is_valid);
+    if (ret != 0)
         goto done;
-    }
 
     r = sqlite3_step(stmt);
     if (r != SQLITE_DONE) {
@@ -551,7 +480,7 @@ _db_insert_file_info(struct db *db, struct lms_file_info *finfo)
     ret = 0;
 
   done:
-    _db_reset_stmt(stmt);
+    lms_db_reset_stmt(stmt);
 
     return ret;
 }
diff --git a/src/lib/lightmediascanner_db.h b/src/lib/lightmediascanner_db.h
new file mode 100644 (file)
index 0000000..6b99d74
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2007 by INdT
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * @author Gustavo Sverzut Barbieri <gustavo.barbieri@openbossa.org>
+ */
+
+#ifndef _LIGHTMEDIASCANNER_DB_H_
+#define _LIGHTMEDIASCANNER_DB_H_ 1
+
+#ifdef API
+#undef API
+#endif
+
+#ifdef __GNUC__
+# if __GNUC__ >= 4
+#  define API __attribute__ ((visibility("default")))
+# else
+#  define API
+# endif
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#  define GNUC_NON_NULL(...) __attribute__((nonnull(__VA_ARGS__)))
+# else
+#  define GNUC_NON_NULL(...)
+# endif
+#else
+#  define API
+#  define GNUC_NON_NULL(...)
+#endif
+
+#include <lightmediascanner_plugin.h>
+#include <lightmediascanner_utils.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /* Image Records */
+    struct lms_gps_info {
+        double latitude;
+        double longitude;
+        double altitude;
+    };
+
+    struct lms_image_info {
+        int64_t id;
+        struct lms_string_size title;
+        struct lms_string_size artist;
+        unsigned int date;
+        unsigned short width;
+        unsigned short height;
+        unsigned short orientation;
+        struct lms_gps_info gps;
+    };
+
+    typedef struct lms_db_image lms_db_image_t;
+
+    API lms_db_image_t *lms_db_image_new(sqlite3 *db) GNUC_NON_NULL(1);
+    API int lms_db_image_free(lms_db_image_t *lms_db_image) GNUC_NON_NULL(1);
+    API int lms_db_image_add(lms_db_image_t *lms_db_image, struct lms_image_info *info) GNUC_NON_NULL(1, 2);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _LIGHTMEDIASCANNER_DB_H_ */
diff --git a/src/lib/lightmediascanner_db_common.c b/src/lib/lightmediascanner_db_common.c
new file mode 100644 (file)
index 0000000..2fd9d7f
--- /dev/null
@@ -0,0 +1,127 @@
+#include "lightmediascanner_db_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+sqlite3_stmt *
+lms_db_compile_stmt(sqlite3 *db, const char *sql)
+{
+    sqlite3_stmt *stmt;
+
+    if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK)
+        fprintf(stderr, "ERROR: could not prepare \"%s\": %s\n", sql,
+                sqlite3_errmsg(db));
+
+    return stmt;
+}
+
+int
+lms_db_finalize_stmt(sqlite3_stmt *stmt, const char *name)
+{
+    int r;
+
+    r = sqlite3_finalize(stmt);
+    if (r != SQLITE_OK) {
+        fprintf(stderr, "ERROR: could not finalize %s statement: #%d\n",
+                name, r);
+        return -1;
+    }
+
+    return 0;
+}
+
+int
+lms_db_reset_stmt(sqlite3_stmt *stmt)
+{
+    int r, ret;
+
+    ret = r = sqlite3_reset(stmt);
+    if (r != SQLITE_OK)
+        fprintf(stderr, "ERROR: could not reset SQL statement: #%d\n", r);
+
+    r = sqlite3_clear_bindings(stmt);
+    ret += r;
+    if (r != SQLITE_OK)
+        fprintf(stderr, "ERROR: could not clear SQL: #%d\n", r);
+
+    return ret;
+}
+
+int
+lms_db_bind_text(sqlite3_stmt *stmt, int col, const char *text, int len)
+{
+    int r;
+
+    if (text)
+        r = sqlite3_bind_text(stmt, col, text, len, SQLITE_STATIC);
+    else
+        r = sqlite3_bind_null(stmt, col);
+
+    if (r == SQLITE_OK)
+        return 0;
+    else {
+        sqlite3 *db;
+        const char *err;
+
+        db = sqlite3_db_handle(stmt);
+        err = sqlite3_errmsg(db);
+        fprintf(stderr, "ERROR: could not bind SQL value %d: %s\n", col, err);
+        return -col;
+    }
+}
+
+int
+lms_db_bind_int64(sqlite3_stmt *stmt, int col, int64_t value)
+{
+    int r;
+
+    r = sqlite3_bind_int64(stmt, col, value);
+    if (r == SQLITE_OK)
+        return 0;
+    else {
+        sqlite3 *db;
+        const char *err;
+
+        db = sqlite3_db_handle(stmt);
+        err = sqlite3_errmsg(db);
+        fprintf(stderr, "ERROR: could not bind SQL value %d: %s\n", col, err);
+        return -col;
+    }
+}
+
+int
+lms_db_bind_int(sqlite3_stmt *stmt, int col, int value)
+{
+    int r;
+
+    r = sqlite3_bind_int(stmt, col, value);
+    if (r == SQLITE_OK)
+        return 0;
+    else {
+        sqlite3 *db;
+        const char *err;
+
+        db = sqlite3_db_handle(stmt);
+        err = sqlite3_errmsg(db);
+        fprintf(stderr, "ERROR: could not bind SQL value %d: %s\n", col, err);
+        return -col;
+    }
+}
+
+int
+lms_db_bind_double(sqlite3_stmt *stmt, int col, double value)
+{
+    int r;
+
+    r = sqlite3_bind_double(stmt, col, value);
+    if (r == SQLITE_OK)
+        return 0;
+    else {
+        sqlite3 *db;
+        const char *err;
+
+        db = sqlite3_db_handle(stmt);
+        err = sqlite3_errmsg(db);
+        fprintf(stderr, "ERROR: could not bind SQL value %d: %s\n", col, err);
+        return -col;
+    }
+}
diff --git a/src/lib/lightmediascanner_db_image.c b/src/lib/lightmediascanner_db_image.c
new file mode 100644 (file)
index 0000000..0817382
--- /dev/null
@@ -0,0 +1,252 @@
+#include <lightmediascanner_db.h>
+#include "lightmediascanner_db_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+struct lms_db_image {
+    sqlite3 *db;
+    sqlite3_stmt *insert;
+    int _references;
+};
+
+lms_db_image_t *_singleton = NULL;
+
+static int
+_db_create_table_if_required(sqlite3 *db)
+{
+    char *errmsg;
+    int r;
+
+    errmsg = NULL;
+    r = sqlite3_exec(db,
+                     "CREATE TABLE IF NOT EXISTS images ("
+                     "id INTEGER PRIMARY KEY, "
+                     "title TEXT, "
+                     "artist TEXT, "
+                     "date INTEGER NOT NULL, "
+                     "width INTEGER NOT NULL, "
+                     "height INTEGER NOT NULL, "
+                     "orientation INTEGER NOT NULL, "
+                     "thumb_width INTEGER NOT NULL, "
+                     "thumb_height INTEGER NOT NULL, "
+                     "gps_lat REAL DEFAULT 0.0, "
+                     "gps_long REAL DEFAULT 0.0, "
+                     "gps_alt REAL DEFAULT 0.0"
+                     ")",
+                     NULL, NULL, &errmsg);
+    if (r != SQLITE_OK) {
+        fprintf(stderr, "ERROR: could not create 'images' table: %s\n", errmsg);
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    r = sqlite3_exec(db,
+                     "CREATE INDEX IF NOT EXISTS images_date_idx ON images ("
+                     "date"
+                     ")",
+                     NULL, NULL, &errmsg);
+    if (r != SQLITE_OK) {
+        fprintf(stderr, "ERROR: could not create 'images_date_idx' index: %s\n",
+                errmsg);
+        sqlite3_free(errmsg);
+        return -2;
+    }
+
+    r = sqlite3_exec(db,
+                     "CREATE TRIGGER IF NOT EXISTS"
+                     "   delete_images_on_files_deleted "
+                     "DELETE ON files "
+                     "FOR EACH ROW BEGIN "
+                     "   DELETE FROM images WHERE id = OLD.id;"
+                     "END;",
+                     NULL, NULL, &errmsg);
+    if (r != SQLITE_OK) {
+        fprintf(stderr, "ERROR: could not create trigger to delete images on "
+                "files deletion: %s\n",
+                errmsg);
+        sqlite3_free(errmsg);
+        return -2;
+    }
+
+    r = sqlite3_exec(db,
+                     "CREATE TRIGGER IF NOT EXISTS"
+                     "   delete_files_on_images_deleted "
+                     "DELETE ON images "
+                     "FOR EACH ROW BEGIN "
+                     "   DELETE FROM files WHERE id = OLD.id;"
+                     "END;",
+                     NULL, NULL, &errmsg);
+    if (r != SQLITE_OK) {
+        fprintf(stderr, "ERROR: could not create trigger to delete files on "
+                "images deletion: %s\n",
+                errmsg);
+        sqlite3_free(errmsg);
+        return -2;
+    }
+
+    return 0;
+}
+
+static int
+_db_compile_all_stmts(lms_db_image_t *ldi)
+{
+    ldi->insert = lms_db_compile_stmt(ldi->db,
+        "INSERT OR REPLACE INTO images ("
+        "id, title, artist, date, width, height, orientation, "
+        "thumb_width, thumb_height, gps_lat, gps_long, gps_alt) VALUES ("
+        "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+    if (!ldi->insert)
+        return -1;
+
+    return 0;
+}
+
+lms_db_image_t *
+lms_db_image_new(sqlite3 *db)
+{
+    lms_db_image_t *ldi;
+
+    if (_singleton) {
+        _singleton->_references++;
+        return _singleton;
+    }
+
+    if (!db)
+        return NULL;
+
+    if (_db_create_table_if_required(db) != 0) {
+        fprintf(stderr, "ERROR: could not create table.\n");
+        return NULL;
+    }
+
+    ldi = calloc(1, sizeof(lms_db_image_t));
+    ldi->_references = 1;
+    ldi->db = db;
+
+    if (_db_compile_all_stmts(ldi) != 0) {
+        fprintf(stderr, "ERROR: could not compile image statements.\n");
+        lms_db_image_free(ldi);
+        return NULL;
+    }
+
+    return ldi;
+}
+
+int
+lms_db_image_free(lms_db_image_t *ldi)
+{
+    if (!ldi)
+        return -1;
+
+    ldi->_references--;
+    if (ldi->_references > 0)
+        return 0;
+
+    if (ldi->insert)
+        lms_db_finalize_stmt(ldi->insert, "insert");
+
+    free(ldi);
+    _singleton = NULL;
+
+    return 0;
+}
+
+int
+_db_insert(lms_db_image_t *ldi, const struct lms_image_info *info)
+{
+    sqlite3_stmt *stmt;
+    int r, ret;
+    unsigned long tw, th;
+
+    if (info->height < info->width) {
+        tw = 128;
+        th = (info->height * 128) / info->width;
+        if (th == 0)
+            th = 1;
+    } else if (info->height == info->width)
+        tw = th = 128;
+    else {
+        th = 128;
+        tw = (info->width * 128) / info->height;
+        if (tw == 0)
+            tw = 1;
+    }
+
+    stmt = ldi->insert;
+
+    ret = lms_db_bind_int64(stmt, 1, info->id);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 4, info->date);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 5, info->width);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 6, info->height);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 7, info->orientation);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 8, tw);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_int(stmt, 9, th);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_double(stmt, 10, info->gps.latitude);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_double(stmt, 11, info->gps.longitude);
+    if (ret != 0)
+        goto done;
+
+    ret = lms_db_bind_double(stmt, 12, info->gps.altitude);
+    if (ret != 0)
+        goto done;
+
+    r = sqlite3_step(stmt);
+    if (r != SQLITE_DONE) {
+        fprintf(stderr, "ERROR: could not insert image info: %s\n",
+                sqlite3_errmsg(ldi->db));
+        ret = -13;
+        goto done;
+    }
+
+    ret = 0;
+
+  done:
+    lms_db_reset_stmt(stmt);
+
+    return ret;
+}
+
+int
+lms_db_image_add(lms_db_image_t *ldi, struct lms_image_info *info)
+{
+    if (!ldi)
+        return -1;
+    if (!info)
+        return -2;
+    if (info->id < 1)
+        return -3;
+
+    return _db_insert(ldi, info);
+}
diff --git a/src/lib/lightmediascanner_db_private.h b/src/lib/lightmediascanner_db_private.h
new file mode 100644 (file)
index 0000000..534b704
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2007 by INdT
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * @author Gustavo Sverzut Barbieri <gustavo.barbieri@openbossa.org>
+ */
+
+#ifndef _LIGHTMEDIASCANNER_DB_PRIVATE_H_
+#define _LIGHTMEDIASCANNER_DB_PRIVATE_H_ 1
+
+#ifdef API
+#undef API
+#endif
+
+#ifdef __GNUC__
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#  define GNUC_NON_NULL(...) __attribute__((nonnull(__VA_ARGS__)))
+# else
+#  define GNUC_NON_NULL(...)
+# endif
+#else
+#  define GNUC_NON_NULL(...)
+#endif
+
+#include <sqlite3.h>
+#include <sys/types.h>
+
+sqlite3_stmt *lms_db_compile_stmt(sqlite3 *db, const char *sql) GNUC_NON_NULL(1, 2);
+int lms_db_finalize_stmt(sqlite3_stmt *stmt, const char *name) GNUC_NON_NULL(1, 2);
+int lms_db_reset_stmt(sqlite3_stmt *stmt) GNUC_NON_NULL(1);
+int lms_db_bind_text(sqlite3_stmt *stmt, int col, const char *text, int len) GNUC_NON_NULL(1);
+int lms_db_bind_int64(sqlite3_stmt *stmt, int col, int64_t value) GNUC_NON_NULL(1);
+int lms_db_bind_int(sqlite3_stmt *stmt, int col, int value) GNUC_NON_NULL(1);
+int lms_db_bind_double(sqlite3_stmt *stmt, int col, double value) GNUC_NON_NULL(1);
+
+#endif /* _LIGHTMEDIASCANNER_DB_PRIVATE_H_ */