[rygel] core: Add get_children and get_object method
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: svn-commits-list gnome org
- Subject: [rygel] core: Add get_children and get_object method
- Date: Thu, 25 Jun 2009 15:46:00 +0000 (UTC)
commit 1eb691e36712f2ef68fd8f8a9ff71ab30212649c
Author: Jens Georg <mail jensge org>
Date: Fri Jun 5 00:25:31 2009 +0200
core: Add get_children and get_object method
src/rygel/Makefile.am | 10 +-
.../rygel-database-backed-media-container.vala | 71 +++++++++
src/rygel/rygel-media-db-object-factory.vala | 69 +++++++++
src/rygel/rygel-media-db.vala | 158 +++++++++++++-------
4 files changed, 252 insertions(+), 56 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index a3b21fc..fcb1e6a 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -64,6 +64,8 @@ BUILT_SOURCES = rygel-1.0.vapi \
rygel-media-item.c \
rygel-metadata-extractor.c \
rygel-media-db.c \
+ rygel-database-backed-media-container.c \
+ rygel-media-db-object-factory.c \
rygel-mp2ts-transcoder.c \
rygel-mp3-transcoder.c \
rygel-l16-transcoder.c \
@@ -113,7 +115,9 @@ rygel_SOURCES = $(VAPI_SOURCE_FILES) \
rygel-mp2ts-transcoder-bin.c \
rygel-mp3-transcoder-bin.c \
rygel-l16-transcoder-bin.c \
- rygel-gst-utils.c
+ rygel-gst-utils.c \
+ rygel-database-backed-media-container.c \
+ rygel-media-db-object-factory.c
rygel.stamp: $(filter %.vala,$(rygel_SOURCES))
$(VALAC) -C --vapidir=$(srcdir) --thread \
@@ -170,7 +174,9 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
rygel-mp3-transcoder-bin.vala \
rygel-l16-transcoder-bin.vala \
rygel-gst-utils.vala \
- rygel-media-db.vala
+ rygel-media-db.vala \
+ rygel-database-backed-media-container.vala \
+ rygel-media-db-object-factory.vala
rygel-1.0.vapi: $(VAPI_SOURCE_FILES)
$(VALAC) -H rygel.h -C --library=rygel-1.0 --vapidir=$(srcdir) \
diff --git a/src/rygel/rygel-database-backed-media-container.vala b/src/rygel/rygel-database-backed-media-container.vala
new file mode 100644
index 0000000..dd32a04
--- /dev/null
+++ b/src/rygel/rygel-database-backed-media-container.vala
@@ -0,0 +1,71 @@
+/*
+ * 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 Rygel;
+
+public class Rygel.DatabaseBackedMediaContainer : Rygel.MediaContainer {
+ private MediaDB media_db;
+
+ public DatabaseBackedMediaContainer (Rygel.MediaDB media_db,
+ string id,
+ string title) {
+ base (id, null, title, 0);
+
+ this.media_db = media_db;
+ }
+
+ public override void get_children (uint offset,
+ uint max_count,
+ Cancellable? cancellable,
+ AsyncReadyCallback callback) {
+ var res = new Rygel.SimpleAsyncResult<Gee.ArrayList<MediaObject>>
+ (this, callback);
+ res.data = this.media_db.get_children (this.id,
+ offset,
+ max_count);
+ res.complete_in_idle ();
+ }
+
+ public override Gee.List<MediaObject>? get_children_finish (
+ AsyncResult res)
+ throws GLib.Error {
+ return ((Rygel.SimpleAsyncResult<Gee.ArrayList<MediaObject>>)res).data;
+ }
+
+
+ public override void find_object (string id,
+ Cancellable? cancellable,
+ AsyncReadyCallback callback) {
+ var res = new Rygel.SimpleAsyncResult<MediaObject> (this, callback);
+
+ res.data = media_db.get_object (id);
+ res.complete_in_idle ();
+ }
+
+ public override MediaObject? find_object_finish (AsyncResult res) {
+ return ((Rygel.SimpleAsyncResult<MediaObject>)res).data;
+ }
+}
+
+
diff --git a/src/rygel/rygel-media-db-object-factory.vala b/src/rygel/rygel-media-db-object-factory.vala
new file mode 100644
index 0000000..b655d89
--- /dev/null
+++ b/src/rygel/rygel-media-db-object-factory.vala
@@ -0,0 +1,69 @@
+/*
+ * 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 Rygel;
+
+/**
+ * Class used by MediaDB to create containers and items on demand
+ *
+ * If a specific kind of Item or Container is needed instead of
+ * the default ones, inherit from this class and override the
+ * corresponding methods.
+ *
+ * The class does not hold a reference to the MediaDB as the
+ * MediaDB is holding a reference to the factory; this is done to
+ * prevent circular references
+ */
+public class Rygel.MediaDBObjectFactory : Object {
+ /**
+ * Return a new instance of DatabaseBackedMediaContainer
+ *
+ * @param media_db instance of MediaDB
+ * @param title title of the container
+ * @param child_count number of children in the container
+ */
+ public virtual MediaContainer get_container (Rygel.MediaDB media_db,
+ string id,
+ string title,
+ uint child_count) {
+ return new DatabaseBackedMediaContainer (media_db,
+ id,
+ title);
+ }
+
+ /**
+ * Return a new instance of MediaItem
+ *
+ * @param media_db instance of MediaDB
+ * @param id id of the item
+ * @param title title of the item
+ * @param upnp_class upnp_class of the item
+ */
+ public virtual MediaItem get_item (Rygel.MediaDB media_db,
+ string id,
+ string title,
+ string upnp_class) {
+ return new MediaItem (id, null, title, upnp_class);
+ }
+}
diff --git a/src/rygel/rygel-media-db.vala b/src/rygel/rygel-media-db.vala
index 1cc5083..b630e47 100644
--- a/src/rygel/rygel-media-db.vala
+++ b/src/rygel/rygel-media-db.vala
@@ -37,6 +37,7 @@ public enum Rygel.MediaDBObjectType {
public class Rygel.MediaDB : Object {
private Database db;
+ private MediaDBObjectFactory factory;
private const string schema_version = "3";
private const string db_schema_v1 =
"BEGIN;" +
@@ -88,14 +89,23 @@ public class Rygel.MediaDB : Object {
private const string URI_INSERT_STRING =
"INSERT INTO Uri (object_fk, uri) VALUES (?,?)";
- private const string ITEM_GET_STRING =
- "SELECT size, mime_type, width, height, class, Object.title, author, album, " +
- "date, bitrate, sample_freq, bits_per_sample, channels, track, " +
- "color_depth, duration " +
- "FROM Meta_Data JOIN Object " +
+ private const string OBJECT_GET_STRING =
+ "SELECT Object.type_fk, Object.title, size, mime_type, width, height, " +
+ "class, author, album, date, bitrate, sample_freq, " +
+ "bits_per_sample, channels, track, color_depth, duration " +
+ "FROM Meta_Data LEFT OUTER JOIN Object " +
"ON Object.metadata_fk = Meta_Data.id WHERE Object.upnp_id = ?";
- public MediaDB (string name) {
+ private const string CHILDREN_GET_STRING =
+ "SELECT Object.type_fk, Object.title, size, mime_type, width, height, " +
+ "class, author, album, date, bitrate, sample_freq, " +
+ "bits_per_sample, channels, track, color_depth, duration " +
+ "FROM Meta_Data LEFT OUTER JOIN Object " +
+ "ON Object.metadata_fk = Meta_Data.id " +
+ "WHERE Object.parent = ? " +
+ "LIMIT ?,?";
+
+ private void open_db (string name) {
var rc = Database.open (name, out this.db);
if (rc != Sqlite.OK) {
warning ("Failed to open database: %d, %s",
@@ -154,6 +164,16 @@ public class Rygel.MediaDB : Object {
}
}
+ public MediaDB (string name) {
+ open_db (name);
+ this.factory = new MediaDBObjectFactory ();
+ }
+
+ public MediaDB.with_factory (string name, MediaDBObjectFactory factory) {
+ open_db (name);
+ this.factory = factory;
+ }
+
public signal void item_added (string item_id);
public void save_object (MediaObject obj) throws Error {
@@ -169,7 +189,7 @@ public class Rygel.MediaDB : Object {
public void save_container (MediaContainer container) throws Error {
var rc = db.exec ("BEGIN");
try {
- save_object (container, -1);
+ create_object (container, -1);
rc = db.exec ("COMMIT");
} catch (Error error) {
rc = db.exec ("ROLLBACK");
@@ -180,7 +200,7 @@ public class Rygel.MediaDB : Object {
var rc = db.exec ("BEGIN;");
try {
var id = save_metadata (item);
- save_object (item, id);
+ create_object (item, id);
save_uris (item);
rc = db.exec ("COMMIT;");
if (rc == Sqlite.OK) {
@@ -228,7 +248,7 @@ public class Rygel.MediaDB : Object {
}
}
- private void save_object (MediaObject item, int64 metadata_id) throws Error {
+ private void create_object (MediaObject item, int64 metadata_id) throws Error {
Statement statement;
var rc = db.prepare_v2 (OBJECT_INSERT_STRING,
@@ -253,7 +273,7 @@ public class Rygel.MediaDB : Object {
statement.bind_int64 (4, metadata_id);
}
- if (item.parent == null || item.parent.id == "0") {
+ if (item.parent == null) {
statement.bind_null (5);
} else {
statement.bind_text (5, item.parent.id);
@@ -312,65 +332,95 @@ public class Rygel.MediaDB : Object {
}
}
- public MediaItem? get_item (string item_id) {
- var item = new MediaItem ("", null, "", "");
- try {
- fill_object (item_id, ref item);
- } catch (Error error) {
- item = null;
+ private MediaObject? get_object_from_statement (string object_id, Statement statement) {
+ MediaObject obj = null;
+ switch (statement.column_int (0)) {
+ case 0:
+ // this is a container
+ obj = factory.get_container (this,
+ object_id,
+ statement.column_text (1),
+ 0);
+ break;
+ case 1:
+ // this is an item
+ obj = factory.get_item (this,
+ object_id,
+ statement.column_text (1),
+ statement.column_text (6));
+ fill_item (statement, (MediaItem)obj);
+ break;
+ default:
+ // should not happen
+ break;
}
- return item;
- }
-
- private void fill_container (string object_id, ref MediaContainer container) {
-
+ return null;
}
- private void fill_item (string object_id, ref MediaItem item) {
+ public MediaObject? get_object (string object_id) {
+ MediaObject obj = null;
Statement statement;
- var rc = db.prepare_v2 (ITEM_GET_STRING,
+
+ // decide what kind of object this is
+ var rc = db.prepare_v2 (OBJECT_GET_STRING,
-1,
out statement,
null);
if (rc == Sqlite.OK) {
statement.bind_text (1, object_id);
while ((rc = statement.step ()) == Sqlite.ROW) {
- item.id = object_id;
- item.title = statement.column_text (5);
- item.upnp_class = statement.column_text (4);
-
- item.author = statement.column_text (6);
- item.album = statement.column_text (7);
- item.date = statement.column_text (8);
- item.mime_type = statement.column_text (1);
- item.duration = (long)statement.column_text (15);
-
- item.size = (long)statement.column_int64 (0);
- item.bitrate = statement.column_int (9);
-
- item.sample_freq = statement.column_int (10);
- item.bits_per_sample = statement.column_int (11);
- item.n_audio_channels = statement.column_int (12);
- item.track_number = statement.column_int (13);
-
- item.width = statement.column_int (2);
- item.height = statement.column_int (3);
- item.color_depth = statement.column_int (14);
+ obj = get_object_from_statement (object_id, statement);
break;
}
+ } else {
}
+
+ return obj;
}
- public void fill_object (string object_id, ref MediaObject obj) throws Error {
- if (obj is MediaItem) {
- MediaItem item = (MediaItem) obj;
- fill_item (object_id, ref item);
- } else if (obj is MediaContainer) {
- MediaContainer container = (MediaContainer) obj;
- fill_container (object_id, ref container);
- } else {
- throw new MediaDBError.GENERAL_ERROR ("Invalid object type");
- }
+ private void fill_item (Statement statement, MediaItem item) {
+ item.author = statement.column_text (7);
+ item.album = statement.column_text (8);
+ item.date = statement.column_text (9);
+ item.mime_type = statement.column_text (3);
+ item.duration = (long)statement.column_text (16);
+
+ item.size = (long)statement.column_int64 (2);
+ item.bitrate = statement.column_int (10);
+
+ item.sample_freq = statement.column_int(11);
+ item.bits_per_sample = statement.column_int (12);
+ item.n_audio_channels = statement.column_int (13);
+ item.track_number = statement.column_int (14);
+
+ item.width = statement.column_int (4);
+ item.height = statement.column_int (5);
+ item.color_depth = statement.column_int (15);
}
+ public Gee.ArrayList<MediaObject>? get_children (string object_id,
+ uint offset,
+ uint max_count) {
+ Statement statement;
+ Gee.ArrayList<MediaObject> children = null;
+ var rc = db.prepare_v2 (CHILDREN_GET_STRING,
+ -1,
+ out statement,
+ null);
+ if (rc == Sqlite.OK) {
+ statement.bind_text (1, object_id);
+ statement.bind_int64 (2, (int64)offset);
+ statement.bind_int64 (3, (int64)max_count);
+ while ((rc = statement.step ()) == Sqlite.ROW) {
+ if (children == null) {
+ children = new Gee.ArrayList<MediaObject> ();
+ }
+
+ children.add (get_object_from_statement (object_id, statement));
+ }
+ }
+
+ return children;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]