[rygel] core: Add basic media database class



commit 90008b8b917620152113f9222c1bda50e646335f
Author: Jens Georg <mail jensge org>
Date:   Mon May 25 22:01:56 2009 +0200

    core: Add basic media database class

 configure.ac                  |    6 ++
 src/rygel/Makefile.am         |   12 ++-
 src/rygel/rygel-media-db.vala |  146 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 160 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 32d5bfa..0f1cb18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,7 @@ GEE_REQUIRED=0.1.5
 UUID_REQUIRED=1.41.3
 LIBSOUP_REQUIRED=2.26.0
 GTK_REQUIRED=2.16
+LIBSQLITE3_REQUIRED=3.5
 
 PKG_CHECK_MODULES(LIBGUPNP, gupnp-1.0 >= $GUPNP_REQUIRED)
 PKG_CHECK_MODULES(LIBGUPNP_AV, gupnp-av-1.0 >= $GUPNP_AV_REQUIRED)
@@ -40,6 +41,7 @@ PKG_CHECK_MODULES(LIBGIO, gio-2.0 >= $GIO_REQUIRED)
 PKG_CHECK_MODULES(GEE, gee-1.0 >= $GEE_REQUIRED)
 PKG_CHECK_MODULES(UUID, uuid >= $UUID_REQUIRED)
 PKG_CHECK_MODULES(LIBSOUP, libsoup-2.4 >= $LIBSOUP_REQUIRED)
+PKG_CHECK_MODULES(LIBSQLITE3, sqlite3 >= $LIBSQLITE3_REQUIRED)
 
 AC_PATH_PROG(GCONFTOOL, gconftool-2)
 AM_GCONF_SOURCE_2
@@ -98,6 +100,10 @@ if test x$enable_vala = xyes ; then
     AC_CHECK_FILE("${VAPIDIR}/gee-1.0.vapi",
                   true,
                   [AC_MSG_ERROR("Unable to find Vala bindings for gee-1.0")])
+
+    AC_CHECK_FILE("${VAPIDIR}/sqlite3.vapi",
+                  true,
+                  [AC_MSG_ERROR("Unable to find Vala bindings for sqlite3")])
 else
     VAPIDIR=`echo ${datadir}/vala/vapi`
 fi
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 6819082..c416e09 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -21,6 +21,7 @@ AM_CFLAGS = $(LIBGUPNP_CFLAGS) \
 	    $(UUID_CFLAGS) \
 	    $(LIBSOUP_CFLAGS) \
 	    $(LIBDBUS_GLIB_CFLAGS) \
+	    $(LIBSQLITE3_CFLAGS) \
 	    -I$(top_srcdir) -DDATA_DIR='"$(shareddir)"' \
 	    -DPLUGIN_DIR='"$(plugindir)"' -DDESKTOP_DIR='"$(desktopdir)"'\
 	    -include config.h
@@ -61,8 +62,8 @@ BUILT_SOURCES = rygel-1.0.vapi \
 		rygel-media-container.c \
 		rygel-simple-async-result.c \
 		rygel-media-item.c \
-		rygel-transcoder.c \
 		rygel-metadata-extractor.c \
+		rygel-media-db.c \
 		rygel-mp2ts-transcoder.c \
 		rygel-mp3-transcoder.c \
 		rygel-l16-transcoder.c \
@@ -116,7 +117,8 @@ rygel_SOURCES = $(VAPI_SOURCE_FILES) \
 rygel.stamp: $(filter %.vala,$(rygel_SOURCES))
 	$(VALAC) -C --vapidir=$(srcdir) --thread \
 	--pkg cstuff --pkg gupnp-1.0 --pkg gupnp-av-1.0 --pkg dbus-glib-1 \
-	--pkg gconf-2.0 --pkg gstreamer-0.10 --pkg gio-2.0 --pkg gee-1.0 $^
+	--pkg gconf-2.0 --pkg gstreamer-0.10 --pkg gio-2.0 --pkg gee-1.0 \
+	--pkg sqlite3 $^
 	touch $@
 
 rygel_LDADD = $(LIBGUPNP_LIBS) \
@@ -128,6 +130,7 @@ rygel_LDADD = $(LIBGUPNP_LIBS) \
 	      $(UUID_LIBS) \
 	      $(LIBSOUP_LIBS) \
 	      $(LIBDBUS_GLIB_LIBS) \
+	      $(LIBSQLITE3_LIBS) \
 	      librygel-configuration.a
 rygel_LDFLAGS = -export-dynamic
 
@@ -165,12 +168,13 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-mp2ts-transcoder-bin.vala \
 		    rygel-mp3-transcoder-bin.vala \
 		    rygel-l16-transcoder-bin.vala \
-		    rygel-gst-utils.vala
+		    rygel-gst-utils.vala \
+		    rygel-media-db.vala
 
 rygel-1.0.vapi: $(VAPI_SOURCE_FILES)
 	$(VALAC) -H rygel.h -C --library=rygel-1.0 --vapidir=$(srcdir) \
 	--pkg cstuff --pkg gupnp-1.0 --pkg gupnp-av-1.0 --pkg gconf-2.0 \
-	--pkg gee-1.0 --pkg gstreamer-0.10 --pkg dbus-glib-1 \
+	--pkg gee-1.0 --pkg gstreamer-0.10 --pkg sqlite3 --pkg dbus-glib-1 \
 	$(VAPI_SOURCE_FILES)
 
 noinst_LIBRARIES = librygel-configuration.a
diff --git a/src/rygel/rygel-media-db.vala b/src/rygel/rygel-media-db.vala
new file mode 100644
index 0000000..e9271b9
--- /dev/null
+++ b/src/rygel/rygel-media-db.vala
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2009 Jens Georg <mail jensge org>.
+ *
+ * Author: Jens Georg <mail jensge org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU 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 General Public License along
+ * with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+using Gee;
+using Sqlite;
+
+public class Rygel.MediaDB : Object {
+    private Database db;
+    private const string schema_version = "1";
+    private const string db_schema_v1 =
+    "BEGIN;" +
+    "CREATE TABLE Schema_Info (version TEXT NOT NULL); " +
+    "CREATE TABLE Object_Type (id INTEGER PRIMARY KEY, " +
+                              "desc TEXT NOT NULL);" +
+    "CREATE TABLE Meta_Data (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
+                            "size INTEGER NOT NULL, " +
+                            "mime_type TEXT NOT NULL, " +
+                            "width INTEGER, " +
+                            "height INTEGER, " +
+                            "class TEXT NOT NULL, " +
+                            "title TEXT NOT NULL, " +
+                            "author TEXT, " +
+                            "album TEXT, " +
+                            "date TEXT, " +
+                            "bitrate INTEGER, " +
+                            "sample_freq INTEGER, " +
+                            "bits_per_sample INTEGER, " +
+                            "channels INTEGER, " +
+                            "track, " +
+                            "color_depth);" +
+    "CREATE TABLE Object (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
+                         "upnp_id TEXT UNIQUE, " +
+                         "type_fk INTEGER REFERENCES Object_Type(id), " +
+                         "metadata_fk INTEGER REFERENCES Meta_Data(id) " +
+                         "ON DELETE CASCADE);" +
+    "CREATE TABLE Uri (object_fk INTEGER REFERENCES Object(id), "+
+                      "uri TEXT NOT NULL);" +
+    "INSERT INTO Object_Type (id, desc) VALUES (0, 'Container'); " +
+    "INSERT INTO Object_Type (id, desc) VALUES (1, 'Item'); " +
+    "INSERT INTO Schema_Info (version) VALUES ('" + MediaDB.schema_version +
+                                                "'); " +
+    "END;";
+
+
+    public MediaDB (string name) {
+        var rc = Database.open (name, out this.db);
+        if (rc != Sqlite.OK) {
+            warning ("Failed to open database: %d, %s",
+                     rc,
+                     db.errmsg ());
+            return;
+        }
+
+        weak string[] schema_info;
+        int nrows;
+        int ncolumns;
+        // FIXME error message causes segfaul
+        rc = db.get_table ("SELECT version FROM Schema_Info;",
+                           out schema_info,
+                           out nrows,
+                           out ncolumns,
+                           null);
+
+        if (rc == Sqlite.OK) {
+            if (nrows == 1 && ncolumns == 1) {
+                if (schema_info[0] == schema_version) {
+                    debug ("Media DB schema has current version");
+                } else {
+                    debug ("Schema version differs... checking for upgrade");
+                    // FIXME implement if necessary
+                }
+            } else {
+                warning ("Incompatible schema... cannot proceed");
+                db = null;
+                return;
+            }
+        } else {
+            debug ("Could not find schema version; checking for empty database...");
+            rc = db.get_table ("SELECT * FROM sqlite_master",
+                               out schema_info,
+                               out nrows,
+                               out ncolumns,
+                               null);
+            if (rc != Sqlite.OK) {
+                warning ("Something weird going on: %s",
+                         db.errmsg ());
+                db = null;
+                return;
+            }
+
+            if (nrows == 0) {
+                debug ("Empty database, creating new schema version %s",
+                       schema_version);
+                if (!create_schema ()) {
+                    return;
+                }
+            } else {
+                warning ("Incompatible schema... cannot proceed");
+                return;
+            }
+        }
+    }
+
+    /**
+     * Create the current schema.
+     *
+     * If schema creation fails, schema will be rolled back
+     * completely.
+     *
+     * @returns: true on success, false on failure
+     */
+    private bool create_schema () {
+        var rc = db.exec (db_schema_v1);
+        if (rc == Sqlite.OK) {
+            debug ("Schema created");
+            return true;
+        } else {
+            warning ("Could not create schema: %d, %s",
+                     rc,
+                     db.errmsg ());
+            rc = db.exec ("ROLLBACK;");
+            return false;
+        }
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]