diff options
28 files changed, 12467 insertions, 1 deletions
diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto/uinput.cfg b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/uinput.cfg new file mode 100644 index 000000000..7996ef1dd --- /dev/null +++ b/meta-agl-bsp/recipes-kernel/linux/linux-yocto/uinput.cfg @@ -0,0 +1,3 @@ +# Enable the User-level Input driver (required by "wayland-fits") +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m diff --git a/meta-agl-bsp/recipes-kernel/linux/linux-yocto_%.bbappend b/meta-agl-bsp/recipes-kernel/linux/linux-yocto_%.bbappend new file mode 100644 index 000000000..24bd38d40 --- /dev/null +++ b/meta-agl-bsp/recipes-kernel/linux/linux-yocto_%.bbappend @@ -0,0 +1,4 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/linux-yocto:" + +# Extra configuration options for the QEMU kernel +SRC_URI += "file://uinput.cfg" diff --git a/meta-agl/conf/bblayers.conf.sample b/meta-agl/conf/bblayers.conf.sample index ed6fe367c..e5e54431c 100644 --- a/meta-agl/conf/bblayers.conf.sample +++ b/meta-agl/conf/bblayers.conf.sample @@ -13,6 +13,7 @@ BBLAYERS ?= " \ ##OEROOT##/../meta-agl/meta-agl \ ##OEROOT##/../meta-agl/meta-agl-bsp \ ##OEROOT##/../meta-openembedded/meta-oe \ + ##OEROOT##/../meta-openembedded/meta-multimedia \ " BBLAYERS_NON_REMOVABLE ?= " \ ##OEROOT##/meta \ diff --git a/meta-agl/conf/conf-notes.txt b/meta-agl/conf/conf-notes.txt index b4f71a11a..f91379f98 100644 --- a/meta-agl/conf/conf-notes.txt +++ b/meta-agl/conf/conf-notes.txt @@ -1,5 +1,6 @@ Common targets are: agl-image-ivi + agl-image-ivi-crosssdk agl-image-minimal agl-image-weston diff --git a/meta-agl/conf/distro/poky-agl.conf b/meta-agl/conf/distro/poky-agl.conf index 8500784c8..58abfcd6a 100644 --- a/meta-agl/conf/distro/poky-agl.conf +++ b/meta-agl/conf/distro/poky-agl.conf @@ -19,7 +19,7 @@ VIRTUAL-RUNTIME_init_manager = "systemd" VIRTUAL-RUNTIME_initscripts = "" # Override these in poky based distros -AGL_DEFAULT_DISTRO_FEATURES = "systemd opengl wayland pam" +AGL_DEFAULT_DISTRO_FEATURES = "systemd opengl wayland pam bluetooth bluez5" AGL_DEFAULT_EXTRA_RDEPENDS = "packagegroup-core-boot" AGL_DEFAULT_EXTRA_RRECOMMENDS = "kernel-module-af-packet" @@ -46,6 +46,9 @@ PREFERRED_VERSION_gstreamer1.0-plugins-ugly ?= "1.4.%" PREFERRED_VERSION_gstreamer1.0-libav ?= "1.4.%" PREFERRED_VERSION_gstreamer1.0-omx ?= "1.2.%" +# Prefer the GStreamer-enabled version of GUPnP-DLNA +PREFERRED_VERSION_gupnp-dlna ?= "0.9.4%" + SDK_NAME = "${DISTRO}-${TCLIBC}-${SDK_ARCH}-${IMAGE_BASENAME}-${TUNE_PKGARCH}" SDKPATH = "/opt/${DISTRO}/${SDK_VERSION}" diff --git a/meta-agl/recipes-connectivity/gupnp/gupnp-dlna_0.9.4.bb b/meta-agl/recipes-connectivity/gupnp/gupnp-dlna_0.9.4.bb new file mode 100644 index 000000000..d55e10825 --- /dev/null +++ b/meta-agl/recipes-connectivity/gupnp/gupnp-dlna_0.9.4.bb @@ -0,0 +1,19 @@ +SUMMARY = "Helpers for AV applications using DLNA" +LICENSE = "LGPLv2" +LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c \ + file://libgupnp-dlna/gupnp-dlna-profile.h;beginline=1;endline=22;md5=1b85459f65cb1e73a885ca137aab6274" + +DEPENDS = "libxml2 glib-2.0" + +SRC_URI = "http://download.gnome.org/sources/${BPN}/0.9/${BPN}-${PV}.tar.xz" +SRC_URI[md5sum] = "f93665e535a512e4d515a86311435cb6" +SRC_URI[sha256sum] = "69969713f36c0e815fbbbcfdfb3ad9bd447cfd10d0fd86227d82dfd8edb6c807" + +inherit autotools pkgconfig + +require recipes-connectivity/gupnp/no-vala.inc + +PACKAGECONFIG ?= "gstreamer" +PACKAGECONFIG[gstreamer] = "--enable-gstreamer-metadata-backend,--disable-gstreamer-metadata-backend,gstreamer1.0 gstreamer1.0-plugins-base" + +FILES_${PN} += "${datadir}/gupnp-dlna-2.0/dlna-profiles" diff --git a/meta-agl/recipes-connectivity/ofono/ofono_%.bbappend b/meta-agl/recipes-connectivity/ofono/ofono_%.bbappend new file mode 100644 index 000000000..6bf323626 --- /dev/null +++ b/meta-agl/recipes-connectivity/ofono/ofono_%.bbappend @@ -0,0 +1,6 @@ +# Prevent BlueZ 4 from being always pulled +DEPENDS_remove = "bluez4" + +# If Bluetooth is asked in DISTRO_FEATURES, verify if Bluez 5 is also +# explicitly specified. If it is not, fall back to BlueZ 4 +DEPENDS_append = "${@bb.utils.contains('DISTRO_FEATURES', 'bluetooth', bb.utils.contains('DISTRO_FEATURES', 'bluez5', 'bluez5', 'bluez4', d), '', d)}" diff --git a/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch b/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch new file mode 100644 index 000000000..eca08ee84 --- /dev/null +++ b/meta-agl/recipes-connectivity/rygel/files/0001-Add-LightMediaScanner-plugin.patch @@ -0,0 +1,2541 @@ +From 8bb9ae73464dd76f5fa94f2e9ba76b0bd88114df Mon Sep 17 00:00:00 2001 +From: Manuel Bachmann <manuel.bachmann@iot.bzh> +Date: Mon, 26 Oct 2015 04:18:33 +0000 +Subject: [PATCH] Add LightMediaScanner plugin + +Add a new plugin based on LightMediaScanner : +https://github.com/profusion/lightmediascanner + +Shorty put, this plugin does not do the indexing itself as +"media-export" does, but defers this task to the +"lightmediascannerd" daemon, with which it communicates +via a D-Bus interface. +The remote indexing daemon installs itself as a separate +package, and is designed to be ultra-lightweight and fast. + +This commit is the rebase and fusion of all work done +first on Maemo (lms.garage.maemo.org), then on Tizen IVI +(review.tizen.org/git/?p=profile/ivi/rygel.git) and right +now on AGL (automotivelinux.org) where several components +depend on LightMediaScanner. +A splitted version (13 commits) can also be seen on : +https://github.com/Tarnyko/rygel + +It difffers mostly in that it lets "media-export" plugin +as the default, just adding itself in "rygel.conf" as an +alternative. + +(note : reporter is not code Author, see patch for details) +(note 2 : rebased on top of 0.26.1) + +Author: Jussi Kukkonen <jussi.kukkonen@intel.com> +Author: Alexander Kanavin <alex.kanavin@gmail.com> +Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh> +--- + configure.ac | 18 + + data/rygel.conf | 6 +- + src/plugins/Makefile.am | 5 + + src/plugins/lms/Makefile.am | 46 +++ + src/plugins/lms/README | 17 + + src/plugins/lms/lms.plugin.in | 7 + + src/plugins/lms/rygel-lms-album.vala | 173 +++++++++ + src/plugins/lms/rygel-lms-albums.vala | 175 +++++++++ + src/plugins/lms/rygel-lms-all-images.vala | 95 +++++ + src/plugins/lms/rygel-lms-all-music.vala | 169 ++++++++ + src/plugins/lms/rygel-lms-all-videos.vala | 123 ++++++ + src/plugins/lms/rygel-lms-artist.vala | 75 ++++ + src/plugins/lms/rygel-lms-artists.vala | 62 +++ + src/plugins/lms/rygel-lms-category-container.vala | 428 +++++++++++++++++++++ + src/plugins/lms/rygel-lms-collate.c | 49 +++ + src/plugins/lms/rygel-lms-database.vala | 294 ++++++++++++++ + src/plugins/lms/rygel-lms-dbus-interfaces.vala | 30 ++ + src/plugins/lms/rygel-lms-image-root.vala | 35 ++ + src/plugins/lms/rygel-lms-image-year.vala | 114 ++++++ + src/plugins/lms/rygel-lms-image-years.vala | 59 +++ + src/plugins/lms/rygel-lms-music-root.vala | 36 ++ + src/plugins/lms/rygel-lms-plugin-factory.vala | 40 ++ + src/plugins/lms/rygel-lms-plugin.vala | 35 ++ + src/plugins/lms/rygel-lms-root-container.vala | 58 +++ + src/plugins/lms/rygel-lms-sql-function.vala | 31 ++ + src/plugins/lms/rygel-lms-sql-operator.vala | 73 ++++ + 26 files changed, 2252 insertions(+), 1 deletion(-) + create mode 100644 src/plugins/lms/Makefile.am + create mode 100644 src/plugins/lms/README + create mode 100644 src/plugins/lms/lms.plugin.in + create mode 100644 src/plugins/lms/rygel-lms-album.vala + create mode 100644 src/plugins/lms/rygel-lms-albums.vala + create mode 100644 src/plugins/lms/rygel-lms-all-images.vala + create mode 100644 src/plugins/lms/rygel-lms-all-music.vala + create mode 100644 src/plugins/lms/rygel-lms-all-videos.vala + create mode 100644 src/plugins/lms/rygel-lms-artist.vala + create mode 100644 src/plugins/lms/rygel-lms-artists.vala + create mode 100644 src/plugins/lms/rygel-lms-category-container.vala + create mode 100644 src/plugins/lms/rygel-lms-collate.c + create mode 100644 src/plugins/lms/rygel-lms-database.vala + create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.vala + create mode 100644 src/plugins/lms/rygel-lms-image-root.vala + create mode 100644 src/plugins/lms/rygel-lms-image-year.vala + create mode 100644 src/plugins/lms/rygel-lms-image-years.vala + create mode 100644 src/plugins/lms/rygel-lms-music-root.vala + create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.vala + create mode 100644 src/plugins/lms/rygel-lms-plugin.vala + create mode 100644 src/plugins/lms/rygel-lms-root-container.vala + create mode 100644 src/plugins/lms/rygel-lms-sql-function.vala + create mode 100644 src/plugins/lms/rygel-lms-sql-operator.vala + +diff --git a/configure.ac b/configure.ac +index 7ae1105..275fd99 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -170,6 +170,18 @@ AS_IF([test "x$enable_ruih_plugin" = "xyes"], + libxml-2.0 >= $LIBXML_REQUIRED]) + ]) + ++ ++RYGEL_ADD_PLUGIN([lms],[LightMediaScanner],[yes]) ++AS_IF([test "x$enable_lms_plugin" = "xyes"], ++ [ ++ PKG_CHECK_MODULES([RYGEL_PLUGIN_LMS_DEPS], ++ [$RYGEL_COMMON_MODULES ++ gio-2.0 >= $GIO_REQUIRED ++ sqlite3 >= $LIBSQLITE3_REQUIRED]) ++ RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS="$RYGEL_COMMON_MODULES_VALAFLAGS --pkg gio-2.0 --pkg gee-0.8 --pkg sqlite3" ++ AC_SUBST([RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS]) ++ ]) ++ + AS_IF([test "x$with_media_engine" = "xgstreamer"], + [ + RYGEL_ADD_PLUGIN([playbin],[GStreamer playbin],[yes]) +@@ -332,6 +344,11 @@ then + fi + fi + ++dnl Check additional requirements for LMS plugin ++if test "x$enable_lms_plugin" = "xyes"; ++then ++ RYGEL_CHECK_PACKAGES([sqlite3]) ++fi + + RYGEL_ADD_PLUGIN([tracker],[Tracker],[yes]) + AS_IF([test "x$enable_tracker_plugin" = "xyes"], +@@ -513,6 +530,7 @@ echo " + version: ${tracker_api_version} + mediathek: ${enable_mediathek_plugin} + media-export ${enable_media_export_plugin} ++ lightmediascanner ${enable_lms_plugin} + external: ${enable_external_plugin} + MPRIS2: ${enable_mpris_plugin} + gst-launch: ${enable_gst_launch_plugin} +diff --git a/data/rygel.conf b/data/rygel.conf +index 6b1c1c4..8677a0d 100644 +--- a/data/rygel.conf ++++ b/data/rygel.conf +@@ -99,7 +99,7 @@ strict-sharing=false + title=@REALNAME@'s media on @PRETTY_HOSTNAME@ + + [MediaExport] +-enabled=true ++enabled=false + title=@REALNAME@'s media on @PRETTY_HOSTNAME@ + # List of URIs to export. Following variables are automatically substituted by + # the appropriate XDG standard media folders by Rygel for you. +@@ -114,6 +114,10 @@ monitor-changes=true + monitor-grace-timeout=5 + virtual-folders=true + ++[LightMediaScanner] ++enabled=true ++title=My Media ++ + [Playbin] + enabled=true + title=Audio/Video playback on @PRETTY_HOSTNAME@ +diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am +index d116f09..40791f0 100644 +--- a/src/plugins/Makefile.am ++++ b/src/plugins/Makefile.am +@@ -10,6 +10,10 @@ if BUILD_MEDIA_EXPORT_PLUGIN + MEDIA_EXPORT_PLUGIN = media-export + endif + ++if BUILD_LMS_PLUGIN ++LMS_PLUGIN = lms ++endif ++ + if BUILD_EXTERNAL_PLUGIN + EXTERNAL_PLUGIN = external + endif +@@ -33,6 +37,7 @@ endif + SUBDIRS = $(TRACKER_PLUGIN) \ + $(MEDIATHEK_PLUGIN) \ + $(MEDIA_EXPORT_PLUGIN) \ ++ $(LMS_PLUGIN) \ + $(EXTERNAL_PLUGIN) \ + $(MPRIS_PLUGIN) \ + $(GST_LAUNCH_PLUGIN) \ +diff --git a/src/plugins/lms/Makefile.am b/src/plugins/lms/Makefile.am +new file mode 100644 +index 0000000..f96a2ab +--- /dev/null ++++ b/src/plugins/lms/Makefile.am +@@ -0,0 +1,46 @@ ++include $(top_srcdir)/common.am ++ ++plugin_LTLIBRARIES = librygel-lms.la ++plugin_DATA = lms.plugin ++ ++librygel_lms_la_SOURCES = \ ++ rygel-lms-plugin.vala \ ++ rygel-lms-plugin-factory.vala \ ++ rygel-lms-root-container.vala \ ++ rygel-lms-music-root.vala \ ++ rygel-lms-image-root.vala \ ++ rygel-lms-category-container.vala \ ++ rygel-lms-all-music.vala \ ++ rygel-lms-album.vala \ ++ rygel-lms-albums.vala \ ++ rygel-lms-artist.vala \ ++ rygel-lms-artists.vala \ ++ rygel-lms-all-videos.vala \ ++ rygel-lms-database.vala \ ++ rygel-lms-all-images.vala \ ++ rygel-lms-image-years.vala \ ++ rygel-lms-image-year.vala \ ++ rygel-lms-sql-function.vala \ ++ rygel-lms-sql-operator.vala \ ++ rygel-lms-collate.c \ ++ rygel-lms-dbus-interfaces.vala ++ ++librygel_lms_la_VALAFLAGS = \ ++ --enable-experimental \ ++ $(RYGEL_PLUGIN_LMS_DEPS_VALAFLAGS) \ ++ $(RYGEL_COMMON_LIBRYGEL_SERVER_VALAFLAGS) \ ++ $(RYGEL_COMMON_VALAFLAGS) ++ ++librygel_lms_la_CFLAGS = \ ++ $(RYGEL_PLUGIN_LMS_DEPS_CFLAGS) \ ++ $(RYGEL_COMMON_LIBRYGEL_SERVER_CFLAGS) \ ++ -DG_LOG_DOMAIN='"Lms"' ++ ++librygel_lms_la_LIBADD = \ ++ $(RYGEL_PLUGIN_LMS_DEPS_LIBS) \ ++ $(RYGEL_COMMON_LIBRYGEL_SERVER_LIBS) ++ ++librygel_lms_la_LDFLAGS = \ ++ $(RYGEL_PLUGIN_LINKER_FLAGS) ++ ++EXTRA_DIST = lms.plugin.in +diff --git a/src/plugins/lms/README b/src/plugins/lms/README +new file mode 100644 +index 0000000..b741806 +--- /dev/null ++++ b/src/plugins/lms/README +@@ -0,0 +1,17 @@ ++rygel-lms ++========= ++ ++A rygel mediaserver plugin that exposes a lightmediascanner database ++as a Mediaserver. ++ ++Configuration in rygel.conf: ++ ++ [LightMediaScanner] ++ db-path=/path/to/lightmediascannerd.sqlite3 ++ title=My Media ++ ++* Supports browsing and searching (but in many cases searches will ++ still fall back to the inefficient simple_search()). ++* UpdateIDs are not yet supported as lightmediascanner seems to have ++ not change signal support yet ++* No real DLNA CTT testing has been done so far +diff --git a/src/plugins/lms/lms.plugin.in b/src/plugins/lms/lms.plugin.in +new file mode 100644 +index 0000000..9db9895 +--- /dev/null ++++ b/src/plugins/lms/lms.plugin.in +@@ -0,0 +1,7 @@ ++[Plugin] ++Version = @VERSION@ ++Module = lms ++Name = LMS ++License = LGPL ++Description = LMS DMS plugin for Rygel ++Copyright = Copyright © Intel +diff --git a/src/plugins/lms/rygel-lms-album.vala b/src/plugins/lms/rygel-lms-album.vala +new file mode 100644 +index 0000000..4fea17a +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-album.vala +@@ -0,0 +1,173 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.Album : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT_TEMPLATE = ++ "SELECT COUNT(audios.id) " + ++ "FROM audios, files " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"; ++ ++ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = ++ "SELECT COUNT(audios.id), audios.title as title, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;"; ++ ++ private static const string SQL_FIND_OBJECT_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name, " + ++ "audio_albums.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.album_id = %s;"; ++ ++ private static const string SQL_ADDED_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ private static const string SQL_REMOVED_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = statement.column_int (0); ++ var path = statement.column_text (1); ++ var mime_type = statement.column_text(10); ++ ++ if (mime_type == null || mime_type.length == 0) { ++ /* TODO is this correct? */ ++ debug ("Music item %d (%s) has no MIME type", ++ id, ++ path); ++ } ++ ++ var title = statement.column_text(3); ++ var song_id = this.build_child_id (id); ++ var song = new MusicItem (song_id, this, title); ++ song.ref_id = this.build_reference_id (id); ++ song.size = statement.column_int(2); ++ song.track_number = statement.column_int(4); ++ song.duration = statement.column_int(5); ++ song.channels = statement.column_int(6); ++ song.sample_freq = statement.column_int(7); ++ song.bitrate = statement.column_int(8); ++ song.dlna_profile = statement.column_text(9); ++ song.mime_type = mime_type; ++ song.artist = statement.column_text(11); ++ song.album = statement.column_text(12); ++ File file = File.new_for_path (path); ++ song.add_uri (file.get_uri ()); ++ ++ return song; ++ } ++ ++ private static string get_sql_all (string db_id) { ++ return (SQL_ALL_TEMPLATE.printf (db_id)); ++ } ++ private static string get_sql_find_object (string db_id) { ++ return (SQL_FIND_OBJECT_TEMPLATE.printf (db_id)); ++ } ++ private static string get_sql_count (string db_id) { ++ return (SQL_COUNT_TEMPLATE.printf (db_id)); ++ } ++ private static string get_sql_added (string db_id) { ++ return (SQL_ADDED_TEMPLATE.printf (db_id)); ++ } ++ private static string get_sql_removed (string db_id) { ++ return (SQL_REMOVED_TEMPLATE.printf (db_id)); ++ } ++ ++ protected override string get_sql_all_with_filter (string filter) { ++ if (filter.length == 0) { ++ return this.sql_all; ++ } ++ var filter_str = "%s AND %s".printf (this.db_id, filter); ++ return (SQL_ALL_TEMPLATE.printf (filter_str)); ++ } ++ ++ protected override string get_sql_count_with_filter (string filter) { ++ if (filter.length == 0) { ++ return this.sql_count; ++ } ++ var filter_str = "%s AND %s".printf (this.db_id, filter); ++ return (SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str)); ++ } ++ ++ public Album (string db_id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db) { ++ base (db_id, ++ parent, ++ title, ++ lms_db, ++ get_sql_all (db_id), ++ get_sql_find_object (db_id), ++ get_sql_count (db_id), ++ get_sql_added (db_id), ++ get_sql_removed (db_id) ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-albums.vala b/src/plugins/lms/rygel-lms-albums.vala +new file mode 100644 +index 0000000..309a352 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-albums.vala +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.Albums : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL = ++ "SELECT audio_albums.id, audio_albums.name as title, " + ++ "audio_artists.name as artist " + ++ "FROM audio_albums " + ++ "LEFT JOIN audio_artists " + ++ "ON audio_albums.artist_id = audio_artists.id " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_ALL_WITH_FILTER_TEMPLATE = ++ "SELECT audio_albums.id, audio_albums.name as title, " + ++ "audio_artists.name as artist " + ++ "FROM audio_albums " + ++ "LEFT JOIN audio_artists " + ++ "ON audio_albums.artist_id = audio_artists.id " + ++ "WHERE %s " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT COUNT(audio_albums.id) " + ++ "FROM audio_albums;"; ++ ++ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = ++ "SELECT COUNT(audio_albums.id), audio_albums.name as title, " + ++ "audio_artists.name as artist " + ++ "FROM audio_albums " + ++ "LEFT JOIN audio_artists " + ++ "ON audio_albums.artist_id = audio_artists.id " + ++ "WHERE %s;"; ++ ++ /* count songs inside albums */ ++ private static const string SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE = ++ "SELECT COUNT(audios.id), audios.title as title, " + ++ "audio_artists.name as artist " + ++ "FROM audios, files, audio_albums " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s;"; ++ ++ /* select songs inside albums */ ++ private static const string SQL_CHILD_ALL_WITH_FILTER_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name, audio_albums.id " + ++ "FROM audios, files, audio_albums " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_albums.id %s " + ++ "LIMIT ? OFFSET ?;"; ++ ++ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT audio_albums.id, audio_albums.name " + ++ "FROM audio_albums " + ++ "WHERE audio_albums.id = ?;"; ++ ++ protected override string get_sql_all_with_filter (string filter) { ++ if (filter.length == 0) { ++ return Albums.SQL_ALL; ++ } ++ return (Albums.SQL_ALL_WITH_FILTER_TEMPLATE.printf (filter)); ++ } ++ ++ protected override string get_sql_count_with_filter (string filter) { ++ if (filter.length == 0) { ++ return Albums.SQL_COUNT; ++ } ++ return (Albums.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter)); ++ } ++ ++ protected override uint get_child_count_with_filter (string where_filter, ++ ValueArray args) ++ { ++ ++ /* search the children (albums) as usual */ ++ var count = base.get_child_count_with_filter (where_filter, args); ++ ++ /* now search the album contents */ ++ var filter = ""; ++ if (where_filter.length > 0) { ++ filter = "AND %s".printf (where_filter); ++ } ++ var query = Albums.SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE.printf (filter); ++ try { ++ var stmt = this.lms_db.prepare_and_init (query, args.values); ++ if (stmt.step () == Sqlite.ROW) { ++ count += stmt.column_int (0); ++ } ++ } catch (DatabaseError e) { ++ warning ("Query failed: %s", e.message); ++ } ++ ++ return count; ++ } ++ ++ protected override MediaObjects? get_children_with_filter (string where_filter, ++ ValueArray args, ++ string sort_criteria, ++ uint offset, ++ uint max_count) { ++ var children = base. get_children_with_filter (where_filter, ++ args, ++ sort_criteria, ++ offset, ++ max_count); ++ var filter = ""; ++ if (where_filter.length > 0) { ++ filter = "AND %s".printf (where_filter); ++ } ++ var query = Albums.SQL_CHILD_ALL_WITH_FILTER_TEMPLATE.printf (filter); ++ try { ++ var stmt = this.lms_db.prepare_and_init (query, args.values); ++ while (Database.get_children_step (stmt)) { ++ var album_id = stmt.column_text (13); ++ var album = new Album (album_id, this, "", this.lms_db); ++ ++ var song = album.object_from_statement (stmt); ++ song.parent_ref = song.parent; ++ children.add (song); ++ ++ } ++ } catch (DatabaseError e) { ++ warning ("Query failed: %s", e.message); ++ } ++ ++ return children; ++ } ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = "%d".printf (statement.column_int (0)); ++ LMS.Album album = new LMS.Album (id, ++ this, ++ statement.column_text (1), ++ this.lms_db); ++ return album; ++ } ++ ++ public Albums (MediaContainer parent, ++ LMS.Database lms_db) { ++ base ("albums", ++ parent, ++ _("Albums"), ++ lms_db, ++ Albums.SQL_ALL, ++ Albums.SQL_FIND_OBJECT, ++ Albums.SQL_COUNT, ++ null, null); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-all-images.vala b/src/plugins/lms/rygel-lms-all-images.vala +new file mode 100644 +index 0000000..0b54c7f +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-images.vala +@@ -0,0 +1,95 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.AllImages : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT count(images.id) " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id;"; ++ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;"; ++ ++ private static const string SQL_ADDED = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ private static const string SQL_REMOVED = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime " + ++ "FROM images, files " + ++ "WHERE dtime <> 0 AND images.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = statement.column_int(0); ++ var path = statement.column_text(6); ++ var mime_type = statement.column_text(9); ++ ++ if (mime_type == null || mime_type.length == 0){ ++ /* TODO is this correct? */ ++ debug ("Image item %d (%s) has no MIME type", ++ id, ++ path); ++ } ++ ++ var title = statement.column_text(1); ++ var image = new ImageItem(this.build_child_id (id), this, title); ++ image.creator = statement.column_text(2); ++ TimeVal tv = { (long) statement.column_int(3), (long) 0 }; ++ image.date = tv.to_iso8601 (); ++ image.width = statement.column_int(4); ++ image.height = statement.column_int(5); ++ image.size = statement.column_int(7); ++ image.mime_type = mime_type; ++ image.dlna_profile = statement.column_text(8); ++ File file = File.new_for_path(path); ++ image.add_uri (file.get_uri ()); ++ ++ return image; ++ } ++ ++ public AllImages (MediaContainer parent, LMS.Database lms_db) { ++ base ("all", ++ parent, ++ _("All"), ++ lms_db, ++ AllImages.SQL_ALL, ++ AllImages.SQL_FIND_OBJECT, ++ AllImages.SQL_COUNT, ++ AllImages.SQL_ADDED, ++ AllImages.SQL_REMOVED ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-all-music.vala b/src/plugins/lms/rygel-lms-all-music.vala +new file mode 100644 +index 0000000..2a7226f +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-music.vala +@@ -0,0 +1,169 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.AllMusic : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL_TEMPLATE = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name, " + ++ "files.mtime, " + ++ "audio_genres.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "LEFT JOIN audio_genres " + ++ "ON audios.genre_id = audio_genres.id " + ++ "WHERE dtime = 0 AND audios.id = files.id %s " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT COUNT(audios.id) " + ++ "FROM audios, files " + ++ "WHERE dtime = 0 AND audios.id = files.id;"; ++ ++ private static const string SQL_COUNT_WITH_FILTER_TEMPLATE = ++ "SELECT COUNT(audios.id), audios.title as title, " + ++ "audio_artists.name as artist " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "WHERE dtime = 0 AND audios.id = files.id %s;"; ++ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name, " + ++ "audio_albums.name, " + ++ "files.mtime, " + ++ "audio_genres.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "LEFT JOIN audio_genres " + ++ "ON audios.genre_id = audio_genres.id " + ++ "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;"; ++ ++ private static const string SQL_ADDED = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name, " + ++ "files.mtime, " + ++ "audio_genres.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "LEFT JOIN audio_genres " + ++ "ON audios.genre_id = audio_genres.id " + ++ "WHERE dtime = 0 AND audios.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ private static const string SQL_REMOVED = ++ "SELECT files.id, files.path, files.size, " + ++ "audios.title as title, audios.trackno, audios.length, audios.channels, audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " + ++ "audio_artists.name as artist, " + ++ "audio_albums.name, " + ++ "files.mtime, " + ++ "audio_genres.name " + ++ "FROM audios, files " + ++ "LEFT JOIN audio_artists " + ++ "ON audios.artist_id = audio_artists.id " + ++ "LEFT JOIN audio_albums " + ++ "ON audios.album_id = audio_albums.id " + ++ "LEFT JOIN audio_genres " + ++ "ON audios.genre_id = audio_genres.id " + ++ "WHERE dtime <> 0 AND audios.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ protected override string get_sql_all_with_filter (string filter) { ++ if (filter.length == 0) { ++ return this.sql_all; ++ } ++ var filter_str = "AND %s".printf (filter); ++ return (AllMusic.SQL_ALL_TEMPLATE.printf (filter_str)); ++ } ++ ++ protected override string get_sql_count_with_filter (string filter) { ++ if (filter.length == 0) { ++ return this.sql_count; ++ } ++ var filter_str = "AND %s".printf (filter); ++ return (AllMusic.SQL_COUNT_WITH_FILTER_TEMPLATE.printf (filter_str)); ++ } ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = statement.column_int (0); ++ var path = statement.column_text (1); ++ var mime_type = statement.column_text(10); ++ ++ if (mime_type == null || mime_type.length == 0) { ++ /* TODO is this correct? */ ++ debug ("Music item %d (%s) has no MIME type", ++ id, ++ path); ++ } ++ ++ var title = statement.column_text(3); ++ var song_id = this.build_child_id (id); ++ var song = new MusicItem (song_id, this, title); ++ song.size = statement.column_int(2); ++ song.track_number = statement.column_int(4); ++ song.duration = statement.column_int(5); ++ song.channels = statement.column_int(6); ++ song.sample_freq = statement.column_int(7); ++ song.bitrate = statement.column_int(8); ++ song.dlna_profile = statement.column_text(9); ++ song.mime_type = mime_type; ++ song.artist = statement.column_text(11); ++ song.album = statement.column_text(12); ++ TimeVal tv = { (long) statement.column_int(13), (long) 0 }; ++ song.date = tv.to_iso8601 (); ++ song.genre = statement.column_text(14); ++ File file = File.new_for_path (path); ++ song.add_uri (file.get_uri ()); ++ ++ return song; ++ } ++ ++ public AllMusic (MediaContainer parent, LMS.Database lms_db) { ++ base("all", ++ parent, ++ _("All"), ++ lms_db, ++ AllMusic.SQL_ALL_TEMPLATE.printf (""), ++ AllMusic.SQL_FIND_OBJECT, ++ AllMusic.SQL_COUNT, ++ AllMusic.SQL_ADDED, ++ AllMusic.SQL_REMOVED ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-all-videos.vala b/src/plugins/lms/rygel-lms-all-videos.vala +new file mode 100644 +index 0000000..dbde0db +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-videos.vala +@@ -0,0 +1,123 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.AllVideos : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL = ++ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + ++ "FROM videos, files " + ++ "WHERE dtime = 0 AND videos.id = files.id " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT count(videos.id) " + ++ "FROM videos, files " + ++ "WHERE dtime = 0 AND videos.id = files.id;"; ++ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + ++ "FROM videos, files " + ++ "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;"; ++ ++ private static const string SQL_ADDED = ++ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + ++ "FROM videos, files " + ++ "WHERE dtime = 0 AND videos.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ private static const string SQL_REMOVED = ++ "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profile, dlna_mime " + ++ "FROM videos, files " + ++ "WHERE dtime <> 0 AND videos.id = files.id " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = statement.column_int(0); ++ var mime_type = statement.column_text(8); ++ var path = statement.column_text(4); ++ var file = File.new_for_path(path); ++ ++ /* TODO: Temporary code to extract the MIME TYPE. LMS does not seem ++ to compute the mime type of videos. Don't know why. */ ++ ++/* if (mime_type == null || mime_type.length == 0) { ++ try { ++ FileInfo info = file.query_info(FileAttribute.STANDARD_CONTENT_TYPE, ++ FileQueryInfoFlags.NONE, null); ++ mime_type = info.get_content_type(); ++ } catch {} ++ } ++*/ ++ ++ if (mime_type == null || mime_type.length == 0) { ++ /* TODO is this correct? */ ++ debug ("Video item %d (%s) has no MIME type", ++ id, ++ path); ++ } ++ ++ var title = statement.column_text(1); ++ var video = new VideoItem(this.build_child_id (id), this, title); ++ video.creator = statement.column_text(2); ++ video.duration = statement.column_int(3); ++ TimeVal tv = { (long) statement.column_int(5), (long) 0 }; ++ video.date = tv.to_iso8601 (); ++ video.size = statement.column_int(6); ++ video.dlna_profile = statement.column_text(7); ++ video.mime_type = mime_type; ++ video.add_uri (file.get_uri ()); ++ ++ // Rygel does not support multiple video and audio tracks in a single file, ++ // so we just take the first one ++ var video_data = "select videos_videos.bitrate + videos_audios.bitrate, width, height, channels, sampling_rate " + ++ "from videos, videos_audios, videos_videos where videos.id = ? " + ++ "and videos.id = videos_audios.video_id and videos.id = videos_videos.video_id;"; ++ try { ++ var stmt = this.lms_db.prepare(video_data); ++ Rygel.LMS.Database.find_object("%d".printf(id), stmt); ++ video.bitrate = stmt.column_int(0) / 8; //convert bits per second into bytes per second ++ video.width = stmt.column_int(1); ++ video.height = stmt.column_int(2); ++ video.channels = stmt.column_int(3); ++ video.sample_freq = stmt.column_int(4); ++ } catch (DatabaseError e) { ++ warning ("Query failed: %s", e.message); ++ } ++ ++ return video; ++ } ++ ++ public AllVideos (string id, MediaContainer parent, string title, LMS.Database lms_db){ ++ base (id, ++ parent, ++ title, ++ lms_db, ++ AllVideos.SQL_ALL, ++ AllVideos.SQL_FIND_OBJECT, ++ AllVideos.SQL_COUNT, ++ AllVideos.SQL_ADDED, ++ AllVideos.SQL_REMOVED ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-artist.vala b/src/plugins/lms/rygel-lms-artist.vala +new file mode 100644 +index 0000000..31e9070 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-artist.vala +@@ -0,0 +1,75 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.Artist : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL_TEMPLATE = ++ "SELECT audio_albums.id, audio_albums.name " + ++ "FROM audio_albums " + ++ "WHERE audio_albums.artist_id = %s " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT_TEMPLATE = ++ "SELECT COUNT(audio_albums.id) " + ++ "FROM audio_albums " + ++ "WHERE audio_albums.artist_id = %s"; ++ ++ private static const string SQL_FIND_OBJECT_TEMPLATE = ++ "SELECT audio_albums.id, audio_albums.name " + ++ "FROM audio_albums " + ++ "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;"; ++ ++ private static string get_sql_all (string id) { ++ return (SQL_ALL_TEMPLATE.printf (id)); ++ } ++ private static string get_sql_find_object (string id) { ++ return (SQL_FIND_OBJECT_TEMPLATE.printf (id)); ++ } ++ private static string get_sql_count (string id) { ++ return (SQL_COUNT_TEMPLATE.printf (id)); ++ } ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var db_id = "%d".printf (statement.column_int (0)); ++ var title = statement.column_text (1); ++ return new LMS.Album (db_id, this, title, this.lms_db); ++ } ++ ++ public Artist (string id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db) { ++ ++ base (id, ++ parent, ++ title, ++ lms_db, ++ get_sql_all (id), ++ get_sql_find_object (id), ++ get_sql_count (id), ++ null, // LMS does not track adding or removing albums ++ null ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-artists.vala b/src/plugins/lms/rygel-lms-artists.vala +new file mode 100644 +index 0000000..a00b2ce +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-artists.vala +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.Artists : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL = ++ "SELECT audio_artists.id, audio_artists.name " + ++ "FROM audio_artists " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT COUNT(audio_artists.id) " + ++ "FROM audio_artists;"; ++ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT audio_artists.id, audio_artists.name " + ++ "FROM audio_artists " + ++ "WHERE audio_artists.id = ?;"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var db_id = "%d".printf (statement.column_int (0)); ++ var title = statement.column_text (1); ++ ++ return new LMS.Artist (db_id, this, title, this.lms_db); ++ } ++ ++ public Artists (string id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db) { ++ base (id, ++ parent, ++ title, ++ lms_db, ++ Artists.SQL_ALL, ++ Artists.SQL_FIND_OBJECT, ++ Artists.SQL_COUNT, ++ null, null ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-category-container.vala b/src/plugins/lms/rygel-lms-category-container.vala +new file mode 100644 +index 0000000..e5430d1 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-category-container.vala +@@ -0,0 +1,428 @@ ++/* ++ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>, ++ * (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Gee; ++using Sqlite; ++ ++public errordomain Rygel.LMS.CategoryContainerError { ++ SQLITE_ERROR, ++ GENERAL_ERROR, ++ INVALID_TYPE, ++ UNSUPPORTED_SEARCH ++} ++ ++public abstract class Rygel.LMS.CategoryContainer : Rygel.MediaContainer, ++ Rygel.TrackableContainer, ++ Rygel.SearchableContainer { ++ public ArrayList<string> search_classes { get; set; } ++ ++ public unowned LMS.Database lms_db { get; construct; } ++ ++ public string db_id { get; construct; } ++ ++ public string sql_all { get; construct; } ++ public string sql_find_object { get; construct; } ++ public string sql_count { get; construct; } ++ public string sql_added { get; construct; } ++ public string sql_removed { get; construct; } ++ ++ protected Statement stmt_all; ++ protected Statement stmt_find_object; ++ protected Statement stmt_added; ++ protected Statement stmt_removed; ++ ++ protected string child_prefix; ++ protected string ref_prefix; ++ ++ protected abstract MediaObject? object_from_statement (Statement statement); ++ ++ /* TODO these should be abstract */ ++ protected virtual string get_sql_all_with_filter (string filter) { ++ return this.sql_all; ++ } ++ protected virtual string get_sql_count_with_filter (string filter) { ++ return this.sql_count; ++ } ++ ++ private static string? map_operand_to_column (string operand, ++ out string? collate = null, ++ bool for_sort = false) ++ throws Error { ++ string column = null; ++ bool use_collation = false; ++ ++ // TODO add all used aliases to sql queries ++ switch (operand) { ++ case "dc:title": ++ column = "title"; ++ use_collation = true; ++ break; ++ case "upnp:artist": ++ column = "artist"; ++ use_collation = true; ++ break; ++ case "dc:creator": ++ column = "creator"; ++ use_collation = true; ++ break; ++ default: ++ var message = "Unsupported column %s".printf (operand); ++ ++ throw new CategoryContainerError.UNSUPPORTED_SEARCH (message); ++ } ++ ++ if (use_collation) { ++ collate = "COLLATE CASEFOLD"; ++ } else { ++ collate = ""; ++ } ++ ++ return column; ++ } ++ ++ private static string? relational_expression_to_sql ++ (RelationalExpression exp, ++ GLib.ValueArray args) ++ throws Error { ++ GLib.Value? v = null; ++ string collate = null; ++ ++ string column = CategoryContainer.map_operand_to_column (exp.operand1, ++ out collate); ++ SqlOperator operator; ++ ++ switch (exp.op) { ++ case GUPnP.SearchCriteriaOp.EXISTS: ++ string sql_function; ++ if (exp.operand2 == "true") { ++ sql_function = "%s IS NOT NULL AND %s != ''"; ++ } else { ++ sql_function = "%s IS NULL OR %s = ''"; ++ } ++ ++ return sql_function.printf (column, column); ++ case GUPnP.SearchCriteriaOp.EQ: ++ case GUPnP.SearchCriteriaOp.NEQ: ++ case GUPnP.SearchCriteriaOp.LESS: ++ case GUPnP.SearchCriteriaOp.LEQ: ++ case GUPnP.SearchCriteriaOp.GREATER: ++ case GUPnP.SearchCriteriaOp.GEQ: ++ v = exp.operand2; ++ operator = new SqlOperator.from_search_criteria_op ++ (exp.op, column, collate); ++ break; ++ case GUPnP.SearchCriteriaOp.CONTAINS: ++ operator = new SqlFunction ("contains", column); ++ v = exp.operand2; ++ break; ++ case GUPnP.SearchCriteriaOp.DOES_NOT_CONTAIN: ++ operator = new SqlFunction ("NOT contains", column); ++ v = exp.operand2; ++ break; ++ case GUPnP.SearchCriteriaOp.DERIVED_FROM: ++ operator = new SqlOperator ("LIKE", column); ++ v = "%s%%".printf (exp.operand2); ++ break; ++ default: ++ warning ("Unsupported op %d", exp.op); ++ return null; ++ } ++ ++ if (v != null) { ++ args.append (v); ++ } ++ ++ return operator.to_string (); ++ } ++ ++ private static string logical_expression_to_sql ++ (LogicalExpression expression, ++ GLib.ValueArray args) ++ throws Error { ++ string left_sql_string = CategoryContainer.search_expression_to_sql ++ (expression.operand1, ++ args); ++ string right_sql_string = CategoryContainer.search_expression_to_sql ++ (expression.operand2, ++ args); ++ unowned string operator_sql_string = "OR"; ++ ++ if (expression.op == LogicalOperator.AND) { ++ operator_sql_string = "AND"; ++ } ++ ++ return "(%s %s %s)".printf (left_sql_string, ++ operator_sql_string, ++ right_sql_string); ++ } ++ ++ private static string? search_expression_to_sql ++ (SearchExpression? expression, ++ GLib.ValueArray args) ++ throws Error { ++ if (expression == null) { ++ return ""; ++ } ++ ++ if (expression is LogicalExpression) { ++ return CategoryContainer.logical_expression_to_sql ++ (expression as LogicalExpression, args); ++ } else { ++ return CategoryContainer.relational_expression_to_sql ++ (expression as RelationalExpression, ++ args); ++ } ++ } ++ ++ protected virtual uint get_child_count_with_filter (string where_filter, ++ ValueArray args) ++ { ++ var query = this.get_sql_count_with_filter (where_filter); ++ try { ++ var stmt = this.lms_db.prepare_and_init (query, args.values); ++ if (stmt.step () != Sqlite.ROW) { ++ return 0; ++ } ++ return stmt.column_int (0); ++ } catch (DatabaseError e) { ++ warning ("Query failed: %s", e.message); ++ return 0; ++ } ++ } ++ ++ protected virtual MediaObjects? get_children_with_filter (string where_filter, ++ ValueArray args, ++ string sort_criteria, ++ uint offset, ++ uint max_count) { ++ var children = new MediaObjects (); ++ GLib.Value v = max_count; ++ args.append (v); ++ v = offset; ++ args.append (v); ++ ++ var query = this.get_sql_all_with_filter (where_filter); ++ try { ++ var stmt = this.lms_db.prepare_and_init (query, args.values); ++ while (Database.get_children_step (stmt)) { ++ children.add (this.object_from_statement (stmt)); ++ } ++ } catch (DatabaseError e) { ++ warning ("Query failed: %s", e.message); ++ } ++ ++ return children; ++ } ++ ++ public async MediaObjects? search (SearchExpression? expression, ++ uint offset, ++ uint max_count, ++ out uint total_matches, ++ string sort_criteria, ++ Cancellable? cancellable) ++ throws Error { ++ debug ("search()"); ++ try { ++ var args = new GLib.ValueArray (0); ++ var filter = CategoryContainer.search_expression_to_sql (expression, ++ args); ++ total_matches = this.get_child_count_with_filter (filter, args); ++ ++ if (expression != null) { ++ debug (" Original search: %s", expression.to_string ()); ++ debug (" Parsed search expression: %s", filter); ++ debug (" Filtered cild count is %u", total_matches); ++ } ++ ++ if (max_count == 0) { ++ max_count = uint.MAX; ++ } ++ return this.get_children_with_filter (filter, ++ args, ++ sort_criteria, ++ offset, ++ max_count); ++ } catch (Error e) { ++ debug (" Falling back to simple_search(): %s", e.message); ++ return yield this.simple_search (expression, ++ offset, ++ max_count, ++ out total_matches, ++ sort_criteria, ++ cancellable); ++ } ++ } ++ ++ public async override MediaObjects? get_children (uint offset, ++ uint max_count, ++ string sort_criteria, ++ Cancellable? cancellable) ++ throws Error { ++ MediaObjects retval = new MediaObjects (); ++ ++ Database.get_children_init (this.stmt_all, ++ offset, ++ max_count, ++ sort_criteria); ++ while (Database.get_children_step (this.stmt_all)) { ++ retval.add (this.object_from_statement (this.stmt_all)); ++ } ++ ++ return retval; ++ } ++ ++ public async override MediaObject? find_object (string id, ++ Cancellable? cancellable) ++ throws Error { ++ if (!id.has_prefix (this.child_prefix)) { ++ /* can't match anything in this container */ ++ return null; ++ } ++ ++ MediaObject object = null; ++ ++ /* remove parent section from id */ ++ var real_id = id.substring (this.child_prefix.length); ++ /* remove grandchildren from id */ ++ var index = real_id.index_of_char (':'); ++ if (index > 0) { ++ real_id = real_id.slice (0, index); ++ } ++ ++ try { ++ Database.find_object (real_id, this.stmt_find_object); ++ var child = this.object_from_statement (this.stmt_find_object); ++ if (index < 0) { ++ object = child; ++ } else { ++ /* try grandchildren */ ++ var container = child as CategoryContainer; ++ object = yield container.find_object (id, cancellable); ++ ++ /* tell object to keep a reference to the parent -- ++ * otherwise parent is freed before object is serialized */ ++ object.parent_ref = object.parent; ++ } ++ } catch (DatabaseError e) { ++ debug ("find_object %s in %s: %s", id, this.id, e.message); ++ /* Happens e.g. if id is not an integer */ ++ } ++ ++ return object; ++ } ++ ++ protected string build_child_id (int db_id) { ++ return "%s%d".printf (this.child_prefix, db_id); ++ } ++ ++ protected string build_reference_id (int db_id) { ++ return "%s%d".printf (this.ref_prefix, db_id); ++ } ++ ++ protected async void add_child (MediaObject object) { ++ } ++ ++ protected async void remove_child (MediaObject object) { ++ } ++ ++ private void on_db_updated(uint64 old_id, uint64 new_id) { ++ try { ++ var stmt_count = this.lms_db.prepare (this.sql_count); ++ ++ if (stmt_count.step () == Sqlite.ROW) { ++ this.child_count = stmt_count.column_int (0); ++ } ++ ++ Database.get_children_with_update_id_init (this.stmt_added, ++ old_id, ++ new_id); ++ while (Database.get_children_step (this.stmt_added)) { ++ this.add_child_tracked.begin(this.object_from_statement (this.stmt_added)); ++ } ++ ++ Database.get_children_with_update_id_init (this.stmt_removed, ++ old_id, ++ new_id); ++ while (Database.get_children_step (this.stmt_removed)) { ++ this.remove_child_tracked.begin(this.object_from_statement (this.stmt_removed)); ++ } ++ ++ } catch (DatabaseError e) { ++ warning ("Can't perform container update: %s", e.message); ++ } ++ ++ } ++ ++ public CategoryContainer (string db_id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db, ++ string sql_all, ++ string sql_find_object, ++ string sql_count, ++ string? sql_added, ++ string? sql_removed ++ ) { ++ Object (id : "%s:%s".printf (parent.id, db_id), ++ db_id : db_id, ++ parent : parent, ++ title : title, ++ lms_db : lms_db, ++ sql_all : sql_all, ++ sql_find_object : sql_find_object, ++ sql_count : sql_count, ++ sql_added : sql_added, ++ sql_removed: sql_removed ++ ); ++ } ++ ++ construct { ++ this.search_classes = new ArrayList<string> (); ++ ++ this.child_prefix = "%s:".printf (this.id); ++ ++ var index = this.id.index_of_char (':'); ++ this.ref_prefix = this.id.slice (0, index) + ":all:"; ++ ++ try { ++ this.stmt_all = this.lms_db.prepare (this.sql_all); ++ this.stmt_find_object = this.lms_db.prepare (this.sql_find_object); ++ var stmt_count = this.lms_db.prepare (this.sql_count); ++ ++ if (stmt_count.step () == Sqlite.ROW) { ++ this.child_count = stmt_count.column_int (0); ++ } ++ // some container implementations don't have a reasonable way to provide ++ // id-based statements to fetch added or removed items ++ if (this.sql_added != null && this.sql_removed != null) { ++ this.stmt_added = this.lms_db.prepare (this.sql_added); ++ this.stmt_removed = this.lms_db.prepare (this.sql_removed); ++ lms_db.db_updated.connect(this.on_db_updated); ++ } ++ } catch (DatabaseError e) { ++ warning ("Container %s: %s", this.title, e.message); ++ } ++ ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-collate.c b/src/plugins/lms/rygel-lms-collate.c +new file mode 100644 +index 0000000..8eee80b +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-collate.c +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (C) 2012 Jens Georg <mail@jensge.org>. ++ * ++ * Author: Jens Georg <mail@jensge.org> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++ ++#ifdef HAVE_UNISTRING ++# include <unistr.h> ++#endif ++ ++gint rygel_lms_utf8_collate_str (const char *a, gsize alen, ++ const char *b, gsize blen) ++{ ++ char *a_str, *b_str; ++ gint result; ++ ++ /* Make sure the passed strings are null terminated */ ++ a_str = g_strndup (a, alen); ++ b_str = g_strndup (b, blen); ++ ++#ifdef HAVE_UNISTRING ++ result = u8_strcoll (a_str, b_str); ++#else ++ return g_utf8_collate (a_str, b_str); ++#endif ++ ++ g_free (a_str); ++ g_free (b_str); ++ ++ return result; ++} +diff --git a/src/plugins/lms/rygel-lms-database.vala b/src/plugins/lms/rygel-lms-database.vala +new file mode 100644 +index 0000000..e898d66 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-database.vala +@@ -0,0 +1,294 @@ ++/* ++ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>, ++ * (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Gee; ++using Sqlite; ++ ++public errordomain Rygel.LMS.DatabaseError { ++ OPEN, ++ PREPARE, ++ BIND, ++ STEP, ++ NOT_FOUND ++} ++ ++namespace Rygel.LMS { ++ extern static int utf8_collate_str (uint8[] a, uint8[] b); ++} ++ ++public class Rygel.LMS.Database { ++ ++ public signal void db_updated(uint64 old_update_id, uint64 new_update_id); ++ ++ private Sqlite.Database db; ++ private LMS.DBus lms_proxy; ++ private uint64 update_id; ++ ++ /** ++ * Function to implement the custom SQL function 'contains' ++ */ ++ private static void utf8_contains (Sqlite.Context context, ++ Sqlite.Value[] args) ++ requires (args.length == 2) { ++ if (args[0].to_text () == null || ++ args[1].to_text () == null) { ++ context.result_int (0); ++ ++ return; ++ } ++ ++ var pattern = Regex.escape_string (args[1].to_text ()); ++ if (Regex.match_simple (pattern, ++ args[0].to_text (), ++ RegexCompileFlags.CASELESS)) { ++ context.result_int (1); ++ } else { ++ context.result_int (0); ++ } ++ } ++ ++ /** ++ * Function to implement the custom SQLite collation 'CASEFOLD'. ++ * ++ * Uses utf8 case-fold to compare the strings. ++ */ ++ private static int utf8_collate (int alen, void* a, int blen, void* b) { ++ // unowned to prevent array copy ++ unowned uint8[] _a = (uint8[]) a; ++ _a.length = alen; ++ ++ unowned uint8[] _b = (uint8[]) b; ++ _b.length = blen; ++ ++ return LMS.utf8_collate_str (_a, _b); ++ } ++ ++ public Database () throws DatabaseError { ++ string db_path; ++ try { ++ lms_proxy = Bus.get_proxy_sync (BusType.SESSION, ++ "org.lightmediascanner", ++ "/org/lightmediascanner/Scanner1"); ++ db_path = lms_proxy.data_base_path; ++ debug ("Got db path %s from LMS over dbus", db_path); ++ update_id = lms_proxy.update_id; ++ debug ("Got updated id %lld from LMS over dbus", update_id); ++ lms_proxy.g_properties_changed.connect (this.on_lms_properties_changed); ++ ++ } catch (IOError e) { ++ warning("Couldn't get LMS Dbus proxy: %s", e.message); ++ db_path = Environment.get_user_config_dir() + ++ "/lightmediascannerd/db.sqlite3"; ++ debug ("Using default sqlite database location %s", db_path); ++ } ++ ++ Sqlite.Database.open (db_path, out this.db); ++ if (this.db.errcode () != Sqlite.OK) { ++ throw new DatabaseError.OPEN ("Failed to open '%s': %d", ++ db_path, ++ this.db.errcode () ); ++ } ++ ++ this.db.create_function ("contains", ++ 2, ++ Sqlite.UTF8, ++ null, ++ LMS.Database.utf8_contains, ++ null, ++ null); ++ ++ this.db.create_collation ("CASEFOLD", ++ Sqlite.UTF8, ++ LMS.Database.utf8_collate); ++ ++ } ++ ++ private void on_lms_properties_changed (DBusProxy lms_proxy, ++ Variant changed, ++ string[] invalidated) { ++ if (!changed.get_type().equal (VariantType.VARDICT)) { ++ return; ++ } ++ ++ foreach (var changed_prop in changed) { ++ var key = (string) changed_prop.get_child_value (0); ++ var value = changed_prop.get_child_value (1).get_child_value (0); ++ ++ debug ("LMS property %s changed value to %s", key, value.print(true)); ++ ++ switch (key) { ++ case "UpdateID": ++ db_updated(update_id, (uint64)value); ++ update_id = (uint64)value; ++ break; ++ } ++ } ++ } ++ ++ ++ public Statement prepare (string query_string) throws DatabaseError { ++ Statement statement; ++ ++ var err = this.db.prepare_v2 (query_string, -1, out statement); ++ if (err != Sqlite.OK) ++ throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d", ++ query_string, ++ err); ++ return statement; ++ } ++ ++ ++ public Statement prepare_and_init (string query, ++ GLib.Value[]? arguments) ++ throws DatabaseError { ++ ++ Statement statement; ++ ++ var err = this.db.prepare_v2 (query, -1, out statement); ++ if (err != Sqlite.OK) ++ throw new DatabaseError.PREPARE ("Unable to create statement '%s': %d", ++ query, ++ err); ++ ++ for (var i = 1; i <= arguments.length; ++i) { ++ int sqlite_err; ++ unowned GLib.Value current_value = arguments[i - 1]; ++ ++ if (current_value.holds (typeof (int))) { ++ sqlite_err = statement.bind_int (i, current_value.get_int ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (int64))) { ++ sqlite_err = statement.bind_int64 (i, current_value.get_int64 ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (uint64))) { ++ sqlite_err = statement.bind_int64 (i, (int64) current_value.get_uint64 ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (long))) { ++ sqlite_err = statement.bind_int64 (i, current_value.get_long ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (uint))) { ++ sqlite_err = statement.bind_int64 (i, current_value.get_uint ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (string))) { ++ sqlite_err = statement.bind_text (i, current_value.get_string ()); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else if (current_value.holds (typeof (void *))) { ++ if (current_value.peek_pointer () == null) { ++ sqlite_err = statement.bind_null (i); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind value %d", ++ sqlite_err); ++ } else { ++ assert_not_reached (); ++ } ++ } else { ++ var type = current_value.type (); ++ warning (_("Unsupported type %s"), type.name ()); ++ assert_not_reached (); ++ } ++ } ++ ++ return statement; ++ } ++ ++ public static void find_object(string id, Statement stmt) throws DatabaseError { ++ ++ (void) stmt.reset(); ++ ++ int integer_id = int.parse(id); ++ int sqlite_err = stmt.bind_int(1, integer_id); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind id %d", sqlite_err); ++ ++ sqlite_err = stmt.step(); ++ if (sqlite_err != Sqlite.ROW) ++ throw new DatabaseError.STEP("Unable to find id %s", id); ++ } ++ ++ public static void get_children_init (Statement stmt, ++ uint offset, uint max_count, string sort_criteria) throws DatabaseError { ++ ++ int sqlite_err; ++ ++ (void) stmt.reset(); ++ ++ sqlite_err = stmt.bind_int(1, (int) max_count); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind max_count %d", ++ sqlite_err); ++ ++ sqlite_err = stmt.bind_int(2, (int) offset); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind offset %d", ++ sqlite_err); ++ } ++ ++ public static void get_children_with_update_id_init (Statement stmt, ++ uint64 old_id, uint64 new_id) throws DatabaseError { ++ ++ int sqlite_err; ++ ++ (void) stmt.reset(); ++ ++ if (new_id < old_id) // id value wrapped over ++ sqlite_err = stmt.bind_int64(1, 0); ++ else ++ sqlite_err = stmt.bind_int64(1, (int64)old_id); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind old_id %d", ++ sqlite_err); ++ ++ sqlite_err = stmt.bind_int64(2, (int64)new_id); ++ if (sqlite_err != Sqlite.OK) ++ throw new DatabaseError.BIND("Unable to bind new_id %d", ++ sqlite_err); ++ } ++ ++ public static bool get_children_step(Statement stmt) throws DatabaseError { ++ ++ bool retval; ++ int sqlite_err; ++ ++ sqlite_err = stmt.step(); ++ retval = sqlite_err == Sqlite.ROW; ++ ++ if (!retval && (sqlite_err != Sqlite.DONE)) ++ throw new DatabaseError.STEP("Error iterating through rows %d", ++ sqlite_err); ++ ++ return retval; ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.vala b/src/plugins/lms/rygel-lms-dbus-interfaces.vala +new file mode 100644 +index 0000000..13f00cb +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-dbus-interfaces.vala +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (C) 2014 Intel Corporation. ++ * ++ * Author: Alexander Kanavin <alex.kanavin@gmail.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++[DBus (name = "org.lightmediascanner.Scanner1")] ++interface Rygel.LMS.DBus : DBusProxy { ++ public abstract string data_base_path { owned get; } ++ [DBus (name = "UpdateID")] ++ public abstract uint64 update_id { get; } ++ ++ //TODO: add all the other API items which are currently unused ++} +\ No newline at end of file +diff --git a/src/plugins/lms/rygel-lms-image-root.vala b/src/plugins/lms/rygel-lms-image-root.vala +new file mode 100644 +index 0000000..466bbe2 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-root.vala +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++ ++public class Rygel.LMS.ImageRoot : Rygel.SimpleContainer { ++ public ImageRoot (string id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db) { ++ base (id, parent, title); ++ ++ this.add_child_container (new AllImages (this, lms_db)); ++ this.add_child_container (new ImageYears (this, lms_db)); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-image-year.vala b/src/plugins/lms/rygel-lms-image-year.vala +new file mode 100644 +index 0000000..a7768f0 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-year.vala +@@ -0,0 +1,114 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.ImageYear : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL_TEMPLATE = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT_TEMPLATE = ++ "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id AND year = '%s';"; ++ ++ private static const string SQL_FIND_OBJECT_TEMPLATE = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '%s';"; ++ ++ private static const string SQL_ADDED_TEMPLATE = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + ++ "FROM images, files " + ++ "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ private static const string SQL_REMOVED_TEMPLATE = ++ "SELECT images.id, title, artist, date, width, height, path, size, dlna_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " + ++ "FROM images, files " + ++ "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " + ++ "AND update_id > ? AND update_id <= ?;"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ var id = statement.column_int(0); ++ var path = statement.column_text(6); ++ var mime_type = statement.column_text(9); ++ ++ if (mime_type == null || mime_type.length == 0){ ++ /* TODO is this correct? */ ++ debug ("Image item %d (%s) has no MIME type", ++ id, ++ path); ++ } ++ ++ var title = statement.column_text(1); ++ var image = new ImageItem(this.build_child_id (id), this, title); ++ image.ref_id = this.build_reference_id (id); ++ image.creator = statement.column_text(2); ++ TimeVal tv = { (long) statement.column_int(3), (long) 0 }; ++ image.date = tv.to_iso8601 (); ++ image.width = statement.column_int(4); ++ image.height = statement.column_int(5); ++ image.size = statement.column_int(7); ++ image.mime_type = mime_type; ++ image.dlna_profile = statement.column_text(8); ++ File file = File.new_for_path(path); ++ image.add_uri (file.get_uri ()); ++ ++ return image; ++ } ++ ++ private static string get_sql_all (string year) { ++ return (SQL_ALL_TEMPLATE.printf (year)); ++ } ++ private static string get_sql_find_object (string year) { ++ return (SQL_FIND_OBJECT_TEMPLATE.printf (year)); ++ } ++ private static string get_sql_count (string year) { ++ return (SQL_COUNT_TEMPLATE.printf (year)); ++ } ++ private static string get_sql_added (string year) { ++ return (SQL_ADDED_TEMPLATE.printf (year)); ++ } ++ private static string get_sql_removed (string year) { ++ return (SQL_REMOVED_TEMPLATE.printf (year)); ++ } ++ ++ public ImageYear (MediaContainer parent, ++ string year, ++ LMS.Database lms_db) { ++ base ("%s".printf (year), ++ parent, ++ year, ++ lms_db, ++ get_sql_all (year), ++ get_sql_find_object (year), ++ get_sql_count (year), ++ get_sql_added (year), ++ get_sql_removed (year) ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-image-years.vala b/src/plugins/lms/rygel-lms-image-years.vala +new file mode 100644 +index 0000000..636f4d1 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-years.vala +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++using Sqlite; ++ ++public class Rygel.LMS.ImageYears : Rygel.LMS.CategoryContainer { ++ private static const string SQL_ALL = ++ "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " + ++ "FROM images " + ++ "LIMIT ? OFFSET ?;"; ++ ++ private static const string SQL_COUNT = ++ "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " + ++ "FROM images;"; ++ ++ /* actually returns multiple times the same result (because no DISTINCT) */ ++ /* Casting the year is a workaround so we can keep using ++ * Database.find_object() without making the argument a variant or something like it*/ ++ private static const string SQL_FIND_OBJECT = ++ "SELECT strftime('%Y', images.date, 'unixepoch') as year " + ++ "FROM images " + ++ "WHERE year = CAST(? AS TEXT)"; ++ ++ protected override MediaObject? object_from_statement (Statement statement) { ++ return new LMS.ImageYear (this, statement.column_text (0), this.lms_db); ++ } ++ ++ public ImageYears (MediaContainer parent, LMS.Database lms_db) { ++ base ("years", ++ parent, ++ _("Years"), ++ lms_db, ++ ImageYears.SQL_ALL, ++ ImageYears.SQL_FIND_OBJECT, ++ ImageYears.SQL_COUNT, ++ null, null ++ ); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-music-root.vala b/src/plugins/lms/rygel-lms-music-root.vala +new file mode 100644 +index 0000000..7b1eb0f +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-music-root.vala +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++ ++public class Rygel.LMS.MusicRoot : Rygel.SimpleContainer { ++ public MusicRoot (string id, ++ MediaContainer parent, ++ string title, ++ LMS.Database lms_db) { ++ base (id, parent, title); ++ ++ this.add_child_container (new AllMusic (this, lms_db)); ++ this.add_child_container (new Artists ("artists", this, _("Artists"), lms_db)); ++ this.add_child_container (new Albums (this, lms_db)); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-plugin-factory.vala b/src/plugins/lms/rygel-lms-plugin-factory.vala +new file mode 100644 +index 0000000..9fa8ccd +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-plugin-factory.vala +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++ ++private Rygel.LMS.PluginFactory plugin_factory; ++ ++public void module_init(PluginLoader loader) { ++ plugin_factory = new Rygel.LMS.PluginFactory(loader); ++} ++ ++public class Rygel.LMS.PluginFactory { ++ ++ PluginLoader loader; ++ ++ public PluginFactory(PluginLoader loader) { ++ this.loader = loader; ++ this.loader.add_plugin(new LMS.Plugin()); ++ } ++ ++} +diff --git a/src/plugins/lms/rygel-lms-plugin.vala b/src/plugins/lms/rygel-lms-plugin.vala +new file mode 100644 +index 0000000..8bf1284 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-plugin.vala +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++ ++public class Rygel.LMS.Plugin : Rygel.MediaServerPlugin { ++ public const string NAME = "LMS"; ++ ++ private static RootContainer root; ++ ++ public Plugin() { ++ if (root == null) ++ root = new RootContainer(); ++ base(root, Plugin.NAME, null, PluginCapabilities.TRACK_CHANGES); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-root-container.vala b/src/plugins/lms/rygel-lms-root-container.vala +new file mode 100644 +index 0000000..1623fa3 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-root-container.vala +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using Rygel; ++ ++using Sqlite; ++ ++public class Rygel.LMS.RootContainer : Rygel.SimpleContainer { ++ ++ private LMS.Database lms_db = null; ++ ++ public RootContainer() { ++ var config = MetaConfig.get_default (); ++ ++ var title = _("Shared media"); ++ try { ++ title = config.get_string ("LightMediaScanner", "title"); ++ } catch (GLib.Error error) {} ++ ++ base.root(title); ++ ++ try { ++ this.lms_db = new LMS.Database (); ++ ++ this.add_child_container (new MusicRoot ("music", this, _("Music"), this.lms_db)); ++ this.add_child_container (new AllVideos ("all-videos", this, _("Videos"), this.lms_db)); ++ this.add_child_container (new ImageRoot ("images", this, _("Pictures"), this.lms_db)); ++ ++ } catch (DatabaseError e) { ++ warning ("%s\n", e.message); ++ ++ /* TODO if db does not exist we should ++ wait for it to be created and then add folders. Best to wait for the ++ LMS notification API. */ ++ } ++ ++ } ++ ++} +diff --git a/src/plugins/lms/rygel-lms-sql-function.vala b/src/plugins/lms/rygel-lms-sql-function.vala +new file mode 100644 +index 0000000..e8580cc +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-sql-function.vala +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. ++ * ++ * Author: Jens Georg <mail@jensge.org> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++internal class Rygel.LMS.SqlFunction : SqlOperator { ++ public SqlFunction (string name, string arg) { ++ base (name, arg); ++ } ++ ++ public override string to_string () { ++ return "%s(%s,?)".printf (name, arg); ++ } ++} +diff --git a/src/plugins/lms/rygel-lms-sql-operator.vala b/src/plugins/lms/rygel-lms-sql-operator.vala +new file mode 100644 +index 0000000..fc4e907 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-sql-operator.vala +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. ++ * ++ * Author: Jens Georg <mail@jensge.org> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++using GUPnP; ++ ++internal class Rygel.LMS.SqlOperator : GLib.Object { ++ protected string name; ++ protected string arg; ++ protected string collate; ++ ++ public SqlOperator (string name, ++ string arg, ++ string collate = "") { ++ this.name = name; ++ this.arg = arg; ++ this.collate = collate; ++ } ++ ++ public SqlOperator.from_search_criteria_op (SearchCriteriaOp op, ++ string arg, ++ string collate) { ++ string sql = null; ++ switch (op) { ++ case SearchCriteriaOp.EQ: ++ sql = "="; ++ break; ++ case SearchCriteriaOp.NEQ: ++ sql = "!="; ++ break; ++ case SearchCriteriaOp.LESS: ++ sql = "<"; ++ break; ++ case SearchCriteriaOp.LEQ: ++ sql = "<="; ++ break; ++ case SearchCriteriaOp.GREATER: ++ sql = ">"; ++ break; ++ case SearchCriteriaOp.GEQ: ++ sql = ">="; ++ break; ++ default: ++ assert_not_reached (); ++ } ++ ++ this (sql, arg, collate); ++ } ++ ++ public virtual string to_string () { ++ return "(%s %s ? %s)".printf (arg, name, collate); ++ } ++} ++ ++ +-- +1.7.10.4 + diff --git a/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch b/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch new file mode 100644 index 000000000..bbd61aa27 --- /dev/null +++ b/meta-agl/recipes-connectivity/rygel/files/0002-lms-add-C-source-files.patch @@ -0,0 +1,9455 @@ +From 5a91b6b6efdaf28a6640126a32e819aef7e10a74 Mon Sep 17 00:00:00 2001 +From: Manuel Bachmann <manuel.bachmann@iot.bzh> +Date: Sun, 25 Oct 2015 14:21:28 +0100 +Subject: [PATCH] lms: add C source files + +C source files are normally generated by Vala at compile +time, but we do not use Vala for Rygel under OpenEmbedded +(because it requires GObject-Introspection support in +dependencies such as GUPnP, and that is still buggy). + +A full tarball release would contain the C files anyway, +so let us include them so the build succeeds with OE. + +Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh> +--- + src/plugins/lms/librygel_lms_la_vala.stamp | 1 + + src/plugins/lms/rygel-lms-album.c | 514 +++++ + src/plugins/lms/rygel-lms-albums.c | 569 +++++ + src/plugins/lms/rygel-lms-all-images.c | 305 +++ + src/plugins/lms/rygel-lms-all-music.c | 417 ++++ + src/plugins/lms/rygel-lms-all-videos.c | 456 ++++ + src/plugins/lms/rygel-lms-artist.c | 274 +++ + src/plugins/lms/rygel-lms-artists.c | 214 ++ + src/plugins/lms/rygel-lms-category-container.c | 2772 ++++++++++++++++++++++++ + src/plugins/lms/rygel-lms-database.c | 1349 ++++++++++++ + src/plugins/lms/rygel-lms-dbus-interfaces.c | 261 +++ + src/plugins/lms/rygel-lms-image-root.c | 178 ++ + src/plugins/lms/rygel-lms-image-year.c | 422 ++++ + src/plugins/lms/rygel-lms-image-years.c | 196 ++ + src/plugins/lms/rygel-lms-music-root.c | 202 ++ + src/plugins/lms/rygel-lms-plugin-factory.c | 307 +++ + src/plugins/lms/rygel-lms-plugin.c | 134 ++ + src/plugins/lms/rygel-lms-root-container.c | 318 +++ + src/plugins/lms/rygel-lms-sql-function.c | 146 ++ + src/plugins/lms/rygel-lms-sql-operator.c | 240 ++ + 21 files changed, 9276 insertions(+), 1 deletion(-) + create mode 100644 src/plugins/lms/librygel_lms_la_vala.stamp + create mode 100644 src/plugins/lms/rygel-lms-album.c + create mode 100644 src/plugins/lms/rygel-lms-albums.c + create mode 100644 src/plugins/lms/rygel-lms-all-images.c + create mode 100644 src/plugins/lms/rygel-lms-all-music.c + create mode 100644 src/plugins/lms/rygel-lms-all-videos.c + create mode 100644 src/plugins/lms/rygel-lms-artist.c + create mode 100644 src/plugins/lms/rygel-lms-artists.c + create mode 100644 src/plugins/lms/rygel-lms-category-container.c + create mode 100644 src/plugins/lms/rygel-lms-database.c + create mode 100644 src/plugins/lms/rygel-lms-dbus-interfaces.c + create mode 100644 src/plugins/lms/rygel-lms-image-root.c + create mode 100644 src/plugins/lms/rygel-lms-image-year.c + create mode 100644 src/plugins/lms/rygel-lms-image-years.c + create mode 100644 src/plugins/lms/rygel-lms-music-root.c + create mode 100644 src/plugins/lms/rygel-lms-plugin-factory.c + create mode 100644 src/plugins/lms/rygel-lms-plugin.c + create mode 100644 src/plugins/lms/rygel-lms-root-container.c + create mode 100644 src/plugins/lms/rygel-lms-sql-function.c + create mode 100644 src/plugins/lms/rygel-lms-sql-operator.c + +diff --git a/src/plugins/lms/librygel_lms_la_vala.stamp b/src/plugins/lms/librygel_lms_la_vala.stamp +new file mode 100644 +index 0000000..859afb1 +--- /dev/null ++++ b/src/plugins/lms/librygel_lms_la_vala.stamp +@@ -0,0 +1 @@ ++stamp +diff --git a/src/plugins/lms/rygel-lms-album.c b/src/plugins/lms/rygel-lms-album.c +new file mode 100644 +index 0000000..9da60bc +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-album.c +@@ -0,0 +1,514 @@ ++/* rygel-lms-album.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-album.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gio/gio.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) ++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) ++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++ ++typedef struct _RygelLMSAlbum RygelLMSAlbum; ++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; ++typedef struct _RygelLMSAlbumPrivate RygelLMSAlbumPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSAlbum { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSAlbumPrivate * priv; ++}; ++ ++struct _RygelLMSAlbumClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_album_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_album_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ALBUM_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;" ++#define RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s;" ++#define RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \ ++"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id AND audios.a" \ ++"lbum_id = %s;" ++#define RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;" ++#define RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "WHERE dtime <> 0 AND audios.id = files.id AND audios.album_id = %s " "AND update_id > ? AND update_id <= ?;" ++static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); ++static gchar* rygel_lms_album_get_sql_all (const gchar* db_id); ++static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id); ++static gchar* rygel_lms_album_get_sql_count (const gchar* db_id); ++static gchar* rygel_lms_album_get_sql_added (const gchar* db_id); ++static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id); ++static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); ++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self); ++static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_album_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSAlbum * self; ++ RygelMediaObject* result = NULL; ++ gint id = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* path = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* mime_type = NULL; ++ sqlite3_stmt* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ gboolean _tmp8_ = FALSE; ++ const gchar* _tmp9_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ gchar* song_id = NULL; ++ gint _tmp18_ = 0; ++ gchar* _tmp19_ = NULL; ++ RygelMusicItem* song = NULL; ++ RygelMusicItem* _tmp20_ = NULL; ++ gint _tmp21_ = 0; ++ gchar* _tmp22_ = NULL; ++ gchar* _tmp23_ = NULL; ++ sqlite3_stmt* _tmp24_ = NULL; ++ gint _tmp25_ = 0; ++ sqlite3_stmt* _tmp26_ = NULL; ++ gint _tmp27_ = 0; ++ sqlite3_stmt* _tmp28_ = NULL; ++ gint _tmp29_ = 0; ++ sqlite3_stmt* _tmp30_ = NULL; ++ gint _tmp31_ = 0; ++ sqlite3_stmt* _tmp32_ = NULL; ++ gint _tmp33_ = 0; ++ sqlite3_stmt* _tmp34_ = NULL; ++ gint _tmp35_ = 0; ++ sqlite3_stmt* _tmp36_ = NULL; ++ const gchar* _tmp37_ = NULL; ++ const gchar* _tmp38_ = NULL; ++ sqlite3_stmt* _tmp39_ = NULL; ++ const gchar* _tmp40_ = NULL; ++ sqlite3_stmt* _tmp41_ = NULL; ++ const gchar* _tmp42_ = NULL; ++ GFile* file = NULL; ++ const gchar* _tmp43_ = NULL; ++ GFile* _tmp44_ = NULL; ++ gchar* _tmp45_ = NULL; ++ gchar* _tmp46_ = NULL; ++ self = (RygelLMSAlbum*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ id = _tmp1_; ++ _tmp2_ = statement; ++ _tmp3_ = sqlite3_column_text (_tmp2_, 1); ++ _tmp4_ = g_strdup (_tmp3_); ++ path = _tmp4_; ++ _tmp5_ = statement; ++ _tmp6_ = sqlite3_column_text (_tmp5_, 10); ++ _tmp7_ = g_strdup (_tmp6_); ++ mime_type = _tmp7_; ++ _tmp9_ = mime_type; ++ if (_tmp9_ == NULL) { ++ _tmp8_ = TRUE; ++ } else { ++ const gchar* _tmp10_ = NULL; ++ gint _tmp11_ = 0; ++ gint _tmp12_ = 0; ++ _tmp10_ = mime_type; ++ _tmp11_ = strlen (_tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp8_ = _tmp12_ == 0; ++ } ++ if (_tmp8_) { ++ gint _tmp13_ = 0; ++ const gchar* _tmp14_ = NULL; ++ _tmp13_ = id; ++ _tmp14_ = path; ++ g_debug ("rygel-lms-album.vala:101: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_); ++ } ++ _tmp15_ = statement; ++ _tmp16_ = sqlite3_column_text (_tmp15_, 3); ++ _tmp17_ = g_strdup (_tmp16_); ++ title = _tmp17_; ++ _tmp18_ = id; ++ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); ++ song_id = _tmp19_; ++ _tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS); ++ song = _tmp20_; ++ _tmp21_ = id; ++ _tmp22_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp21_); ++ _tmp23_ = _tmp22_; ++ rygel_media_object_set_ref_id ((RygelMediaObject*) song, _tmp23_); ++ _g_free0 (_tmp23_); ++ _tmp24_ = statement; ++ _tmp25_ = sqlite3_column_int (_tmp24_, 2); ++ rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp25_); ++ _tmp26_ = statement; ++ _tmp27_ = sqlite3_column_int (_tmp26_, 4); ++ rygel_music_item_set_track_number (song, _tmp27_); ++ _tmp28_ = statement; ++ _tmp29_ = sqlite3_column_int (_tmp28_, 5); ++ rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp29_); ++ _tmp30_ = statement; ++ _tmp31_ = sqlite3_column_int (_tmp30_, 6); ++ rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp31_); ++ _tmp32_ = statement; ++ _tmp33_ = sqlite3_column_int (_tmp32_, 7); ++ rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp33_); ++ _tmp34_ = statement; ++ _tmp35_ = sqlite3_column_int (_tmp34_, 8); ++ rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp35_); ++ _tmp36_ = statement; ++ _tmp37_ = sqlite3_column_text (_tmp36_, 9); ++ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp37_); ++ _tmp38_ = mime_type; ++ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp38_); ++ _tmp39_ = statement; ++ _tmp40_ = sqlite3_column_text (_tmp39_, 11); ++ rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp40_); ++ _tmp41_ = statement; ++ _tmp42_ = sqlite3_column_text (_tmp41_, 12); ++ rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp42_); ++ _tmp43_ = path; ++ _tmp44_ = g_file_new_for_path (_tmp43_); ++ file = _tmp44_; ++ _tmp45_ = g_file_get_uri (file); ++ _tmp46_ = _tmp45_; ++ rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp46_); ++ _g_free0 (_tmp46_); ++ result = (RygelMediaObject*) song; ++ _g_object_unref0 (file); ++ _g_free0 (song_id); ++ _g_free0 (title); ++ _g_free0 (mime_type); ++ _g_free0 (path); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_get_sql_all (const gchar* db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_get_sql_find_object (const gchar* db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_get_sql_count (const gchar* db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_get_sql_added (const gchar* db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ADDED_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_get_sql_removed (const gchar* db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_REMOVED_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAlbum * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ gchar* filter_str = NULL; ++ const gchar* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ self = (RygelLMSAlbum*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ const gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ _tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self); ++ _tmp4_ = _tmp3_; ++ _tmp5_ = g_strdup (_tmp4_); ++ result = _tmp5_; ++ return result; ++ } ++ _tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self); ++ _tmp7_ = _tmp6_; ++ _tmp8_ = filter; ++ _tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_); ++ filter_str = _tmp9_; ++ _tmp10_ = filter_str; ++ _tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_ALL_TEMPLATE, _tmp10_); ++ result = _tmp11_; ++ _g_free0 (filter_str); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_album_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAlbum * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ gchar* filter_str = NULL; ++ const gchar* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ self = (RygelLMSAlbum*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ const gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ _tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self); ++ _tmp4_ = _tmp3_; ++ _tmp5_ = g_strdup (_tmp4_); ++ result = _tmp5_; ++ return result; ++ } ++ _tmp6_ = rygel_lms_category_container_get_db_id ((RygelLMSCategoryContainer*) self); ++ _tmp7_ = _tmp6_; ++ _tmp8_ = filter; ++ _tmp9_ = g_strdup_printf ("%s AND %s", _tmp7_, _tmp8_); ++ filter_str = _tmp9_; ++ _tmp10_ = filter_str; ++ _tmp11_ = g_strdup_printf (RYGEL_LMS_ALBUM_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp10_); ++ result = _tmp11_; ++ _g_free0 (filter_str); ++ return result; ++} ++ ++ ++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSAlbum * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ gchar* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ const gchar* _tmp13_ = NULL; ++ gchar* _tmp14_ = NULL; ++ gchar* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ gchar* _tmp18_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = db_id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ _tmp3_ = lms_db; ++ _tmp4_ = db_id; ++ _tmp5_ = rygel_lms_album_get_sql_all (_tmp4_); ++ _tmp6_ = _tmp5_; ++ _tmp7_ = db_id; ++ _tmp8_ = rygel_lms_album_get_sql_find_object (_tmp7_); ++ _tmp9_ = _tmp8_; ++ _tmp10_ = db_id; ++ _tmp11_ = rygel_lms_album_get_sql_count (_tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp13_ = db_id; ++ _tmp14_ = rygel_lms_album_get_sql_added (_tmp13_); ++ _tmp15_ = _tmp14_; ++ _tmp16_ = db_id; ++ _tmp17_ = rygel_lms_album_get_sql_removed (_tmp16_); ++ _tmp18_ = _tmp17_; ++ self = (RygelLMSAlbum*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, _tmp15_, _tmp18_); ++ _g_free0 (_tmp18_); ++ _g_free0 (_tmp15_); ++ _g_free0 (_tmp12_); ++ _g_free0 (_tmp9_); ++ _g_free0 (_tmp6_); ++ return self; ++} ++ ++ ++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_album_construct (RYGEL_LMS_TYPE_ALBUM, db_id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_album_class_init (RygelLMSAlbumClass * klass) { ++ rygel_lms_album_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_album_real_object_from_statement; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_album_real_get_sql_all_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_album_real_get_sql_count_with_filter; ++} ++ ++ ++static void rygel_lms_album_instance_init (RygelLMSAlbum * self) { ++} ++ ++ ++GType rygel_lms_album_get_type (void) { ++ static volatile gsize rygel_lms_album_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_album_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_album_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbum), 0, (GInstanceInitFunc) rygel_lms_album_instance_init, NULL }; ++ GType rygel_lms_album_type_id; ++ rygel_lms_album_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbum", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_album_type_id__volatile, rygel_lms_album_type_id); ++ } ++ return rygel_lms_album_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-albums.c b/src/plugins/lms/rygel-lms-albums.c +new file mode 100644 +index 0000000..f9fabe7 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-albums.c +@@ -0,0 +1,569 @@ ++/* rygel-lms-albums.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-albums.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gee.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ()) ++#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums)) ++#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) ++#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS)) ++#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS)) ++#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) ++ ++typedef struct _RygelLMSAlbums RygelLMSAlbums; ++typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass; ++typedef struct _RygelLMSAlbumsPrivate RygelLMSAlbumsPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) ++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) ++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) ++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++ ++typedef struct _RygelLMSAlbum RygelLMSAlbum; ++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSAlbums { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSAlbumsPrivate * priv; ++}; ++ ++struct _RygelLMSAlbumsClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++typedef enum { ++ RYGEL_LMS_DATABASE_ERROR_OPEN, ++ RYGEL_LMS_DATABASE_ERROR_PREPARE, ++ RYGEL_LMS_DATABASE_ERROR_BIND, ++ RYGEL_LMS_DATABASE_ERROR_STEP, ++ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND ++} RygelLMSDatabaseError; ++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () ++ ++static gpointer rygel_lms_albums_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_albums_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ALBUMS_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ALBUMS_SQL_ALL "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE "SELECT audio_albums.id, audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALBUMS_SQL_COUNT "SELECT COUNT(audio_albums.id) " "FROM audio_albums;" ++#define RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audio_albums.id), audio_albums.name as title, " "audio_artists.name as artist " "FROM audio_albums " "LEFT JOIN audio_artists " "ON audio_albums.artist_id = audio_artists.id " "WHERE %s;" ++#define RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \ ++"lbums.id %s;" ++#define RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, audio_albums.id " "FROM audios, files, audio_albums " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id AND audios.album_id = audio_a" \ ++"lbums.id %s " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ?;" ++static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args); ++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++GQuark rygel_lms_database_error_quark (void); ++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); ++static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); ++GType rygel_lms_album_get_type (void) G_GNUC_CONST; ++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static gchar* rygel_lms_albums_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAlbums * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ self = (RygelLMSAlbums*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ gchar* _tmp3_ = NULL; ++ _tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_ALL); ++ result = _tmp3_; ++ return result; ++ } ++ _tmp4_ = filter; ++ _tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_ALL_WITH_FILTER_TEMPLATE, _tmp4_); ++ result = _tmp5_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_albums_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAlbums * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ self = (RygelLMSAlbums*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ gchar* _tmp3_ = NULL; ++ _tmp3_ = g_strdup (RYGEL_LMS_ALBUMS_SQL_COUNT); ++ result = _tmp3_; ++ return result; ++ } ++ _tmp4_ = filter; ++ _tmp5_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp4_); ++ result = _tmp5_; ++ return result; ++} ++ ++ ++static guint rygel_lms_albums_real_get_child_count_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args) { ++ RygelLMSAlbums * self; ++ guint result = 0U; ++ guint count = 0U; ++ const gchar* _tmp0_ = NULL; ++ GValueArray* _tmp1_ = NULL; ++ guint _tmp2_ = 0U; ++ gchar* filter = NULL; ++ gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gint _tmp5_ = 0; ++ gint _tmp6_ = 0; ++ gchar* query = NULL; ++ const gchar* _tmp9_ = NULL; ++ gchar* _tmp10_ = NULL; ++ GError * _inner_error_ = NULL; ++ self = (RygelLMSAlbums*) base; ++ g_return_val_if_fail (where_filter != NULL, 0U); ++ g_return_val_if_fail (args != NULL, 0U); ++ _tmp0_ = where_filter; ++ _tmp1_ = args; ++ _tmp2_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_child_count_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_); ++ count = _tmp2_; ++ _tmp3_ = g_strdup (""); ++ filter = _tmp3_; ++ _tmp4_ = where_filter; ++ _tmp5_ = strlen (_tmp4_); ++ _tmp6_ = _tmp5_; ++ if (_tmp6_ > 0) { ++ const gchar* _tmp7_ = NULL; ++ gchar* _tmp8_ = NULL; ++ _tmp7_ = where_filter; ++ _tmp8_ = g_strdup_printf ("AND %s", _tmp7_); ++ _g_free0 (filter); ++ filter = _tmp8_; ++ } ++ _tmp9_ = filter; ++ _tmp10_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_COUNT_WITH_FILTER_TEMPLATE, _tmp9_); ++ query = _tmp10_; ++ { ++ sqlite3_stmt* stmt = NULL; ++ RygelLMSDatabase* _tmp11_ = NULL; ++ RygelLMSDatabase* _tmp12_ = NULL; ++ GValueArray* _tmp13_ = NULL; ++ GValue* _tmp14_ = NULL; ++ gint _tmp14__length1 = 0; ++ sqlite3_stmt* _tmp15_ = NULL; ++ gint _tmp16_ = 0; ++ _tmp11_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp12_ = _tmp11_; ++ _tmp13_ = args; ++ _tmp14_ = _tmp13_->values; ++ _tmp14__length1 = (gint) _tmp13_->n_values; ++ _tmp15_ = rygel_lms_database_prepare_and_init (_tmp12_, query, _tmp14_, _tmp14__length1, &_inner_error_); ++ stmt = _tmp15_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch8_rygel_lms_database_error; ++ } ++ _g_free0 (query); ++ _g_free0 (filter); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return 0U; ++ } ++ _tmp16_ = sqlite3_step (stmt); ++ if (_tmp16_ == SQLITE_ROW) { ++ guint _tmp17_ = 0U; ++ gint _tmp18_ = 0; ++ _tmp17_ = count; ++ _tmp18_ = sqlite3_column_int (stmt, 0); ++ count = _tmp17_ + _tmp18_; ++ } ++ _sqlite3_finalize0 (stmt); ++ } ++ goto __finally8; ++ __catch8_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp19_ = NULL; ++ const gchar* _tmp20_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp19_ = e; ++ _tmp20_ = _tmp19_->message; ++ g_warning ("rygel-lms-albums.vala:116: Query failed: %s", _tmp20_); ++ _g_error_free0 (e); ++ } ++ __finally8: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (query); ++ _g_free0 (filter); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return 0U; ++ } ++ result = count; ++ _g_free0 (query); ++ _g_free0 (filter); ++ return result; ++} ++ ++ ++static RygelMediaObjects* rygel_lms_albums_real_get_children_with_filter (RygelLMSCategoryContainer* base, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { ++ RygelLMSAlbums * self; ++ RygelMediaObjects* result = NULL; ++ RygelMediaObjects* children = NULL; ++ const gchar* _tmp0_ = NULL; ++ GValueArray* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ guint _tmp3_ = 0U; ++ guint _tmp4_ = 0U; ++ RygelMediaObjects* _tmp5_ = NULL; ++ gchar* filter = NULL; ++ gchar* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ gint _tmp8_ = 0; ++ gint _tmp9_ = 0; ++ gchar* query = NULL; ++ const gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ GError * _inner_error_ = NULL; ++ self = (RygelLMSAlbums*) base; ++ g_return_val_if_fail (where_filter != NULL, NULL); ++ g_return_val_if_fail (args != NULL, NULL); ++ g_return_val_if_fail (sort_criteria != NULL, NULL); ++ _tmp0_ = where_filter; ++ _tmp1_ = args; ++ _tmp2_ = sort_criteria; ++ _tmp3_ = offset; ++ _tmp4_ = max_count; ++ _tmp5_ = RYGEL_LMS_CATEGORY_CONTAINER_CLASS (rygel_lms_albums_parent_class)->get_children_with_filter (G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer), _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp4_); ++ children = _tmp5_; ++ _tmp6_ = g_strdup (""); ++ filter = _tmp6_; ++ _tmp7_ = where_filter; ++ _tmp8_ = strlen (_tmp7_); ++ _tmp9_ = _tmp8_; ++ if (_tmp9_ > 0) { ++ const gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ _tmp10_ = where_filter; ++ _tmp11_ = g_strdup_printf ("AND %s", _tmp10_); ++ _g_free0 (filter); ++ filter = _tmp11_; ++ } ++ _tmp12_ = filter; ++ _tmp13_ = g_strdup_printf (RYGEL_LMS_ALBUMS_SQL_CHILD_ALL_WITH_FILTER_TEMPLATE, _tmp12_); ++ query = _tmp13_; ++ { ++ sqlite3_stmt* stmt = NULL; ++ RygelLMSDatabase* _tmp14_ = NULL; ++ RygelLMSDatabase* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ GValueArray* _tmp17_ = NULL; ++ GValue* _tmp18_ = NULL; ++ gint _tmp18__length1 = 0; ++ sqlite3_stmt* _tmp19_ = NULL; ++ _tmp14_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp15_ = _tmp14_; ++ _tmp16_ = query; ++ _tmp17_ = args; ++ _tmp18_ = _tmp17_->values; ++ _tmp18__length1 = (gint) _tmp17_->n_values; ++ _tmp19_ = rygel_lms_database_prepare_and_init (_tmp15_, _tmp16_, _tmp18_, _tmp18__length1, &_inner_error_); ++ stmt = _tmp19_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch9_rygel_lms_database_error; ++ } ++ _g_free0 (query); ++ _g_free0 (filter); ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ while (TRUE) { ++ gboolean _tmp20_ = FALSE; ++ sqlite3_stmt* _tmp21_ = NULL; ++ gboolean _tmp22_ = FALSE; ++ gchar* album_id = NULL; ++ sqlite3_stmt* _tmp23_ = NULL; ++ const gchar* _tmp24_ = NULL; ++ gchar* _tmp25_ = NULL; ++ RygelLMSAlbum* album = NULL; ++ const gchar* _tmp26_ = NULL; ++ RygelLMSDatabase* _tmp27_ = NULL; ++ RygelLMSDatabase* _tmp28_ = NULL; ++ RygelLMSAlbum* _tmp29_ = NULL; ++ RygelMediaObject* song = NULL; ++ RygelLMSAlbum* _tmp30_ = NULL; ++ sqlite3_stmt* _tmp31_ = NULL; ++ RygelMediaObject* _tmp32_ = NULL; ++ RygelMediaObject* _tmp33_ = NULL; ++ RygelMediaObject* _tmp34_ = NULL; ++ RygelMediaContainer* _tmp35_ = NULL; ++ RygelMediaContainer* _tmp36_ = NULL; ++ RygelMediaObjects* _tmp37_ = NULL; ++ RygelMediaObject* _tmp38_ = NULL; ++ _tmp21_ = stmt; ++ _tmp22_ = rygel_lms_database_get_children_step (_tmp21_, &_inner_error_); ++ _tmp20_ = _tmp22_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch9_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt); ++ _g_free0 (query); ++ _g_free0 (filter); ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ if (!_tmp20_) { ++ break; ++ } ++ _tmp23_ = stmt; ++ _tmp24_ = sqlite3_column_text (_tmp23_, 13); ++ _tmp25_ = g_strdup (_tmp24_); ++ album_id = _tmp25_; ++ _tmp26_ = album_id; ++ _tmp27_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp28_ = _tmp27_; ++ _tmp29_ = rygel_lms_album_new (_tmp26_, (RygelMediaContainer*) self, "", _tmp28_); ++ album = _tmp29_; ++ _tmp30_ = album; ++ _tmp31_ = stmt; ++ _tmp32_ = rygel_lms_category_container_object_from_statement ((RygelLMSCategoryContainer*) _tmp30_, _tmp31_); ++ song = _tmp32_; ++ _tmp33_ = song; ++ _tmp34_ = song; ++ _tmp35_ = rygel_media_object_get_parent (_tmp34_); ++ _tmp36_ = _tmp35_; ++ rygel_media_object_set_parent_ref (_tmp33_, _tmp36_); ++ _tmp37_ = children; ++ _tmp38_ = song; ++ gee_abstract_collection_add ((GeeAbstractCollection*) _tmp37_, _tmp38_); ++ _g_object_unref0 (song); ++ _g_object_unref0 (album); ++ _g_free0 (album_id); ++ } ++ _sqlite3_finalize0 (stmt); ++ } ++ goto __finally9; ++ __catch9_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp39_ = NULL; ++ const gchar* _tmp40_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp39_ = e; ++ _tmp40_ = _tmp39_->message; ++ g_warning ("rygel-lms-albums.vala:149: Query failed: %s", _tmp40_); ++ _g_error_free0 (e); ++ } ++ __finally9: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (query); ++ _g_free0 (filter); ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ result = children; ++ _g_free0 (query); ++ _g_free0 (filter); ++ return result; ++} ++ ++ ++static RygelMediaObject* rygel_lms_albums_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSAlbums * self; ++ RygelMediaObject* result = NULL; ++ gchar* id = NULL; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* _tmp2_ = NULL; ++ RygelLMSAlbum* album = NULL; ++ sqlite3_stmt* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ RygelLMSDatabase* _tmp5_ = NULL; ++ RygelLMSDatabase* _tmp6_ = NULL; ++ RygelLMSAlbum* _tmp7_ = NULL; ++ self = (RygelLMSAlbums*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ _tmp2_ = g_strdup_printf ("%d", _tmp1_); ++ id = _tmp2_; ++ _tmp3_ = statement; ++ _tmp4_ = sqlite3_column_text (_tmp3_, 1); ++ _tmp5_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp6_ = _tmp5_; ++ _tmp7_ = rygel_lms_album_new (id, (RygelMediaContainer*) self, _tmp4_, _tmp6_); ++ album = _tmp7_; ++ result = (RygelMediaObject*) album; ++ _g_free0 (id); ++ return result; ++} ++ ++ ++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ RygelLMSAlbums * self = NULL; ++ RygelMediaContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = parent; ++ _tmp1_ = _ ("Albums"); ++ _tmp2_ = lms_db; ++ self = (RygelLMSAlbums*) rygel_lms_category_container_construct (object_type, "albums", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALBUMS_SQL_ALL, RYGEL_LMS_ALBUMS_SQL_FIND_OBJECT, RYGEL_LMS_ALBUMS_SQL_COUNT, NULL, NULL); ++ return self; ++} ++ ++ ++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ return rygel_lms_albums_construct (RYGEL_LMS_TYPE_ALBUMS, parent, lms_db); ++} ++ ++ ++static void rygel_lms_albums_class_init (RygelLMSAlbumsClass * klass) { ++ rygel_lms_albums_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_albums_real_get_sql_all_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_albums_real_get_sql_count_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_albums_real_get_child_count_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_albums_real_get_children_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_albums_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_albums_instance_init (RygelLMSAlbums * self) { ++} ++ ++ ++GType rygel_lms_albums_get_type (void) { ++ static volatile gsize rygel_lms_albums_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_albums_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAlbumsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_albums_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAlbums), 0, (GInstanceInitFunc) rygel_lms_albums_instance_init, NULL }; ++ GType rygel_lms_albums_type_id; ++ rygel_lms_albums_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAlbums", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_albums_type_id__volatile, rygel_lms_albums_type_id); ++ } ++ return rygel_lms_albums_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-all-images.c b/src/plugins/lms/rygel-lms-all-images.c +new file mode 100644 +index 0000000..33fb8c1 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-images.c +@@ -0,0 +1,305 @@ ++/* rygel-lms-all-images.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-all-images.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gio/gio.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ()) ++#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages)) ++#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) ++#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES)) ++#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES)) ++#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) ++ ++typedef struct _RygelLMSAllImages RygelLMSAllImages; ++typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass; ++typedef struct _RygelLMSAllImagesPrivate RygelLMSAllImagesPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSAllImages { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSAllImagesPrivate * priv; ++}; ++ ++struct _RygelLMSAllImagesClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_all_images_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_images_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ALL_IMAGES_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ALL_IMAGES_SQL_ALL "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALL_IMAGES_SQL_COUNT "SELECT count(images.id) " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id;" ++#define RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id;" ++#define RYGEL_LMS_ALL_IMAGES_SQL_ADDED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;" ++#define RYGEL_LMS_ALL_IMAGES_SQL_REMOVED "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id " "AND update_id > ? AND update_id <= ?;" ++static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_all_images_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSAllImages * self; ++ RygelMediaObject* result = NULL; ++ gint id = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* path = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* mime_type = NULL; ++ sqlite3_stmt* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ gboolean _tmp8_ = FALSE; ++ const gchar* _tmp9_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ RygelImageItem* image = NULL; ++ gint _tmp18_ = 0; ++ gchar* _tmp19_ = NULL; ++ gchar* _tmp20_ = NULL; ++ RygelImageItem* _tmp21_ = NULL; ++ RygelImageItem* _tmp22_ = NULL; ++ sqlite3_stmt* _tmp23_ = NULL; ++ const gchar* _tmp24_ = NULL; ++ GTimeVal tv = {0}; ++ sqlite3_stmt* _tmp25_ = NULL; ++ gint _tmp26_ = 0; ++ GTimeVal _tmp27_ = {0}; ++ gchar* _tmp28_ = NULL; ++ gchar* _tmp29_ = NULL; ++ sqlite3_stmt* _tmp30_ = NULL; ++ gint _tmp31_ = 0; ++ sqlite3_stmt* _tmp32_ = NULL; ++ gint _tmp33_ = 0; ++ sqlite3_stmt* _tmp34_ = NULL; ++ gint _tmp35_ = 0; ++ const gchar* _tmp36_ = NULL; ++ sqlite3_stmt* _tmp37_ = NULL; ++ const gchar* _tmp38_ = NULL; ++ GFile* file = NULL; ++ const gchar* _tmp39_ = NULL; ++ GFile* _tmp40_ = NULL; ++ gchar* _tmp41_ = NULL; ++ gchar* _tmp42_ = NULL; ++ self = (RygelLMSAllImages*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ id = _tmp1_; ++ _tmp2_ = statement; ++ _tmp3_ = sqlite3_column_text (_tmp2_, 6); ++ _tmp4_ = g_strdup (_tmp3_); ++ path = _tmp4_; ++ _tmp5_ = statement; ++ _tmp6_ = sqlite3_column_text (_tmp5_, 9); ++ _tmp7_ = g_strdup (_tmp6_); ++ mime_type = _tmp7_; ++ _tmp9_ = mime_type; ++ if (_tmp9_ == NULL) { ++ _tmp8_ = TRUE; ++ } else { ++ const gchar* _tmp10_ = NULL; ++ gint _tmp11_ = 0; ++ gint _tmp12_ = 0; ++ _tmp10_ = mime_type; ++ _tmp11_ = strlen (_tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp8_ = _tmp12_ == 0; ++ } ++ if (_tmp8_) { ++ gint _tmp13_ = 0; ++ const gchar* _tmp14_ = NULL; ++ _tmp13_ = id; ++ _tmp14_ = path; ++ g_debug ("rygel-lms-all-images.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_); ++ } ++ _tmp15_ = statement; ++ _tmp16_ = sqlite3_column_text (_tmp15_, 1); ++ _tmp17_ = g_strdup (_tmp16_); ++ title = _tmp17_; ++ _tmp18_ = id; ++ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); ++ _tmp20_ = _tmp19_; ++ _tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS); ++ _tmp22_ = _tmp21_; ++ _g_free0 (_tmp20_); ++ image = _tmp22_; ++ _tmp23_ = statement; ++ _tmp24_ = sqlite3_column_text (_tmp23_, 2); ++ rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp24_); ++ _tmp25_ = statement; ++ _tmp26_ = sqlite3_column_int (_tmp25_, 3); ++ _tmp27_.tv_sec = (glong) _tmp26_; ++ _tmp27_.tv_usec = (glong) 0; ++ tv = _tmp27_; ++ _tmp28_ = g_time_val_to_iso8601 (&tv); ++ _tmp29_ = _tmp28_; ++ rygel_media_object_set_date ((RygelMediaObject*) image, _tmp29_); ++ _g_free0 (_tmp29_); ++ _tmp30_ = statement; ++ _tmp31_ = sqlite3_column_int (_tmp30_, 4); ++ rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp31_); ++ _tmp32_ = statement; ++ _tmp33_ = sqlite3_column_int (_tmp32_, 5); ++ rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp33_); ++ _tmp34_ = statement; ++ _tmp35_ = sqlite3_column_int (_tmp34_, 7); ++ rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp35_); ++ _tmp36_ = mime_type; ++ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp36_); ++ _tmp37_ = statement; ++ _tmp38_ = sqlite3_column_text (_tmp37_, 8); ++ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp38_); ++ _tmp39_ = path; ++ _tmp40_ = g_file_new_for_path (_tmp39_); ++ file = _tmp40_; ++ _tmp41_ = g_file_get_uri (file); ++ _tmp42_ = _tmp41_; ++ rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp42_); ++ _g_free0 (_tmp42_); ++ result = (RygelMediaObject*) image; ++ _g_object_unref0 (file); ++ _g_free0 (title); ++ _g_free0 (mime_type); ++ _g_free0 (path); ++ return result; ++} ++ ++ ++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ RygelLMSAllImages * self = NULL; ++ RygelMediaContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = parent; ++ _tmp1_ = _ ("All"); ++ _tmp2_ = lms_db; ++ self = (RygelLMSAllImages*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_ALL_IMAGES_SQL_ALL, RYGEL_LMS_ALL_IMAGES_SQL_FIND_OBJECT, RYGEL_LMS_ALL_IMAGES_SQL_COUNT, RYGEL_LMS_ALL_IMAGES_SQL_ADDED, RYGEL_LMS_ALL_IMAGES_SQL_REMOVED); ++ return self; ++} ++ ++ ++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ return rygel_lms_all_images_construct (RYGEL_LMS_TYPE_ALL_IMAGES, parent, lms_db); ++} ++ ++ ++static void rygel_lms_all_images_class_init (RygelLMSAllImagesClass * klass) { ++ rygel_lms_all_images_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_images_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_all_images_instance_init (RygelLMSAllImages * self) { ++} ++ ++ ++GType rygel_lms_all_images_get_type (void) { ++ static volatile gsize rygel_lms_all_images_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_all_images_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllImagesClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_images_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllImages), 0, (GInstanceInitFunc) rygel_lms_all_images_instance_init, NULL }; ++ GType rygel_lms_all_images_type_id; ++ rygel_lms_all_images_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllImages", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_all_images_type_id__volatile, rygel_lms_all_images_type_id); ++ } ++ return rygel_lms_all_images_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-all-music.c b/src/plugins/lms/rygel-lms-all-music.c +new file mode 100644 +index 0000000..ee6118f +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-music.c +@@ -0,0 +1,417 @@ ++/* rygel-lms-all-music.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-all-music.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gio/gio.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ()) ++#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic)) ++#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) ++#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC)) ++#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC)) ++#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) ++ ++typedef struct _RygelLMSAllMusic RygelLMSAllMusic; ++typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass; ++typedef struct _RygelLMSAllMusicPrivate RygelLMSAllMusicPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSAllMusic { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSAllMusicPrivate * priv; ++}; ++ ++struct _RygelLMSAllMusicClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_all_music_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_music_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ALL_MUSIC_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id %s " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT "SELECT COUNT(audios.id) " "FROM audios, files " "WHERE dtime = 0 AND audios.id = files.id;" ++#define RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE "SELECT COUNT(audios.id), audios.title as title, " "audio_artists.name as artist " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "WHERE dtime = 0 AND audios.id = files.id %s;" ++#define RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT "SELECT files.id, files.path, files.size, " "audios.title, audios.trackno, audios.length, audios.channels, audios.s" \ ++"ampling_rate, audios.bitrate, audios.dlna_profile, audios.dlna_mime, " "audio_artists.name, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND files.id = ? AND audios.id = files.id;" ++#define RYGEL_LMS_ALL_MUSIC_SQL_ADDED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime = 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;" ++#define RYGEL_LMS_ALL_MUSIC_SQL_REMOVED "SELECT files.id, files.path, files.size, " "audios.title as title, audios.trackno, audios.length, audios.channels," \ ++" audios.sampling_rate, audios.bitrate, audios.dlna_profile, audios.dln" \ ++"a_mime, " "audio_artists.name as artist, " "audio_albums.name, " "files.mtime, " "audio_genres.name " "FROM audios, files " "LEFT JOIN audio_artists " "ON audios.artist_id = audio_artists.id " "LEFT JOIN audio_albums " "ON audios.album_id = audio_albums.id " "LEFT JOIN audio_genres " "ON audios.genre_id = audio_genres.id " "WHERE dtime <> 0 AND audios.id = files.id " "AND update_id > ? AND update_id <= ?;" ++static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); ++static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); ++static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static gchar* rygel_lms_all_music_real_get_sql_all_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAllMusic * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ gchar* filter_str = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ self = (RygelLMSAllMusic*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ const gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ _tmp3_ = rygel_lms_category_container_get_sql_all ((RygelLMSCategoryContainer*) self); ++ _tmp4_ = _tmp3_; ++ _tmp5_ = g_strdup (_tmp4_); ++ result = _tmp5_; ++ return result; ++ } ++ _tmp6_ = filter; ++ _tmp7_ = g_strdup_printf ("AND %s", _tmp6_); ++ filter_str = _tmp7_; ++ _tmp8_ = filter_str; ++ _tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, _tmp8_); ++ result = _tmp9_; ++ _g_free0 (filter_str); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_all_music_real_get_sql_count_with_filter (RygelLMSCategoryContainer* base, const gchar* filter) { ++ RygelLMSAllMusic * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ gchar* filter_str = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ self = (RygelLMSAllMusic*) base; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = filter; ++ _tmp1_ = strlen (_tmp0_); ++ _tmp2_ = _tmp1_; ++ if (_tmp2_ == 0) { ++ const gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ _tmp3_ = rygel_lms_category_container_get_sql_count ((RygelLMSCategoryContainer*) self); ++ _tmp4_ = _tmp3_; ++ _tmp5_ = g_strdup (_tmp4_); ++ result = _tmp5_; ++ return result; ++ } ++ _tmp6_ = filter; ++ _tmp7_ = g_strdup_printf ("AND %s", _tmp6_); ++ filter_str = _tmp7_; ++ _tmp8_ = filter_str; ++ _tmp9_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_COUNT_WITH_FILTER_TEMPLATE, _tmp8_); ++ result = _tmp9_; ++ _g_free0 (filter_str); ++ return result; ++} ++ ++ ++static RygelMediaObject* rygel_lms_all_music_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSAllMusic * self; ++ RygelMediaObject* result = NULL; ++ gint id = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* path = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* mime_type = NULL; ++ sqlite3_stmt* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ gboolean _tmp8_ = FALSE; ++ const gchar* _tmp9_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ gchar* song_id = NULL; ++ gint _tmp18_ = 0; ++ gchar* _tmp19_ = NULL; ++ RygelMusicItem* song = NULL; ++ RygelMusicItem* _tmp20_ = NULL; ++ sqlite3_stmt* _tmp21_ = NULL; ++ gint _tmp22_ = 0; ++ sqlite3_stmt* _tmp23_ = NULL; ++ gint _tmp24_ = 0; ++ sqlite3_stmt* _tmp25_ = NULL; ++ gint _tmp26_ = 0; ++ sqlite3_stmt* _tmp27_ = NULL; ++ gint _tmp28_ = 0; ++ sqlite3_stmt* _tmp29_ = NULL; ++ gint _tmp30_ = 0; ++ sqlite3_stmt* _tmp31_ = NULL; ++ gint _tmp32_ = 0; ++ sqlite3_stmt* _tmp33_ = NULL; ++ const gchar* _tmp34_ = NULL; ++ const gchar* _tmp35_ = NULL; ++ sqlite3_stmt* _tmp36_ = NULL; ++ const gchar* _tmp37_ = NULL; ++ sqlite3_stmt* _tmp38_ = NULL; ++ const gchar* _tmp39_ = NULL; ++ GTimeVal tv = {0}; ++ sqlite3_stmt* _tmp40_ = NULL; ++ gint _tmp41_ = 0; ++ GTimeVal _tmp42_ = {0}; ++ gchar* _tmp43_ = NULL; ++ gchar* _tmp44_ = NULL; ++ sqlite3_stmt* _tmp45_ = NULL; ++ const gchar* _tmp46_ = NULL; ++ GFile* file = NULL; ++ const gchar* _tmp47_ = NULL; ++ GFile* _tmp48_ = NULL; ++ gchar* _tmp49_ = NULL; ++ gchar* _tmp50_ = NULL; ++ self = (RygelLMSAllMusic*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ id = _tmp1_; ++ _tmp2_ = statement; ++ _tmp3_ = sqlite3_column_text (_tmp2_, 1); ++ _tmp4_ = g_strdup (_tmp3_); ++ path = _tmp4_; ++ _tmp5_ = statement; ++ _tmp6_ = sqlite3_column_text (_tmp5_, 10); ++ _tmp7_ = g_strdup (_tmp6_); ++ mime_type = _tmp7_; ++ _tmp9_ = mime_type; ++ if (_tmp9_ == NULL) { ++ _tmp8_ = TRUE; ++ } else { ++ const gchar* _tmp10_ = NULL; ++ gint _tmp11_ = 0; ++ gint _tmp12_ = 0; ++ _tmp10_ = mime_type; ++ _tmp11_ = strlen (_tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp8_ = _tmp12_ == 0; ++ } ++ if (_tmp8_) { ++ gint _tmp13_ = 0; ++ const gchar* _tmp14_ = NULL; ++ _tmp13_ = id; ++ _tmp14_ = path; ++ g_debug ("rygel-lms-all-music.vala:130: Music item %d (%s) has no MIME type", _tmp13_, _tmp14_); ++ } ++ _tmp15_ = statement; ++ _tmp16_ = sqlite3_column_text (_tmp15_, 3); ++ _tmp17_ = g_strdup (_tmp16_); ++ title = _tmp17_; ++ _tmp18_ = id; ++ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); ++ song_id = _tmp19_; ++ _tmp20_ = rygel_music_item_new (song_id, (RygelMediaContainer*) self, title, RYGEL_MUSIC_ITEM_UPNP_CLASS); ++ song = _tmp20_; ++ _tmp21_ = statement; ++ _tmp22_ = sqlite3_column_int (_tmp21_, 2); ++ rygel_media_file_item_set_size ((RygelMediaFileItem*) song, (gint64) _tmp22_); ++ _tmp23_ = statement; ++ _tmp24_ = sqlite3_column_int (_tmp23_, 4); ++ rygel_music_item_set_track_number (song, _tmp24_); ++ _tmp25_ = statement; ++ _tmp26_ = sqlite3_column_int (_tmp25_, 5); ++ rygel_audio_item_set_duration ((RygelAudioItem*) song, (glong) _tmp26_); ++ _tmp27_ = statement; ++ _tmp28_ = sqlite3_column_int (_tmp27_, 6); ++ rygel_audio_item_set_channels ((RygelAudioItem*) song, _tmp28_); ++ _tmp29_ = statement; ++ _tmp30_ = sqlite3_column_int (_tmp29_, 7); ++ rygel_audio_item_set_sample_freq ((RygelAudioItem*) song, _tmp30_); ++ _tmp31_ = statement; ++ _tmp32_ = sqlite3_column_int (_tmp31_, 8); ++ rygel_audio_item_set_bitrate ((RygelAudioItem*) song, _tmp32_); ++ _tmp33_ = statement; ++ _tmp34_ = sqlite3_column_text (_tmp33_, 9); ++ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) song, _tmp34_); ++ _tmp35_ = mime_type; ++ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) song, _tmp35_); ++ _tmp36_ = statement; ++ _tmp37_ = sqlite3_column_text (_tmp36_, 11); ++ rygel_media_object_set_artist ((RygelMediaObject*) song, _tmp37_); ++ _tmp38_ = statement; ++ _tmp39_ = sqlite3_column_text (_tmp38_, 12); ++ rygel_audio_item_set_album ((RygelAudioItem*) song, _tmp39_); ++ _tmp40_ = statement; ++ _tmp41_ = sqlite3_column_int (_tmp40_, 13); ++ _tmp42_.tv_sec = (glong) _tmp41_; ++ _tmp42_.tv_usec = (glong) 0; ++ tv = _tmp42_; ++ _tmp43_ = g_time_val_to_iso8601 (&tv); ++ _tmp44_ = _tmp43_; ++ rygel_media_object_set_date ((RygelMediaObject*) song, _tmp44_); ++ _g_free0 (_tmp44_); ++ _tmp45_ = statement; ++ _tmp46_ = sqlite3_column_text (_tmp45_, 14); ++ rygel_media_object_set_genre ((RygelMediaObject*) song, _tmp46_); ++ _tmp47_ = path; ++ _tmp48_ = g_file_new_for_path (_tmp47_); ++ file = _tmp48_; ++ _tmp49_ = g_file_get_uri (file); ++ _tmp50_ = _tmp49_; ++ rygel_media_object_add_uri ((RygelMediaObject*) song, _tmp50_); ++ _g_free0 (_tmp50_); ++ result = (RygelMediaObject*) song; ++ _g_object_unref0 (file); ++ _g_free0 (song_id); ++ _g_free0 (title); ++ _g_free0 (mime_type); ++ _g_free0 (path); ++ return result; ++} ++ ++ ++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ RygelLMSAllMusic * self = NULL; ++ RygelMediaContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = parent; ++ _tmp1_ = _ ("All"); ++ _tmp2_ = lms_db; ++ _tmp3_ = g_strdup_printf (RYGEL_LMS_ALL_MUSIC_SQL_ALL_TEMPLATE, ""); ++ _tmp4_ = _tmp3_; ++ self = (RygelLMSAllMusic*) rygel_lms_category_container_construct (object_type, "all", _tmp0_, _tmp1_, _tmp2_, _tmp4_, RYGEL_LMS_ALL_MUSIC_SQL_FIND_OBJECT, RYGEL_LMS_ALL_MUSIC_SQL_COUNT, RYGEL_LMS_ALL_MUSIC_SQL_ADDED, RYGEL_LMS_ALL_MUSIC_SQL_REMOVED); ++ _g_free0 (_tmp4_); ++ return self; ++} ++ ++ ++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ return rygel_lms_all_music_construct (RYGEL_LMS_TYPE_ALL_MUSIC, parent, lms_db); ++} ++ ++ ++static void rygel_lms_all_music_class_init (RygelLMSAllMusicClass * klass) { ++ rygel_lms_all_music_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_all_music_real_get_sql_all_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_all_music_real_get_sql_count_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_music_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_all_music_instance_init (RygelLMSAllMusic * self) { ++} ++ ++ ++GType rygel_lms_all_music_get_type (void) { ++ static volatile gsize rygel_lms_all_music_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_all_music_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllMusicClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_music_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllMusic), 0, (GInstanceInitFunc) rygel_lms_all_music_instance_init, NULL }; ++ GType rygel_lms_all_music_type_id; ++ rygel_lms_all_music_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllMusic", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_all_music_type_id__volatile, rygel_lms_all_music_type_id); ++ } ++ return rygel_lms_all_music_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-all-videos.c b/src/plugins/lms/rygel-lms-all-videos.c +new file mode 100644 +index 0000000..51ba52c +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-all-videos.c +@@ -0,0 +1,456 @@ ++/* rygel-lms-all-videos.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-all-videos.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gio/gio.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ()) ++#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos)) ++#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) ++#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS)) ++#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS)) ++#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) ++ ++typedef struct _RygelLMSAllVideos RygelLMSAllVideos; ++typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass; ++typedef struct _RygelLMSAllVideosPrivate RygelLMSAllVideosPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) ++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSAllVideos { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSAllVideosPrivate * priv; ++}; ++ ++struct _RygelLMSAllVideosClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++typedef enum { ++ RYGEL_LMS_DATABASE_ERROR_OPEN, ++ RYGEL_LMS_DATABASE_ERROR_PREPARE, ++ RYGEL_LMS_DATABASE_ERROR_BIND, ++ RYGEL_LMS_DATABASE_ERROR_STEP, ++ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND ++} RygelLMSDatabaseError; ++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () ++ ++static gpointer rygel_lms_all_videos_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ALL_VIDEOS_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ALL_VIDEOS_SQL_ALL "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ ++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ALL_VIDEOS_SQL_COUNT "SELECT count(videos.id) " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id;" ++#define RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ ++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND files.id = ? AND videos.id = files.id;" ++#define RYGEL_LMS_ALL_VIDEOS_SQL_ADDED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ ++"le, dlna_mime " "FROM videos, files " "WHERE dtime = 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;" ++#define RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED "SELECT videos.id, title, artist, length, path, mtime, size, dlna_profi" \ ++"le, dlna_mime " "FROM videos, files " "WHERE dtime <> 0 AND videos.id = files.id " "AND update_id > ? AND update_id <= ?;" ++static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++GQuark rygel_lms_database_error_quark (void); ++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); ++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); ++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_all_videos_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSAllVideos * self; ++ RygelMediaObject* result = NULL; ++ gint id = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* mime_type = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* path = NULL; ++ sqlite3_stmt* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ GFile* file = NULL; ++ const gchar* _tmp8_ = NULL; ++ GFile* _tmp9_ = NULL; ++ gboolean _tmp10_ = FALSE; ++ const gchar* _tmp11_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp17_ = NULL; ++ const gchar* _tmp18_ = NULL; ++ gchar* _tmp19_ = NULL; ++ RygelVideoItem* video = NULL; ++ gint _tmp20_ = 0; ++ gchar* _tmp21_ = NULL; ++ gchar* _tmp22_ = NULL; ++ const gchar* _tmp23_ = NULL; ++ RygelVideoItem* _tmp24_ = NULL; ++ RygelVideoItem* _tmp25_ = NULL; ++ RygelVideoItem* _tmp26_ = NULL; ++ sqlite3_stmt* _tmp27_ = NULL; ++ const gchar* _tmp28_ = NULL; ++ RygelVideoItem* _tmp29_ = NULL; ++ sqlite3_stmt* _tmp30_ = NULL; ++ gint _tmp31_ = 0; ++ GTimeVal tv = {0}; ++ sqlite3_stmt* _tmp32_ = NULL; ++ gint _tmp33_ = 0; ++ GTimeVal _tmp34_ = {0}; ++ RygelVideoItem* _tmp35_ = NULL; ++ gchar* _tmp36_ = NULL; ++ gchar* _tmp37_ = NULL; ++ RygelVideoItem* _tmp38_ = NULL; ++ sqlite3_stmt* _tmp39_ = NULL; ++ gint _tmp40_ = 0; ++ RygelVideoItem* _tmp41_ = NULL; ++ sqlite3_stmt* _tmp42_ = NULL; ++ const gchar* _tmp43_ = NULL; ++ RygelVideoItem* _tmp44_ = NULL; ++ const gchar* _tmp45_ = NULL; ++ RygelVideoItem* _tmp46_ = NULL; ++ GFile* _tmp47_ = NULL; ++ gchar* _tmp48_ = NULL; ++ gchar* _tmp49_ = NULL; ++ gchar* video_data = NULL; ++ gchar* _tmp50_ = NULL; ++ GError * _inner_error_ = NULL; ++ self = (RygelLMSAllVideos*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ id = _tmp1_; ++ _tmp2_ = statement; ++ _tmp3_ = sqlite3_column_text (_tmp2_, 8); ++ _tmp4_ = g_strdup (_tmp3_); ++ mime_type = _tmp4_; ++ _tmp5_ = statement; ++ _tmp6_ = sqlite3_column_text (_tmp5_, 4); ++ _tmp7_ = g_strdup (_tmp6_); ++ path = _tmp7_; ++ _tmp8_ = path; ++ _tmp9_ = g_file_new_for_path (_tmp8_); ++ file = _tmp9_; ++ _tmp11_ = mime_type; ++ if (_tmp11_ == NULL) { ++ _tmp10_ = TRUE; ++ } else { ++ const gchar* _tmp12_ = NULL; ++ gint _tmp13_ = 0; ++ gint _tmp14_ = 0; ++ _tmp12_ = mime_type; ++ _tmp13_ = strlen (_tmp12_); ++ _tmp14_ = _tmp13_; ++ _tmp10_ = _tmp14_ == 0; ++ } ++ if (_tmp10_) { ++ gint _tmp15_ = 0; ++ const gchar* _tmp16_ = NULL; ++ _tmp15_ = id; ++ _tmp16_ = path; ++ g_debug ("rygel-lms-all-videos.vala:75: Video item %d (%s) has no MIME type", _tmp15_, _tmp16_); ++ } ++ _tmp17_ = statement; ++ _tmp18_ = sqlite3_column_text (_tmp17_, 1); ++ _tmp19_ = g_strdup (_tmp18_); ++ title = _tmp19_; ++ _tmp20_ = id; ++ _tmp21_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp20_); ++ _tmp22_ = _tmp21_; ++ _tmp23_ = title; ++ _tmp24_ = rygel_video_item_new (_tmp22_, (RygelMediaContainer*) self, _tmp23_, RYGEL_VIDEO_ITEM_UPNP_CLASS); ++ _tmp25_ = _tmp24_; ++ _g_free0 (_tmp22_); ++ video = _tmp25_; ++ _tmp26_ = video; ++ _tmp27_ = statement; ++ _tmp28_ = sqlite3_column_text (_tmp27_, 2); ++ rygel_media_object_set_creator ((RygelMediaObject*) _tmp26_, _tmp28_); ++ _tmp29_ = video; ++ _tmp30_ = statement; ++ _tmp31_ = sqlite3_column_int (_tmp30_, 3); ++ rygel_audio_item_set_duration ((RygelAudioItem*) _tmp29_, (glong) _tmp31_); ++ _tmp32_ = statement; ++ _tmp33_ = sqlite3_column_int (_tmp32_, 5); ++ _tmp34_.tv_sec = (glong) _tmp33_; ++ _tmp34_.tv_usec = (glong) 0; ++ tv = _tmp34_; ++ _tmp35_ = video; ++ _tmp36_ = g_time_val_to_iso8601 (&tv); ++ _tmp37_ = _tmp36_; ++ rygel_media_object_set_date ((RygelMediaObject*) _tmp35_, _tmp37_); ++ _g_free0 (_tmp37_); ++ _tmp38_ = video; ++ _tmp39_ = statement; ++ _tmp40_ = sqlite3_column_int (_tmp39_, 6); ++ rygel_media_file_item_set_size ((RygelMediaFileItem*) _tmp38_, (gint64) _tmp40_); ++ _tmp41_ = video; ++ _tmp42_ = statement; ++ _tmp43_ = sqlite3_column_text (_tmp42_, 7); ++ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) _tmp41_, _tmp43_); ++ _tmp44_ = video; ++ _tmp45_ = mime_type; ++ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) _tmp44_, _tmp45_); ++ _tmp46_ = video; ++ _tmp47_ = file; ++ _tmp48_ = g_file_get_uri (_tmp47_); ++ _tmp49_ = _tmp48_; ++ rygel_media_object_add_uri ((RygelMediaObject*) _tmp46_, _tmp49_); ++ _g_free0 (_tmp49_); ++ _tmp50_ = g_strdup ("select videos_videos.bitrate + videos_audios.bitrate, width, height, c" \ ++"hannels, sampling_rate " "from videos, videos_audios, videos_videos where videos.id = ? " "and videos.id = videos_audios.video_id and videos.id = videos_videos.v" \ ++"ideo_id;"); ++ video_data = _tmp50_; ++ { ++ sqlite3_stmt* stmt = NULL; ++ RygelLMSDatabase* _tmp51_ = NULL; ++ RygelLMSDatabase* _tmp52_ = NULL; ++ const gchar* _tmp53_ = NULL; ++ sqlite3_stmt* _tmp54_ = NULL; ++ gint _tmp55_ = 0; ++ gchar* _tmp56_ = NULL; ++ gchar* _tmp57_ = NULL; ++ sqlite3_stmt* _tmp58_ = NULL; ++ RygelVideoItem* _tmp59_ = NULL; ++ sqlite3_stmt* _tmp60_ = NULL; ++ gint _tmp61_ = 0; ++ RygelVideoItem* _tmp62_ = NULL; ++ sqlite3_stmt* _tmp63_ = NULL; ++ gint _tmp64_ = 0; ++ RygelVideoItem* _tmp65_ = NULL; ++ sqlite3_stmt* _tmp66_ = NULL; ++ gint _tmp67_ = 0; ++ RygelVideoItem* _tmp68_ = NULL; ++ sqlite3_stmt* _tmp69_ = NULL; ++ gint _tmp70_ = 0; ++ RygelVideoItem* _tmp71_ = NULL; ++ sqlite3_stmt* _tmp72_ = NULL; ++ gint _tmp73_ = 0; ++ _tmp51_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp52_ = _tmp51_; ++ _tmp53_ = video_data; ++ _tmp54_ = rygel_lms_database_prepare (_tmp52_, _tmp53_, &_inner_error_); ++ stmt = _tmp54_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch10_rygel_lms_database_error; ++ } ++ _g_free0 (video_data); ++ _g_object_unref0 (video); ++ _g_free0 (title); ++ _g_object_unref0 (file); ++ _g_free0 (path); ++ _g_free0 (mime_type); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _tmp55_ = id; ++ _tmp56_ = g_strdup_printf ("%d", _tmp55_); ++ _tmp57_ = _tmp56_; ++ _tmp58_ = stmt; ++ rygel_lms_database_find_object (_tmp57_, _tmp58_, &_inner_error_); ++ _g_free0 (_tmp57_); ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch10_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt); ++ _g_free0 (video_data); ++ _g_object_unref0 (video); ++ _g_free0 (title); ++ _g_object_unref0 (file); ++ _g_free0 (path); ++ _g_free0 (mime_type); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _tmp59_ = video; ++ _tmp60_ = stmt; ++ _tmp61_ = sqlite3_column_int (_tmp60_, 0); ++ rygel_audio_item_set_bitrate ((RygelAudioItem*) _tmp59_, _tmp61_ / 8); ++ _tmp62_ = video; ++ _tmp63_ = stmt; ++ _tmp64_ = sqlite3_column_int (_tmp63_, 1); ++ rygel_visual_item_set_width ((RygelVisualItem*) _tmp62_, _tmp64_); ++ _tmp65_ = video; ++ _tmp66_ = stmt; ++ _tmp67_ = sqlite3_column_int (_tmp66_, 2); ++ rygel_visual_item_set_height ((RygelVisualItem*) _tmp65_, _tmp67_); ++ _tmp68_ = video; ++ _tmp69_ = stmt; ++ _tmp70_ = sqlite3_column_int (_tmp69_, 3); ++ rygel_audio_item_set_channels ((RygelAudioItem*) _tmp68_, _tmp70_); ++ _tmp71_ = video; ++ _tmp72_ = stmt; ++ _tmp73_ = sqlite3_column_int (_tmp72_, 4); ++ rygel_audio_item_set_sample_freq ((RygelAudioItem*) _tmp71_, _tmp73_); ++ _sqlite3_finalize0 (stmt); ++ } ++ goto __finally10; ++ __catch10_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp74_ = NULL; ++ const gchar* _tmp75_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp74_ = e; ++ _tmp75_ = _tmp74_->message; ++ g_warning ("rygel-lms-all-videos.vala:105: Query failed: %s", _tmp75_); ++ _g_error_free0 (e); ++ } ++ __finally10: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (video_data); ++ _g_object_unref0 (video); ++ _g_free0 (title); ++ _g_object_unref0 (file); ++ _g_free0 (path); ++ _g_free0 (mime_type); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ result = (RygelMediaObject*) video; ++ _g_free0 (video_data); ++ _g_free0 (title); ++ _g_object_unref0 (file); ++ _g_free0 (path); ++ _g_free0 (mime_type); ++ return result; ++} ++ ++ ++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSAllVideos * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ _tmp3_ = lms_db; ++ self = (RygelLMSAllVideos*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ALL_VIDEOS_SQL_ALL, RYGEL_LMS_ALL_VIDEOS_SQL_FIND_OBJECT, RYGEL_LMS_ALL_VIDEOS_SQL_COUNT, RYGEL_LMS_ALL_VIDEOS_SQL_ADDED, RYGEL_LMS_ALL_VIDEOS_SQL_REMOVED); ++ return self; ++} ++ ++ ++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_all_videos_construct (RYGEL_LMS_TYPE_ALL_VIDEOS, id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_all_videos_class_init (RygelLMSAllVideosClass * klass) { ++ rygel_lms_all_videos_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_all_videos_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_all_videos_instance_init (RygelLMSAllVideos * self) { ++} ++ ++ ++GType rygel_lms_all_videos_get_type (void) { ++ static volatile gsize rygel_lms_all_videos_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_all_videos_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSAllVideosClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_all_videos_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSAllVideos), 0, (GInstanceInitFunc) rygel_lms_all_videos_instance_init, NULL }; ++ GType rygel_lms_all_videos_type_id; ++ rygel_lms_all_videos_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSAllVideos", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_all_videos_type_id__volatile, rygel_lms_all_videos_type_id); ++ } ++ return rygel_lms_all_videos_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-artist.c b/src/plugins/lms/rygel-lms-artist.c +new file mode 100644 +index 0000000..e686ea4 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-artist.c +@@ -0,0 +1,274 @@ ++/* rygel-lms-artist.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-artist.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ()) ++#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist)) ++#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) ++#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST)) ++#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST)) ++#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) ++ ++typedef struct _RygelLMSArtist RygelLMSArtist; ++typedef struct _RygelLMSArtistClass RygelLMSArtistClass; ++typedef struct _RygelLMSArtistPrivate RygelLMSArtistPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++#define RYGEL_LMS_TYPE_ALBUM (rygel_lms_album_get_type ()) ++#define RYGEL_LMS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbum)) ++#define RYGEL_LMS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++#define RYGEL_LMS_IS_ALBUM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_IS_ALBUM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUM)) ++#define RYGEL_LMS_ALBUM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUM, RygelLMSAlbumClass)) ++ ++typedef struct _RygelLMSAlbum RygelLMSAlbum; ++typedef struct _RygelLMSAlbumClass RygelLMSAlbumClass; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSArtist { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSArtistPrivate * priv; ++}; ++ ++struct _RygelLMSArtistClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_artist_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_artist_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ARTIST_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.artist_id = %s " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE "SELECT COUNT(audio_albums.id) " "FROM audio_albums " "WHERE audio_albums.artist_id = %s" ++#define RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE "SELECT audio_albums.id, audio_albums.name " "FROM audio_albums " "WHERE audio_albums.id = ? AND audio_albums.artist_id = %s;" ++static gchar* rygel_lms_artist_get_sql_all (const gchar* id); ++static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id); ++static gchar* rygel_lms_artist_get_sql_count (const gchar* id); ++static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++RygelLMSAlbum* rygel_lms_album_new (const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAlbum* rygel_lms_album_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_album_get_type (void) G_GNUC_CONST; ++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static gchar* rygel_lms_artist_get_sql_all (const gchar* id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_ALL_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_artist_get_sql_find_object (const gchar* id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_artist_get_sql_count (const gchar* id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_ARTIST_SQL_COUNT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static RygelMediaObject* rygel_lms_artist_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSArtist * self; ++ RygelMediaObject* result = NULL; ++ gchar* db_id = NULL; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* _tmp2_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ RygelLMSDatabase* _tmp6_ = NULL; ++ RygelLMSDatabase* _tmp7_ = NULL; ++ RygelLMSAlbum* _tmp8_ = NULL; ++ self = (RygelLMSArtist*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ _tmp2_ = g_strdup_printf ("%d", _tmp1_); ++ db_id = _tmp2_; ++ _tmp3_ = statement; ++ _tmp4_ = sqlite3_column_text (_tmp3_, 1); ++ _tmp5_ = g_strdup (_tmp4_); ++ title = _tmp5_; ++ _tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp7_ = _tmp6_; ++ _tmp8_ = rygel_lms_album_new (db_id, (RygelMediaContainer*) self, title, _tmp7_); ++ result = (RygelMediaObject*) _tmp8_; ++ _g_free0 (title); ++ _g_free0 (db_id); ++ return result; ++} ++ ++ ++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSArtist * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ gchar* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ gchar* _tmp8_ = NULL; ++ gchar* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ _tmp3_ = lms_db; ++ _tmp4_ = id; ++ _tmp5_ = rygel_lms_artist_get_sql_all (_tmp4_); ++ _tmp6_ = _tmp5_; ++ _tmp7_ = id; ++ _tmp8_ = rygel_lms_artist_get_sql_find_object (_tmp7_); ++ _tmp9_ = _tmp8_; ++ _tmp10_ = id; ++ _tmp11_ = rygel_lms_artist_get_sql_count (_tmp10_); ++ _tmp12_ = _tmp11_; ++ self = (RygelLMSArtist*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, _tmp6_, _tmp9_, _tmp12_, NULL, NULL); ++ _g_free0 (_tmp12_); ++ _g_free0 (_tmp9_); ++ _g_free0 (_tmp6_); ++ return self; ++} ++ ++ ++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_artist_construct (RYGEL_LMS_TYPE_ARTIST, id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_artist_class_init (RygelLMSArtistClass * klass) { ++ rygel_lms_artist_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artist_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_artist_instance_init (RygelLMSArtist * self) { ++} ++ ++ ++GType rygel_lms_artist_get_type (void) { ++ static volatile gsize rygel_lms_artist_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_artist_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artist_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtist), 0, (GInstanceInitFunc) rygel_lms_artist_instance_init, NULL }; ++ GType rygel_lms_artist_type_id; ++ rygel_lms_artist_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtist", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_artist_type_id__volatile, rygel_lms_artist_type_id); ++ } ++ return rygel_lms_artist_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-artists.c b/src/plugins/lms/rygel-lms-artists.c +new file mode 100644 +index 0000000..3ac85bc +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-artists.c +@@ -0,0 +1,214 @@ ++/* rygel-lms-artists.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-artists.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ()) ++#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists)) ++#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) ++#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS)) ++#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS)) ++#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) ++ ++typedef struct _RygelLMSArtists RygelLMSArtists; ++typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass; ++typedef struct _RygelLMSArtistsPrivate RygelLMSArtistsPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++#define RYGEL_LMS_TYPE_ARTIST (rygel_lms_artist_get_type ()) ++#define RYGEL_LMS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtist)) ++#define RYGEL_LMS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) ++#define RYGEL_LMS_IS_ARTIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTIST)) ++#define RYGEL_LMS_IS_ARTIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTIST)) ++#define RYGEL_LMS_ARTIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTIST, RygelLMSArtistClass)) ++ ++typedef struct _RygelLMSArtist RygelLMSArtist; ++typedef struct _RygelLMSArtistClass RygelLMSArtistClass; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSArtists { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSArtistsPrivate * priv; ++}; ++ ++struct _RygelLMSArtistsClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_artists_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_artists_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_ARTISTS_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_ARTISTS_SQL_ALL "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_ARTISTS_SQL_COUNT "SELECT COUNT(audio_artists.id) " "FROM audio_artists;" ++#define RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT "SELECT audio_artists.id, audio_artists.name " "FROM audio_artists " "WHERE audio_artists.id = ?;" ++static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++RygelLMSArtist* rygel_lms_artist_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSArtist* rygel_lms_artist_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_artist_get_type (void) G_GNUC_CONST; ++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_artists_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSArtists * self; ++ RygelMediaObject* result = NULL; ++ gchar* db_id = NULL; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* _tmp2_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ RygelLMSDatabase* _tmp6_ = NULL; ++ RygelLMSDatabase* _tmp7_ = NULL; ++ RygelLMSArtist* _tmp8_ = NULL; ++ self = (RygelLMSArtists*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ _tmp2_ = g_strdup_printf ("%d", _tmp1_); ++ db_id = _tmp2_; ++ _tmp3_ = statement; ++ _tmp4_ = sqlite3_column_text (_tmp3_, 1); ++ _tmp5_ = g_strdup (_tmp4_); ++ title = _tmp5_; ++ _tmp6_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp7_ = _tmp6_; ++ _tmp8_ = rygel_lms_artist_new (db_id, (RygelMediaContainer*) self, title, _tmp7_); ++ result = (RygelMediaObject*) _tmp8_; ++ _g_free0 (title); ++ _g_free0 (db_id); ++ return result; ++} ++ ++ ++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSArtists * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ _tmp3_ = lms_db; ++ self = (RygelLMSArtists*) rygel_lms_category_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_, _tmp3_, RYGEL_LMS_ARTISTS_SQL_ALL, RYGEL_LMS_ARTISTS_SQL_FIND_OBJECT, RYGEL_LMS_ARTISTS_SQL_COUNT, NULL, NULL); ++ return self; ++} ++ ++ ++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_artists_construct (RYGEL_LMS_TYPE_ARTISTS, id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_artists_class_init (RygelLMSArtistsClass * klass) { ++ rygel_lms_artists_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_artists_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_artists_instance_init (RygelLMSArtists * self) { ++} ++ ++ ++GType rygel_lms_artists_get_type (void) { ++ static volatile gsize rygel_lms_artists_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_artists_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSArtistsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_artists_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSArtists), 0, (GInstanceInitFunc) rygel_lms_artists_instance_init, NULL }; ++ GType rygel_lms_artists_type_id; ++ rygel_lms_artists_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSArtists", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_artists_type_id__volatile, rygel_lms_artists_type_id); ++ } ++ return rygel_lms_artists_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-category-container.c b/src/plugins/lms/rygel-lms-category-container.c +new file mode 100644 +index 0000000..21692d0 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-category-container.c +@@ -0,0 +1,2772 @@ ++/* rygel-lms-category-container.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-category-container.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2009,2010 Jens Georg <mail@jensge.org>, ++ * (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gee.h> ++#include <libgupnp-av/gupnp-av.h> ++#include <gio/gio.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) ++#define __vala_GValue_free0(var) ((var == NULL) ? NULL : (var = (_vala_GValue_free (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) ++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) ++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++ ++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; ++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; ++ ++#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ()) ++#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction)) ++#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) ++#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION)) ++#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION)) ++#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) ++ ++typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction; ++typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass; ++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) ++#define _rygel_search_expression_unref0(var) ((var == NULL) ? NULL : (var = (rygel_search_expression_unref (var), NULL))) ++#define _g_value_array_free0(var) ((var == NULL) ? NULL : (var = (g_value_array_free (var), NULL))) ++typedef struct _RygelLmsCategoryContainerSearchData RygelLmsCategoryContainerSearchData; ++typedef struct _RygelLmsCategoryContainerGetChildrenData RygelLmsCategoryContainerGetChildrenData; ++typedef struct _RygelLmsCategoryContainerFindObjectData RygelLmsCategoryContainerFindObjectData; ++typedef struct _RygelLmsCategoryContainerAddChildData RygelLmsCategoryContainerAddChildData; ++typedef struct _RygelLmsCategoryContainerRemoveChildData RygelLmsCategoryContainerRemoveChildData; ++ ++typedef enum { ++ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_SQLITE_ERROR, ++ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_GENERAL_ERROR, ++ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_INVALID_TYPE, ++ RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH ++} RygelLMSCategoryContainerError; ++#define RYGEL_LMS_CATEGORY_CONTAINER_ERROR rygel_lms_category_container_error_quark () ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSCategoryContainerPrivate { ++ GeeArrayList* _search_classes; ++ RygelLMSDatabase* _lms_db; ++ gchar* _db_id; ++ gchar* _sql_all; ++ gchar* _sql_find_object; ++ gchar* _sql_count; ++ gchar* _sql_added; ++ gchar* _sql_removed; ++}; ++ ++typedef enum { ++ RYGEL_LMS_DATABASE_ERROR_OPEN, ++ RYGEL_LMS_DATABASE_ERROR_PREPARE, ++ RYGEL_LMS_DATABASE_ERROR_BIND, ++ RYGEL_LMS_DATABASE_ERROR_STEP, ++ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND ++} RygelLMSDatabaseError; ++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () ++struct _RygelLmsCategoryContainerSearchData { ++ int _state_; ++ GObject* _source_object_; ++ GAsyncResult* _res_; ++ GSimpleAsyncResult* _async_result; ++ RygelLMSCategoryContainer* self; ++ RygelSearchExpression* expression; ++ guint offset; ++ guint max_count; ++ guint total_matches; ++ gchar* sort_criteria; ++ GCancellable* cancellable; ++ RygelMediaObjects* result; ++ GValueArray* args; ++ GValueArray* _tmp0_; ++ gchar* filter; ++ RygelSearchExpression* _tmp1_; ++ GValueArray* _tmp2_; ++ gchar* _tmp3_; ++ const gchar* _tmp4_; ++ GValueArray* _tmp5_; ++ guint _tmp6_; ++ RygelSearchExpression* _tmp7_; ++ RygelSearchExpression* _tmp8_; ++ gchar* _tmp9_; ++ gchar* _tmp10_; ++ const gchar* _tmp11_; ++ guint _tmp12_; ++ guint _tmp13_; ++ const gchar* _tmp14_; ++ GValueArray* _tmp15_; ++ const gchar* _tmp16_; ++ guint _tmp17_; ++ guint _tmp18_; ++ RygelMediaObjects* _tmp19_; ++ GError* e; ++ GError* _tmp20_; ++ const gchar* _tmp21_; ++ RygelMediaObjects* _tmp22_; ++ RygelSearchExpression* _tmp23_; ++ guint _tmp24_; ++ guint _tmp25_; ++ const gchar* _tmp26_; ++ GCancellable* _tmp27_; ++ guint _tmp28_; ++ RygelMediaObjects* _tmp29_; ++ RygelMediaObjects* _tmp30_; ++ GError * _inner_error_; ++}; ++ ++struct _RygelLmsCategoryContainerGetChildrenData { ++ int _state_; ++ GObject* _source_object_; ++ GAsyncResult* _res_; ++ GSimpleAsyncResult* _async_result; ++ RygelLMSCategoryContainer* self; ++ guint offset; ++ guint max_count; ++ gchar* sort_criteria; ++ GCancellable* cancellable; ++ RygelMediaObjects* result; ++ RygelMediaObjects* retval; ++ RygelMediaObjects* _tmp0_; ++ sqlite3_stmt* _tmp1_; ++ guint _tmp2_; ++ guint _tmp3_; ++ const gchar* _tmp4_; ++ gboolean _tmp5_; ++ sqlite3_stmt* _tmp6_; ++ gboolean _tmp7_; ++ RygelMediaObjects* _tmp8_; ++ sqlite3_stmt* _tmp9_; ++ RygelMediaObject* _tmp10_; ++ RygelMediaObject* _tmp11_; ++ GError * _inner_error_; ++}; ++ ++struct _RygelLmsCategoryContainerFindObjectData { ++ int _state_; ++ GObject* _source_object_; ++ GAsyncResult* _res_; ++ GSimpleAsyncResult* _async_result; ++ RygelLMSCategoryContainer* self; ++ gchar* id; ++ GCancellable* cancellable; ++ RygelMediaObject* result; ++ const gchar* _tmp0_; ++ const gchar* _tmp1_; ++ gboolean _tmp2_; ++ RygelMediaObject* object; ++ gchar* real_id; ++ const gchar* _tmp3_; ++ const gchar* _tmp4_; ++ gint _tmp5_; ++ gint _tmp6_; ++ gchar* _tmp7_; ++ gint index; ++ const gchar* _tmp8_; ++ gint _tmp9_; ++ gint _tmp10_; ++ const gchar* _tmp11_; ++ gint _tmp12_; ++ gchar* _tmp13_; ++ const gchar* _tmp14_; ++ sqlite3_stmt* _tmp15_; ++ RygelMediaObject* child; ++ sqlite3_stmt* _tmp16_; ++ RygelMediaObject* _tmp17_; ++ gint _tmp18_; ++ RygelMediaObject* _tmp19_; ++ RygelMediaObject* _tmp20_; ++ RygelLMSCategoryContainer* container; ++ RygelMediaObject* _tmp21_; ++ RygelLMSCategoryContainer* _tmp22_; ++ RygelMediaObject* _tmp23_; ++ RygelLMSCategoryContainer* _tmp24_; ++ const gchar* _tmp25_; ++ GCancellable* _tmp26_; ++ RygelMediaObject* _tmp27_; ++ RygelMediaObject* _tmp28_; ++ RygelMediaObject* _tmp29_; ++ RygelMediaObject* _tmp30_; ++ RygelMediaContainer* _tmp31_; ++ RygelMediaContainer* _tmp32_; ++ GError* e; ++ const gchar* _tmp33_; ++ const gchar* _tmp34_; ++ const gchar* _tmp35_; ++ GError* _tmp36_; ++ const gchar* _tmp37_; ++ GError * _inner_error_; ++}; ++ ++struct _RygelLmsCategoryContainerAddChildData { ++ int _state_; ++ GObject* _source_object_; ++ GAsyncResult* _res_; ++ GSimpleAsyncResult* _async_result; ++ RygelLMSCategoryContainer* self; ++ RygelMediaObject* object; ++}; ++ ++struct _RygelLmsCategoryContainerRemoveChildData { ++ int _state_; ++ GObject* _source_object_; ++ GAsyncResult* _res_; ++ GSimpleAsyncResult* _async_result; ++ RygelLMSCategoryContainer* self; ++ RygelMediaObject* object; ++}; ++ ++ ++static gpointer rygel_lms_category_container_parent_class = NULL; ++static RygelTrackableContainerIface* rygel_lms_category_container_rygel_trackable_container_parent_iface = NULL; ++static RygelSearchableContainerIface* rygel_lms_category_container_rygel_searchable_container_parent_iface = NULL; ++ ++GQuark rygel_lms_category_container_error_quark (void); ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerPrivate)) ++enum { ++ RYGEL_LMS_CATEGORY_CONTAINER_DUMMY_PROPERTY, ++ RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES, ++ RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB, ++ RYGEL_LMS_CATEGORY_CONTAINER_DB_ID, ++ RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL, ++ RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT, ++ RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT, ++ RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED, ++ RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED ++}; ++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); ++static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self); ++gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); ++static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter); ++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self); ++static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error); ++static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error); ++static void _vala_GValue_free (GValue* self); ++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; ++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); ++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg); ++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg); ++GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST; ++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); ++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self); ++static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error); ++static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error); ++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++GQuark rygel_lms_database_error_quark (void); ++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); ++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); ++static void rygel_lms_category_container_real_search_data_free (gpointer _data); ++static void rygel_lms_category_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); ++static gboolean rygel_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_); ++static void rygel_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_); ++static void rygel_lms_category_container_real_get_children_data_free (gpointer _data); ++static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); ++static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_); ++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error); ++static void rygel_lms_category_container_real_find_object_data_free (gpointer _data); ++static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_); ++static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_); ++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); ++static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); ++static void rygel_lms_category_container_real_add_child_data_free (gpointer _data); ++static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_); ++static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_); ++static void rygel_lms_category_container_real_remove_child_data_free (gpointer _data); ++static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_); ++static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_); ++static void rygel_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id); ++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); ++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value); ++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self); ++static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value); ++static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value); ++const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self); ++static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value); ++static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value); ++const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self); ++static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value); ++const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self); ++static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value); ++static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties); ++static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self); ++static void rygel_lms_category_container_finalize (GObject* obj); ++static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec); ++static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); ++ ++ ++GQuark rygel_lms_category_container_error_quark (void) { ++ return g_quark_from_static_string ("rygel_lms_category_container_error-quark"); ++} ++ ++ ++static RygelMediaObject* rygel_lms_category_container_real_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) { ++ g_critical ("Type `%s' does not implement abstract method `rygel_lms_category_container_object_from_statement'", g_type_name (G_TYPE_FROM_INSTANCE (self))); ++ return NULL; ++} ++ ++ ++RygelMediaObject* rygel_lms_category_container_object_from_statement (RygelLMSCategoryContainer* self, sqlite3_stmt* statement) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->object_from_statement (self, statement); ++} ++ ++ ++static gchar* rygel_lms_category_container_real_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = self->priv->_sql_all; ++ _tmp1_ = g_strdup (_tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++gchar* rygel_lms_category_container_get_sql_all_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_all_with_filter (self, filter); ++} ++ ++ ++static gchar* rygel_lms_category_container_real_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (filter != NULL, NULL); ++ _tmp0_ = self->priv->_sql_count; ++ _tmp1_ = g_strdup (_tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++gchar* rygel_lms_category_container_get_sql_count_with_filter (RygelLMSCategoryContainer* self, const gchar* filter) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_sql_count_with_filter (self, filter); ++} ++ ++ ++static gchar* rygel_lms_category_container_map_operand_to_column (const gchar* operand, gchar** collate, gboolean for_sort, GError** error) { ++ gchar* _vala_collate = NULL; ++ gchar* result = NULL; ++ gchar* column = NULL; ++ gboolean use_collation = FALSE; ++ const gchar* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ GQuark _tmp3_ = 0U; ++ static GQuark _tmp2_label0 = 0; ++ static GQuark _tmp2_label1 = 0; ++ static GQuark _tmp2_label2 = 0; ++ gboolean _tmp11_ = FALSE; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (operand != NULL, NULL); ++ column = NULL; ++ use_collation = FALSE; ++ _tmp0_ = operand; ++ _tmp1_ = _tmp0_; ++ _tmp3_ = (NULL == _tmp1_) ? 0 : g_quark_from_string (_tmp1_); ++ if (_tmp3_ == ((0 != _tmp2_label0) ? _tmp2_label0 : (_tmp2_label0 = g_quark_from_static_string ("dc:title")))) { ++ switch (0) { ++ default: ++ { ++ gchar* _tmp4_ = NULL; ++ _tmp4_ = g_strdup ("title"); ++ _g_free0 (column); ++ column = _tmp4_; ++ use_collation = TRUE; ++ break; ++ } ++ } ++ } else if (_tmp3_ == ((0 != _tmp2_label1) ? _tmp2_label1 : (_tmp2_label1 = g_quark_from_static_string ("upnp:artist")))) { ++ switch (0) { ++ default: ++ { ++ gchar* _tmp5_ = NULL; ++ _tmp5_ = g_strdup ("artist"); ++ _g_free0 (column); ++ column = _tmp5_; ++ use_collation = TRUE; ++ break; ++ } ++ } ++ } else if (_tmp3_ == ((0 != _tmp2_label2) ? _tmp2_label2 : (_tmp2_label2 = g_quark_from_static_string ("dc:creator")))) { ++ switch (0) { ++ default: ++ { ++ gchar* _tmp6_ = NULL; ++ _tmp6_ = g_strdup ("creator"); ++ _g_free0 (column); ++ column = _tmp6_; ++ use_collation = TRUE; ++ break; ++ } ++ } ++ } else { ++ switch (0) { ++ default: ++ { ++ gchar* message = NULL; ++ const gchar* _tmp7_ = NULL; ++ gchar* _tmp8_ = NULL; ++ const gchar* _tmp9_ = NULL; ++ GError* _tmp10_ = NULL; ++ _tmp7_ = operand; ++ _tmp8_ = g_strdup_printf ("Unsupported column %s", _tmp7_); ++ message = _tmp8_; ++ _tmp9_ = message; ++ _tmp10_ = g_error_new_literal (RYGEL_LMS_CATEGORY_CONTAINER_ERROR, RYGEL_LMS_CATEGORY_CONTAINER_ERROR_UNSUPPORTED_SEARCH, _tmp9_); ++ _inner_error_ = _tmp10_; ++ g_propagate_error (error, _inner_error_); ++ _g_free0 (message); ++ _g_free0 (column); ++ return NULL; ++ } ++ } ++ } ++ _tmp11_ = use_collation; ++ if (_tmp11_) { ++ gchar* _tmp12_ = NULL; ++ _tmp12_ = g_strdup ("COLLATE CASEFOLD"); ++ _g_free0 (_vala_collate); ++ _vala_collate = _tmp12_; ++ } else { ++ gchar* _tmp13_ = NULL; ++ _tmp13_ = g_strdup (""); ++ _g_free0 (_vala_collate); ++ _vala_collate = _tmp13_; ++ } ++ result = column; ++ if (collate) { ++ *collate = _vala_collate; ++ } else { ++ _g_free0 (_vala_collate); ++ } ++ return result; ++} ++ ++ ++static void _vala_GValue_free (GValue* self) { ++ g_value_unset (self); ++ g_free (self); ++} ++ ++ ++static gchar* rygel_lms_category_container_relational_expression_to_sql (RygelRelationalExpression* exp, GValueArray* args, GError** error) { ++ gchar* result = NULL; ++ GValue* v = NULL; ++ gchar* collate = NULL; ++ gchar* column = NULL; ++ RygelRelationalExpression* _tmp0_ = NULL; ++ gconstpointer _tmp1_ = NULL; ++ gchar* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ RygelLMSSqlOperator* operator = NULL; ++ RygelRelationalExpression* _tmp4_ = NULL; ++ gconstpointer _tmp5_ = NULL; ++ GValue* _tmp40_ = NULL; ++ RygelLMSSqlOperator* _tmp44_ = NULL; ++ gchar* _tmp45_ = NULL; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (exp != NULL, NULL); ++ g_return_val_if_fail (args != NULL, NULL); ++ v = NULL; ++ collate = NULL; ++ _tmp0_ = exp; ++ _tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1; ++ _tmp3_ = rygel_lms_category_container_map_operand_to_column ((const gchar*) _tmp1_, &_tmp2_, FALSE, &_inner_error_); ++ _g_free0 (collate); ++ collate = _tmp2_; ++ column = _tmp3_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_propagate_error (error, _inner_error_); ++ _g_free0 (collate); ++ __vala_GValue_free0 (v); ++ return NULL; ++ } ++ _tmp4_ = exp; ++ _tmp5_ = ((RygelSearchExpression*) _tmp4_)->op; ++ switch ((GUPnPSearchCriteriaOp) ((gintptr) _tmp5_)) { ++ case GUPNP_SEARCH_CRITERIA_OP_EXISTS: ++ { ++ gchar* sql_function = NULL; ++ RygelRelationalExpression* _tmp6_ = NULL; ++ gconstpointer _tmp7_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ const gchar* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ _tmp6_ = exp; ++ _tmp7_ = ((RygelSearchExpression*) _tmp6_)->operand2; ++ if (g_strcmp0 ((const gchar*) _tmp7_, "true") == 0) { ++ gchar* _tmp8_ = NULL; ++ _tmp8_ = g_strdup ("%s IS NOT NULL AND %s != ''"); ++ _g_free0 (sql_function); ++ sql_function = _tmp8_; ++ } else { ++ gchar* _tmp9_ = NULL; ++ _tmp9_ = g_strdup ("%s IS NULL OR %s = ''"); ++ _g_free0 (sql_function); ++ sql_function = _tmp9_; ++ } ++ _tmp10_ = sql_function; ++ _tmp11_ = column; ++ _tmp12_ = column; ++ _tmp13_ = g_strdup_printf (_tmp10_, _tmp11_, _tmp12_); ++ result = _tmp13_; ++ _g_free0 (sql_function); ++ _g_object_unref0 (operator); ++ _g_free0 (column); ++ _g_free0 (collate); ++ __vala_GValue_free0 (v); ++ return result; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_EQ: ++ case GUPNP_SEARCH_CRITERIA_OP_NEQ: ++ case GUPNP_SEARCH_CRITERIA_OP_LESS: ++ case GUPNP_SEARCH_CRITERIA_OP_LEQ: ++ case GUPNP_SEARCH_CRITERIA_OP_GREATER: ++ case GUPNP_SEARCH_CRITERIA_OP_GEQ: ++ { ++ RygelRelationalExpression* _tmp14_ = NULL; ++ gconstpointer _tmp15_ = NULL; ++ GValue* _tmp16_ = NULL; ++ RygelRelationalExpression* _tmp17_ = NULL; ++ gconstpointer _tmp18_ = NULL; ++ const gchar* _tmp19_ = NULL; ++ const gchar* _tmp20_ = NULL; ++ RygelLMSSqlOperator* _tmp21_ = NULL; ++ _tmp14_ = exp; ++ _tmp15_ = ((RygelSearchExpression*) _tmp14_)->operand2; ++ _tmp16_ = g_new0 (GValue, 1); ++ g_value_init (_tmp16_, G_TYPE_STRING); ++ g_value_set_string (_tmp16_, (const gchar*) _tmp15_); ++ __vala_GValue_free0 (v); ++ v = _tmp16_; ++ _tmp17_ = exp; ++ _tmp18_ = ((RygelSearchExpression*) _tmp17_)->op; ++ _tmp19_ = column; ++ _tmp20_ = collate; ++ _tmp21_ = rygel_lms_sql_operator_new_from_search_criteria_op ((GUPnPSearchCriteriaOp) ((gintptr) _tmp18_), _tmp19_, _tmp20_); ++ _g_object_unref0 (operator); ++ operator = _tmp21_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_CONTAINS: ++ { ++ const gchar* _tmp22_ = NULL; ++ RygelLMSSqlFunction* _tmp23_ = NULL; ++ RygelRelationalExpression* _tmp24_ = NULL; ++ gconstpointer _tmp25_ = NULL; ++ GValue* _tmp26_ = NULL; ++ _tmp22_ = column; ++ _tmp23_ = rygel_lms_sql_function_new ("contains", _tmp22_); ++ _g_object_unref0 (operator); ++ operator = (RygelLMSSqlOperator*) _tmp23_; ++ _tmp24_ = exp; ++ _tmp25_ = ((RygelSearchExpression*) _tmp24_)->operand2; ++ _tmp26_ = g_new0 (GValue, 1); ++ g_value_init (_tmp26_, G_TYPE_STRING); ++ g_value_set_string (_tmp26_, (const gchar*) _tmp25_); ++ __vala_GValue_free0 (v); ++ v = _tmp26_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_DOES_NOT_CONTAIN: ++ { ++ const gchar* _tmp27_ = NULL; ++ RygelLMSSqlFunction* _tmp28_ = NULL; ++ RygelRelationalExpression* _tmp29_ = NULL; ++ gconstpointer _tmp30_ = NULL; ++ GValue* _tmp31_ = NULL; ++ _tmp27_ = column; ++ _tmp28_ = rygel_lms_sql_function_new ("NOT contains", _tmp27_); ++ _g_object_unref0 (operator); ++ operator = (RygelLMSSqlOperator*) _tmp28_; ++ _tmp29_ = exp; ++ _tmp30_ = ((RygelSearchExpression*) _tmp29_)->operand2; ++ _tmp31_ = g_new0 (GValue, 1); ++ g_value_init (_tmp31_, G_TYPE_STRING); ++ g_value_set_string (_tmp31_, (const gchar*) _tmp30_); ++ __vala_GValue_free0 (v); ++ v = _tmp31_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_DERIVED_FROM: ++ { ++ const gchar* _tmp32_ = NULL; ++ RygelLMSSqlOperator* _tmp33_ = NULL; ++ RygelRelationalExpression* _tmp34_ = NULL; ++ gconstpointer _tmp35_ = NULL; ++ gchar* _tmp36_ = NULL; ++ GValue* _tmp37_ = NULL; ++ _tmp32_ = column; ++ _tmp33_ = rygel_lms_sql_operator_new ("LIKE", _tmp32_, ""); ++ _g_object_unref0 (operator); ++ operator = _tmp33_; ++ _tmp34_ = exp; ++ _tmp35_ = ((RygelSearchExpression*) _tmp34_)->operand2; ++ _tmp36_ = g_strdup_printf ("%s%%", (const gchar*) _tmp35_); ++ _tmp37_ = g_new0 (GValue, 1); ++ g_value_init (_tmp37_, G_TYPE_STRING); ++ g_value_take_string (_tmp37_, _tmp36_); ++ __vala_GValue_free0 (v); ++ v = _tmp37_; ++ break; ++ } ++ default: ++ { ++ RygelRelationalExpression* _tmp38_ = NULL; ++ gconstpointer _tmp39_ = NULL; ++ _tmp38_ = exp; ++ _tmp39_ = ((RygelSearchExpression*) _tmp38_)->op; ++ g_warning ("rygel-lms-category-container.vala:148: Unsupported op %d", (gint) ((GUPnPSearchCriteriaOp) ((gintptr) _tmp39_))); ++ result = NULL; ++ _g_object_unref0 (operator); ++ _g_free0 (column); ++ _g_free0 (collate); ++ __vala_GValue_free0 (v); ++ return result; ++ } ++ } ++ _tmp40_ = v; ++ if (_tmp40_ != NULL) { ++ GValueArray* _tmp41_ = NULL; ++ GValue* _tmp42_ = NULL; ++ GValue _tmp43_ = {0}; ++ _tmp41_ = args; ++ _tmp42_ = v; ++ _tmp43_ = *_tmp42_; ++ g_value_array_append (_tmp41_, &_tmp43_); ++ } ++ _tmp44_ = operator; ++ _tmp45_ = rygel_lms_sql_operator_to_string (_tmp44_); ++ result = _tmp45_; ++ _g_object_unref0 (operator); ++ _g_free0 (column); ++ _g_free0 (collate); ++ __vala_GValue_free0 (v); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_category_container_logical_expression_to_sql (RygelLogicalExpression* expression, GValueArray* args, GError** error) { ++ gchar* result = NULL; ++ gchar* left_sql_string = NULL; ++ RygelLogicalExpression* _tmp0_ = NULL; ++ gconstpointer _tmp1_ = NULL; ++ GValueArray* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ gchar* right_sql_string = NULL; ++ RygelLogicalExpression* _tmp4_ = NULL; ++ gconstpointer _tmp5_ = NULL; ++ GValueArray* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ const gchar* operator_sql_string = NULL; ++ RygelLogicalExpression* _tmp8_ = NULL; ++ gconstpointer _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ const gchar* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (expression != NULL, NULL); ++ g_return_val_if_fail (args != NULL, NULL); ++ _tmp0_ = expression; ++ _tmp1_ = ((RygelSearchExpression*) _tmp0_)->operand1; ++ _tmp2_ = args; ++ _tmp3_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp1_, _tmp2_, &_inner_error_); ++ left_sql_string = _tmp3_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_propagate_error (error, _inner_error_); ++ return NULL; ++ } ++ _tmp4_ = expression; ++ _tmp5_ = ((RygelSearchExpression*) _tmp4_)->operand2; ++ _tmp6_ = args; ++ _tmp7_ = rygel_lms_category_container_search_expression_to_sql ((RygelSearchExpression*) _tmp5_, _tmp6_, &_inner_error_); ++ right_sql_string = _tmp7_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_propagate_error (error, _inner_error_); ++ _g_free0 (left_sql_string); ++ return NULL; ++ } ++ operator_sql_string = "OR"; ++ _tmp8_ = expression; ++ _tmp9_ = ((RygelSearchExpression*) _tmp8_)->op; ++ if (((RygelLogicalOperator) ((gintptr) _tmp9_)) == RYGEL_LOGICAL_OPERATOR_AND) { ++ operator_sql_string = "AND"; ++ } ++ _tmp10_ = left_sql_string; ++ _tmp11_ = operator_sql_string; ++ _tmp12_ = right_sql_string; ++ _tmp13_ = g_strdup_printf ("(%s %s %s)", _tmp10_, _tmp11_, _tmp12_); ++ result = _tmp13_; ++ _g_free0 (right_sql_string); ++ _g_free0 (left_sql_string); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_category_container_search_expression_to_sql (RygelSearchExpression* expression, GValueArray* args, GError** error) { ++ gchar* result = NULL; ++ RygelSearchExpression* _tmp0_ = NULL; ++ RygelSearchExpression* _tmp2_ = NULL; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (args != NULL, NULL); ++ _tmp0_ = expression; ++ if (_tmp0_ == NULL) { ++ gchar* _tmp1_ = NULL; ++ _tmp1_ = g_strdup (""); ++ result = _tmp1_; ++ return result; ++ } ++ _tmp2_ = expression; ++ if (G_TYPE_CHECK_INSTANCE_TYPE (_tmp2_, RYGEL_TYPE_LOGICAL_EXPRESSION)) { ++ gchar* _tmp3_ = NULL; ++ RygelSearchExpression* _tmp4_ = NULL; ++ GValueArray* _tmp5_ = NULL; ++ gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ _tmp4_ = expression; ++ _tmp5_ = args; ++ _tmp6_ = rygel_lms_category_container_logical_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp4_, RYGEL_TYPE_LOGICAL_EXPRESSION) ? ((RygelLogicalExpression*) _tmp4_) : NULL, _tmp5_, &_inner_error_); ++ _tmp3_ = _tmp6_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_propagate_error (error, _inner_error_); ++ return NULL; ++ } ++ _tmp7_ = _tmp3_; ++ _tmp3_ = NULL; ++ result = _tmp7_; ++ _g_free0 (_tmp3_); ++ return result; ++ } else { ++ gchar* _tmp8_ = NULL; ++ RygelSearchExpression* _tmp9_ = NULL; ++ GValueArray* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ _tmp9_ = expression; ++ _tmp10_ = args; ++ _tmp11_ = rygel_lms_category_container_relational_expression_to_sql (G_TYPE_CHECK_INSTANCE_TYPE (_tmp9_, RYGEL_TYPE_RELATIONAL_EXPRESSION) ? ((RygelRelationalExpression*) _tmp9_) : NULL, _tmp10_, &_inner_error_); ++ _tmp8_ = _tmp11_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_propagate_error (error, _inner_error_); ++ return NULL; ++ } ++ _tmp12_ = _tmp8_; ++ _tmp8_ = NULL; ++ result = _tmp12_; ++ _g_free0 (_tmp8_); ++ return result; ++ } ++} ++ ++ ++static guint rygel_lms_category_container_real_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) { ++ guint result = 0U; ++ gchar* query = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (where_filter != NULL, 0U); ++ g_return_val_if_fail (args != NULL, 0U); ++ _tmp0_ = where_filter; ++ _tmp1_ = rygel_lms_category_container_get_sql_count_with_filter (self, _tmp0_); ++ query = _tmp1_; ++ { ++ sqlite3_stmt* stmt = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ GValueArray* _tmp4_ = NULL; ++ GValue* _tmp5_ = NULL; ++ gint _tmp5__length1 = 0; ++ sqlite3_stmt* _tmp6_ = NULL; ++ sqlite3_stmt* _tmp7_ = NULL; ++ gint _tmp8_ = 0; ++ sqlite3_stmt* _tmp9_ = NULL; ++ gint _tmp10_ = 0; ++ _tmp2_ = self->priv->_lms_db; ++ _tmp3_ = query; ++ _tmp4_ = args; ++ _tmp5_ = _tmp4_->values; ++ _tmp5__length1 = (gint) _tmp4_->n_values; ++ _tmp6_ = rygel_lms_database_prepare_and_init (_tmp2_, _tmp3_, _tmp5_, _tmp5__length1, &_inner_error_); ++ stmt = _tmp6_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch2_rygel_lms_database_error; ++ } ++ _g_free0 (query); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return 0U; ++ } ++ _tmp7_ = stmt; ++ _tmp8_ = sqlite3_step (_tmp7_); ++ if (_tmp8_ != SQLITE_ROW) { ++ result = (guint) 0; ++ _sqlite3_finalize0 (stmt); ++ _g_free0 (query); ++ return result; ++ } ++ _tmp9_ = stmt; ++ _tmp10_ = sqlite3_column_int (_tmp9_, 0); ++ result = (guint) _tmp10_; ++ _sqlite3_finalize0 (stmt); ++ _g_free0 (query); ++ return result; ++ } ++ goto __finally2; ++ __catch2_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp11_ = e; ++ _tmp12_ = _tmp11_->message; ++ g_warning ("rygel-lms-category-container.vala:209: Query failed: %s", _tmp12_); ++ result = (guint) 0; ++ _g_error_free0 (e); ++ _g_free0 (query); ++ return result; ++ } ++ __finally2: ++ _g_free0 (query); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return 0U; ++} ++ ++ ++guint rygel_lms_category_container_get_child_count_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args) { ++ g_return_val_if_fail (self != NULL, 0U); ++ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_child_count_with_filter (self, where_filter, args); ++} ++ ++ ++static RygelMediaObjects* rygel_lms_category_container_real_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { ++ RygelMediaObjects* result = NULL; ++ RygelMediaObjects* children = NULL; ++ RygelMediaObjects* _tmp0_ = NULL; ++ GValue v = {0}; ++ guint _tmp1_ = 0U; ++ GValue _tmp2_ = {0}; ++ GValueArray* _tmp3_ = NULL; ++ GValue _tmp4_ = {0}; ++ guint _tmp5_ = 0U; ++ GValue _tmp6_ = {0}; ++ GValueArray* _tmp7_ = NULL; ++ GValue _tmp8_ = {0}; ++ gchar* query = NULL; ++ const gchar* _tmp9_ = NULL; ++ gchar* _tmp10_ = NULL; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (where_filter != NULL, NULL); ++ g_return_val_if_fail (args != NULL, NULL); ++ g_return_val_if_fail (sort_criteria != NULL, NULL); ++ _tmp0_ = rygel_media_objects_new (); ++ children = _tmp0_; ++ _tmp1_ = max_count; ++ g_value_init (&_tmp2_, G_TYPE_UINT); ++ g_value_set_uint (&_tmp2_, _tmp1_); ++ v = _tmp2_; ++ _tmp3_ = args; ++ _tmp4_ = v; ++ g_value_array_append (_tmp3_, &_tmp4_); ++ _tmp5_ = offset; ++ g_value_init (&_tmp6_, G_TYPE_UINT); ++ g_value_set_uint (&_tmp6_, _tmp5_); ++ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; ++ v = _tmp6_; ++ _tmp7_ = args; ++ _tmp8_ = v; ++ g_value_array_append (_tmp7_, &_tmp8_); ++ _tmp9_ = where_filter; ++ _tmp10_ = rygel_lms_category_container_get_sql_all_with_filter (self, _tmp9_); ++ query = _tmp10_; ++ { ++ sqlite3_stmt* stmt = NULL; ++ RygelLMSDatabase* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ GValueArray* _tmp13_ = NULL; ++ GValue* _tmp14_ = NULL; ++ gint _tmp14__length1 = 0; ++ sqlite3_stmt* _tmp15_ = NULL; ++ _tmp11_ = self->priv->_lms_db; ++ _tmp12_ = query; ++ _tmp13_ = args; ++ _tmp14_ = _tmp13_->values; ++ _tmp14__length1 = (gint) _tmp13_->n_values; ++ _tmp15_ = rygel_lms_database_prepare_and_init (_tmp11_, _tmp12_, _tmp14_, _tmp14__length1, &_inner_error_); ++ stmt = _tmp15_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch3_rygel_lms_database_error; ++ } ++ _g_free0 (query); ++ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ while (TRUE) { ++ gboolean _tmp16_ = FALSE; ++ sqlite3_stmt* _tmp17_ = NULL; ++ gboolean _tmp18_ = FALSE; ++ RygelMediaObjects* _tmp19_ = NULL; ++ sqlite3_stmt* _tmp20_ = NULL; ++ RygelMediaObject* _tmp21_ = NULL; ++ RygelMediaObject* _tmp22_ = NULL; ++ _tmp17_ = stmt; ++ _tmp18_ = rygel_lms_database_get_children_step (_tmp17_, &_inner_error_); ++ _tmp16_ = _tmp18_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch3_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt); ++ _g_free0 (query); ++ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ if (!_tmp16_) { ++ break; ++ } ++ _tmp19_ = children; ++ _tmp20_ = stmt; ++ _tmp21_ = rygel_lms_category_container_object_from_statement (self, _tmp20_); ++ _tmp22_ = _tmp21_; ++ gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, _tmp22_); ++ _g_object_unref0 (_tmp22_); ++ } ++ _sqlite3_finalize0 (stmt); ++ } ++ goto __finally3; ++ __catch3_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp23_ = NULL; ++ const gchar* _tmp24_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp23_ = e; ++ _tmp24_ = _tmp23_->message; ++ g_warning ("rygel-lms-category-container.vala:232: Query failed: %s", _tmp24_); ++ _g_error_free0 (e); ++ } ++ __finally3: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (query); ++ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; ++ _g_object_unref0 (children); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ result = children; ++ _g_free0 (query); ++ G_IS_VALUE (&v) ? (g_value_unset (&v), NULL) : NULL; ++ return result; ++} ++ ++ ++RygelMediaObjects* rygel_lms_category_container_get_children_with_filter (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS (self)->get_children_with_filter (self, where_filter, args, sort_criteria, offset, max_count); ++} ++ ++ ++static void rygel_lms_category_container_real_search_data_free (gpointer _data) { ++ RygelLmsCategoryContainerSearchData* _data_; ++ _data_ = _data; ++ _rygel_search_expression_unref0 (_data_->expression); ++ _g_free0 (_data_->sort_criteria); ++ _g_object_unref0 (_data_->cancellable); ++ _g_object_unref0 (_data_->result); ++ _g_object_unref0 (_data_->self); ++ g_slice_free (RygelLmsCategoryContainerSearchData, _data_); ++} ++ ++ ++static gpointer _g_object_ref0 (gpointer self) { ++ return self ? g_object_ref (self) : NULL; ++} ++ ++ ++static gpointer _rygel_search_expression_ref0 (gpointer self) { ++ return self ? rygel_search_expression_ref (self) : NULL; ++} ++ ++ ++static void rygel_lms_category_container_real_search (RygelSearchableContainer* base, RygelSearchExpression* expression, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { ++ RygelLMSCategoryContainer * self; ++ RygelLmsCategoryContainerSearchData* _data_; ++ RygelLMSCategoryContainer* _tmp0_ = NULL; ++ RygelSearchExpression* _tmp1_ = NULL; ++ RygelSearchExpression* _tmp2_ = NULL; ++ guint _tmp3_ = 0U; ++ guint _tmp4_ = 0U; ++ const gchar* _tmp5_ = NULL; ++ gchar* _tmp6_ = NULL; ++ GCancellable* _tmp7_ = NULL; ++ GCancellable* _tmp8_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _data_ = g_slice_new0 (RygelLmsCategoryContainerSearchData); ++ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_search); ++ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_search_data_free); ++ _tmp0_ = _g_object_ref0 (self); ++ _data_->self = _tmp0_; ++ _tmp1_ = expression; ++ _tmp2_ = _rygel_search_expression_ref0 (_tmp1_); ++ _rygel_search_expression_unref0 (_data_->expression); ++ _data_->expression = _tmp2_; ++ _tmp3_ = offset; ++ _data_->offset = _tmp3_; ++ _tmp4_ = max_count; ++ _data_->max_count = _tmp4_; ++ _tmp5_ = sort_criteria; ++ _tmp6_ = g_strdup (_tmp5_); ++ _g_free0 (_data_->sort_criteria); ++ _data_->sort_criteria = _tmp6_; ++ _tmp7_ = cancellable; ++ _tmp8_ = _g_object_ref0 (_tmp7_); ++ _g_object_unref0 (_data_->cancellable); ++ _data_->cancellable = _tmp8_; ++ rygel_lms_category_container_real_search_co (_data_); ++} ++ ++ ++static RygelMediaObjects* rygel_lms_category_container_real_search_finish (RygelSearchableContainer* base, GAsyncResult* _res_, guint* total_matches, GError** error) { ++ RygelMediaObjects* result; ++ RygelLmsCategoryContainerSearchData* _data_; ++ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { ++ return NULL; ++ } ++ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); ++ if (total_matches) { ++ *total_matches = _data_->total_matches; ++ } ++ result = _data_->result; ++ _data_->result = NULL; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_search_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) { ++ RygelLmsCategoryContainerSearchData* _data_; ++ _data_ = _user_data_; ++ _data_->_source_object_ = source_object; ++ _data_->_res_ = _res_; ++ rygel_lms_category_container_real_search_co (_data_); ++} ++ ++ ++static gboolean rygel_lms_category_container_real_search_co (RygelLmsCategoryContainerSearchData* _data_) { ++ switch (_data_->_state_) { ++ case 0: ++ goto _state_0; ++ case 1: ++ goto _state_1; ++ default: ++ g_assert_not_reached (); ++ } ++ _state_0: ++ g_debug ("rygel-lms-category-container.vala:245: search()"); ++ { ++ _data_->_tmp0_ = NULL; ++ _data_->_tmp0_ = g_value_array_new ((guint) 0); ++ _data_->args = _data_->_tmp0_; ++ _data_->_tmp1_ = NULL; ++ _data_->_tmp1_ = _data_->expression; ++ _data_->_tmp2_ = NULL; ++ _data_->_tmp2_ = _data_->args; ++ _data_->_tmp3_ = NULL; ++ _data_->_tmp3_ = rygel_lms_category_container_search_expression_to_sql (_data_->_tmp1_, _data_->_tmp2_, &_data_->_inner_error_); ++ _data_->filter = _data_->_tmp3_; ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ _g_value_array_free0 (_data_->args); ++ goto __catch4_g_error; ++ } ++ _data_->_tmp4_ = NULL; ++ _data_->_tmp4_ = _data_->filter; ++ _data_->_tmp5_ = NULL; ++ _data_->_tmp5_ = _data_->args; ++ _data_->_tmp6_ = 0U; ++ _data_->_tmp6_ = rygel_lms_category_container_get_child_count_with_filter (_data_->self, _data_->_tmp4_, _data_->_tmp5_); ++ _data_->total_matches = _data_->_tmp6_; ++ _data_->_tmp7_ = NULL; ++ _data_->_tmp7_ = _data_->expression; ++ if (_data_->_tmp7_ != NULL) { ++ _data_->_tmp8_ = NULL; ++ _data_->_tmp8_ = _data_->expression; ++ _data_->_tmp9_ = NULL; ++ _data_->_tmp9_ = rygel_search_expression_to_string (_data_->_tmp8_); ++ _data_->_tmp10_ = NULL; ++ _data_->_tmp10_ = _data_->_tmp9_; ++ g_debug ("rygel-lms-category-container.vala:253: Original search: %s", _data_->_tmp10_); ++ _g_free0 (_data_->_tmp10_); ++ _data_->_tmp11_ = NULL; ++ _data_->_tmp11_ = _data_->filter; ++ g_debug ("rygel-lms-category-container.vala:254: Parsed search expression: %s", _data_->_tmp11_); ++ _data_->_tmp12_ = 0U; ++ _data_->_tmp12_ = _data_->total_matches; ++ g_debug ("rygel-lms-category-container.vala:255: Filtered cild count is %u", _data_->_tmp12_); ++ } ++ _data_->_tmp13_ = 0U; ++ _data_->_tmp13_ = _data_->max_count; ++ if (_data_->_tmp13_ == ((guint) 0)) { ++ _data_->max_count = G_MAXUINT; ++ } ++ _data_->_tmp14_ = NULL; ++ _data_->_tmp14_ = _data_->filter; ++ _data_->_tmp15_ = NULL; ++ _data_->_tmp15_ = _data_->args; ++ _data_->_tmp16_ = NULL; ++ _data_->_tmp16_ = _data_->sort_criteria; ++ _data_->_tmp17_ = 0U; ++ _data_->_tmp17_ = _data_->offset; ++ _data_->_tmp18_ = 0U; ++ _data_->_tmp18_ = _data_->max_count; ++ _data_->_tmp19_ = NULL; ++ _data_->_tmp19_ = rygel_lms_category_container_get_children_with_filter (_data_->self, _data_->_tmp14_, _data_->_tmp15_, _data_->_tmp16_, _data_->_tmp17_, _data_->_tmp18_); ++ _data_->result = _data_->_tmp19_; ++ _g_free0 (_data_->filter); ++ _g_value_array_free0 (_data_->args); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ goto __finally4; ++ __catch4_g_error: ++ { ++ _data_->e = _data_->_inner_error_; ++ _data_->_inner_error_ = NULL; ++ _data_->_tmp20_ = NULL; ++ _data_->_tmp20_ = _data_->e; ++ _data_->_tmp21_ = NULL; ++ _data_->_tmp21_ = _data_->_tmp20_->message; ++ g_debug ("rygel-lms-category-container.vala:267: Falling back to simple_search" \ ++"(): %s", _data_->_tmp21_); ++ _data_->_tmp23_ = NULL; ++ _data_->_tmp23_ = _data_->expression; ++ _data_->_tmp24_ = 0U; ++ _data_->_tmp24_ = _data_->offset; ++ _data_->_tmp25_ = 0U; ++ _data_->_tmp25_ = _data_->max_count; ++ _data_->_tmp26_ = NULL; ++ _data_->_tmp26_ = _data_->sort_criteria; ++ _data_->_tmp27_ = NULL; ++ _data_->_tmp27_ = _data_->cancellable; ++ _data_->_tmp28_ = 0U; ++ _data_->_state_ = 1; ++ rygel_searchable_container_simple_search ((RygelSearchableContainer*) _data_->self, _data_->_tmp23_, _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, _data_->_tmp27_, rygel_lms_category_container_search_ready, _data_); ++ return FALSE; ++ _state_1: ++ _data_->_tmp29_ = NULL; ++ _data_->_tmp29_ = rygel_searchable_container_simple_search_finish ((RygelSearchableContainer*) _data_->self, _data_->_res_, &_data_->_tmp28_, &_data_->_inner_error_); ++ _data_->total_matches = _data_->_tmp28_; ++ _data_->_tmp22_ = _data_->_tmp29_; ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ _g_error_free0 (_data_->e); ++ goto __finally4; ++ } ++ _data_->_tmp30_ = NULL; ++ _data_->_tmp30_ = _data_->_tmp22_; ++ _data_->_tmp22_ = NULL; ++ _data_->result = _data_->_tmp30_; ++ _g_object_unref0 (_data_->_tmp22_); ++ _g_error_free0 (_data_->e); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ __finally4: ++ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); ++ g_error_free (_data_->_inner_error_); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++} ++ ++ ++static void rygel_lms_category_container_real_get_children_data_free (gpointer _data) { ++ RygelLmsCategoryContainerGetChildrenData* _data_; ++ _data_ = _data; ++ _g_free0 (_data_->sort_criteria); ++ _g_object_unref0 (_data_->cancellable); ++ _g_object_unref0 (_data_->result); ++ _g_object_unref0 (_data_->self); ++ g_slice_free (RygelLmsCategoryContainerGetChildrenData, _data_); ++} ++ ++ ++static void rygel_lms_category_container_real_get_children (RygelMediaContainer* base, guint offset, guint max_count, const gchar* sort_criteria, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { ++ RygelLMSCategoryContainer * self; ++ RygelLmsCategoryContainerGetChildrenData* _data_; ++ RygelLMSCategoryContainer* _tmp0_ = NULL; ++ guint _tmp1_ = 0U; ++ guint _tmp2_ = 0U; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ GCancellable* _tmp5_ = NULL; ++ GCancellable* _tmp6_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _data_ = g_slice_new0 (RygelLmsCategoryContainerGetChildrenData); ++ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_get_children); ++ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_get_children_data_free); ++ _tmp0_ = _g_object_ref0 (self); ++ _data_->self = _tmp0_; ++ _tmp1_ = offset; ++ _data_->offset = _tmp1_; ++ _tmp2_ = max_count; ++ _data_->max_count = _tmp2_; ++ _tmp3_ = sort_criteria; ++ _tmp4_ = g_strdup (_tmp3_); ++ _g_free0 (_data_->sort_criteria); ++ _data_->sort_criteria = _tmp4_; ++ _tmp5_ = cancellable; ++ _tmp6_ = _g_object_ref0 (_tmp5_); ++ _g_object_unref0 (_data_->cancellable); ++ _data_->cancellable = _tmp6_; ++ rygel_lms_category_container_real_get_children_co (_data_); ++} ++ ++ ++static RygelMediaObjects* rygel_lms_category_container_real_get_children_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) { ++ RygelMediaObjects* result; ++ RygelLmsCategoryContainerGetChildrenData* _data_; ++ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { ++ return NULL; ++ } ++ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); ++ result = _data_->result; ++ _data_->result = NULL; ++ return result; ++} ++ ++ ++static gboolean rygel_lms_category_container_real_get_children_co (RygelLmsCategoryContainerGetChildrenData* _data_) { ++ switch (_data_->_state_) { ++ case 0: ++ goto _state_0; ++ default: ++ g_assert_not_reached (); ++ } ++ _state_0: ++ _data_->_tmp0_ = NULL; ++ _data_->_tmp0_ = rygel_media_objects_new (); ++ _data_->retval = _data_->_tmp0_; ++ _data_->_tmp1_ = NULL; ++ _data_->_tmp1_ = _data_->self->stmt_all; ++ _data_->_tmp2_ = 0U; ++ _data_->_tmp2_ = _data_->offset; ++ _data_->_tmp3_ = 0U; ++ _data_->_tmp3_ = _data_->max_count; ++ _data_->_tmp4_ = NULL; ++ _data_->_tmp4_ = _data_->sort_criteria; ++ rygel_lms_database_get_children_init (_data_->_tmp1_, _data_->_tmp2_, _data_->_tmp3_, _data_->_tmp4_, &_data_->_inner_error_); ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); ++ g_error_free (_data_->_inner_error_); ++ _g_object_unref0 (_data_->retval); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ while (TRUE) { ++ _data_->_tmp6_ = NULL; ++ _data_->_tmp6_ = _data_->self->stmt_all; ++ _data_->_tmp7_ = FALSE; ++ _data_->_tmp7_ = rygel_lms_database_get_children_step (_data_->_tmp6_, &_data_->_inner_error_); ++ _data_->_tmp5_ = _data_->_tmp7_; ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); ++ g_error_free (_data_->_inner_error_); ++ _g_object_unref0 (_data_->retval); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ if (!_data_->_tmp5_) { ++ break; ++ } ++ _data_->_tmp8_ = NULL; ++ _data_->_tmp8_ = _data_->retval; ++ _data_->_tmp9_ = NULL; ++ _data_->_tmp9_ = _data_->self->stmt_all; ++ _data_->_tmp10_ = NULL; ++ _data_->_tmp10_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp9_); ++ _data_->_tmp11_ = NULL; ++ _data_->_tmp11_ = _data_->_tmp10_; ++ gee_abstract_collection_add ((GeeAbstractCollection*) _data_->_tmp8_, _data_->_tmp11_); ++ _g_object_unref0 (_data_->_tmp11_); ++ } ++ _data_->result = _data_->retval; ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ _g_object_unref0 (_data_->retval); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++} ++ ++ ++static void rygel_lms_category_container_real_find_object_data_free (gpointer _data) { ++ RygelLmsCategoryContainerFindObjectData* _data_; ++ _data_ = _data; ++ _g_free0 (_data_->id); ++ _g_object_unref0 (_data_->cancellable); ++ _g_object_unref0 (_data_->result); ++ _g_object_unref0 (_data_->self); ++ g_slice_free (RygelLmsCategoryContainerFindObjectData, _data_); ++} ++ ++ ++static void rygel_lms_category_container_real_find_object (RygelMediaContainer* base, const gchar* id, GCancellable* cancellable, GAsyncReadyCallback _callback_, gpointer _user_data_) { ++ RygelLMSCategoryContainer * self; ++ RygelLmsCategoryContainerFindObjectData* _data_; ++ RygelLMSCategoryContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ gchar* _tmp2_ = NULL; ++ GCancellable* _tmp3_ = NULL; ++ GCancellable* _tmp4_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _data_ = g_slice_new0 (RygelLmsCategoryContainerFindObjectData); ++ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_find_object); ++ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_find_object_data_free); ++ _tmp0_ = _g_object_ref0 (self); ++ _data_->self = _tmp0_; ++ _tmp1_ = id; ++ _tmp2_ = g_strdup (_tmp1_); ++ _g_free0 (_data_->id); ++ _data_->id = _tmp2_; ++ _tmp3_ = cancellable; ++ _tmp4_ = _g_object_ref0 (_tmp3_); ++ _g_object_unref0 (_data_->cancellable); ++ _data_->cancellable = _tmp4_; ++ rygel_lms_category_container_real_find_object_co (_data_); ++} ++ ++ ++static RygelMediaObject* rygel_lms_category_container_real_find_object_finish (RygelMediaContainer* base, GAsyncResult* _res_, GError** error) { ++ RygelMediaObject* result; ++ RygelLmsCategoryContainerFindObjectData* _data_; ++ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) { ++ return NULL; ++ } ++ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); ++ result = _data_->result; ++ _data_->result = NULL; ++ return result; ++} ++ ++ ++static glong string_strnlen (gchar* str, glong maxlen) { ++ glong result = 0L; ++ gchar* end = NULL; ++ gchar* _tmp0_ = NULL; ++ glong _tmp1_ = 0L; ++ gchar* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ _tmp0_ = str; ++ _tmp1_ = maxlen; ++ _tmp2_ = memchr (_tmp0_, 0, (gsize) _tmp1_); ++ end = _tmp2_; ++ _tmp3_ = end; ++ if (_tmp3_ == NULL) { ++ glong _tmp4_ = 0L; ++ _tmp4_ = maxlen; ++ result = _tmp4_; ++ return result; ++ } else { ++ gchar* _tmp5_ = NULL; ++ gchar* _tmp6_ = NULL; ++ _tmp5_ = end; ++ _tmp6_ = str; ++ result = (glong) (_tmp5_ - _tmp6_); ++ return result; ++ } ++} ++ ++ ++static gchar* string_substring (const gchar* self, glong offset, glong len) { ++ gchar* result = NULL; ++ glong string_length = 0L; ++ gboolean _tmp0_ = FALSE; ++ glong _tmp1_ = 0L; ++ glong _tmp8_ = 0L; ++ glong _tmp14_ = 0L; ++ glong _tmp17_ = 0L; ++ glong _tmp18_ = 0L; ++ glong _tmp19_ = 0L; ++ glong _tmp20_ = 0L; ++ glong _tmp21_ = 0L; ++ gchar* _tmp22_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp1_ = offset; ++ if (_tmp1_ >= ((glong) 0)) { ++ glong _tmp2_ = 0L; ++ _tmp2_ = len; ++ _tmp0_ = _tmp2_ >= ((glong) 0); ++ } else { ++ _tmp0_ = FALSE; ++ } ++ if (_tmp0_) { ++ glong _tmp3_ = 0L; ++ glong _tmp4_ = 0L; ++ glong _tmp5_ = 0L; ++ _tmp3_ = offset; ++ _tmp4_ = len; ++ _tmp5_ = string_strnlen ((gchar*) self, _tmp3_ + _tmp4_); ++ string_length = _tmp5_; ++ } else { ++ gint _tmp6_ = 0; ++ gint _tmp7_ = 0; ++ _tmp6_ = strlen (self); ++ _tmp7_ = _tmp6_; ++ string_length = (glong) _tmp7_; ++ } ++ _tmp8_ = offset; ++ if (_tmp8_ < ((glong) 0)) { ++ glong _tmp9_ = 0L; ++ glong _tmp10_ = 0L; ++ glong _tmp11_ = 0L; ++ _tmp9_ = string_length; ++ _tmp10_ = offset; ++ offset = _tmp9_ + _tmp10_; ++ _tmp11_ = offset; ++ g_return_val_if_fail (_tmp11_ >= ((glong) 0), NULL); ++ } else { ++ glong _tmp12_ = 0L; ++ glong _tmp13_ = 0L; ++ _tmp12_ = offset; ++ _tmp13_ = string_length; ++ g_return_val_if_fail (_tmp12_ <= _tmp13_, NULL); ++ } ++ _tmp14_ = len; ++ if (_tmp14_ < ((glong) 0)) { ++ glong _tmp15_ = 0L; ++ glong _tmp16_ = 0L; ++ _tmp15_ = string_length; ++ _tmp16_ = offset; ++ len = _tmp15_ - _tmp16_; ++ } ++ _tmp17_ = offset; ++ _tmp18_ = len; ++ _tmp19_ = string_length; ++ g_return_val_if_fail ((_tmp17_ + _tmp18_) <= _tmp19_, NULL); ++ _tmp20_ = offset; ++ _tmp21_ = len; ++ _tmp22_ = g_strndup (((gchar*) self) + _tmp20_, (gsize) _tmp21_); ++ result = _tmp22_; ++ return result; ++} ++ ++ ++static gint string_index_of_char (const gchar* self, gunichar c, gint start_index) { ++ gint result = 0; ++ gchar* _result_ = NULL; ++ gint _tmp0_ = 0; ++ gunichar _tmp1_ = 0U; ++ gchar* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ g_return_val_if_fail (self != NULL, 0); ++ _tmp0_ = start_index; ++ _tmp1_ = c; ++ _tmp2_ = g_utf8_strchr (((gchar*) self) + _tmp0_, (gssize) (-1), _tmp1_); ++ _result_ = _tmp2_; ++ _tmp3_ = _result_; ++ if (_tmp3_ != NULL) { ++ gchar* _tmp4_ = NULL; ++ _tmp4_ = _result_; ++ result = (gint) (_tmp4_ - ((gchar*) self)); ++ return result; ++ } else { ++ result = -1; ++ return result; ++ } ++} ++ ++ ++static gchar* string_slice (const gchar* self, glong start, glong end) { ++ gchar* result = NULL; ++ glong string_length = 0L; ++ gint _tmp0_ = 0; ++ gint _tmp1_ = 0; ++ glong _tmp2_ = 0L; ++ glong _tmp5_ = 0L; ++ gboolean _tmp8_ = FALSE; ++ glong _tmp9_ = 0L; ++ gboolean _tmp12_ = FALSE; ++ glong _tmp13_ = 0L; ++ glong _tmp16_ = 0L; ++ glong _tmp17_ = 0L; ++ glong _tmp18_ = 0L; ++ glong _tmp19_ = 0L; ++ glong _tmp20_ = 0L; ++ gchar* _tmp21_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = strlen (self); ++ _tmp1_ = _tmp0_; ++ string_length = (glong) _tmp1_; ++ _tmp2_ = start; ++ if (_tmp2_ < ((glong) 0)) { ++ glong _tmp3_ = 0L; ++ glong _tmp4_ = 0L; ++ _tmp3_ = string_length; ++ _tmp4_ = start; ++ start = _tmp3_ + _tmp4_; ++ } ++ _tmp5_ = end; ++ if (_tmp5_ < ((glong) 0)) { ++ glong _tmp6_ = 0L; ++ glong _tmp7_ = 0L; ++ _tmp6_ = string_length; ++ _tmp7_ = end; ++ end = _tmp6_ + _tmp7_; ++ } ++ _tmp9_ = start; ++ if (_tmp9_ >= ((glong) 0)) { ++ glong _tmp10_ = 0L; ++ glong _tmp11_ = 0L; ++ _tmp10_ = start; ++ _tmp11_ = string_length; ++ _tmp8_ = _tmp10_ <= _tmp11_; ++ } else { ++ _tmp8_ = FALSE; ++ } ++ g_return_val_if_fail (_tmp8_, NULL); ++ _tmp13_ = end; ++ if (_tmp13_ >= ((glong) 0)) { ++ glong _tmp14_ = 0L; ++ glong _tmp15_ = 0L; ++ _tmp14_ = end; ++ _tmp15_ = string_length; ++ _tmp12_ = _tmp14_ <= _tmp15_; ++ } else { ++ _tmp12_ = FALSE; ++ } ++ g_return_val_if_fail (_tmp12_, NULL); ++ _tmp16_ = start; ++ _tmp17_ = end; ++ g_return_val_if_fail (_tmp16_ <= _tmp17_, NULL); ++ _tmp18_ = start; ++ _tmp19_ = end; ++ _tmp20_ = start; ++ _tmp21_ = g_strndup (((gchar*) self) + _tmp18_, (gsize) (_tmp19_ - _tmp20_)); ++ result = _tmp21_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_find_object_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) { ++ RygelLmsCategoryContainerFindObjectData* _data_; ++ _data_ = _user_data_; ++ _data_->_source_object_ = source_object; ++ _data_->_res_ = _res_; ++ rygel_lms_category_container_real_find_object_co (_data_); ++} ++ ++ ++static gboolean rygel_lms_category_container_real_find_object_co (RygelLmsCategoryContainerFindObjectData* _data_) { ++ switch (_data_->_state_) { ++ case 0: ++ goto _state_0; ++ case 1: ++ goto _state_1; ++ default: ++ g_assert_not_reached (); ++ } ++ _state_0: ++ _data_->_tmp0_ = NULL; ++ _data_->_tmp0_ = _data_->id; ++ _data_->_tmp1_ = NULL; ++ _data_->_tmp1_ = _data_->self->child_prefix; ++ _data_->_tmp2_ = FALSE; ++ _data_->_tmp2_ = g_str_has_prefix (_data_->_tmp0_, _data_->_tmp1_); ++ if (!_data_->_tmp2_) { ++ _data_->result = NULL; ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ _data_->object = NULL; ++ _data_->_tmp3_ = NULL; ++ _data_->_tmp3_ = _data_->id; ++ _data_->_tmp4_ = NULL; ++ _data_->_tmp4_ = _data_->self->child_prefix; ++ _data_->_tmp5_ = 0; ++ _data_->_tmp5_ = strlen (_data_->_tmp4_); ++ _data_->_tmp6_ = 0; ++ _data_->_tmp6_ = _data_->_tmp5_; ++ _data_->_tmp7_ = NULL; ++ _data_->_tmp7_ = string_substring (_data_->_tmp3_, (glong) _data_->_tmp6_, (glong) (-1)); ++ _data_->real_id = _data_->_tmp7_; ++ _data_->_tmp8_ = NULL; ++ _data_->_tmp8_ = _data_->real_id; ++ _data_->_tmp9_ = 0; ++ _data_->_tmp9_ = string_index_of_char (_data_->_tmp8_, (gunichar) ':', 0); ++ _data_->index = _data_->_tmp9_; ++ _data_->_tmp10_ = 0; ++ _data_->_tmp10_ = _data_->index; ++ if (_data_->_tmp10_ > 0) { ++ _data_->_tmp11_ = NULL; ++ _data_->_tmp11_ = _data_->real_id; ++ _data_->_tmp12_ = 0; ++ _data_->_tmp12_ = _data_->index; ++ _data_->_tmp13_ = NULL; ++ _data_->_tmp13_ = string_slice (_data_->_tmp11_, (glong) 0, (glong) _data_->_tmp12_); ++ _g_free0 (_data_->real_id); ++ _data_->real_id = _data_->_tmp13_; ++ } ++ { ++ _data_->_tmp14_ = NULL; ++ _data_->_tmp14_ = _data_->real_id; ++ _data_->_tmp15_ = NULL; ++ _data_->_tmp15_ = _data_->self->stmt_find_object; ++ rygel_lms_database_find_object (_data_->_tmp14_, _data_->_tmp15_, &_data_->_inner_error_); ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch5_rygel_lms_database_error; ++ } ++ _g_free0 (_data_->real_id); ++ _g_object_unref0 (_data_->object); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code); ++ g_clear_error (&_data_->_inner_error_); ++ return FALSE; ++ } ++ _data_->_tmp16_ = NULL; ++ _data_->_tmp16_ = _data_->self->stmt_find_object; ++ _data_->_tmp17_ = NULL; ++ _data_->_tmp17_ = rygel_lms_category_container_object_from_statement (_data_->self, _data_->_tmp16_); ++ _data_->child = _data_->_tmp17_; ++ _data_->_tmp18_ = 0; ++ _data_->_tmp18_ = _data_->index; ++ if (_data_->_tmp18_ < 0) { ++ _data_->_tmp19_ = NULL; ++ _data_->_tmp19_ = _data_->child; ++ _data_->_tmp20_ = NULL; ++ _data_->_tmp20_ = _g_object_ref0 (_data_->_tmp19_); ++ _g_object_unref0 (_data_->object); ++ _data_->object = _data_->_tmp20_; ++ } else { ++ _data_->_tmp21_ = NULL; ++ _data_->_tmp21_ = _data_->child; ++ _data_->_tmp22_ = NULL; ++ _data_->_tmp22_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_data_->_tmp21_, RYGEL_LMS_TYPE_CATEGORY_CONTAINER) ? ((RygelLMSCategoryContainer*) _data_->_tmp21_) : NULL); ++ _data_->container = _data_->_tmp22_; ++ _data_->_tmp24_ = NULL; ++ _data_->_tmp24_ = _data_->container; ++ _data_->_tmp25_ = NULL; ++ _data_->_tmp25_ = _data_->id; ++ _data_->_tmp26_ = NULL; ++ _data_->_tmp26_ = _data_->cancellable; ++ _data_->_state_ = 1; ++ rygel_media_container_find_object ((RygelMediaContainer*) _data_->_tmp24_, _data_->_tmp25_, _data_->_tmp26_, rygel_lms_category_container_find_object_ready, _data_); ++ return FALSE; ++ _state_1: ++ _data_->_tmp27_ = NULL; ++ _data_->_tmp27_ = rygel_media_container_find_object_finish ((RygelMediaContainer*) _data_->_tmp24_, _data_->_res_, &_data_->_inner_error_); ++ _data_->_tmp23_ = _data_->_tmp27_; ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ _g_object_unref0 (_data_->container); ++ _g_object_unref0 (_data_->child); ++ if (_data_->_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch5_rygel_lms_database_error; ++ } ++ goto __finally5; ++ } ++ _data_->_tmp28_ = NULL; ++ _data_->_tmp28_ = _data_->_tmp23_; ++ _data_->_tmp23_ = NULL; ++ _g_object_unref0 (_data_->object); ++ _data_->object = _data_->_tmp28_; ++ _data_->_tmp29_ = NULL; ++ _data_->_tmp29_ = _data_->object; ++ _data_->_tmp30_ = NULL; ++ _data_->_tmp30_ = _data_->object; ++ _data_->_tmp31_ = NULL; ++ _data_->_tmp31_ = rygel_media_object_get_parent (_data_->_tmp30_); ++ _data_->_tmp32_ = NULL; ++ _data_->_tmp32_ = _data_->_tmp31_; ++ rygel_media_object_set_parent_ref (_data_->_tmp29_, _data_->_tmp32_); ++ _g_object_unref0 (_data_->_tmp23_); ++ _g_object_unref0 (_data_->container); ++ } ++ _g_object_unref0 (_data_->child); ++ } ++ goto __finally5; ++ __catch5_rygel_lms_database_error: ++ { ++ _data_->e = _data_->_inner_error_; ++ _data_->_inner_error_ = NULL; ++ _data_->_tmp33_ = NULL; ++ _data_->_tmp33_ = _data_->id; ++ _data_->_tmp34_ = NULL; ++ _data_->_tmp34_ = rygel_media_object_get_id ((RygelMediaObject*) _data_->self); ++ _data_->_tmp35_ = NULL; ++ _data_->_tmp35_ = _data_->_tmp34_; ++ _data_->_tmp36_ = NULL; ++ _data_->_tmp36_ = _data_->e; ++ _data_->_tmp37_ = NULL; ++ _data_->_tmp37_ = _data_->_tmp36_->message; ++ g_debug ("rygel-lms-category-container.vala:328: find_object %s in %s: %s", _data_->_tmp33_, _data_->_tmp35_, _data_->_tmp37_); ++ _g_error_free0 (_data_->e); ++ } ++ __finally5: ++ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) { ++ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); ++ g_error_free (_data_->_inner_error_); ++ _g_free0 (_data_->real_id); ++ _g_object_unref0 (_data_->object); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ } ++ _data_->result = _data_->object; ++ _g_free0 (_data_->real_id); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++ _g_free0 (_data_->real_id); ++ _g_object_unref0 (_data_->object); ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++} ++ ++ ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* _tmp2_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->child_prefix; ++ _tmp1_ = db_id; ++ _tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_); ++ result = _tmp2_; ++ return result; ++} ++ ++ ++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* _tmp2_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->ref_prefix; ++ _tmp1_ = db_id; ++ _tmp2_ = g_strdup_printf ("%s%d", _tmp0_, _tmp1_); ++ result = _tmp2_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_real_add_child_data_free (gpointer _data) { ++ RygelLmsCategoryContainerAddChildData* _data_; ++ _data_ = _data; ++ _g_object_unref0 (_data_->object); ++ _g_object_unref0 (_data_->self); ++ g_slice_free (RygelLmsCategoryContainerAddChildData, _data_); ++} ++ ++ ++static void rygel_lms_category_container_real_add_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) { ++ RygelLMSCategoryContainer * self; ++ RygelLmsCategoryContainerAddChildData* _data_; ++ RygelLMSCategoryContainer* _tmp0_ = NULL; ++ RygelMediaObject* _tmp1_ = NULL; ++ RygelMediaObject* _tmp2_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _data_ = g_slice_new0 (RygelLmsCategoryContainerAddChildData); ++ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_add_child); ++ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_add_child_data_free); ++ _tmp0_ = _g_object_ref0 (self); ++ _data_->self = _tmp0_; ++ _tmp1_ = object; ++ _tmp2_ = _g_object_ref0 (_tmp1_); ++ _g_object_unref0 (_data_->object); ++ _data_->object = _tmp2_; ++ rygel_lms_category_container_real_add_child_co (_data_); ++} ++ ++ ++static void rygel_lms_category_container_real_add_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) { ++ RygelLmsCategoryContainerAddChildData* _data_; ++ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); ++} ++ ++ ++static gboolean rygel_lms_category_container_real_add_child_co (RygelLmsCategoryContainerAddChildData* _data_) { ++ switch (_data_->_state_) { ++ case 0: ++ goto _state_0; ++ default: ++ g_assert_not_reached (); ++ } ++ _state_0: ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++} ++ ++ ++static void rygel_lms_category_container_real_remove_child_data_free (gpointer _data) { ++ RygelLmsCategoryContainerRemoveChildData* _data_; ++ _data_ = _data; ++ _g_object_unref0 (_data_->object); ++ _g_object_unref0 (_data_->self); ++ g_slice_free (RygelLmsCategoryContainerRemoveChildData, _data_); ++} ++ ++ ++static void rygel_lms_category_container_real_remove_child (RygelTrackableContainer* base, RygelMediaObject* object, GAsyncReadyCallback _callback_, gpointer _user_data_) { ++ RygelLMSCategoryContainer * self; ++ RygelLmsCategoryContainerRemoveChildData* _data_; ++ RygelLMSCategoryContainer* _tmp0_ = NULL; ++ RygelMediaObject* _tmp1_ = NULL; ++ RygelMediaObject* _tmp2_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _data_ = g_slice_new0 (RygelLmsCategoryContainerRemoveChildData); ++ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, rygel_lms_category_container_real_remove_child); ++ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, rygel_lms_category_container_real_remove_child_data_free); ++ _tmp0_ = _g_object_ref0 (self); ++ _data_->self = _tmp0_; ++ _tmp1_ = object; ++ _tmp2_ = _g_object_ref0 (_tmp1_); ++ _g_object_unref0 (_data_->object); ++ _data_->object = _tmp2_; ++ rygel_lms_category_container_real_remove_child_co (_data_); ++} ++ ++ ++static void rygel_lms_category_container_real_remove_child_finish (RygelTrackableContainer* base, GAsyncResult* _res_) { ++ RygelLmsCategoryContainerRemoveChildData* _data_; ++ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_)); ++} ++ ++ ++static gboolean rygel_lms_category_container_real_remove_child_co (RygelLmsCategoryContainerRemoveChildData* _data_) { ++ switch (_data_->_state_) { ++ case 0: ++ goto _state_0; ++ default: ++ g_assert_not_reached (); ++ } ++ _state_0: ++ if (_data_->_state_ == 0) { ++ g_simple_async_result_complete_in_idle (_data_->_async_result); ++ } else { ++ g_simple_async_result_complete (_data_->_async_result); ++ } ++ g_object_unref (_data_->_async_result); ++ return FALSE; ++} ++ ++ ++static void rygel_lms_category_container_on_db_updated (RygelLMSCategoryContainer* self, guint64 old_id, guint64 new_id) { ++ GError * _inner_error_ = NULL; ++ g_return_if_fail (self != NULL); ++ { ++ sqlite3_stmt* stmt_count = NULL; ++ RygelLMSDatabase* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ sqlite3_stmt* _tmp3_ = NULL; ++ gint _tmp4_ = 0; ++ sqlite3_stmt* _tmp7_ = NULL; ++ guint64 _tmp8_ = 0ULL; ++ guint64 _tmp9_ = 0ULL; ++ sqlite3_stmt* _tmp16_ = NULL; ++ guint64 _tmp17_ = 0ULL; ++ guint64 _tmp18_ = 0ULL; ++ _tmp0_ = self->priv->_lms_db; ++ _tmp1_ = self->priv->_sql_count; ++ _tmp2_ = rygel_lms_database_prepare (_tmp0_, _tmp1_, &_inner_error_); ++ stmt_count = _tmp2_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch6_rygel_lms_database_error; ++ } ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ _tmp3_ = stmt_count; ++ _tmp4_ = sqlite3_step (_tmp3_); ++ if (_tmp4_ == SQLITE_ROW) { ++ sqlite3_stmt* _tmp5_ = NULL; ++ gint _tmp6_ = 0; ++ _tmp5_ = stmt_count; ++ _tmp6_ = sqlite3_column_int (_tmp5_, 0); ++ rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp6_); ++ } ++ _tmp7_ = self->stmt_added; ++ _tmp8_ = old_id; ++ _tmp9_ = new_id; ++ rygel_lms_database_get_children_with_update_id_init (_tmp7_, _tmp8_, _tmp9_, &_inner_error_); ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt_count); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch6_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt_count); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ while (TRUE) { ++ gboolean _tmp10_ = FALSE; ++ sqlite3_stmt* _tmp11_ = NULL; ++ gboolean _tmp12_ = FALSE; ++ sqlite3_stmt* _tmp13_ = NULL; ++ RygelMediaObject* _tmp14_ = NULL; ++ RygelMediaObject* _tmp15_ = NULL; ++ _tmp11_ = self->stmt_added; ++ _tmp12_ = rygel_lms_database_get_children_step (_tmp11_, &_inner_error_); ++ _tmp10_ = _tmp12_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt_count); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch6_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt_count); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ if (!_tmp10_) { ++ break; ++ } ++ _tmp13_ = self->stmt_added; ++ _tmp14_ = rygel_lms_category_container_object_from_statement (self, _tmp13_); ++ _tmp15_ = _tmp14_; ++ rygel_trackable_container_add_child_tracked ((RygelTrackableContainer*) self, _tmp15_, NULL, NULL); ++ _g_object_unref0 (_tmp15_); ++ } ++ _tmp16_ = self->stmt_removed; ++ _tmp17_ = old_id; ++ _tmp18_ = new_id; ++ rygel_lms_database_get_children_with_update_id_init (_tmp16_, _tmp17_, _tmp18_, &_inner_error_); ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt_count); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch6_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt_count); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ while (TRUE) { ++ gboolean _tmp19_ = FALSE; ++ sqlite3_stmt* _tmp20_ = NULL; ++ gboolean _tmp21_ = FALSE; ++ sqlite3_stmt* _tmp22_ = NULL; ++ RygelMediaObject* _tmp23_ = NULL; ++ RygelMediaObject* _tmp24_ = NULL; ++ _tmp20_ = self->stmt_removed; ++ _tmp21_ = rygel_lms_database_get_children_step (_tmp20_, &_inner_error_); ++ _tmp19_ = _tmp21_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt_count); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch6_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt_count); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ if (!_tmp19_) { ++ break; ++ } ++ _tmp22_ = self->stmt_removed; ++ _tmp23_ = rygel_lms_category_container_object_from_statement (self, _tmp22_); ++ _tmp24_ = _tmp23_; ++ rygel_trackable_container_remove_child_tracked ((RygelTrackableContainer*) self, _tmp24_, NULL, NULL); ++ _g_object_unref0 (_tmp24_); ++ } ++ _sqlite3_finalize0 (stmt_count); ++ } ++ goto __finally6; ++ __catch6_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp25_ = NULL; ++ const gchar* _tmp26_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp25_ = e; ++ _tmp26_ = _tmp25_->message; ++ g_warning ("rygel-lms-category-container.vala:372: Can't perform container update:" \ ++" %s", _tmp26_); ++ _g_error_free0 (e); ++ } ++ __finally6: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++} ++ ++ ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed) { ++ RygelLMSCategoryContainer * self = NULL; ++ RygelMediaContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ RygelMediaContainer* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ RygelLMSDatabase* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ const gchar* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ const gchar* _tmp13_ = NULL; ++ const gchar* _tmp14_ = NULL; ++ g_return_val_if_fail (db_id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ g_return_val_if_fail (sql_all != NULL, NULL); ++ g_return_val_if_fail (sql_find_object != NULL, NULL); ++ g_return_val_if_fail (sql_count != NULL, NULL); ++ _tmp0_ = parent; ++ _tmp1_ = rygel_media_object_get_id ((RygelMediaObject*) _tmp0_); ++ _tmp2_ = _tmp1_; ++ _tmp3_ = db_id; ++ _tmp4_ = g_strdup_printf ("%s:%s", _tmp2_, _tmp3_); ++ _tmp5_ = _tmp4_; ++ _tmp6_ = db_id; ++ _tmp7_ = parent; ++ _tmp8_ = title; ++ _tmp9_ = lms_db; ++ _tmp10_ = sql_all; ++ _tmp11_ = sql_find_object; ++ _tmp12_ = sql_count; ++ _tmp13_ = sql_added; ++ _tmp14_ = sql_removed; ++ self = (RygelLMSCategoryContainer*) g_object_new (object_type, "id", _tmp5_, "db-id", _tmp6_, "parent", _tmp7_, "title", _tmp8_, "lms-db", _tmp9_, "sql-all", _tmp10_, "sql-find-object", _tmp11_, "sql-count", _tmp12_, "sql-added", _tmp13_, "sql-removed", _tmp14_, NULL); ++ _g_free0 (_tmp5_); ++ return self; ++} ++ ++ ++static GeeArrayList* rygel_lms_category_container_real_get_search_classes (RygelSearchableContainer* base) { ++ GeeArrayList* result; ++ RygelLMSCategoryContainer* self; ++ GeeArrayList* _tmp0_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _tmp0_ = self->priv->_search_classes; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_real_set_search_classes (RygelSearchableContainer* base, GeeArrayList* value) { ++ RygelLMSCategoryContainer* self; ++ GeeArrayList* _tmp0_ = NULL; ++ GeeArrayList* _tmp1_ = NULL; ++ self = (RygelLMSCategoryContainer*) base; ++ _tmp0_ = value; ++ _tmp1_ = _g_object_ref0 (_tmp0_); ++ _g_object_unref0 (self->priv->_search_classes); ++ self->priv->_search_classes = _tmp1_; ++ g_object_notify ((GObject *) self, "search-classes"); ++} ++ ++ ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self) { ++ RygelLMSDatabase* result; ++ RygelLMSDatabase* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_lms_db; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_lms_db (RygelLMSCategoryContainer* self, RygelLMSDatabase* value) { ++ RygelLMSDatabase* _tmp0_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ self->priv->_lms_db = _tmp0_; ++ g_object_notify ((GObject *) self, "lms-db"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_db_id (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_db_id; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_db_id (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_db_id); ++ self->priv->_db_id = _tmp1_; ++ g_object_notify ((GObject *) self, "db-id"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_sql_all (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_sql_all; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_sql_all (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_sql_all); ++ self->priv->_sql_all = _tmp1_; ++ g_object_notify ((GObject *) self, "sql-all"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_sql_find_object (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_sql_find_object; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_sql_find_object (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_sql_find_object); ++ self->priv->_sql_find_object = _tmp1_; ++ g_object_notify ((GObject *) self, "sql-find-object"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_sql_count (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_sql_count; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_sql_count (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_sql_count); ++ self->priv->_sql_count = _tmp1_; ++ g_object_notify ((GObject *) self, "sql-count"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_sql_added (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_sql_added; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_sql_added (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_sql_added); ++ self->priv->_sql_added = _tmp1_; ++ g_object_notify ((GObject *) self, "sql-added"); ++} ++ ++ ++const gchar* rygel_lms_category_container_get_sql_removed (RygelLMSCategoryContainer* self) { ++ const gchar* result; ++ const gchar* _tmp0_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ _tmp0_ = self->priv->_sql_removed; ++ result = _tmp0_; ++ return result; ++} ++ ++ ++static void rygel_lms_category_container_set_sql_removed (RygelLMSCategoryContainer* self, const gchar* value) { ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_if_fail (self != NULL); ++ _tmp0_ = value; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->priv->_sql_removed); ++ self->priv->_sql_removed = _tmp1_; ++ g_object_notify ((GObject *) self, "sql-removed"); ++} ++ ++ ++static void _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated (RygelLMSDatabase* _sender, guint64 old_update_id, guint64 new_update_id, gpointer self) { ++ rygel_lms_category_container_on_db_updated ((RygelLMSCategoryContainer*) self, old_update_id, new_update_id); ++} ++ ++ ++static GObject * rygel_lms_category_container_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) { ++ GObject * obj; ++ GObjectClass * parent_class; ++ RygelLMSCategoryContainer * self; ++ GeeArrayList* _tmp0_ = NULL; ++ GeeArrayList* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gint index = 0; ++ const gchar* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gint _tmp7_ = 0; ++ const gchar* _tmp8_ = NULL; ++ const gchar* _tmp9_ = NULL; ++ gint _tmp10_ = 0; ++ gchar* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ GError * _inner_error_ = NULL; ++ parent_class = G_OBJECT_CLASS (rygel_lms_category_container_parent_class); ++ obj = parent_class->constructor (type, n_construct_properties, construct_properties); ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); ++ _tmp0_ = gee_array_list_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL); ++ _tmp1_ = _tmp0_; ++ rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, _tmp1_); ++ _g_object_unref0 (_tmp1_); ++ _tmp2_ = rygel_media_object_get_id ((RygelMediaObject*) self); ++ _tmp3_ = _tmp2_; ++ _tmp4_ = g_strdup_printf ("%s:", _tmp3_); ++ _g_free0 (self->child_prefix); ++ self->child_prefix = _tmp4_; ++ _tmp5_ = rygel_media_object_get_id ((RygelMediaObject*) self); ++ _tmp6_ = _tmp5_; ++ _tmp7_ = string_index_of_char (_tmp6_, (gunichar) ':', 0); ++ index = _tmp7_; ++ _tmp8_ = rygel_media_object_get_id ((RygelMediaObject*) self); ++ _tmp9_ = _tmp8_; ++ _tmp10_ = index; ++ _tmp11_ = string_slice (_tmp9_, (glong) 0, (glong) _tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp13_ = g_strconcat (_tmp12_, ":all:", NULL); ++ _g_free0 (self->ref_prefix); ++ self->ref_prefix = _tmp13_; ++ _g_free0 (_tmp12_); ++ { ++ sqlite3_stmt* _tmp14_ = NULL; ++ RygelLMSDatabase* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ sqlite3_stmt* _tmp17_ = NULL; ++ sqlite3_stmt* _tmp18_ = NULL; ++ sqlite3_stmt* _tmp19_ = NULL; ++ RygelLMSDatabase* _tmp20_ = NULL; ++ const gchar* _tmp21_ = NULL; ++ sqlite3_stmt* _tmp22_ = NULL; ++ sqlite3_stmt* _tmp23_ = NULL; ++ sqlite3_stmt* stmt_count = NULL; ++ RygelLMSDatabase* _tmp24_ = NULL; ++ const gchar* _tmp25_ = NULL; ++ sqlite3_stmt* _tmp26_ = NULL; ++ sqlite3_stmt* _tmp27_ = NULL; ++ gint _tmp28_ = 0; ++ gboolean _tmp31_ = FALSE; ++ const gchar* _tmp32_ = NULL; ++ _tmp15_ = self->priv->_lms_db; ++ _tmp16_ = self->priv->_sql_all; ++ _tmp17_ = rygel_lms_database_prepare (_tmp15_, _tmp16_, &_inner_error_); ++ _tmp14_ = _tmp17_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch7_rygel_lms_database_error; ++ } ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ _tmp18_ = _tmp14_; ++ _tmp14_ = NULL; ++ _sqlite3_finalize0 (self->stmt_all); ++ self->stmt_all = _tmp18_; ++ _tmp20_ = self->priv->_lms_db; ++ _tmp21_ = self->priv->_sql_find_object; ++ _tmp22_ = rygel_lms_database_prepare (_tmp20_, _tmp21_, &_inner_error_); ++ _tmp19_ = _tmp22_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (_tmp14_); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch7_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (_tmp14_); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ _tmp23_ = _tmp19_; ++ _tmp19_ = NULL; ++ _sqlite3_finalize0 (self->stmt_find_object); ++ self->stmt_find_object = _tmp23_; ++ _tmp24_ = self->priv->_lms_db; ++ _tmp25_ = self->priv->_sql_count; ++ _tmp26_ = rygel_lms_database_prepare (_tmp24_, _tmp25_, &_inner_error_); ++ stmt_count = _tmp26_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch7_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ _tmp27_ = stmt_count; ++ _tmp28_ = sqlite3_step (_tmp27_); ++ if (_tmp28_ == SQLITE_ROW) { ++ sqlite3_stmt* _tmp29_ = NULL; ++ gint _tmp30_ = 0; ++ _tmp29_ = stmt_count; ++ _tmp30_ = sqlite3_column_int (_tmp29_, 0); ++ rygel_media_container_set_child_count ((RygelMediaContainer*) self, _tmp30_); ++ } ++ _tmp32_ = self->priv->_sql_added; ++ if (_tmp32_ != NULL) { ++ const gchar* _tmp33_ = NULL; ++ _tmp33_ = self->priv->_sql_removed; ++ _tmp31_ = _tmp33_ != NULL; ++ } else { ++ _tmp31_ = FALSE; ++ } ++ if (_tmp31_) { ++ sqlite3_stmt* _tmp34_ = NULL; ++ RygelLMSDatabase* _tmp35_ = NULL; ++ const gchar* _tmp36_ = NULL; ++ sqlite3_stmt* _tmp37_ = NULL; ++ sqlite3_stmt* _tmp38_ = NULL; ++ sqlite3_stmt* _tmp39_ = NULL; ++ RygelLMSDatabase* _tmp40_ = NULL; ++ const gchar* _tmp41_ = NULL; ++ sqlite3_stmt* _tmp42_ = NULL; ++ sqlite3_stmt* _tmp43_ = NULL; ++ RygelLMSDatabase* _tmp44_ = NULL; ++ _tmp35_ = self->priv->_lms_db; ++ _tmp36_ = self->priv->_sql_added; ++ _tmp37_ = rygel_lms_database_prepare (_tmp35_, _tmp36_, &_inner_error_); ++ _tmp34_ = _tmp37_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (stmt_count); ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch7_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (stmt_count); ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ _tmp38_ = _tmp34_; ++ _tmp34_ = NULL; ++ _sqlite3_finalize0 (self->stmt_added); ++ self->stmt_added = _tmp38_; ++ _tmp40_ = self->priv->_lms_db; ++ _tmp41_ = self->priv->_sql_removed; ++ _tmp42_ = rygel_lms_database_prepare (_tmp40_, _tmp41_, &_inner_error_); ++ _tmp39_ = _tmp42_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _sqlite3_finalize0 (_tmp34_); ++ _sqlite3_finalize0 (stmt_count); ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch7_rygel_lms_database_error; ++ } ++ _sqlite3_finalize0 (_tmp34_); ++ _sqlite3_finalize0 (stmt_count); ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ _tmp43_ = _tmp39_; ++ _tmp39_ = NULL; ++ _sqlite3_finalize0 (self->stmt_removed); ++ self->stmt_removed = _tmp43_; ++ _tmp44_ = self->priv->_lms_db; ++ g_signal_connect_object (_tmp44_, "db-updated", (GCallback) _rygel_lms_category_container_on_db_updated_rygel_lms_database_db_updated, self, 0); ++ _sqlite3_finalize0 (_tmp39_); ++ _sqlite3_finalize0 (_tmp34_); ++ } ++ _sqlite3_finalize0 (stmt_count); ++ _sqlite3_finalize0 (_tmp19_); ++ _sqlite3_finalize0 (_tmp14_); ++ } ++ goto __finally7; ++ __catch7_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ const gchar* _tmp45_ = NULL; ++ const gchar* _tmp46_ = NULL; ++ GError* _tmp47_ = NULL; ++ const gchar* _tmp48_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp45_ = rygel_media_object_get_title ((RygelMediaObject*) self); ++ _tmp46_ = _tmp45_; ++ _tmp47_ = e; ++ _tmp48_ = _tmp47_->message; ++ g_warning ("rygel-lms-category-container.vala:424: Container %s: %s", _tmp46_, _tmp48_); ++ _g_error_free0 (e); ++ } ++ __finally7: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ } ++ return obj; ++} ++ ++ ++static void rygel_lms_category_container_class_init (RygelLMSCategoryContainerClass * klass) { ++ rygel_lms_category_container_parent_class = g_type_class_peek_parent (klass); ++ g_type_class_add_private (klass, sizeof (RygelLMSCategoryContainerPrivate)); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_category_container_real_object_from_statement; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_all_with_filter = rygel_lms_category_container_real_get_sql_all_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_sql_count_with_filter = rygel_lms_category_container_real_get_sql_count_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_child_count_with_filter = rygel_lms_category_container_real_get_child_count_with_filter; ++ ((RygelLMSCategoryContainerClass *) klass)->get_children_with_filter = rygel_lms_category_container_real_get_children_with_filter; ++ ((RygelMediaContainerClass *) klass)->get_children = rygel_lms_category_container_real_get_children; ++ ((RygelMediaContainerClass *) klass)->get_children_finish = rygel_lms_category_container_real_get_children_finish; ++ ((RygelMediaContainerClass *) klass)->find_object = rygel_lms_category_container_real_find_object; ++ ((RygelMediaContainerClass *) klass)->find_object_finish = rygel_lms_category_container_real_find_object_finish; ++ G_OBJECT_CLASS (klass)->get_property = _vala_rygel_lms_category_container_get_property; ++ G_OBJECT_CLASS (klass)->set_property = _vala_rygel_lms_category_container_set_property; ++ G_OBJECT_CLASS (klass)->constructor = rygel_lms_category_container_constructor; ++ G_OBJECT_CLASS (klass)->finalize = rygel_lms_category_container_finalize; ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES, g_param_spec_object ("search-classes", "search-classes", "search-classes", GEE_TYPE_ARRAY_LIST, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB, rygel_lms_param_spec_database ("lms-db", "lms-db", "lms-db", RYGEL_LMS_TYPE_DATABASE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_DB_ID, g_param_spec_string ("db-id", "db-id", "db-id", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL, g_param_spec_string ("sql-all", "sql-all", "sql-all", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT, g_param_spec_string ("sql-find-object", "sql-find-object", "sql-find-object", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT, g_param_spec_string ("sql-count", "sql-count", "sql-count", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED, g_param_spec_string ("sql-added", "sql-added", "sql-added", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++ g_object_class_install_property (G_OBJECT_CLASS (klass), RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED, g_param_spec_string ("sql-removed", "sql-removed", "sql-removed", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); ++} ++ ++ ++static void rygel_lms_category_container_rygel_trackable_container_interface_init (RygelTrackableContainerIface * iface) { ++ rygel_lms_category_container_rygel_trackable_container_parent_iface = g_type_interface_peek_parent (iface); ++ iface->add_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_add_child; ++ iface->add_child_finish = rygel_lms_category_container_real_add_child_finish; ++ iface->remove_child = (void (*)(RygelTrackableContainer*, RygelMediaObject*)) rygel_lms_category_container_real_remove_child; ++ iface->remove_child_finish = rygel_lms_category_container_real_remove_child_finish; ++} ++ ++ ++static void rygel_lms_category_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface * iface) { ++ rygel_lms_category_container_rygel_searchable_container_parent_iface = g_type_interface_peek_parent (iface); ++ iface->search = (RygelMediaObjects* (*)(RygelSearchableContainer*, RygelSearchExpression*, guint, guint, guint*, const gchar*, GCancellable*, GError**)) rygel_lms_category_container_real_search; ++ iface->search_finish = rygel_lms_category_container_real_search_finish; ++ iface->get_search_classes = rygel_lms_category_container_real_get_search_classes; ++ iface->set_search_classes = rygel_lms_category_container_real_set_search_classes; ++} ++ ++ ++static void rygel_lms_category_container_instance_init (RygelLMSCategoryContainer * self) { ++ self->priv = RYGEL_LMS_CATEGORY_CONTAINER_GET_PRIVATE (self); ++} ++ ++ ++static void rygel_lms_category_container_finalize (GObject* obj) { ++ RygelLMSCategoryContainer * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); ++ _g_object_unref0 (self->priv->_search_classes); ++ _g_free0 (self->priv->_db_id); ++ _g_free0 (self->priv->_sql_all); ++ _g_free0 (self->priv->_sql_find_object); ++ _g_free0 (self->priv->_sql_count); ++ _g_free0 (self->priv->_sql_added); ++ _g_free0 (self->priv->_sql_removed); ++ _sqlite3_finalize0 (self->stmt_all); ++ _sqlite3_finalize0 (self->stmt_find_object); ++ _sqlite3_finalize0 (self->stmt_added); ++ _sqlite3_finalize0 (self->stmt_removed); ++ _g_free0 (self->child_prefix); ++ _g_free0 (self->ref_prefix); ++ G_OBJECT_CLASS (rygel_lms_category_container_parent_class)->finalize (obj); ++} ++ ++ ++GType rygel_lms_category_container_get_type (void) { ++ static volatile gsize rygel_lms_category_container_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_category_container_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSCategoryContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_category_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSCategoryContainer), 0, (GInstanceInitFunc) rygel_lms_category_container_instance_init, NULL }; ++ static const GInterfaceInfo rygel_trackable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_trackable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}; ++ static const GInterfaceInfo rygel_searchable_container_info = { (GInterfaceInitFunc) rygel_lms_category_container_rygel_searchable_container_interface_init, (GInterfaceFinalizeFunc) NULL, NULL}; ++ GType rygel_lms_category_container_type_id; ++ rygel_lms_category_container_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_CONTAINER, "RygelLMSCategoryContainer", &g_define_type_info, G_TYPE_FLAG_ABSTRACT); ++ g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_TRACKABLE_CONTAINER, &rygel_trackable_container_info); ++ g_type_add_interface_static (rygel_lms_category_container_type_id, RYGEL_TYPE_SEARCHABLE_CONTAINER, &rygel_searchable_container_info); ++ g_once_init_leave (&rygel_lms_category_container_type_id__volatile, rygel_lms_category_container_type_id); ++ } ++ return rygel_lms_category_container_type_id__volatile; ++} ++ ++ ++static void _vala_rygel_lms_category_container_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { ++ RygelLMSCategoryContainer * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); ++ switch (property_id) { ++ case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES: ++ g_value_set_object (value, rygel_searchable_container_get_search_classes ((RygelSearchableContainer*) self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB: ++ rygel_lms_value_set_database (value, rygel_lms_category_container_get_lms_db (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID: ++ g_value_set_string (value, rygel_lms_category_container_get_db_id (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL: ++ g_value_set_string (value, rygel_lms_category_container_get_sql_all (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT: ++ g_value_set_string (value, rygel_lms_category_container_get_sql_find_object (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT: ++ g_value_set_string (value, rygel_lms_category_container_get_sql_count (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED: ++ g_value_set_string (value, rygel_lms_category_container_get_sql_added (self)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED: ++ g_value_set_string (value, rygel_lms_category_container_get_sql_removed (self)); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); ++ break; ++ } ++} ++ ++ ++static void _vala_rygel_lms_category_container_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { ++ RygelLMSCategoryContainer * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (object, RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer); ++ switch (property_id) { ++ case RYGEL_LMS_CATEGORY_CONTAINER_SEARCH_CLASSES: ++ rygel_searchable_container_set_search_classes ((RygelSearchableContainer*) self, g_value_get_object (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_LMS_DB: ++ rygel_lms_category_container_set_lms_db (self, rygel_lms_value_get_database (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_DB_ID: ++ rygel_lms_category_container_set_db_id (self, g_value_get_string (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ALL: ++ rygel_lms_category_container_set_sql_all (self, g_value_get_string (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_FIND_OBJECT: ++ rygel_lms_category_container_set_sql_find_object (self, g_value_get_string (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_COUNT: ++ rygel_lms_category_container_set_sql_count (self, g_value_get_string (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_ADDED: ++ rygel_lms_category_container_set_sql_added (self, g_value_get_string (value)); ++ break; ++ case RYGEL_LMS_CATEGORY_CONTAINER_SQL_REMOVED: ++ rygel_lms_category_container_set_sql_removed (self, g_value_get_string (value)); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); ++ break; ++ } ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-database.c b/src/plugins/lms/rygel-lms-database.c +new file mode 100644 +index 0000000..687ef64 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-database.c +@@ -0,0 +1,1349 @@ ++/* rygel-lms-database.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-database.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2009,2011 Jens Georg <mail@jensge.org>, ++ * (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <sqlite3.h> ++#include <gio/gio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <glib/gi18n-lib.h> ++#include <gobject/gvaluecollector.h> ++ ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++typedef struct _RygelLMSDatabasePrivate RygelLMSDatabasePrivate; ++ ++#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ()) ++#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus)) ++#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS)) ++#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface)) ++ ++typedef struct _RygelLMSDBus RygelLMSDBus; ++typedef struct _RygelLMSDBusIface RygelLMSDBusIface; ++ ++#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ()) ++#define _sqlite3_close0(var) ((var == NULL) ? NULL : (var = (sqlite3_close (var), NULL))) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) ++#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL))) ++#define _g_variant_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_unref (var), NULL))) ++#define _g_variant_iter_free0(var) ((var == NULL) ? NULL : (var = (g_variant_iter_free (var), NULL))) ++#define _sqlite3_finalize0(var) ((var == NULL) ? NULL : (var = (sqlite3_finalize (var), NULL))) ++typedef struct _RygelLMSParamSpecDatabase RygelLMSParamSpecDatabase; ++#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); ++#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; } ++#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; } ++#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); ++ ++typedef enum { ++ RYGEL_LMS_DATABASE_ERROR_OPEN, ++ RYGEL_LMS_DATABASE_ERROR_PREPARE, ++ RYGEL_LMS_DATABASE_ERROR_BIND, ++ RYGEL_LMS_DATABASE_ERROR_STEP, ++ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND ++} RygelLMSDatabaseError; ++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () ++struct _RygelLMSDatabase { ++ GTypeInstance parent_instance; ++ volatile int ref_count; ++ RygelLMSDatabasePrivate * priv; ++}; ++ ++struct _RygelLMSDatabaseClass { ++ GTypeClass parent_class; ++ void (*finalize) (RygelLMSDatabase *self); ++}; ++ ++struct _RygelLMSDBusIface { ++ GTypeInterface parent_iface; ++ gchar* (*get_data_base_path) (RygelLMSDBus* self); ++ guint64 (*get_update_id) (RygelLMSDBus* self); ++}; ++ ++struct _RygelLMSDatabasePrivate { ++ sqlite3* db; ++ RygelLMSDBus* lms_proxy; ++ guint64 update_id; ++}; ++ ++struct _RygelLMSParamSpecDatabase { ++ GParamSpec parent_instance; ++}; ++ ++ ++static gpointer rygel_lms_database_parent_class = NULL; ++ ++GQuark rygel_lms_database_error_quark (void); ++gint rygel_lms_utf8_collate_str (guint8* a, int a_length1, guint8* b, int b_length1); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++GType rygel_lms_dbus_get_type (void) G_GNUC_CONST; ++GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST; ++guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); ++#define RYGEL_LMS_DATABASE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabasePrivate)) ++enum { ++ RYGEL_LMS_DATABASE_DUMMY_PROPERTY ++}; ++static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1); ++static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b); ++RygelLMSDatabase* rygel_lms_database_new (GError** error); ++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error); ++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); ++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self); ++static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1); ++static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self); ++static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values); ++static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b); ++static gchar* _variant_get1 (GVariant* value); ++static guint64 _variant_get2 (GVariant* value); ++static guint64 _variant_get3 (GVariant* value); ++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error); ++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error); ++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error); ++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error); ++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error); ++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error); ++static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); ++static void rygel_lms_database_finalize (RygelLMSDatabase* obj); ++static gint _vala_array_length (gpointer array); ++ ++ ++GQuark rygel_lms_database_error_quark (void) { ++ return g_quark_from_static_string ("rygel_lms_database_error-quark"); ++} ++ ++ ++/** ++ * Function to implement the custom SQL function 'contains' ++ */ ++static void rygel_lms_database_utf8_contains (sqlite3_context* context, sqlite3_value** args, int args_length1) { ++ sqlite3_value** _tmp0_ = NULL; ++ gint _tmp0__length1 = 0; ++ gboolean _tmp1_ = FALSE; ++ sqlite3_value** _tmp2_ = NULL; ++ gint _tmp2__length1 = 0; ++ sqlite3_value* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* pattern = NULL; ++ sqlite3_value** _tmp9_ = NULL; ++ gint _tmp9__length1 = 0; ++ sqlite3_value* _tmp10_ = NULL; ++ const gchar* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ const gchar* _tmp13_ = NULL; ++ sqlite3_value** _tmp14_ = NULL; ++ gint _tmp14__length1 = 0; ++ sqlite3_value* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gboolean _tmp17_ = FALSE; ++ g_return_if_fail (context != NULL); ++ _tmp0_ = args; ++ _tmp0__length1 = args_length1; ++ _vala_return_if_fail (_tmp0__length1 == 2, "args.length == 2"); ++ _tmp2_ = args; ++ _tmp2__length1 = args_length1; ++ _tmp3_ = _tmp2_[0]; ++ _tmp4_ = sqlite3_value_text (_tmp3_); ++ if (_tmp4_ == NULL) { ++ _tmp1_ = TRUE; ++ } else { ++ sqlite3_value** _tmp5_ = NULL; ++ gint _tmp5__length1 = 0; ++ sqlite3_value* _tmp6_ = NULL; ++ const gchar* _tmp7_ = NULL; ++ _tmp5_ = args; ++ _tmp5__length1 = args_length1; ++ _tmp6_ = _tmp5_[1]; ++ _tmp7_ = sqlite3_value_text (_tmp6_); ++ _tmp1_ = _tmp7_ == NULL; ++ } ++ if (_tmp1_) { ++ sqlite3_context* _tmp8_ = NULL; ++ _tmp8_ = context; ++ sqlite3_result_int (_tmp8_, 0); ++ return; ++ } ++ _tmp9_ = args; ++ _tmp9__length1 = args_length1; ++ _tmp10_ = _tmp9_[1]; ++ _tmp11_ = sqlite3_value_text (_tmp10_); ++ _tmp12_ = g_regex_escape_string (_tmp11_, -1); ++ pattern = _tmp12_; ++ _tmp13_ = pattern; ++ _tmp14_ = args; ++ _tmp14__length1 = args_length1; ++ _tmp15_ = _tmp14_[0]; ++ _tmp16_ = sqlite3_value_text (_tmp15_); ++ _tmp17_ = g_regex_match_simple (_tmp13_, _tmp16_, G_REGEX_CASELESS, 0); ++ if (_tmp17_) { ++ sqlite3_context* _tmp18_ = NULL; ++ _tmp18_ = context; ++ sqlite3_result_int (_tmp18_, 1); ++ } else { ++ sqlite3_context* _tmp19_ = NULL; ++ _tmp19_ = context; ++ sqlite3_result_int (_tmp19_, 0); ++ } ++ _g_free0 (pattern); ++} ++ ++ ++/** ++ * Function to implement the custom SQLite collation 'CASEFOLD'. ++ * ++ * Uses utf8 case-fold to compare the strings. ++ */ ++static gint rygel_lms_database_utf8_collate (gint alen, void* a, gint blen, void* b) { ++ gint result = 0; ++ guint8* _a = NULL; ++ void* _tmp0_ = NULL; ++ gint _a_length1 = 0; ++ gint __a_size_ = 0; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ guint8* _b = NULL; ++ void* _tmp3_ = NULL; ++ gint _b_length1 = 0; ++ gint __b_size_ = 0; ++ gint _tmp4_ = 0; ++ gint _tmp5_ = 0; ++ gint _tmp6_ = 0; ++ _tmp0_ = a; ++ _a = (guint8*) _tmp0_; ++ _a_length1 = -1; ++ __a_size_ = _a_length1; ++ _tmp1_ = alen; ++ _a_length1 = _tmp1_; ++ _tmp2_ = _a_length1; ++ _tmp3_ = b; ++ _b = (guint8*) _tmp3_; ++ _b_length1 = -1; ++ __b_size_ = _b_length1; ++ _tmp4_ = blen; ++ _b_length1 = _tmp4_; ++ _tmp5_ = _b_length1; ++ _tmp6_ = rygel_lms_utf8_collate_str (_a, _a_length1, _b, _b_length1); ++ result = _tmp6_; ++ return result; ++} ++ ++ ++static void _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed (GDBusProxy* _sender, GVariant* changed_properties, gchar** invalidated_properties, gpointer self) { ++ rygel_lms_database_on_lms_properties_changed ((RygelLMSDatabase*) self, _sender, changed_properties, invalidated_properties, _vala_array_length (invalidated_properties)); ++} ++ ++ ++static void _rygel_lms_database_utf8_contains_sqlite_user_func_callback (sqlite3_context* context, int values_length1, sqlite3_value** values) { ++ rygel_lms_database_utf8_contains (context, values, values_length1); ++} ++ ++ ++static gint _rygel_lms_database_utf8_collate_sqlite_compare_callback (gpointer self, gint alen, void* a, gint blen, void* b) { ++ gint result; ++ result = rygel_lms_database_utf8_collate (alen, a, blen, b); ++ return result; ++} ++ ++ ++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error) { ++ RygelLMSDatabase* self = NULL; ++ gchar* db_path = NULL; ++ const gchar* _tmp17_ = NULL; ++ sqlite3* _tmp18_ = NULL; ++ sqlite3* _tmp19_ = NULL; ++ gint _tmp20_ = 0; ++ sqlite3* _tmp25_ = NULL; ++ sqlite3* _tmp26_ = NULL; ++ GError * _inner_error_ = NULL; ++ self = (RygelLMSDatabase*) g_type_create_instance (object_type); ++ { ++ RygelLMSDBus* _tmp0_ = NULL; ++ RygelLMSDBus* _tmp1_ = NULL; ++ RygelLMSDBus* _tmp2_ = NULL; ++ RygelLMSDBus* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ RygelLMSDBus* _tmp7_ = NULL; ++ guint64 _tmp8_ = 0ULL; ++ guint64 _tmp9_ = 0ULL; ++ guint64 _tmp10_ = 0ULL; ++ RygelLMSDBus* _tmp11_ = NULL; ++ _tmp1_ = g_initable_new (RYGEL_LMS_TYPE_DBUS_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.lightmediascanner", "g-bus-type", G_BUS_TYPE_SESSION, "g-object-path", "/org/lightmediascanner/Scanner1", "g-interface-name", "org.lightmediascanner.Scanner1", "g-interface-info", g_type_get_qdata (RYGEL_LMS_TYPE_DBUS, g_quark_from_static_string ("vala-dbus-interface-info")), NULL); ++ _tmp0_ = (RygelLMSDBus*) _tmp1_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == G_IO_ERROR) { ++ goto __catch11_g_io_error; ++ } ++ _g_free0 (db_path); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _tmp2_ = _tmp0_; ++ _tmp0_ = NULL; ++ _g_object_unref0 (self->priv->lms_proxy); ++ self->priv->lms_proxy = _tmp2_; ++ _tmp3_ = self->priv->lms_proxy; ++ _tmp4_ = rygel_lms_dbus_get_data_base_path (_tmp3_); ++ _tmp5_ = _tmp4_; ++ _g_free0 (db_path); ++ db_path = _tmp5_; ++ _tmp6_ = db_path; ++ g_debug ("rygel-lms-database.vala:94: Got db path %s from LMS over dbus", _tmp6_); ++ _tmp7_ = self->priv->lms_proxy; ++ _tmp8_ = rygel_lms_dbus_get_update_id (_tmp7_); ++ _tmp9_ = _tmp8_; ++ self->priv->update_id = _tmp9_; ++ _tmp10_ = self->priv->update_id; ++ g_debug ("rygel-lms-database.vala:96: Got updated id %lld from LMS over dbus", _tmp10_); ++ _tmp11_ = self->priv->lms_proxy; ++ g_signal_connect ((GDBusProxy*) _tmp11_, "g-properties-changed", (GCallback) _rygel_lms_database_on_lms_properties_changed_g_dbus_proxy_g_properties_changed, self); ++ _g_object_unref0 (_tmp0_); ++ } ++ goto __finally11; ++ __catch11_g_io_error: ++ { ++ GError* e = NULL; ++ GError* _tmp12_ = NULL; ++ const gchar* _tmp13_ = NULL; ++ const gchar* _tmp14_ = NULL; ++ gchar* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp12_ = e; ++ _tmp13_ = _tmp12_->message; ++ g_warning ("rygel-lms-database.vala:100: Couldn't get LMS Dbus proxy: %s", _tmp13_); ++ _tmp14_ = g_get_user_config_dir (); ++ _tmp15_ = g_strconcat (_tmp14_, "/lightmediascannerd/db.sqlite3", NULL); ++ _g_free0 (db_path); ++ db_path = _tmp15_; ++ _tmp16_ = db_path; ++ g_debug ("rygel-lms-database.vala:103: Using default sqlite database location %s", _tmp16_); ++ _g_error_free0 (e); ++ } ++ __finally11: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _g_free0 (db_path); ++ _rygel_lms_database_unref0 (self); ++ return NULL; ++ } else { ++ _g_free0 (db_path); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ _tmp17_ = db_path; ++ sqlite3_open (_tmp17_, &_tmp18_); ++ _sqlite3_close0 (self->priv->db); ++ self->priv->db = _tmp18_; ++ _tmp19_ = self->priv->db; ++ _tmp20_ = sqlite3_errcode (_tmp19_); ++ if (_tmp20_ != SQLITE_OK) { ++ const gchar* _tmp21_ = NULL; ++ sqlite3* _tmp22_ = NULL; ++ gint _tmp23_ = 0; ++ GError* _tmp24_ = NULL; ++ _tmp21_ = db_path; ++ _tmp22_ = self->priv->db; ++ _tmp23_ = sqlite3_errcode (_tmp22_); ++ _tmp24_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_OPEN, "Failed to open '%s': %d", _tmp21_, _tmp23_); ++ _inner_error_ = _tmp24_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _g_free0 (db_path); ++ _rygel_lms_database_unref0 (self); ++ return NULL; ++ } else { ++ _g_free0 (db_path); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ _tmp25_ = self->priv->db; ++ sqlite3_create_function (_tmp25_, "contains", 2, SQLITE_UTF8, NULL, _rygel_lms_database_utf8_contains_sqlite_user_func_callback, NULL, NULL); ++ _tmp26_ = self->priv->db; ++ sqlite3_create_collation (_tmp26_, "CASEFOLD", SQLITE_UTF8, NULL, (int (*)(void *, int, const void *, int, const void *)) _rygel_lms_database_utf8_collate_sqlite_compare_callback); ++ _g_free0 (db_path); ++ return self; ++} ++ ++ ++RygelLMSDatabase* rygel_lms_database_new (GError** error) { ++ return rygel_lms_database_construct (RYGEL_LMS_TYPE_DATABASE, error); ++} ++ ++ ++static gchar* _variant_get1 (GVariant* value) { ++ return g_variant_dup_string (value, NULL); ++} ++ ++ ++static guint64 _variant_get2 (GVariant* value) { ++ return g_variant_get_uint64 (value); ++} ++ ++ ++static guint64 _variant_get3 (GVariant* value) { ++ return g_variant_get_uint64 (value); ++} ++ ++ ++static void rygel_lms_database_on_lms_properties_changed (RygelLMSDatabase* self, GDBusProxy* lms_proxy, GVariant* changed, gchar** invalidated, int invalidated_length1) { ++ GVariant* _tmp0_ = NULL; ++ const GVariantType* _tmp1_ = NULL; ++ const GVariantType* _tmp2_ = NULL; ++ gboolean _tmp3_ = FALSE; ++ g_return_if_fail (self != NULL); ++ g_return_if_fail (lms_proxy != NULL); ++ g_return_if_fail (changed != NULL); ++ _tmp0_ = changed; ++ _tmp1_ = g_variant_get_type (_tmp0_); ++ _tmp2_ = G_VARIANT_TYPE_VARDICT; ++ _tmp3_ = g_variant_type_equal (_tmp1_, _tmp2_); ++ if (!_tmp3_) { ++ return; ++ } ++ { ++ GVariantIter* _changed_prop_it = NULL; ++ GVariant* _tmp4_ = NULL; ++ GVariantIter* _tmp5_ = NULL; ++ GVariant* changed_prop = NULL; ++ _tmp4_ = changed; ++ _tmp5_ = g_variant_iter_new (_tmp4_); ++ _changed_prop_it = _tmp5_; ++ while (TRUE) { ++ GVariantIter* _tmp6_ = NULL; ++ GVariant* _tmp7_ = NULL; ++ GVariant* _tmp8_ = NULL; ++ gchar* key = NULL; ++ GVariant* _tmp9_ = NULL; ++ GVariant* _tmp10_ = NULL; ++ GVariant* _tmp11_ = NULL; ++ gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ GVariant* value = NULL; ++ GVariant* _tmp14_ = NULL; ++ GVariant* _tmp15_ = NULL; ++ GVariant* _tmp16_ = NULL; ++ GVariant* _tmp17_ = NULL; ++ GVariant* _tmp18_ = NULL; ++ const gchar* _tmp19_ = NULL; ++ GVariant* _tmp20_ = NULL; ++ gchar* _tmp21_ = NULL; ++ gchar* _tmp22_ = NULL; ++ const gchar* _tmp23_ = NULL; ++ const gchar* _tmp24_ = NULL; ++ GQuark _tmp26_ = 0U; ++ static GQuark _tmp25_label0 = 0; ++ _tmp6_ = _changed_prop_it; ++ _tmp7_ = g_variant_iter_next_value (_tmp6_); ++ _g_variant_unref0 (changed_prop); ++ changed_prop = _tmp7_; ++ _tmp8_ = changed_prop; ++ if (!(_tmp8_ != NULL)) { ++ break; ++ } ++ _tmp9_ = changed_prop; ++ _tmp10_ = g_variant_get_child_value (_tmp9_, (gsize) 0); ++ _tmp11_ = _tmp10_; ++ _tmp12_ = _variant_get1 (_tmp11_); ++ _tmp13_ = _tmp12_; ++ _g_variant_unref0 (_tmp11_); ++ key = _tmp13_; ++ _tmp14_ = changed_prop; ++ _tmp15_ = g_variant_get_child_value (_tmp14_, (gsize) 1); ++ _tmp16_ = _tmp15_; ++ _tmp17_ = g_variant_get_child_value (_tmp16_, (gsize) 0); ++ _tmp18_ = _tmp17_; ++ _g_variant_unref0 (_tmp16_); ++ value = _tmp18_; ++ _tmp19_ = key; ++ _tmp20_ = value; ++ _tmp21_ = g_variant_print (_tmp20_, TRUE); ++ _tmp22_ = _tmp21_; ++ g_debug ("rygel-lms-database.vala:138: LMS property %s changed value to %s", _tmp19_, _tmp22_); ++ _g_free0 (_tmp22_); ++ _tmp23_ = key; ++ _tmp24_ = _tmp23_; ++ _tmp26_ = (NULL == _tmp24_) ? 0 : g_quark_from_string (_tmp24_); ++ if (_tmp26_ == ((0 != _tmp25_label0) ? _tmp25_label0 : (_tmp25_label0 = g_quark_from_static_string ("UpdateID")))) { ++ switch (0) { ++ default: ++ { ++ guint64 _tmp27_ = 0ULL; ++ GVariant* _tmp28_ = NULL; ++ guint64 _tmp29_ = 0ULL; ++ GVariant* _tmp30_ = NULL; ++ guint64 _tmp31_ = 0ULL; ++ _tmp27_ = self->priv->update_id; ++ _tmp28_ = value; ++ _tmp29_ = _variant_get2 (_tmp28_); ++ g_signal_emit_by_name (self, "db-updated", _tmp27_, _tmp29_); ++ _tmp30_ = value; ++ _tmp31_ = _variant_get3 (_tmp30_); ++ self->priv->update_id = _tmp31_; ++ break; ++ } ++ } ++ } ++ _g_variant_unref0 (value); ++ _g_free0 (key); ++ } ++ _g_variant_unref0 (changed_prop); ++ _g_variant_iter_free0 (_changed_prop_it); ++ } ++} ++ ++ ++sqlite3_stmt* rygel_lms_database_prepare (RygelLMSDatabase* self, const gchar* query_string, GError** error) { ++ sqlite3_stmt* result = NULL; ++ sqlite3_stmt* statement = NULL; ++ gint err = 0; ++ sqlite3* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ gint _tmp3_ = 0; ++ gint _tmp4_ = 0; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ g_return_val_if_fail (query_string != NULL, NULL); ++ _tmp0_ = self->priv->db; ++ _tmp1_ = query_string; ++ _tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL); ++ _sqlite3_finalize0 (statement); ++ statement = _tmp2_; ++ err = _tmp3_; ++ _tmp4_ = err; ++ if (_tmp4_ != SQLITE_OK) { ++ const gchar* _tmp5_ = NULL; ++ gint _tmp6_ = 0; ++ GError* _tmp7_ = NULL; ++ _tmp5_ = query_string; ++ _tmp6_ = err; ++ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_); ++ _inner_error_ = _tmp7_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ result = statement; ++ return result; ++} ++ ++ ++sqlite3_stmt* rygel_lms_database_prepare_and_init (RygelLMSDatabase* self, const gchar* query, GValue* arguments, int arguments_length1, GError** error) { ++ sqlite3_stmt* result = NULL; ++ sqlite3_stmt* statement = NULL; ++ gint err = 0; ++ sqlite3* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ gint _tmp3_ = 0; ++ gint _tmp4_ = 0; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (self != NULL, NULL); ++ g_return_val_if_fail (query != NULL, NULL); ++ _tmp0_ = self->priv->db; ++ _tmp1_ = query; ++ _tmp3_ = sqlite3_prepare_v2 (_tmp0_, _tmp1_, -1, &_tmp2_, NULL); ++ _sqlite3_finalize0 (statement); ++ statement = _tmp2_; ++ err = _tmp3_; ++ _tmp4_ = err; ++ if (_tmp4_ != SQLITE_OK) { ++ const gchar* _tmp5_ = NULL; ++ gint _tmp6_ = 0; ++ GError* _tmp7_ = NULL; ++ _tmp5_ = query; ++ _tmp6_ = err; ++ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_PREPARE, "Unable to create statement '%s': %d", _tmp5_, _tmp6_); ++ _inner_error_ = _tmp7_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ { ++ gint i = 0; ++ i = 1; ++ { ++ gboolean _tmp8_ = FALSE; ++ _tmp8_ = TRUE; ++ while (TRUE) { ++ gint _tmp10_ = 0; ++ GValue* _tmp11_ = NULL; ++ gint _tmp11__length1 = 0; ++ gint sqlite_err = 0; ++ GValue current_value = {0}; ++ GValue* _tmp12_ = NULL; ++ gint _tmp12__length1 = 0; ++ gint _tmp13_ = 0; ++ GValue _tmp14_ = {0}; ++ gboolean _tmp15_ = FALSE; ++ if (!_tmp8_) { ++ gint _tmp9_ = 0; ++ _tmp9_ = i; ++ i = _tmp9_ + 1; ++ } ++ _tmp8_ = FALSE; ++ _tmp10_ = i; ++ _tmp11_ = arguments; ++ _tmp11__length1 = arguments_length1; ++ if (!(_tmp10_ <= _tmp11__length1)) { ++ break; ++ } ++ _tmp12_ = arguments; ++ _tmp12__length1 = arguments_length1; ++ _tmp13_ = i; ++ _tmp14_ = _tmp12_[_tmp13_ - 1]; ++ current_value = _tmp14_; ++ _tmp15_ = G_VALUE_HOLDS (¤t_value, G_TYPE_INT); ++ if (_tmp15_) { ++ sqlite3_stmt* _tmp16_ = NULL; ++ gint _tmp17_ = 0; ++ gint _tmp18_ = 0; ++ gint _tmp19_ = 0; ++ gint _tmp20_ = 0; ++ _tmp16_ = statement; ++ _tmp17_ = i; ++ _tmp18_ = g_value_get_int (¤t_value); ++ _tmp19_ = sqlite3_bind_int (_tmp16_, _tmp17_, _tmp18_); ++ sqlite_err = _tmp19_; ++ _tmp20_ = sqlite_err; ++ if (_tmp20_ != SQLITE_OK) { ++ gint _tmp21_ = 0; ++ GError* _tmp22_ = NULL; ++ _tmp21_ = sqlite_err; ++ _tmp22_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp21_); ++ _inner_error_ = _tmp22_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp23_ = FALSE; ++ _tmp23_ = G_VALUE_HOLDS (¤t_value, G_TYPE_INT64); ++ if (_tmp23_) { ++ sqlite3_stmt* _tmp24_ = NULL; ++ gint _tmp25_ = 0; ++ gint64 _tmp26_ = 0LL; ++ gint _tmp27_ = 0; ++ gint _tmp28_ = 0; ++ _tmp24_ = statement; ++ _tmp25_ = i; ++ _tmp26_ = g_value_get_int64 (¤t_value); ++ _tmp27_ = sqlite3_bind_int64 (_tmp24_, _tmp25_, _tmp26_); ++ sqlite_err = _tmp27_; ++ _tmp28_ = sqlite_err; ++ if (_tmp28_ != SQLITE_OK) { ++ gint _tmp29_ = 0; ++ GError* _tmp30_ = NULL; ++ _tmp29_ = sqlite_err; ++ _tmp30_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp29_); ++ _inner_error_ = _tmp30_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp31_ = FALSE; ++ _tmp31_ = G_VALUE_HOLDS (¤t_value, G_TYPE_UINT64); ++ if (_tmp31_) { ++ sqlite3_stmt* _tmp32_ = NULL; ++ gint _tmp33_ = 0; ++ guint64 _tmp34_ = 0ULL; ++ gint _tmp35_ = 0; ++ gint _tmp36_ = 0; ++ _tmp32_ = statement; ++ _tmp33_ = i; ++ _tmp34_ = g_value_get_uint64 (¤t_value); ++ _tmp35_ = sqlite3_bind_int64 (_tmp32_, _tmp33_, (gint64) _tmp34_); ++ sqlite_err = _tmp35_; ++ _tmp36_ = sqlite_err; ++ if (_tmp36_ != SQLITE_OK) { ++ gint _tmp37_ = 0; ++ GError* _tmp38_ = NULL; ++ _tmp37_ = sqlite_err; ++ _tmp38_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp37_); ++ _inner_error_ = _tmp38_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp39_ = FALSE; ++ _tmp39_ = G_VALUE_HOLDS (¤t_value, G_TYPE_LONG); ++ if (_tmp39_) { ++ sqlite3_stmt* _tmp40_ = NULL; ++ gint _tmp41_ = 0; ++ glong _tmp42_ = 0L; ++ gint _tmp43_ = 0; ++ gint _tmp44_ = 0; ++ _tmp40_ = statement; ++ _tmp41_ = i; ++ _tmp42_ = g_value_get_long (¤t_value); ++ _tmp43_ = sqlite3_bind_int64 (_tmp40_, _tmp41_, (gint64) _tmp42_); ++ sqlite_err = _tmp43_; ++ _tmp44_ = sqlite_err; ++ if (_tmp44_ != SQLITE_OK) { ++ gint _tmp45_ = 0; ++ GError* _tmp46_ = NULL; ++ _tmp45_ = sqlite_err; ++ _tmp46_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp45_); ++ _inner_error_ = _tmp46_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp47_ = FALSE; ++ _tmp47_ = G_VALUE_HOLDS (¤t_value, G_TYPE_UINT); ++ if (_tmp47_) { ++ sqlite3_stmt* _tmp48_ = NULL; ++ gint _tmp49_ = 0; ++ guint _tmp50_ = 0U; ++ gint _tmp51_ = 0; ++ gint _tmp52_ = 0; ++ _tmp48_ = statement; ++ _tmp49_ = i; ++ _tmp50_ = g_value_get_uint (¤t_value); ++ _tmp51_ = sqlite3_bind_int64 (_tmp48_, _tmp49_, (gint64) _tmp50_); ++ sqlite_err = _tmp51_; ++ _tmp52_ = sqlite_err; ++ if (_tmp52_ != SQLITE_OK) { ++ gint _tmp53_ = 0; ++ GError* _tmp54_ = NULL; ++ _tmp53_ = sqlite_err; ++ _tmp54_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp53_); ++ _inner_error_ = _tmp54_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp55_ = FALSE; ++ _tmp55_ = G_VALUE_HOLDS (¤t_value, G_TYPE_STRING); ++ if (_tmp55_) { ++ sqlite3_stmt* _tmp56_ = NULL; ++ gint _tmp57_ = 0; ++ const gchar* _tmp58_ = NULL; ++ gchar* _tmp59_ = NULL; ++ GDestroyNotify _tmp60_ = NULL; ++ gint _tmp61_ = 0; ++ gint _tmp62_ = 0; ++ _tmp56_ = statement; ++ _tmp57_ = i; ++ _tmp58_ = g_value_get_string (¤t_value); ++ _tmp59_ = g_strdup (_tmp58_); ++ _tmp60_ = g_free; ++ _tmp61_ = sqlite3_bind_text (_tmp56_, _tmp57_, _tmp59_, -1, _tmp60_); ++ sqlite_err = _tmp61_; ++ _tmp62_ = sqlite_err; ++ if (_tmp62_ != SQLITE_OK) { ++ gint _tmp63_ = 0; ++ GError* _tmp64_ = NULL; ++ _tmp63_ = sqlite_err; ++ _tmp64_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp63_); ++ _inner_error_ = _tmp64_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ gboolean _tmp65_ = FALSE; ++ _tmp65_ = G_VALUE_HOLDS (¤t_value, G_TYPE_POINTER); ++ if (_tmp65_) { ++ void* _tmp66_ = NULL; ++ _tmp66_ = g_value_peek_pointer (¤t_value); ++ if (_tmp66_ == NULL) { ++ sqlite3_stmt* _tmp67_ = NULL; ++ gint _tmp68_ = 0; ++ gint _tmp69_ = 0; ++ gint _tmp70_ = 0; ++ _tmp67_ = statement; ++ _tmp68_ = i; ++ _tmp69_ = sqlite3_bind_null (_tmp67_, _tmp68_); ++ sqlite_err = _tmp69_; ++ _tmp70_ = sqlite_err; ++ if (_tmp70_ != SQLITE_OK) { ++ gint _tmp71_ = 0; ++ GError* _tmp72_ = NULL; ++ _tmp71_ = sqlite_err; ++ _tmp72_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind value %d", _tmp71_); ++ _inner_error_ = _tmp72_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ _sqlite3_finalize0 (statement); ++ return NULL; ++ } else { ++ _sqlite3_finalize0 (statement); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ } ++ } else { ++ g_assert_not_reached (); ++ } ++ } else { ++ GType type = 0UL; ++ GType _tmp73_ = 0UL; ++ const gchar* _tmp74_ = NULL; ++ const gchar* _tmp75_ = NULL; ++ _tmp73_ = G_VALUE_TYPE (¤t_value); ++ type = _tmp73_; ++ _tmp74_ = _ ("Unsupported type %s"); ++ _tmp75_ = g_type_name (type); ++ g_warning (_tmp74_, _tmp75_); ++ g_assert_not_reached (); ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ result = statement; ++ return result; ++} ++ ++ ++void rygel_lms_database_find_object (const gchar* id, sqlite3_stmt* stmt, GError** error) { ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint integer_id = 0; ++ const gchar* _tmp2_ = NULL; ++ gint _tmp3_ = 0; ++ gint sqlite_err = 0; ++ sqlite3_stmt* _tmp4_ = NULL; ++ gint _tmp5_ = 0; ++ gint _tmp6_ = 0; ++ gint _tmp7_ = 0; ++ sqlite3_stmt* _tmp10_ = NULL; ++ gint _tmp11_ = 0; ++ gint _tmp12_ = 0; ++ GError * _inner_error_ = NULL; ++ g_return_if_fail (id != NULL); ++ g_return_if_fail (stmt != NULL); ++ _tmp0_ = stmt; ++ _tmp1_ = sqlite3_reset (_tmp0_); ++ _tmp2_ = id; ++ _tmp3_ = atoi (_tmp2_); ++ integer_id = _tmp3_; ++ _tmp4_ = stmt; ++ _tmp5_ = integer_id; ++ _tmp6_ = sqlite3_bind_int (_tmp4_, 1, _tmp5_); ++ sqlite_err = _tmp6_; ++ _tmp7_ = sqlite_err; ++ if (_tmp7_ != SQLITE_OK) { ++ gint _tmp8_ = 0; ++ GError* _tmp9_ = NULL; ++ _tmp8_ = sqlite_err; ++ _tmp9_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind id %d", _tmp8_); ++ _inner_error_ = _tmp9_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++ _tmp10_ = stmt; ++ _tmp11_ = sqlite3_step (_tmp10_); ++ sqlite_err = _tmp11_; ++ _tmp12_ = sqlite_err; ++ if (_tmp12_ != SQLITE_ROW) { ++ const gchar* _tmp13_ = NULL; ++ GError* _tmp14_ = NULL; ++ _tmp13_ = id; ++ _tmp14_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Unable to find id %s", _tmp13_); ++ _inner_error_ = _tmp14_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++} ++ ++ ++void rygel_lms_database_get_children_init (sqlite3_stmt* stmt, guint offset, guint max_count, const gchar* sort_criteria, GError** error) { ++ gint sqlite_err = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ sqlite3_stmt* _tmp2_ = NULL; ++ guint _tmp3_ = 0U; ++ gint _tmp4_ = 0; ++ gint _tmp5_ = 0; ++ sqlite3_stmt* _tmp8_ = NULL; ++ guint _tmp9_ = 0U; ++ gint _tmp10_ = 0; ++ gint _tmp11_ = 0; ++ GError * _inner_error_ = NULL; ++ g_return_if_fail (stmt != NULL); ++ g_return_if_fail (sort_criteria != NULL); ++ _tmp0_ = stmt; ++ _tmp1_ = sqlite3_reset (_tmp0_); ++ _tmp2_ = stmt; ++ _tmp3_ = max_count; ++ _tmp4_ = sqlite3_bind_int (_tmp2_, 1, (gint) _tmp3_); ++ sqlite_err = _tmp4_; ++ _tmp5_ = sqlite_err; ++ if (_tmp5_ != SQLITE_OK) { ++ gint _tmp6_ = 0; ++ GError* _tmp7_ = NULL; ++ _tmp6_ = sqlite_err; ++ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind max_count %d", _tmp6_); ++ _inner_error_ = _tmp7_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++ _tmp8_ = stmt; ++ _tmp9_ = offset; ++ _tmp10_ = sqlite3_bind_int (_tmp8_, 2, (gint) _tmp9_); ++ sqlite_err = _tmp10_; ++ _tmp11_ = sqlite_err; ++ if (_tmp11_ != SQLITE_OK) { ++ gint _tmp12_ = 0; ++ GError* _tmp13_ = NULL; ++ _tmp12_ = sqlite_err; ++ _tmp13_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind offset %d", _tmp12_); ++ _inner_error_ = _tmp13_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++} ++ ++ ++void rygel_lms_database_get_children_with_update_id_init (sqlite3_stmt* stmt, guint64 old_id, guint64 new_id, GError** error) { ++ gint sqlite_err = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ guint64 _tmp2_ = 0ULL; ++ guint64 _tmp3_ = 0ULL; ++ gint _tmp9_ = 0; ++ sqlite3_stmt* _tmp12_ = NULL; ++ guint64 _tmp13_ = 0ULL; ++ gint _tmp14_ = 0; ++ gint _tmp15_ = 0; ++ GError * _inner_error_ = NULL; ++ g_return_if_fail (stmt != NULL); ++ _tmp0_ = stmt; ++ _tmp1_ = sqlite3_reset (_tmp0_); ++ _tmp2_ = new_id; ++ _tmp3_ = old_id; ++ if (_tmp2_ < _tmp3_) { ++ sqlite3_stmt* _tmp4_ = NULL; ++ gint _tmp5_ = 0; ++ _tmp4_ = stmt; ++ _tmp5_ = sqlite3_bind_int64 (_tmp4_, 1, (gint64) 0); ++ sqlite_err = _tmp5_; ++ } else { ++ sqlite3_stmt* _tmp6_ = NULL; ++ guint64 _tmp7_ = 0ULL; ++ gint _tmp8_ = 0; ++ _tmp6_ = stmt; ++ _tmp7_ = old_id; ++ _tmp8_ = sqlite3_bind_int64 (_tmp6_, 1, (gint64) _tmp7_); ++ sqlite_err = _tmp8_; ++ } ++ _tmp9_ = sqlite_err; ++ if (_tmp9_ != SQLITE_OK) { ++ gint _tmp10_ = 0; ++ GError* _tmp11_ = NULL; ++ _tmp10_ = sqlite_err; ++ _tmp11_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind old_id %d", _tmp10_); ++ _inner_error_ = _tmp11_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++ _tmp12_ = stmt; ++ _tmp13_ = new_id; ++ _tmp14_ = sqlite3_bind_int64 (_tmp12_, 2, (gint64) _tmp13_); ++ sqlite_err = _tmp14_; ++ _tmp15_ = sqlite_err; ++ if (_tmp15_ != SQLITE_OK) { ++ gint _tmp16_ = 0; ++ GError* _tmp17_ = NULL; ++ _tmp16_ = sqlite_err; ++ _tmp17_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_BIND, "Unable to bind new_id %d", _tmp16_); ++ _inner_error_ = _tmp17_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return; ++ } ++ } ++} ++ ++ ++gboolean rygel_lms_database_get_children_step (sqlite3_stmt* stmt, GError** error) { ++ gboolean result = FALSE; ++ gboolean retval = FALSE; ++ gint sqlite_err = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gint _tmp2_ = 0; ++ gboolean _tmp3_ = FALSE; ++ gboolean _tmp4_ = FALSE; ++ GError * _inner_error_ = NULL; ++ g_return_val_if_fail (stmt != NULL, FALSE); ++ _tmp0_ = stmt; ++ _tmp1_ = sqlite3_step (_tmp0_); ++ sqlite_err = _tmp1_; ++ _tmp2_ = sqlite_err; ++ retval = _tmp2_ == SQLITE_ROW; ++ _tmp4_ = retval; ++ if (!_tmp4_) { ++ gint _tmp5_ = 0; ++ _tmp5_ = sqlite_err; ++ _tmp3_ = _tmp5_ != SQLITE_DONE; ++ } else { ++ _tmp3_ = FALSE; ++ } ++ if (_tmp3_) { ++ gint _tmp6_ = 0; ++ GError* _tmp7_ = NULL; ++ _tmp6_ = sqlite_err; ++ _tmp7_ = g_error_new (RYGEL_LMS_DATABASE_ERROR, RYGEL_LMS_DATABASE_ERROR_STEP, "Error iterating through rows %d", _tmp6_); ++ _inner_error_ = _tmp7_; ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ g_propagate_error (error, _inner_error_); ++ return FALSE; ++ } else { ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return FALSE; ++ } ++ } ++ result = retval; ++ return result; ++} ++ ++ ++static void g_cclosure_user_marshal_VOID__UINT64_UINT64 (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { ++ typedef void (*GMarshalFunc_VOID__UINT64_UINT64) (gpointer data1, guint64 arg_1, guint64 arg_2, gpointer data2); ++ register GMarshalFunc_VOID__UINT64_UINT64 callback; ++ register GCClosure * cc; ++ register gpointer data1; ++ register gpointer data2; ++ cc = (GCClosure *) closure; ++ g_return_if_fail (n_param_values == 3); ++ if (G_CCLOSURE_SWAP_DATA (closure)) { ++ data1 = closure->data; ++ data2 = param_values->data[0].v_pointer; ++ } else { ++ data1 = param_values->data[0].v_pointer; ++ data2 = closure->data; ++ } ++ callback = (GMarshalFunc_VOID__UINT64_UINT64) (marshal_data ? marshal_data : cc->callback); ++ callback (data1, g_value_get_uint64 (param_values + 1), g_value_get_uint64 (param_values + 2), data2); ++} ++ ++ ++static void rygel_lms_value_database_init (GValue* value) { ++ value->data[0].v_pointer = NULL; ++} ++ ++ ++static void rygel_lms_value_database_free_value (GValue* value) { ++ if (value->data[0].v_pointer) { ++ rygel_lms_database_unref (value->data[0].v_pointer); ++ } ++} ++ ++ ++static void rygel_lms_value_database_copy_value (const GValue* src_value, GValue* dest_value) { ++ if (src_value->data[0].v_pointer) { ++ dest_value->data[0].v_pointer = rygel_lms_database_ref (src_value->data[0].v_pointer); ++ } else { ++ dest_value->data[0].v_pointer = NULL; ++ } ++} ++ ++ ++static gpointer rygel_lms_value_database_peek_pointer (const GValue* value) { ++ return value->data[0].v_pointer; ++} ++ ++ ++static gchar* rygel_lms_value_database_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ++ if (collect_values[0].v_pointer) { ++ RygelLMSDatabase* object; ++ object = collect_values[0].v_pointer; ++ if (object->parent_instance.g_class == NULL) { ++ return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); ++ } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { ++ return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); ++ } ++ value->data[0].v_pointer = rygel_lms_database_ref (object); ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ return NULL; ++} ++ ++ ++static gchar* rygel_lms_value_database_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ++ RygelLMSDatabase** object_p; ++ object_p = collect_values[0].v_pointer; ++ if (!object_p) { ++ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); ++ } ++ if (!value->data[0].v_pointer) { ++ *object_p = NULL; ++ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { ++ *object_p = value->data[0].v_pointer; ++ } else { ++ *object_p = rygel_lms_database_ref (value->data[0].v_pointer); ++ } ++ return NULL; ++} ++ ++ ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { ++ RygelLMSParamSpecDatabase* spec; ++ g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_DATABASE), NULL); ++ spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); ++ G_PARAM_SPEC (spec)->value_type = object_type; ++ return G_PARAM_SPEC (spec); ++} ++ ++ ++gpointer rygel_lms_value_get_database (const GValue* value) { ++ g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE), NULL); ++ return value->data[0].v_pointer; ++} ++ ++ ++void rygel_lms_value_set_database (GValue* value, gpointer v_object) { ++ RygelLMSDatabase* old; ++ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE)); ++ old = value->data[0].v_pointer; ++ if (v_object) { ++ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE)); ++ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); ++ value->data[0].v_pointer = v_object; ++ rygel_lms_database_ref (value->data[0].v_pointer); ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ if (old) { ++ rygel_lms_database_unref (old); ++ } ++} ++ ++ ++void rygel_lms_value_take_database (GValue* value, gpointer v_object) { ++ RygelLMSDatabase* old; ++ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_DATABASE)); ++ old = value->data[0].v_pointer; ++ if (v_object) { ++ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_DATABASE)); ++ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); ++ value->data[0].v_pointer = v_object; ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ if (old) { ++ rygel_lms_database_unref (old); ++ } ++} ++ ++ ++static void rygel_lms_database_class_init (RygelLMSDatabaseClass * klass) { ++ rygel_lms_database_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSDatabaseClass *) klass)->finalize = rygel_lms_database_finalize; ++ g_type_class_add_private (klass, sizeof (RygelLMSDatabasePrivate)); ++ g_signal_new ("db_updated", RYGEL_LMS_TYPE_DATABASE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT64_UINT64, G_TYPE_NONE, 2, G_TYPE_UINT64, G_TYPE_UINT64); ++} ++ ++ ++static void rygel_lms_database_instance_init (RygelLMSDatabase * self) { ++ self->priv = RYGEL_LMS_DATABASE_GET_PRIVATE (self); ++ self->ref_count = 1; ++} ++ ++ ++static void rygel_lms_database_finalize (RygelLMSDatabase* obj) { ++ RygelLMSDatabase * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase); ++ g_signal_handlers_destroy (self); ++ _sqlite3_close0 (self->priv->db); ++ _g_object_unref0 (self->priv->lms_proxy); ++} ++ ++ ++GType rygel_lms_database_get_type (void) { ++ static volatile gsize rygel_lms_database_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_database_type_id__volatile)) { ++ static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_database_init, rygel_lms_value_database_free_value, rygel_lms_value_database_copy_value, rygel_lms_value_database_peek_pointer, "p", rygel_lms_value_database_collect_value, "p", rygel_lms_value_database_lcopy_value }; ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDatabaseClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_database_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSDatabase), 0, (GInstanceInitFunc) rygel_lms_database_instance_init, &g_define_type_value_table }; ++ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; ++ GType rygel_lms_database_type_id; ++ rygel_lms_database_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSDatabase", &g_define_type_info, &g_define_type_fundamental_info, 0); ++ g_once_init_leave (&rygel_lms_database_type_id__volatile, rygel_lms_database_type_id); ++ } ++ return rygel_lms_database_type_id__volatile; ++} ++ ++ ++gpointer rygel_lms_database_ref (gpointer instance) { ++ RygelLMSDatabase* self; ++ self = instance; ++ g_atomic_int_inc (&self->ref_count); ++ return instance; ++} ++ ++ ++void rygel_lms_database_unref (gpointer instance) { ++ RygelLMSDatabase* self; ++ self = instance; ++ if (g_atomic_int_dec_and_test (&self->ref_count)) { ++ RYGEL_LMS_DATABASE_GET_CLASS (self)->finalize (self); ++ g_type_free_instance ((GTypeInstance *) self); ++ } ++} ++ ++ ++static gint _vala_array_length (gpointer array) { ++ int length; ++ length = 0; ++ if (array) { ++ while (((gpointer*) array)[length]) { ++ length++; ++ } ++ } ++ return length; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-dbus-interfaces.c b/src/plugins/lms/rygel-lms-dbus-interfaces.c +new file mode 100644 +index 0000000..b511b17 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-dbus-interfaces.c +@@ -0,0 +1,261 @@ ++/* rygel-lms-dbus-interfaces.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-dbus-interfaces.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2014 Intel Corporation. ++ * ++ * Author: Alexander Kanavin <alex.kanavin@gmail.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <gio/gio.h> ++#include <stdlib.h> ++#include <string.h> ++ ++ ++#define RYGEL_LMS_TYPE_DBUS (rygel_lms_dbus_get_type ()) ++#define RYGEL_LMS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBus)) ++#define RYGEL_LMS_IS_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DBUS)) ++#define RYGEL_LMS_DBUS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_LMS_TYPE_DBUS, RygelLMSDBusIface)) ++ ++typedef struct _RygelLMSDBus RygelLMSDBus; ++typedef struct _RygelLMSDBusIface RygelLMSDBusIface; ++ ++#define RYGEL_LMS_TYPE_DBUS_PROXY (rygel_lms_dbus_proxy_get_type ()) ++typedef GDBusProxy RygelLMSDBusProxy; ++typedef GDBusProxyClass RygelLMSDBusProxyClass; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++struct _RygelLMSDBusIface { ++ GTypeInterface parent_iface; ++ gchar* (*get_data_base_path) (RygelLMSDBus* self); ++ guint64 (*get_update_id) (RygelLMSDBus* self); ++}; ++ ++ ++ ++GType rygel_lms_dbus_get_type (void) G_GNUC_CONST; ++GType rygel_lms_dbus_proxy_get_type (void) G_GNUC_CONST; ++guint rygel_lms_dbus_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); ++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); ++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self); ++static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); ++static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self); ++static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self); ++static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface); ++static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); ++static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); ++static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self); ++static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self); ++static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); ++static void _rygel_lms_dbus_unregister_object (gpointer user_data); ++ ++static const GDBusMethodInfo * const _rygel_lms_dbus_dbus_method_info[] = {NULL}; ++static const GDBusSignalInfo * const _rygel_lms_dbus_dbus_signal_info[] = {NULL}; ++static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_data_base_path = {-1, "DataBasePath", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; ++static const GDBusPropertyInfo _rygel_lms_dbus_dbus_property_info_update_id = {-1, "UpdateID", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; ++static const GDBusPropertyInfo * const _rygel_lms_dbus_dbus_property_info[] = {&_rygel_lms_dbus_dbus_property_info_data_base_path, &_rygel_lms_dbus_dbus_property_info_update_id, NULL}; ++static const GDBusInterfaceInfo _rygel_lms_dbus_dbus_interface_info = {-1, "org.lightmediascanner.Scanner1", (GDBusMethodInfo **) (&_rygel_lms_dbus_dbus_method_info), (GDBusSignalInfo **) (&_rygel_lms_dbus_dbus_signal_info), (GDBusPropertyInfo **) (&_rygel_lms_dbus_dbus_property_info)}; ++static const GDBusInterfaceVTable _rygel_lms_dbus_dbus_interface_vtable = {rygel_lms_dbus_dbus_interface_method_call, rygel_lms_dbus_dbus_interface_get_property, rygel_lms_dbus_dbus_interface_set_property}; ++ ++gchar* rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_data_base_path (self); ++} ++ ++ ++guint64 rygel_lms_dbus_get_update_id (RygelLMSDBus* self) { ++ g_return_val_if_fail (self != NULL, 0ULL); ++ return RYGEL_LMS_DBUS_GET_INTERFACE (self)->get_update_id (self); ++} ++ ++ ++static void rygel_lms_dbus_base_init (RygelLMSDBusIface * iface) { ++ static gboolean initialized = FALSE; ++ if (!initialized) { ++ initialized = TRUE; ++ } ++} ++ ++ ++GType rygel_lms_dbus_get_type (void) { ++ static volatile gsize rygel_lms_dbus_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_dbus_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSDBusIface), (GBaseInitFunc) rygel_lms_dbus_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; ++ GType rygel_lms_dbus_type_id; ++ rygel_lms_dbus_type_id = g_type_register_static (G_TYPE_INTERFACE, "RygelLMSDBus", &g_define_type_info, 0); ++ g_type_interface_add_prerequisite (rygel_lms_dbus_type_id, G_TYPE_DBUS_PROXY); ++ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) rygel_lms_dbus_proxy_get_type); ++ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.lightmediascanner.Scanner1"); ++ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-interface-info"), (void*) (&_rygel_lms_dbus_dbus_interface_info)); ++ g_type_set_qdata (rygel_lms_dbus_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) rygel_lms_dbus_register_object); ++ g_once_init_leave (&rygel_lms_dbus_type_id__volatile, rygel_lms_dbus_type_id); ++ } ++ return rygel_lms_dbus_type_id__volatile; ++} ++ ++ ++G_DEFINE_TYPE_EXTENDED (RygelLMSDBusProxy, rygel_lms_dbus_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (RYGEL_LMS_TYPE_DBUS, rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init) ) ++static void rygel_lms_dbus_proxy_class_init (RygelLMSDBusProxyClass* klass) { ++ G_DBUS_PROXY_CLASS (klass)->g_signal = rygel_lms_dbus_proxy_g_signal; ++} ++ ++ ++static void rygel_lms_dbus_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { ++} ++ ++ ++static void rygel_lms_dbus_proxy_init (RygelLMSDBusProxy* self) { ++} ++ ++ ++static gchar* rygel_lms_dbus_dbus_proxy_get_data_base_path (RygelLMSDBus* self) { ++ GVariant *_inner_reply; ++ gchar* _result; ++ _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "DataBasePath"); ++ if (!_inner_reply) { ++ GVariant *_arguments; ++ GVariant *_reply; ++ GVariantBuilder _arguments_builder; ++ g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); ++ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1")); ++ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("DataBasePath")); ++ _arguments = g_variant_builder_end (&_arguments_builder); ++ _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); ++ if (!_reply) { ++ return NULL; ++ } ++ g_variant_get (_reply, "(v)", &_inner_reply); ++ g_variant_unref (_reply); ++ } ++ _result = g_variant_dup_string (_inner_reply, NULL); ++ g_variant_unref (_inner_reply); ++ return _result; ++} ++ ++ ++static guint64 rygel_lms_dbus_dbus_proxy_get_update_id (RygelLMSDBus* self) { ++ GVariant *_inner_reply; ++ guint64 _result; ++ _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "UpdateID"); ++ if (!_inner_reply) { ++ GVariant *_arguments; ++ GVariant *_reply; ++ GVariantBuilder _arguments_builder; ++ g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); ++ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.lightmediascanner.Scanner1")); ++ g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("UpdateID")); ++ _arguments = g_variant_builder_end (&_arguments_builder); ++ _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); ++ if (!_reply) { ++ return 0ULL; ++ } ++ g_variant_get (_reply, "(v)", &_inner_reply); ++ g_variant_unref (_reply); ++ } ++ _result = g_variant_get_uint64 (_inner_reply); ++ g_variant_unref (_inner_reply); ++ return _result; ++} ++ ++ ++static void rygel_lms_dbus_proxy_rygel_lms_dbus_interface_init (RygelLMSDBusIface* iface) { ++ iface->get_data_base_path = rygel_lms_dbus_dbus_proxy_get_data_base_path; ++ iface->get_update_id = rygel_lms_dbus_dbus_proxy_get_update_id; ++} ++ ++ ++static void rygel_lms_dbus_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { ++ gpointer* data; ++ gpointer object; ++ data = user_data; ++ object = data[0]; ++ g_object_unref (invocation); ++} ++ ++ ++static GVariant* _dbus_rygel_lms_dbus_get_data_base_path (RygelLMSDBus* self) { ++ gchar* result; ++ GVariant* _reply; ++ result = rygel_lms_dbus_get_data_base_path (self); ++ _reply = g_variant_new_string (result); ++ _g_free0 (result); ++ return _reply; ++} ++ ++ ++static GVariant* _dbus_rygel_lms_dbus_get_update_id (RygelLMSDBus* self) { ++ guint64 result; ++ GVariant* _reply; ++ result = rygel_lms_dbus_get_update_id (self); ++ _reply = g_variant_new_uint64 (result); ++ return _reply; ++} ++ ++ ++static GVariant* rygel_lms_dbus_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { ++ gpointer* data; ++ gpointer object; ++ data = user_data; ++ object = data[0]; ++ if (strcmp (property_name, "DataBasePath") == 0) { ++ return _dbus_rygel_lms_dbus_get_data_base_path (object); ++ } else if (strcmp (property_name, "UpdateID") == 0) { ++ return _dbus_rygel_lms_dbus_get_update_id (object); ++ } ++ return NULL; ++} ++ ++ ++static gboolean rygel_lms_dbus_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { ++ gpointer* data; ++ gpointer object; ++ data = user_data; ++ object = data[0]; ++ return FALSE; ++} ++ ++ ++guint rygel_lms_dbus_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { ++ guint result; ++ gpointer *data; ++ data = g_new (gpointer, 3); ++ data[0] = g_object_ref (object); ++ data[1] = g_object_ref (connection); ++ data[2] = g_strdup (path); ++ result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_rygel_lms_dbus_dbus_interface_info), &_rygel_lms_dbus_dbus_interface_vtable, data, _rygel_lms_dbus_unregister_object, error); ++ if (!result) { ++ return 0; ++ } ++ return result; ++} ++ ++ ++static void _rygel_lms_dbus_unregister_object (gpointer user_data) { ++ gpointer* data; ++ data = user_data; ++ g_object_unref (data[0]); ++ g_object_unref (data[1]); ++ g_free (data[2]); ++ g_free (data); ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-image-root.c b/src/plugins/lms/rygel-lms-image-root.c +new file mode 100644 +index 0000000..5ef358a +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-root.c +@@ -0,0 +1,178 @@ ++/* rygel-lms-image-root.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-image-root.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <stdlib.h> ++#include <string.h> ++ ++ ++#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ()) ++#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot)) ++#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) ++#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT)) ++#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT)) ++#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) ++ ++typedef struct _RygelLMSImageRoot RygelLMSImageRoot; ++typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass; ++typedef struct _RygelLMSImageRootPrivate RygelLMSImageRootPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++ ++#define RYGEL_LMS_TYPE_ALL_IMAGES (rygel_lms_all_images_get_type ()) ++#define RYGEL_LMS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImages)) ++#define RYGEL_LMS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) ++#define RYGEL_LMS_IS_ALL_IMAGES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_IMAGES)) ++#define RYGEL_LMS_IS_ALL_IMAGES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_IMAGES)) ++#define RYGEL_LMS_ALL_IMAGES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_IMAGES, RygelLMSAllImagesClass)) ++ ++typedef struct _RygelLMSAllImages RygelLMSAllImages; ++typedef struct _RygelLMSAllImagesClass RygelLMSAllImagesClass; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ()) ++#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears)) ++#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) ++#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS)) ++#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS)) ++#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) ++ ++typedef struct _RygelLMSImageYears RygelLMSImageYears; ++typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass; ++ ++struct _RygelLMSImageRoot { ++ RygelSimpleContainer parent_instance; ++ RygelLMSImageRootPrivate * priv; ++}; ++ ++struct _RygelLMSImageRootClass { ++ RygelSimpleContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_image_root_parent_class = NULL; ++ ++GType rygel_lms_image_root_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_IMAGE_ROOT_DUMMY_PROPERTY ++}; ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAllImages* rygel_lms_all_images_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAllImages* rygel_lms_all_images_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_images_get_type (void) G_GNUC_CONST; ++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++GType rygel_lms_image_years_get_type (void) G_GNUC_CONST; ++ ++ ++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSImageRoot * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ RygelLMSAllImages* _tmp4_ = NULL; ++ RygelLMSAllImages* _tmp5_ = NULL; ++ RygelLMSDatabase* _tmp6_ = NULL; ++ RygelLMSImageYears* _tmp7_ = NULL; ++ RygelLMSImageYears* _tmp8_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ self = (RygelLMSImageRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_); ++ _tmp3_ = lms_db; ++ _tmp4_ = rygel_lms_all_images_new ((RygelMediaContainer*) self, _tmp3_); ++ _tmp5_ = _tmp4_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_); ++ _g_object_unref0 (_tmp5_); ++ _tmp6_ = lms_db; ++ _tmp7_ = rygel_lms_image_years_new ((RygelMediaContainer*) self, _tmp6_); ++ _tmp8_ = _tmp7_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp8_); ++ _g_object_unref0 (_tmp8_); ++ return self; ++} ++ ++ ++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_image_root_construct (RYGEL_LMS_TYPE_IMAGE_ROOT, id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_image_root_class_init (RygelLMSImageRootClass * klass) { ++ rygel_lms_image_root_parent_class = g_type_class_peek_parent (klass); ++} ++ ++ ++static void rygel_lms_image_root_instance_init (RygelLMSImageRoot * self) { ++} ++ ++ ++GType rygel_lms_image_root_get_type (void) { ++ static volatile gsize rygel_lms_image_root_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_image_root_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageRoot), 0, (GInstanceInitFunc) rygel_lms_image_root_instance_init, NULL }; ++ GType rygel_lms_image_root_type_id; ++ rygel_lms_image_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSImageRoot", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_image_root_type_id__volatile, rygel_lms_image_root_type_id); ++ } ++ return rygel_lms_image_root_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-image-year.c b/src/plugins/lms/rygel-lms-image-year.c +new file mode 100644 +index 0000000..5eb2721 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-year.c +@@ -0,0 +1,422 @@ ++/* rygel-lms-image-year.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-image-year.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <gio/gio.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ()) ++#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear)) ++#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) ++#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR)) ++#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR)) ++#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) ++ ++typedef struct _RygelLMSImageYear RygelLMSImageYear; ++typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass; ++typedef struct _RygelLMSImageYearPrivate RygelLMSImageYearPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSImageYear { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSImageYearPrivate * priv; ++}; ++ ++struct _RygelLMSImageYearClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_image_year_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_image_year_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_IMAGE_YEAR_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE "SELECT count(images.id), strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s';" ++#define RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND files.id = ? AND images.id = files.id AND year = '" \ ++"%s';" ++#define RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime = 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;" ++#define RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE "SELECT images.id, title, artist, date, width, height, path, size, dlna" \ ++"_profile, dlna_mime, strftime('%Y', date, 'unixepoch') as year " "FROM images, files " "WHERE dtime <> 0 AND images.id = files.id AND year = '%s' " "AND update_id > ? AND update_id <= ?;" ++static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gchar* rygel_lms_category_container_build_child_id (RygelLMSCategoryContainer* self, gint db_id); ++gchar* rygel_lms_category_container_build_reference_id (RygelLMSCategoryContainer* self, gint db_id); ++static gchar* rygel_lms_image_year_get_sql_all (const gchar* year); ++static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year); ++static gchar* rygel_lms_image_year_get_sql_count (const gchar* year); ++static gchar* rygel_lms_image_year_get_sql_added (const gchar* year); ++static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); ++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_image_year_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSImageYear * self; ++ RygelMediaObject* result = NULL; ++ gint id = 0; ++ sqlite3_stmt* _tmp0_ = NULL; ++ gint _tmp1_ = 0; ++ gchar* path = NULL; ++ sqlite3_stmt* _tmp2_ = NULL; ++ const gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* mime_type = NULL; ++ sqlite3_stmt* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ gboolean _tmp8_ = FALSE; ++ const gchar* _tmp9_ = NULL; ++ gchar* title = NULL; ++ sqlite3_stmt* _tmp15_ = NULL; ++ const gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ RygelImageItem* image = NULL; ++ gint _tmp18_ = 0; ++ gchar* _tmp19_ = NULL; ++ gchar* _tmp20_ = NULL; ++ RygelImageItem* _tmp21_ = NULL; ++ RygelImageItem* _tmp22_ = NULL; ++ gint _tmp23_ = 0; ++ gchar* _tmp24_ = NULL; ++ gchar* _tmp25_ = NULL; ++ sqlite3_stmt* _tmp26_ = NULL; ++ const gchar* _tmp27_ = NULL; ++ GTimeVal tv = {0}; ++ sqlite3_stmt* _tmp28_ = NULL; ++ gint _tmp29_ = 0; ++ GTimeVal _tmp30_ = {0}; ++ gchar* _tmp31_ = NULL; ++ gchar* _tmp32_ = NULL; ++ sqlite3_stmt* _tmp33_ = NULL; ++ gint _tmp34_ = 0; ++ sqlite3_stmt* _tmp35_ = NULL; ++ gint _tmp36_ = 0; ++ sqlite3_stmt* _tmp37_ = NULL; ++ gint _tmp38_ = 0; ++ const gchar* _tmp39_ = NULL; ++ sqlite3_stmt* _tmp40_ = NULL; ++ const gchar* _tmp41_ = NULL; ++ GFile* file = NULL; ++ const gchar* _tmp42_ = NULL; ++ GFile* _tmp43_ = NULL; ++ gchar* _tmp44_ = NULL; ++ gchar* _tmp45_ = NULL; ++ self = (RygelLMSImageYear*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_int (_tmp0_, 0); ++ id = _tmp1_; ++ _tmp2_ = statement; ++ _tmp3_ = sqlite3_column_text (_tmp2_, 6); ++ _tmp4_ = g_strdup (_tmp3_); ++ path = _tmp4_; ++ _tmp5_ = statement; ++ _tmp6_ = sqlite3_column_text (_tmp5_, 9); ++ _tmp7_ = g_strdup (_tmp6_); ++ mime_type = _tmp7_; ++ _tmp9_ = mime_type; ++ if (_tmp9_ == NULL) { ++ _tmp8_ = TRUE; ++ } else { ++ const gchar* _tmp10_ = NULL; ++ gint _tmp11_ = 0; ++ gint _tmp12_ = 0; ++ _tmp10_ = mime_type; ++ _tmp11_ = strlen (_tmp10_); ++ _tmp12_ = _tmp11_; ++ _tmp8_ = _tmp12_ == 0; ++ } ++ if (_tmp8_) { ++ gint _tmp13_ = 0; ++ const gchar* _tmp14_ = NULL; ++ _tmp13_ = id; ++ _tmp14_ = path; ++ g_debug ("rygel-lms-image-year.vala:62: Image item %d (%s) has no MIME type", _tmp13_, _tmp14_); ++ } ++ _tmp15_ = statement; ++ _tmp16_ = sqlite3_column_text (_tmp15_, 1); ++ _tmp17_ = g_strdup (_tmp16_); ++ title = _tmp17_; ++ _tmp18_ = id; ++ _tmp19_ = rygel_lms_category_container_build_child_id ((RygelLMSCategoryContainer*) self, _tmp18_); ++ _tmp20_ = _tmp19_; ++ _tmp21_ = rygel_image_item_new (_tmp20_, (RygelMediaContainer*) self, title, RYGEL_IMAGE_ITEM_UPNP_CLASS); ++ _tmp22_ = _tmp21_; ++ _g_free0 (_tmp20_); ++ image = _tmp22_; ++ _tmp23_ = id; ++ _tmp24_ = rygel_lms_category_container_build_reference_id ((RygelLMSCategoryContainer*) self, _tmp23_); ++ _tmp25_ = _tmp24_; ++ rygel_media_object_set_ref_id ((RygelMediaObject*) image, _tmp25_); ++ _g_free0 (_tmp25_); ++ _tmp26_ = statement; ++ _tmp27_ = sqlite3_column_text (_tmp26_, 2); ++ rygel_media_object_set_creator ((RygelMediaObject*) image, _tmp27_); ++ _tmp28_ = statement; ++ _tmp29_ = sqlite3_column_int (_tmp28_, 3); ++ _tmp30_.tv_sec = (glong) _tmp29_; ++ _tmp30_.tv_usec = (glong) 0; ++ tv = _tmp30_; ++ _tmp31_ = g_time_val_to_iso8601 (&tv); ++ _tmp32_ = _tmp31_; ++ rygel_media_object_set_date ((RygelMediaObject*) image, _tmp32_); ++ _g_free0 (_tmp32_); ++ _tmp33_ = statement; ++ _tmp34_ = sqlite3_column_int (_tmp33_, 4); ++ rygel_visual_item_set_width ((RygelVisualItem*) image, _tmp34_); ++ _tmp35_ = statement; ++ _tmp36_ = sqlite3_column_int (_tmp35_, 5); ++ rygel_visual_item_set_height ((RygelVisualItem*) image, _tmp36_); ++ _tmp37_ = statement; ++ _tmp38_ = sqlite3_column_int (_tmp37_, 7); ++ rygel_media_file_item_set_size ((RygelMediaFileItem*) image, (gint64) _tmp38_); ++ _tmp39_ = mime_type; ++ rygel_media_file_item_set_mime_type ((RygelMediaFileItem*) image, _tmp39_); ++ _tmp40_ = statement; ++ _tmp41_ = sqlite3_column_text (_tmp40_, 8); ++ rygel_media_file_item_set_dlna_profile ((RygelMediaFileItem*) image, _tmp41_); ++ _tmp42_ = path; ++ _tmp43_ = g_file_new_for_path (_tmp42_); ++ file = _tmp43_; ++ _tmp44_ = g_file_get_uri (file); ++ _tmp45_ = _tmp44_; ++ rygel_media_object_add_uri ((RygelMediaObject*) image, _tmp45_); ++ _g_free0 (_tmp45_); ++ result = (RygelMediaObject*) image; ++ _g_object_unref0 (file); ++ _g_free0 (title); ++ _g_free0 (mime_type); ++ _g_free0 (path); ++ return result; ++} ++ ++ ++static gchar* rygel_lms_image_year_get_sql_all (const gchar* year) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (year != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ALL_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_image_year_get_sql_find_object (const gchar* year) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (year != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_FIND_OBJECT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_image_year_get_sql_count (const gchar* year) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (year != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_COUNT_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_image_year_get_sql_added (const gchar* year) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (year != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_ADDED_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++static gchar* rygel_lms_image_year_get_sql_removed (const gchar* year) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (year != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf (RYGEL_LMS_IMAGE_YEAR_SQL_REMOVED_TEMPLATE, _tmp0_); ++ result = _tmp1_; ++ return result; ++} ++ ++ ++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) { ++ RygelLMSImageYear * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ gchar* _tmp2_ = NULL; ++ RygelMediaContainer* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ RygelLMSDatabase* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ gchar* _tmp7_ = NULL; ++ gchar* _tmp8_ = NULL; ++ const gchar* _tmp9_ = NULL; ++ gchar* _tmp10_ = NULL; ++ gchar* _tmp11_ = NULL; ++ const gchar* _tmp12_ = NULL; ++ gchar* _tmp13_ = NULL; ++ gchar* _tmp14_ = NULL; ++ const gchar* _tmp15_ = NULL; ++ gchar* _tmp16_ = NULL; ++ gchar* _tmp17_ = NULL; ++ const gchar* _tmp18_ = NULL; ++ gchar* _tmp19_ = NULL; ++ gchar* _tmp20_ = NULL; ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (year != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = year; ++ _tmp1_ = g_strdup_printf ("%s", _tmp0_); ++ _tmp2_ = _tmp1_; ++ _tmp3_ = parent; ++ _tmp4_ = year; ++ _tmp5_ = lms_db; ++ _tmp6_ = year; ++ _tmp7_ = rygel_lms_image_year_get_sql_all (_tmp6_); ++ _tmp8_ = _tmp7_; ++ _tmp9_ = year; ++ _tmp10_ = rygel_lms_image_year_get_sql_find_object (_tmp9_); ++ _tmp11_ = _tmp10_; ++ _tmp12_ = year; ++ _tmp13_ = rygel_lms_image_year_get_sql_count (_tmp12_); ++ _tmp14_ = _tmp13_; ++ _tmp15_ = year; ++ _tmp16_ = rygel_lms_image_year_get_sql_added (_tmp15_); ++ _tmp17_ = _tmp16_; ++ _tmp18_ = year; ++ _tmp19_ = rygel_lms_image_year_get_sql_removed (_tmp18_); ++ _tmp20_ = _tmp19_; ++ self = (RygelLMSImageYear*) rygel_lms_category_container_construct (object_type, _tmp2_, _tmp3_, _tmp4_, _tmp5_, _tmp8_, _tmp11_, _tmp14_, _tmp17_, _tmp20_); ++ _g_free0 (_tmp20_); ++ _g_free0 (_tmp17_); ++ _g_free0 (_tmp14_); ++ _g_free0 (_tmp11_); ++ _g_free0 (_tmp8_); ++ _g_free0 (_tmp2_); ++ return self; ++} ++ ++ ++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db) { ++ return rygel_lms_image_year_construct (RYGEL_LMS_TYPE_IMAGE_YEAR, parent, year, lms_db); ++} ++ ++ ++static void rygel_lms_image_year_class_init (RygelLMSImageYearClass * klass) { ++ rygel_lms_image_year_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_year_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_image_year_instance_init (RygelLMSImageYear * self) { ++} ++ ++ ++GType rygel_lms_image_year_get_type (void) { ++ static volatile gsize rygel_lms_image_year_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_image_year_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_year_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYear), 0, (GInstanceInitFunc) rygel_lms_image_year_instance_init, NULL }; ++ GType rygel_lms_image_year_type_id; ++ rygel_lms_image_year_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYear", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_image_year_type_id__volatile, rygel_lms_image_year_type_id); ++ } ++ return rygel_lms_image_year_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-image-years.c b/src/plugins/lms/rygel-lms-image-years.c +new file mode 100644 +index 0000000..35033a0 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-image-years.c +@@ -0,0 +1,196 @@ ++/* rygel-lms-image-years.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-image-years.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <sqlite3.h> ++#include <stdlib.h> ++#include <string.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++typedef struct _RygelLMSCategoryContainerPrivate RygelLMSCategoryContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_IMAGE_YEARS (rygel_lms_image_years_get_type ()) ++#define RYGEL_LMS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYears)) ++#define RYGEL_LMS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) ++#define RYGEL_LMS_IS_IMAGE_YEARS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS)) ++#define RYGEL_LMS_IS_IMAGE_YEARS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEARS)) ++#define RYGEL_LMS_IMAGE_YEARS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEARS, RygelLMSImageYearsClass)) ++ ++typedef struct _RygelLMSImageYears RygelLMSImageYears; ++typedef struct _RygelLMSImageYearsClass RygelLMSImageYearsClass; ++typedef struct _RygelLMSImageYearsPrivate RygelLMSImageYearsPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++#define RYGEL_LMS_TYPE_IMAGE_YEAR (rygel_lms_image_year_get_type ()) ++#define RYGEL_LMS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYear)) ++#define RYGEL_LMS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) ++#define RYGEL_LMS_IS_IMAGE_YEAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR)) ++#define RYGEL_LMS_IS_IMAGE_YEAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_YEAR)) ++#define RYGEL_LMS_IMAGE_YEAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_YEAR, RygelLMSImageYearClass)) ++ ++typedef struct _RygelLMSImageYear RygelLMSImageYear; ++typedef struct _RygelLMSImageYearClass RygelLMSImageYearClass; ++ ++struct _RygelLMSCategoryContainer { ++ RygelMediaContainer parent_instance; ++ RygelLMSCategoryContainerPrivate * priv; ++ sqlite3_stmt* stmt_all; ++ sqlite3_stmt* stmt_find_object; ++ sqlite3_stmt* stmt_added; ++ sqlite3_stmt* stmt_removed; ++ gchar* child_prefix; ++ gchar* ref_prefix; ++}; ++ ++struct _RygelLMSCategoryContainerClass { ++ RygelMediaContainerClass parent_class; ++ RygelMediaObject* (*object_from_statement) (RygelLMSCategoryContainer* self, sqlite3_stmt* statement); ++ gchar* (*get_sql_all_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ gchar* (*get_sql_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* filter); ++ guint (*get_child_count_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args); ++ RygelMediaObjects* (*get_children_with_filter) (RygelLMSCategoryContainer* self, const gchar* where_filter, GValueArray* args, const gchar* sort_criteria, guint offset, guint max_count); ++}; ++ ++struct _RygelLMSImageYears { ++ RygelLMSCategoryContainer parent_instance; ++ RygelLMSImageYearsPrivate * priv; ++}; ++ ++struct _RygelLMSImageYearsClass { ++ RygelLMSCategoryContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_image_years_parent_class = NULL; ++ ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_image_years_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_IMAGE_YEARS_DUMMY_PROPERTY ++}; ++#define RYGEL_LMS_IMAGE_YEARS_SQL_ALL "SELECT DISTINCT(strftime('%Y', images.date, 'unixepoch')) as year " "FROM images " "LIMIT ? OFFSET ?;" ++#define RYGEL_LMS_IMAGE_YEARS_SQL_COUNT "SELECT COUNT(DISTINCT(strftime('%Y', images.date, 'unixepoch'))) " "FROM images;" ++#define RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT "SELECT strftime('%Y', images.date, 'unixepoch') as year " "FROM images " "WHERE year = CAST(? AS TEXT)" ++static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement); ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSDatabase* rygel_lms_category_container_get_lms_db (RygelLMSCategoryContainer* self); ++RygelLMSImageYear* rygel_lms_image_year_new (RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); ++RygelLMSImageYear* rygel_lms_image_year_construct (GType object_type, RygelMediaContainer* parent, const gchar* year, RygelLMSDatabase* lms_db); ++GType rygel_lms_image_year_get_type (void) G_GNUC_CONST; ++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSCategoryContainer* rygel_lms_category_container_construct (GType object_type, const gchar* db_id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db, const gchar* sql_all, const gchar* sql_find_object, const gchar* sql_count, const gchar* sql_added, const gchar* sql_removed); ++ ++ ++static RygelMediaObject* rygel_lms_image_years_real_object_from_statement (RygelLMSCategoryContainer* base, sqlite3_stmt* statement) { ++ RygelLMSImageYears * self; ++ RygelMediaObject* result = NULL; ++ sqlite3_stmt* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ RygelLMSImageYear* _tmp4_ = NULL; ++ self = (RygelLMSImageYears*) base; ++ g_return_val_if_fail (statement != NULL, NULL); ++ _tmp0_ = statement; ++ _tmp1_ = sqlite3_column_text (_tmp0_, 0); ++ _tmp2_ = rygel_lms_category_container_get_lms_db ((RygelLMSCategoryContainer*) self); ++ _tmp3_ = _tmp2_; ++ _tmp4_ = rygel_lms_image_year_new ((RygelMediaContainer*) self, _tmp1_, _tmp3_); ++ result = (RygelMediaObject*) _tmp4_; ++ return result; ++} ++ ++ ++RygelLMSImageYears* rygel_lms_image_years_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ RygelLMSImageYears * self = NULL; ++ RygelMediaContainer* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ RygelLMSDatabase* _tmp2_ = NULL; ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = parent; ++ _tmp1_ = _ ("Years"); ++ _tmp2_ = lms_db; ++ self = (RygelLMSImageYears*) rygel_lms_category_container_construct (object_type, "years", _tmp0_, _tmp1_, _tmp2_, RYGEL_LMS_IMAGE_YEARS_SQL_ALL, RYGEL_LMS_IMAGE_YEARS_SQL_FIND_OBJECT, RYGEL_LMS_IMAGE_YEARS_SQL_COUNT, NULL, NULL); ++ return self; ++} ++ ++ ++RygelLMSImageYears* rygel_lms_image_years_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db) { ++ return rygel_lms_image_years_construct (RYGEL_LMS_TYPE_IMAGE_YEARS, parent, lms_db); ++} ++ ++ ++static void rygel_lms_image_years_class_init (RygelLMSImageYearsClass * klass) { ++ rygel_lms_image_years_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSCategoryContainerClass *) klass)->object_from_statement = rygel_lms_image_years_real_object_from_statement; ++} ++ ++ ++static void rygel_lms_image_years_instance_init (RygelLMSImageYears * self) { ++} ++ ++ ++GType rygel_lms_image_years_get_type (void) { ++ static volatile gsize rygel_lms_image_years_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_image_years_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSImageYearsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_image_years_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSImageYears), 0, (GInstanceInitFunc) rygel_lms_image_years_instance_init, NULL }; ++ GType rygel_lms_image_years_type_id; ++ rygel_lms_image_years_type_id = g_type_register_static (RYGEL_LMS_TYPE_CATEGORY_CONTAINER, "RygelLMSImageYears", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_image_years_type_id__volatile, rygel_lms_image_years_type_id); ++ } ++ return rygel_lms_image_years_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-music-root.c b/src/plugins/lms/rygel-lms-music-root.c +new file mode 100644 +index 0000000..753906d +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-music-root.c +@@ -0,0 +1,202 @@ ++/* rygel-lms-music-root.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-music-root.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <stdlib.h> ++#include <string.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ()) ++#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot)) ++#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) ++#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT)) ++#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT)) ++#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) ++ ++typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot; ++typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass; ++typedef struct _RygelLMSMusicRootPrivate RygelLMSMusicRootPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++ ++#define RYGEL_LMS_TYPE_ALL_MUSIC (rygel_lms_all_music_get_type ()) ++#define RYGEL_LMS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusic)) ++#define RYGEL_LMS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) ++#define RYGEL_LMS_IS_ALL_MUSIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_MUSIC)) ++#define RYGEL_LMS_IS_ALL_MUSIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_MUSIC)) ++#define RYGEL_LMS_ALL_MUSIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_MUSIC, RygelLMSAllMusicClass)) ++ ++typedef struct _RygelLMSAllMusic RygelLMSAllMusic; ++typedef struct _RygelLMSAllMusicClass RygelLMSAllMusicClass; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_ARTISTS (rygel_lms_artists_get_type ()) ++#define RYGEL_LMS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtists)) ++#define RYGEL_LMS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) ++#define RYGEL_LMS_IS_ARTISTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ARTISTS)) ++#define RYGEL_LMS_IS_ARTISTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ARTISTS)) ++#define RYGEL_LMS_ARTISTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ARTISTS, RygelLMSArtistsClass)) ++ ++typedef struct _RygelLMSArtists RygelLMSArtists; ++typedef struct _RygelLMSArtistsClass RygelLMSArtistsClass; ++ ++#define RYGEL_LMS_TYPE_ALBUMS (rygel_lms_albums_get_type ()) ++#define RYGEL_LMS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbums)) ++#define RYGEL_LMS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) ++#define RYGEL_LMS_IS_ALBUMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALBUMS)) ++#define RYGEL_LMS_IS_ALBUMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALBUMS)) ++#define RYGEL_LMS_ALBUMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALBUMS, RygelLMSAlbumsClass)) ++ ++typedef struct _RygelLMSAlbums RygelLMSAlbums; ++typedef struct _RygelLMSAlbumsClass RygelLMSAlbumsClass; ++ ++struct _RygelLMSMusicRoot { ++ RygelSimpleContainer parent_instance; ++ RygelLMSMusicRootPrivate * priv; ++}; ++ ++struct _RygelLMSMusicRootClass { ++ RygelSimpleContainerClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_music_root_parent_class = NULL; ++ ++GType rygel_lms_music_root_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_MUSIC_ROOT_DUMMY_PROPERTY ++}; ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAllMusic* rygel_lms_all_music_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAllMusic* rygel_lms_all_music_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_music_get_type (void) G_GNUC_CONST; ++RygelLMSArtists* rygel_lms_artists_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSArtists* rygel_lms_artists_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_artists_get_type (void) G_GNUC_CONST; ++RygelLMSAlbums* rygel_lms_albums_new (RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++RygelLMSAlbums* rygel_lms_albums_construct (GType object_type, RygelMediaContainer* parent, RygelLMSDatabase* lms_db); ++GType rygel_lms_albums_get_type (void) G_GNUC_CONST; ++ ++ ++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ RygelLMSMusicRoot * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ RygelMediaContainer* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ RygelLMSDatabase* _tmp3_ = NULL; ++ RygelLMSAllMusic* _tmp4_ = NULL; ++ RygelLMSAllMusic* _tmp5_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ RygelLMSDatabase* _tmp7_ = NULL; ++ RygelLMSArtists* _tmp8_ = NULL; ++ RygelLMSArtists* _tmp9_ = NULL; ++ RygelLMSDatabase* _tmp10_ = NULL; ++ RygelLMSAlbums* _tmp11_ = NULL; ++ RygelLMSAlbums* _tmp12_ = NULL; ++ g_return_val_if_fail (id != NULL, NULL); ++ g_return_val_if_fail (parent != NULL, NULL); ++ g_return_val_if_fail (title != NULL, NULL); ++ g_return_val_if_fail (lms_db != NULL, NULL); ++ _tmp0_ = id; ++ _tmp1_ = parent; ++ _tmp2_ = title; ++ self = (RygelLMSMusicRoot*) rygel_simple_container_construct (object_type, _tmp0_, _tmp1_, _tmp2_); ++ _tmp3_ = lms_db; ++ _tmp4_ = rygel_lms_all_music_new ((RygelMediaContainer*) self, _tmp3_); ++ _tmp5_ = _tmp4_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp5_); ++ _g_object_unref0 (_tmp5_); ++ _tmp6_ = _ ("Artists"); ++ _tmp7_ = lms_db; ++ _tmp8_ = rygel_lms_artists_new ("artists", (RygelMediaContainer*) self, _tmp6_, _tmp7_); ++ _tmp9_ = _tmp8_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp9_); ++ _g_object_unref0 (_tmp9_); ++ _tmp10_ = lms_db; ++ _tmp11_ = rygel_lms_albums_new ((RygelMediaContainer*) self, _tmp10_); ++ _tmp12_ = _tmp11_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp12_); ++ _g_object_unref0 (_tmp12_); ++ return self; ++} ++ ++ ++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db) { ++ return rygel_lms_music_root_construct (RYGEL_LMS_TYPE_MUSIC_ROOT, id, parent, title, lms_db); ++} ++ ++ ++static void rygel_lms_music_root_class_init (RygelLMSMusicRootClass * klass) { ++ rygel_lms_music_root_parent_class = g_type_class_peek_parent (klass); ++} ++ ++ ++static void rygel_lms_music_root_instance_init (RygelLMSMusicRoot * self) { ++} ++ ++ ++GType rygel_lms_music_root_get_type (void) { ++ static volatile gsize rygel_lms_music_root_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_music_root_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSMusicRootClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_music_root_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSMusicRoot), 0, (GInstanceInitFunc) rygel_lms_music_root_instance_init, NULL }; ++ GType rygel_lms_music_root_type_id; ++ rygel_lms_music_root_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSMusicRoot", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_music_root_type_id__volatile, rygel_lms_music_root_type_id); ++ } ++ return rygel_lms_music_root_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-plugin-factory.c b/src/plugins/lms/rygel-lms-plugin-factory.c +new file mode 100644 +index 0000000..de4a5ab +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-plugin-factory.c +@@ -0,0 +1,307 @@ ++/* rygel-lms-plugin-factory.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-plugin-factory.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-core.h> ++#include <rygel-server.h> ++#include <gobject/gvaluecollector.h> ++ ++ ++#define RYGEL_LMS_TYPE_PLUGIN_FACTORY (rygel_lms_plugin_factory_get_type ()) ++#define RYGEL_LMS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory)) ++#define RYGEL_LMS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass)) ++#define RYGEL_LMS_IS_PLUGIN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY)) ++#define RYGEL_LMS_IS_PLUGIN_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN_FACTORY)) ++#define RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryClass)) ++ ++typedef struct _RygelLMSPluginFactory RygelLMSPluginFactory; ++typedef struct _RygelLMSPluginFactoryClass RygelLMSPluginFactoryClass; ++#define _rygel_lms_plugin_factory_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_plugin_factory_unref (var), NULL))) ++typedef struct _RygelLMSPluginFactoryPrivate RygelLMSPluginFactoryPrivate; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ()) ++#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin)) ++#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) ++#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN)) ++#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN)) ++#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) ++ ++typedef struct _RygelLMSPlugin RygelLMSPlugin; ++typedef struct _RygelLMSPluginClass RygelLMSPluginClass; ++typedef struct _RygelLMSParamSpecPluginFactory RygelLMSParamSpecPluginFactory; ++ ++struct _RygelLMSPluginFactory { ++ GTypeInstance parent_instance; ++ volatile int ref_count; ++ RygelLMSPluginFactoryPrivate * priv; ++}; ++ ++struct _RygelLMSPluginFactoryClass { ++ GTypeClass parent_class; ++ void (*finalize) (RygelLMSPluginFactory *self); ++}; ++ ++struct _RygelLMSPluginFactoryPrivate { ++ RygelPluginLoader* loader; ++}; ++ ++struct _RygelLMSParamSpecPluginFactory { ++ GParamSpec parent_instance; ++}; ++ ++ ++extern RygelLMSPluginFactory* plugin_factory; ++RygelLMSPluginFactory* plugin_factory = NULL; ++static gpointer rygel_lms_plugin_factory_parent_class = NULL; ++ ++gpointer rygel_lms_plugin_factory_ref (gpointer instance); ++void rygel_lms_plugin_factory_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object); ++void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_plugin_factory (const GValue* value); ++GType rygel_lms_plugin_factory_get_type (void) G_GNUC_CONST; ++void module_init (RygelPluginLoader* loader); ++RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader); ++RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader); ++#define RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactoryPrivate)) ++enum { ++ RYGEL_LMS_PLUGIN_FACTORY_DUMMY_PROPERTY ++}; ++RygelLMSPlugin* rygel_lms_plugin_new (void); ++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type); ++GType rygel_lms_plugin_get_type (void) G_GNUC_CONST; ++static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj); ++ ++ ++void module_init (RygelPluginLoader* loader) { ++ RygelPluginLoader* _tmp0_ = NULL; ++ RygelLMSPluginFactory* _tmp1_ = NULL; ++ g_return_if_fail (loader != NULL); ++ _tmp0_ = loader; ++ _tmp1_ = rygel_lms_plugin_factory_new (_tmp0_); ++ _rygel_lms_plugin_factory_unref0 (plugin_factory); ++ plugin_factory = _tmp1_; ++} ++ ++ ++static gpointer _g_object_ref0 (gpointer self) { ++ return self ? g_object_ref (self) : NULL; ++} ++ ++ ++RygelLMSPluginFactory* rygel_lms_plugin_factory_construct (GType object_type, RygelPluginLoader* loader) { ++ RygelLMSPluginFactory* self = NULL; ++ RygelPluginLoader* _tmp0_ = NULL; ++ RygelPluginLoader* _tmp1_ = NULL; ++ RygelPluginLoader* _tmp2_ = NULL; ++ RygelLMSPlugin* _tmp3_ = NULL; ++ RygelLMSPlugin* _tmp4_ = NULL; ++ g_return_val_if_fail (loader != NULL, NULL); ++ self = (RygelLMSPluginFactory*) g_type_create_instance (object_type); ++ _tmp0_ = loader; ++ _tmp1_ = _g_object_ref0 (_tmp0_); ++ _g_object_unref0 (self->priv->loader); ++ self->priv->loader = _tmp1_; ++ _tmp2_ = self->priv->loader; ++ _tmp3_ = rygel_lms_plugin_new (); ++ _tmp4_ = _tmp3_; ++ rygel_plugin_loader_add_plugin (_tmp2_, (RygelPlugin*) _tmp4_); ++ _g_object_unref0 (_tmp4_); ++ return self; ++} ++ ++ ++RygelLMSPluginFactory* rygel_lms_plugin_factory_new (RygelPluginLoader* loader) { ++ return rygel_lms_plugin_factory_construct (RYGEL_LMS_TYPE_PLUGIN_FACTORY, loader); ++} ++ ++ ++static void rygel_lms_value_plugin_factory_init (GValue* value) { ++ value->data[0].v_pointer = NULL; ++} ++ ++ ++static void rygel_lms_value_plugin_factory_free_value (GValue* value) { ++ if (value->data[0].v_pointer) { ++ rygel_lms_plugin_factory_unref (value->data[0].v_pointer); ++ } ++} ++ ++ ++static void rygel_lms_value_plugin_factory_copy_value (const GValue* src_value, GValue* dest_value) { ++ if (src_value->data[0].v_pointer) { ++ dest_value->data[0].v_pointer = rygel_lms_plugin_factory_ref (src_value->data[0].v_pointer); ++ } else { ++ dest_value->data[0].v_pointer = NULL; ++ } ++} ++ ++ ++static gpointer rygel_lms_value_plugin_factory_peek_pointer (const GValue* value) { ++ return value->data[0].v_pointer; ++} ++ ++ ++static gchar* rygel_lms_value_plugin_factory_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ++ if (collect_values[0].v_pointer) { ++ RygelLMSPluginFactory* object; ++ object = collect_values[0].v_pointer; ++ if (object->parent_instance.g_class == NULL) { ++ return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); ++ } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { ++ return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); ++ } ++ value->data[0].v_pointer = rygel_lms_plugin_factory_ref (object); ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ return NULL; ++} ++ ++ ++static gchar* rygel_lms_value_plugin_factory_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { ++ RygelLMSPluginFactory** object_p; ++ object_p = collect_values[0].v_pointer; ++ if (!object_p) { ++ return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); ++ } ++ if (!value->data[0].v_pointer) { ++ *object_p = NULL; ++ } else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) { ++ *object_p = value->data[0].v_pointer; ++ } else { ++ *object_p = rygel_lms_plugin_factory_ref (value->data[0].v_pointer); ++ } ++ return NULL; ++} ++ ++ ++GParamSpec* rygel_lms_param_spec_plugin_factory (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { ++ RygelLMSParamSpecPluginFactory* spec; ++ g_return_val_if_fail (g_type_is_a (object_type, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL); ++ spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); ++ G_PARAM_SPEC (spec)->value_type = object_type; ++ return G_PARAM_SPEC (spec); ++} ++ ++ ++gpointer rygel_lms_value_get_plugin_factory (const GValue* value) { ++ g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY), NULL); ++ return value->data[0].v_pointer; ++} ++ ++ ++void rygel_lms_value_set_plugin_factory (GValue* value, gpointer v_object) { ++ RygelLMSPluginFactory* old; ++ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); ++ old = value->data[0].v_pointer; ++ if (v_object) { ++ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); ++ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); ++ value->data[0].v_pointer = v_object; ++ rygel_lms_plugin_factory_ref (value->data[0].v_pointer); ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ if (old) { ++ rygel_lms_plugin_factory_unref (old); ++ } ++} ++ ++ ++void rygel_lms_value_take_plugin_factory (GValue* value, gpointer v_object) { ++ RygelLMSPluginFactory* old; ++ g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); ++ old = value->data[0].v_pointer; ++ if (v_object) { ++ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, RYGEL_LMS_TYPE_PLUGIN_FACTORY)); ++ g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); ++ value->data[0].v_pointer = v_object; ++ } else { ++ value->data[0].v_pointer = NULL; ++ } ++ if (old) { ++ rygel_lms_plugin_factory_unref (old); ++ } ++} ++ ++ ++static void rygel_lms_plugin_factory_class_init (RygelLMSPluginFactoryClass * klass) { ++ rygel_lms_plugin_factory_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSPluginFactoryClass *) klass)->finalize = rygel_lms_plugin_factory_finalize; ++ g_type_class_add_private (klass, sizeof (RygelLMSPluginFactoryPrivate)); ++} ++ ++ ++static void rygel_lms_plugin_factory_instance_init (RygelLMSPluginFactory * self) { ++ self->priv = RYGEL_LMS_PLUGIN_FACTORY_GET_PRIVATE (self); ++ self->ref_count = 1; ++} ++ ++ ++static void rygel_lms_plugin_factory_finalize (RygelLMSPluginFactory* obj) { ++ RygelLMSPluginFactory * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN_FACTORY, RygelLMSPluginFactory); ++ g_signal_handlers_destroy (self); ++ _g_object_unref0 (self->priv->loader); ++} ++ ++ ++GType rygel_lms_plugin_factory_get_type (void) { ++ static volatile gsize rygel_lms_plugin_factory_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_plugin_factory_type_id__volatile)) { ++ static const GTypeValueTable g_define_type_value_table = { rygel_lms_value_plugin_factory_init, rygel_lms_value_plugin_factory_free_value, rygel_lms_value_plugin_factory_copy_value, rygel_lms_value_plugin_factory_peek_pointer, "p", rygel_lms_value_plugin_factory_collect_value, "p", rygel_lms_value_plugin_factory_lcopy_value }; ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginFactoryClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_factory_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPluginFactory), 0, (GInstanceInitFunc) rygel_lms_plugin_factory_instance_init, &g_define_type_value_table }; ++ static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; ++ GType rygel_lms_plugin_factory_type_id; ++ rygel_lms_plugin_factory_type_id = g_type_register_fundamental (g_type_fundamental_next (), "RygelLMSPluginFactory", &g_define_type_info, &g_define_type_fundamental_info, 0); ++ g_once_init_leave (&rygel_lms_plugin_factory_type_id__volatile, rygel_lms_plugin_factory_type_id); ++ } ++ return rygel_lms_plugin_factory_type_id__volatile; ++} ++ ++ ++gpointer rygel_lms_plugin_factory_ref (gpointer instance) { ++ RygelLMSPluginFactory* self; ++ self = instance; ++ g_atomic_int_inc (&self->ref_count); ++ return instance; ++} ++ ++ ++void rygel_lms_plugin_factory_unref (gpointer instance) { ++ RygelLMSPluginFactory* self; ++ self = instance; ++ if (g_atomic_int_dec_and_test (&self->ref_count)) { ++ RYGEL_LMS_PLUGIN_FACTORY_GET_CLASS (self)->finalize (self); ++ g_type_free_instance ((GTypeInstance *) self); ++ } ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-plugin.c b/src/plugins/lms/rygel-lms-plugin.c +new file mode 100644 +index 0000000..980de64 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-plugin.c +@@ -0,0 +1,134 @@ ++/* rygel-lms-plugin.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-plugin.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <stdlib.h> ++#include <string.h> ++#include <rygel-core.h> ++ ++ ++#define RYGEL_LMS_TYPE_PLUGIN (rygel_lms_plugin_get_type ()) ++#define RYGEL_LMS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin)) ++#define RYGEL_LMS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) ++#define RYGEL_LMS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_PLUGIN)) ++#define RYGEL_LMS_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_PLUGIN)) ++#define RYGEL_LMS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_PLUGIN, RygelLMSPluginClass)) ++ ++typedef struct _RygelLMSPlugin RygelLMSPlugin; ++typedef struct _RygelLMSPluginClass RygelLMSPluginClass; ++typedef struct _RygelLMSPluginPrivate RygelLMSPluginPrivate; ++ ++#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ()) ++#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer)) ++#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) ++#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER)) ++#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER)) ++#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) ++ ++typedef struct _RygelLMSRootContainer RygelLMSRootContainer; ++typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass; ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++struct _RygelLMSPlugin { ++ RygelMediaServerPlugin parent_instance; ++ RygelLMSPluginPrivate * priv; ++}; ++ ++struct _RygelLMSPluginClass { ++ RygelMediaServerPluginClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_plugin_parent_class = NULL; ++static RygelLMSRootContainer* rygel_lms_plugin_root; ++static RygelLMSRootContainer* rygel_lms_plugin_root = NULL; ++ ++GType rygel_lms_plugin_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_PLUGIN_DUMMY_PROPERTY ++}; ++GType rygel_lms_root_container_get_type (void) G_GNUC_CONST; ++#define RYGEL_LMS_PLUGIN_NAME "LMS" ++RygelLMSPlugin* rygel_lms_plugin_new (void); ++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type); ++RygelLMSRootContainer* rygel_lms_root_container_new (void); ++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type); ++static void rygel_lms_plugin_finalize (GObject* obj); ++ ++ ++RygelLMSPlugin* rygel_lms_plugin_construct (GType object_type) { ++ RygelLMSPlugin * self = NULL; ++ RygelLMSRootContainer* _tmp0_ = NULL; ++ RygelLMSRootContainer* _tmp2_ = NULL; ++ _tmp0_ = rygel_lms_plugin_root; ++ if (_tmp0_ == NULL) { ++ RygelLMSRootContainer* _tmp1_ = NULL; ++ _tmp1_ = rygel_lms_root_container_new (); ++ _g_object_unref0 (rygel_lms_plugin_root); ++ rygel_lms_plugin_root = _tmp1_; ++ } ++ _tmp2_ = rygel_lms_plugin_root; ++ self = (RygelLMSPlugin*) rygel_media_server_plugin_construct (object_type, (RygelMediaContainer*) _tmp2_, RYGEL_LMS_PLUGIN_NAME, NULL, RYGEL_PLUGIN_CAPABILITIES_TRACK_CHANGES); ++ return self; ++} ++ ++ ++RygelLMSPlugin* rygel_lms_plugin_new (void) { ++ return rygel_lms_plugin_construct (RYGEL_LMS_TYPE_PLUGIN); ++} ++ ++ ++static void rygel_lms_plugin_class_init (RygelLMSPluginClass * klass) { ++ rygel_lms_plugin_parent_class = g_type_class_peek_parent (klass); ++ G_OBJECT_CLASS (klass)->finalize = rygel_lms_plugin_finalize; ++} ++ ++ ++static void rygel_lms_plugin_instance_init (RygelLMSPlugin * self) { ++} ++ ++ ++static void rygel_lms_plugin_finalize (GObject* obj) { ++ RygelLMSPlugin * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_PLUGIN, RygelLMSPlugin); ++ G_OBJECT_CLASS (rygel_lms_plugin_parent_class)->finalize (obj); ++} ++ ++ ++GType rygel_lms_plugin_get_type (void) { ++ static volatile gsize rygel_lms_plugin_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_plugin_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSPluginClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_plugin_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSPlugin), 0, (GInstanceInitFunc) rygel_lms_plugin_instance_init, NULL }; ++ GType rygel_lms_plugin_type_id; ++ rygel_lms_plugin_type_id = g_type_register_static (RYGEL_TYPE_MEDIA_SERVER_PLUGIN, "RygelLMSPlugin", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_plugin_type_id__volatile, rygel_lms_plugin_type_id); ++ } ++ return rygel_lms_plugin_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-root-container.c b/src/plugins/lms/rygel-lms-root-container.c +new file mode 100644 +index 0000000..625ed2f +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-root-container.c +@@ -0,0 +1,318 @@ ++/* rygel-lms-root-container.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-root-container.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2013 Intel Corporation. ++ * ++ * Author: Jussi Kukkonen <jussi.kukkonen@intel.com> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <rygel-server.h> ++#include <rygel-core.h> ++#include <stdlib.h> ++#include <string.h> ++#include <glib/gi18n-lib.h> ++ ++ ++#define RYGEL_LMS_TYPE_ROOT_CONTAINER (rygel_lms_root_container_get_type ()) ++#define RYGEL_LMS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer)) ++#define RYGEL_LMS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) ++#define RYGEL_LMS_IS_ROOT_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER)) ++#define RYGEL_LMS_IS_ROOT_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ROOT_CONTAINER)) ++#define RYGEL_LMS_ROOT_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerClass)) ++ ++typedef struct _RygelLMSRootContainer RygelLMSRootContainer; ++typedef struct _RygelLMSRootContainerClass RygelLMSRootContainerClass; ++typedef struct _RygelLMSRootContainerPrivate RygelLMSRootContainerPrivate; ++ ++#define RYGEL_LMS_TYPE_DATABASE (rygel_lms_database_get_type ()) ++#define RYGEL_LMS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabase)) ++#define RYGEL_LMS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++#define RYGEL_LMS_IS_DATABASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_IS_DATABASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_DATABASE)) ++#define RYGEL_LMS_DATABASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_DATABASE, RygelLMSDatabaseClass)) ++ ++typedef struct _RygelLMSDatabase RygelLMSDatabase; ++typedef struct _RygelLMSDatabaseClass RygelLMSDatabaseClass; ++#define _rygel_lms_database_unref0(var) ((var == NULL) ? NULL : (var = (rygel_lms_database_unref (var), NULL))) ++#define _g_free0(var) (var = (g_free (var), NULL)) ++#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) ++#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) ++ ++#define RYGEL_LMS_TYPE_MUSIC_ROOT (rygel_lms_music_root_get_type ()) ++#define RYGEL_LMS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRoot)) ++#define RYGEL_LMS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) ++#define RYGEL_LMS_IS_MUSIC_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT)) ++#define RYGEL_LMS_IS_MUSIC_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_MUSIC_ROOT)) ++#define RYGEL_LMS_MUSIC_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_MUSIC_ROOT, RygelLMSMusicRootClass)) ++ ++typedef struct _RygelLMSMusicRoot RygelLMSMusicRoot; ++typedef struct _RygelLMSMusicRootClass RygelLMSMusicRootClass; ++ ++#define RYGEL_LMS_TYPE_CATEGORY_CONTAINER (rygel_lms_category_container_get_type ()) ++#define RYGEL_LMS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainer)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_IS_CATEGORY_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_CATEGORY_CONTAINER)) ++#define RYGEL_LMS_CATEGORY_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_CATEGORY_CONTAINER, RygelLMSCategoryContainerClass)) ++ ++typedef struct _RygelLMSCategoryContainer RygelLMSCategoryContainer; ++typedef struct _RygelLMSCategoryContainerClass RygelLMSCategoryContainerClass; ++ ++#define RYGEL_LMS_TYPE_ALL_VIDEOS (rygel_lms_all_videos_get_type ()) ++#define RYGEL_LMS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideos)) ++#define RYGEL_LMS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) ++#define RYGEL_LMS_IS_ALL_VIDEOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS)) ++#define RYGEL_LMS_IS_ALL_VIDEOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_ALL_VIDEOS)) ++#define RYGEL_LMS_ALL_VIDEOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_ALL_VIDEOS, RygelLMSAllVideosClass)) ++ ++typedef struct _RygelLMSAllVideos RygelLMSAllVideos; ++typedef struct _RygelLMSAllVideosClass RygelLMSAllVideosClass; ++ ++#define RYGEL_LMS_TYPE_IMAGE_ROOT (rygel_lms_image_root_get_type ()) ++#define RYGEL_LMS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRoot)) ++#define RYGEL_LMS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) ++#define RYGEL_LMS_IS_IMAGE_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT)) ++#define RYGEL_LMS_IS_IMAGE_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_IMAGE_ROOT)) ++#define RYGEL_LMS_IMAGE_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_IMAGE_ROOT, RygelLMSImageRootClass)) ++ ++typedef struct _RygelLMSImageRoot RygelLMSImageRoot; ++typedef struct _RygelLMSImageRootClass RygelLMSImageRootClass; ++ ++struct _RygelLMSRootContainer { ++ RygelSimpleContainer parent_instance; ++ RygelLMSRootContainerPrivate * priv; ++}; ++ ++struct _RygelLMSRootContainerClass { ++ RygelSimpleContainerClass parent_class; ++}; ++ ++struct _RygelLMSRootContainerPrivate { ++ RygelLMSDatabase* lms_db; ++}; ++ ++typedef enum { ++ RYGEL_LMS_DATABASE_ERROR_OPEN, ++ RYGEL_LMS_DATABASE_ERROR_PREPARE, ++ RYGEL_LMS_DATABASE_ERROR_BIND, ++ RYGEL_LMS_DATABASE_ERROR_STEP, ++ RYGEL_LMS_DATABASE_ERROR_NOT_FOUND ++} RygelLMSDatabaseError; ++#define RYGEL_LMS_DATABASE_ERROR rygel_lms_database_error_quark () ++ ++static gpointer rygel_lms_root_container_parent_class = NULL; ++ ++GType rygel_lms_root_container_get_type (void) G_GNUC_CONST; ++gpointer rygel_lms_database_ref (gpointer instance); ++void rygel_lms_database_unref (gpointer instance); ++GParamSpec* rygel_lms_param_spec_database (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); ++void rygel_lms_value_set_database (GValue* value, gpointer v_object); ++void rygel_lms_value_take_database (GValue* value, gpointer v_object); ++gpointer rygel_lms_value_get_database (const GValue* value); ++GType rygel_lms_database_get_type (void) G_GNUC_CONST; ++#define RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainerPrivate)) ++enum { ++ RYGEL_LMS_ROOT_CONTAINER_DUMMY_PROPERTY ++}; ++RygelLMSRootContainer* rygel_lms_root_container_new (void); ++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type); ++GQuark rygel_lms_database_error_quark (void); ++RygelLMSDatabase* rygel_lms_database_new (GError** error); ++RygelLMSDatabase* rygel_lms_database_construct (GType object_type, GError** error); ++RygelLMSMusicRoot* rygel_lms_music_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSMusicRoot* rygel_lms_music_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_music_root_get_type (void) G_GNUC_CONST; ++RygelLMSAllVideos* rygel_lms_all_videos_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSAllVideos* rygel_lms_all_videos_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_category_container_get_type (void) G_GNUC_CONST; ++GType rygel_lms_all_videos_get_type (void) G_GNUC_CONST; ++RygelLMSImageRoot* rygel_lms_image_root_new (const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++RygelLMSImageRoot* rygel_lms_image_root_construct (GType object_type, const gchar* id, RygelMediaContainer* parent, const gchar* title, RygelLMSDatabase* lms_db); ++GType rygel_lms_image_root_get_type (void) G_GNUC_CONST; ++static void rygel_lms_root_container_finalize (GObject* obj); ++ ++ ++RygelLMSRootContainer* rygel_lms_root_container_construct (GType object_type) { ++ RygelLMSRootContainer * self = NULL; ++ RygelMetaConfig* config = NULL; ++ RygelMetaConfig* _tmp0_ = NULL; ++ gchar* title = NULL; ++ const gchar* _tmp1_ = NULL; ++ gchar* _tmp2_ = NULL; ++ const gchar* _tmp6_ = NULL; ++ GError * _inner_error_ = NULL; ++ _tmp0_ = rygel_meta_config_get_default (); ++ config = _tmp0_; ++ _tmp1_ = _ ("Shared media"); ++ _tmp2_ = g_strdup (_tmp1_); ++ title = _tmp2_; ++ { ++ gchar* _tmp3_ = NULL; ++ gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ _tmp4_ = rygel_configuration_get_string ((RygelConfiguration*) config, "LightMediaScanner", "title", &_inner_error_); ++ _tmp3_ = _tmp4_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ goto __catch0_g_error; ++ } ++ _tmp5_ = _tmp3_; ++ _tmp3_ = NULL; ++ _g_free0 (title); ++ title = _tmp5_; ++ _g_free0 (_tmp3_); ++ } ++ goto __finally0; ++ __catch0_g_error: ++ { ++ GError* _error_ = NULL; ++ _error_ = _inner_error_; ++ _inner_error_ = NULL; ++ _g_error_free0 (_error_); ++ } ++ __finally0: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (title); ++ _g_object_unref0 (config); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _tmp6_ = title; ++ self = (RygelLMSRootContainer*) rygel_simple_container_construct_root (object_type, _tmp6_); ++ { ++ RygelLMSDatabase* _tmp7_ = NULL; ++ RygelLMSDatabase* _tmp8_ = NULL; ++ RygelLMSDatabase* _tmp9_ = NULL; ++ const gchar* _tmp10_ = NULL; ++ RygelLMSDatabase* _tmp11_ = NULL; ++ RygelLMSMusicRoot* _tmp12_ = NULL; ++ RygelLMSMusicRoot* _tmp13_ = NULL; ++ const gchar* _tmp14_ = NULL; ++ RygelLMSDatabase* _tmp15_ = NULL; ++ RygelLMSAllVideos* _tmp16_ = NULL; ++ RygelLMSAllVideos* _tmp17_ = NULL; ++ const gchar* _tmp18_ = NULL; ++ RygelLMSDatabase* _tmp19_ = NULL; ++ RygelLMSImageRoot* _tmp20_ = NULL; ++ RygelLMSImageRoot* _tmp21_ = NULL; ++ _tmp8_ = rygel_lms_database_new (&_inner_error_); ++ _tmp7_ = _tmp8_; ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ if (_inner_error_->domain == RYGEL_LMS_DATABASE_ERROR) { ++ goto __catch1_rygel_lms_database_error; ++ } ++ _g_free0 (title); ++ _g_object_unref0 (config); ++ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _tmp9_ = _tmp7_; ++ _tmp7_ = NULL; ++ _rygel_lms_database_unref0 (self->priv->lms_db); ++ self->priv->lms_db = _tmp9_; ++ _tmp10_ = _ ("Music"); ++ _tmp11_ = self->priv->lms_db; ++ _tmp12_ = rygel_lms_music_root_new ("music", (RygelMediaContainer*) self, _tmp10_, _tmp11_); ++ _tmp13_ = _tmp12_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp13_); ++ _g_object_unref0 (_tmp13_); ++ _tmp14_ = _ ("Videos"); ++ _tmp15_ = self->priv->lms_db; ++ _tmp16_ = rygel_lms_all_videos_new ("all-videos", (RygelMediaContainer*) self, _tmp14_, _tmp15_); ++ _tmp17_ = _tmp16_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp17_); ++ _g_object_unref0 (_tmp17_); ++ _tmp18_ = _ ("Pictures"); ++ _tmp19_ = self->priv->lms_db; ++ _tmp20_ = rygel_lms_image_root_new ("images", (RygelMediaContainer*) self, _tmp18_, _tmp19_); ++ _tmp21_ = _tmp20_; ++ rygel_simple_container_add_child_container ((RygelSimpleContainer*) self, (RygelMediaContainer*) _tmp21_); ++ _g_object_unref0 (_tmp21_); ++ _rygel_lms_database_unref0 (_tmp7_); ++ } ++ goto __finally1; ++ __catch1_rygel_lms_database_error: ++ { ++ GError* e = NULL; ++ GError* _tmp22_ = NULL; ++ const gchar* _tmp23_ = NULL; ++ e = _inner_error_; ++ _inner_error_ = NULL; ++ _tmp22_ = e; ++ _tmp23_ = _tmp22_->message; ++ g_warning ("rygel-lms-root-container.vala:49: %s\n", _tmp23_); ++ _g_error_free0 (e); ++ } ++ __finally1: ++ if (G_UNLIKELY (_inner_error_ != NULL)) { ++ _g_free0 (title); ++ _g_object_unref0 (config); ++ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); ++ g_clear_error (&_inner_error_); ++ return NULL; ++ } ++ _g_free0 (title); ++ _g_object_unref0 (config); ++ return self; ++} ++ ++ ++RygelLMSRootContainer* rygel_lms_root_container_new (void) { ++ return rygel_lms_root_container_construct (RYGEL_LMS_TYPE_ROOT_CONTAINER); ++} ++ ++ ++static void rygel_lms_root_container_class_init (RygelLMSRootContainerClass * klass) { ++ rygel_lms_root_container_parent_class = g_type_class_peek_parent (klass); ++ g_type_class_add_private (klass, sizeof (RygelLMSRootContainerPrivate)); ++ G_OBJECT_CLASS (klass)->finalize = rygel_lms_root_container_finalize; ++} ++ ++ ++static void rygel_lms_root_container_instance_init (RygelLMSRootContainer * self) { ++ self->priv = RYGEL_LMS_ROOT_CONTAINER_GET_PRIVATE (self); ++ self->priv->lms_db = NULL; ++} ++ ++ ++static void rygel_lms_root_container_finalize (GObject* obj) { ++ RygelLMSRootContainer * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_ROOT_CONTAINER, RygelLMSRootContainer); ++ _rygel_lms_database_unref0 (self->priv->lms_db); ++ G_OBJECT_CLASS (rygel_lms_root_container_parent_class)->finalize (obj); ++} ++ ++ ++GType rygel_lms_root_container_get_type (void) { ++ static volatile gsize rygel_lms_root_container_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_root_container_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSRootContainerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_root_container_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSRootContainer), 0, (GInstanceInitFunc) rygel_lms_root_container_instance_init, NULL }; ++ GType rygel_lms_root_container_type_id; ++ rygel_lms_root_container_type_id = g_type_register_static (RYGEL_TYPE_SIMPLE_CONTAINER, "RygelLMSRootContainer", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_root_container_type_id__volatile, rygel_lms_root_container_type_id); ++ } ++ return rygel_lms_root_container_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-sql-function.c b/src/plugins/lms/rygel-lms-sql-function.c +new file mode 100644 +index 0000000..a56c7be +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-sql-function.c +@@ -0,0 +1,146 @@ ++/* rygel-lms-sql-function.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-sql-function.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. ++ * ++ * Author: Jens Georg <mail@jensge.org> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <stdlib.h> ++#include <string.h> ++ ++ ++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) ++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) ++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++ ++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; ++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; ++typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate; ++ ++#define RYGEL_LMS_TYPE_SQL_FUNCTION (rygel_lms_sql_function_get_type ()) ++#define RYGEL_LMS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunction)) ++#define RYGEL_LMS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) ++#define RYGEL_LMS_IS_SQL_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION)) ++#define RYGEL_LMS_IS_SQL_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_FUNCTION)) ++#define RYGEL_LMS_SQL_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_FUNCTION, RygelLMSSqlFunctionClass)) ++ ++typedef struct _RygelLMSSqlFunction RygelLMSSqlFunction; ++typedef struct _RygelLMSSqlFunctionClass RygelLMSSqlFunctionClass; ++typedef struct _RygelLMSSqlFunctionPrivate RygelLMSSqlFunctionPrivate; ++ ++struct _RygelLMSSqlOperator { ++ GObject parent_instance; ++ RygelLMSSqlOperatorPrivate * priv; ++ gchar* name; ++ gchar* arg; ++ gchar* collate; ++}; ++ ++struct _RygelLMSSqlOperatorClass { ++ GObjectClass parent_class; ++ gchar* (*to_string) (RygelLMSSqlOperator* self); ++}; ++ ++struct _RygelLMSSqlFunction { ++ RygelLMSSqlOperator parent_instance; ++ RygelLMSSqlFunctionPrivate * priv; ++}; ++ ++struct _RygelLMSSqlFunctionClass { ++ RygelLMSSqlOperatorClass parent_class; ++}; ++ ++ ++static gpointer rygel_lms_sql_function_parent_class = NULL; ++ ++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; ++GType rygel_lms_sql_function_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_SQL_FUNCTION_DUMMY_PROPERTY ++}; ++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg); ++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg); ++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); ++static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base); ++ ++ ++RygelLMSSqlFunction* rygel_lms_sql_function_construct (GType object_type, const gchar* name, const gchar* arg) { ++ RygelLMSSqlFunction * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ g_return_val_if_fail (name != NULL, NULL); ++ g_return_val_if_fail (arg != NULL, NULL); ++ _tmp0_ = name; ++ _tmp1_ = arg; ++ self = (RygelLMSSqlFunction*) rygel_lms_sql_operator_construct (object_type, _tmp0_, _tmp1_, ""); ++ return self; ++} ++ ++ ++RygelLMSSqlFunction* rygel_lms_sql_function_new (const gchar* name, const gchar* arg) { ++ return rygel_lms_sql_function_construct (RYGEL_LMS_TYPE_SQL_FUNCTION, name, arg); ++} ++ ++ ++static gchar* rygel_lms_sql_function_real_to_string (RygelLMSSqlOperator* base) { ++ RygelLMSSqlFunction * self; ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ gchar* _tmp2_ = NULL; ++ self = (RygelLMSSqlFunction*) base; ++ _tmp0_ = ((RygelLMSSqlOperator*) self)->name; ++ _tmp1_ = ((RygelLMSSqlOperator*) self)->arg; ++ _tmp2_ = g_strdup_printf ("%s(%s,?)", _tmp0_, _tmp1_); ++ result = _tmp2_; ++ return result; ++} ++ ++ ++static void rygel_lms_sql_function_class_init (RygelLMSSqlFunctionClass * klass) { ++ rygel_lms_sql_function_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_function_real_to_string; ++} ++ ++ ++static void rygel_lms_sql_function_instance_init (RygelLMSSqlFunction * self) { ++} ++ ++ ++GType rygel_lms_sql_function_get_type (void) { ++ static volatile gsize rygel_lms_sql_function_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_sql_function_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlFunctionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_function_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlFunction), 0, (GInstanceInitFunc) rygel_lms_sql_function_instance_init, NULL }; ++ GType rygel_lms_sql_function_type_id; ++ rygel_lms_sql_function_type_id = g_type_register_static (RYGEL_LMS_TYPE_SQL_OPERATOR, "RygelLMSSqlFunction", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_sql_function_type_id__volatile, rygel_lms_sql_function_type_id); ++ } ++ return rygel_lms_sql_function_type_id__volatile; ++} ++ ++ ++ +diff --git a/src/plugins/lms/rygel-lms-sql-operator.c b/src/plugins/lms/rygel-lms-sql-operator.c +new file mode 100644 +index 0000000..90db1a9 +--- /dev/null ++++ b/src/plugins/lms/rygel-lms-sql-operator.c +@@ -0,0 +1,240 @@ ++/* rygel-lms-sql-operator.c generated by valac 0.28.0, the Vala compiler ++ * generated from rygel-lms-sql-operator.vala, do not modify */ ++ ++/* ++ * Copyright (C) 2010 Jens Georg <mail@jensge.org>. ++ * ++ * Author: Jens Georg <mail@jensge.org> ++ * ++ * This file is part of Rygel. ++ * ++ * Rygel 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. ++ * ++ * Rygel 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include <glib.h> ++#include <glib-object.h> ++#include <stdlib.h> ++#include <string.h> ++#include <libgupnp-av/gupnp-av.h> ++ ++ ++#define RYGEL_LMS_TYPE_SQL_OPERATOR (rygel_lms_sql_operator_get_type ()) ++#define RYGEL_LMS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator)) ++#define RYGEL_LMS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++#define RYGEL_LMS_IS_SQL_OPERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_IS_SQL_OPERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_LMS_TYPE_SQL_OPERATOR)) ++#define RYGEL_LMS_SQL_OPERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperatorClass)) ++ ++typedef struct _RygelLMSSqlOperator RygelLMSSqlOperator; ++typedef struct _RygelLMSSqlOperatorClass RygelLMSSqlOperatorClass; ++typedef struct _RygelLMSSqlOperatorPrivate RygelLMSSqlOperatorPrivate; ++#define _g_free0(var) (var = (g_free (var), NULL)) ++ ++struct _RygelLMSSqlOperator { ++ GObject parent_instance; ++ RygelLMSSqlOperatorPrivate * priv; ++ gchar* name; ++ gchar* arg; ++ gchar* collate; ++}; ++ ++struct _RygelLMSSqlOperatorClass { ++ GObjectClass parent_class; ++ gchar* (*to_string) (RygelLMSSqlOperator* self); ++}; ++ ++ ++static gpointer rygel_lms_sql_operator_parent_class = NULL; ++ ++GType rygel_lms_sql_operator_get_type (void) G_GNUC_CONST; ++enum { ++ RYGEL_LMS_SQL_OPERATOR_DUMMY_PROPERTY ++}; ++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate); ++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self); ++static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self); ++static void rygel_lms_sql_operator_finalize (GObject* obj); ++ ++ ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct (GType object_type, const gchar* name, const gchar* arg, const gchar* collate) { ++ RygelLMSSqlOperator * self = NULL; ++ const gchar* _tmp0_ = NULL; ++ gchar* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ const gchar* _tmp4_ = NULL; ++ gchar* _tmp5_ = NULL; ++ g_return_val_if_fail (name != NULL, NULL); ++ g_return_val_if_fail (arg != NULL, NULL); ++ g_return_val_if_fail (collate != NULL, NULL); ++ self = (RygelLMSSqlOperator*) g_object_new (object_type, NULL); ++ _tmp0_ = name; ++ _tmp1_ = g_strdup (_tmp0_); ++ _g_free0 (self->name); ++ self->name = _tmp1_; ++ _tmp2_ = arg; ++ _tmp3_ = g_strdup (_tmp2_); ++ _g_free0 (self->arg); ++ self->arg = _tmp3_; ++ _tmp4_ = collate; ++ _tmp5_ = g_strdup (_tmp4_); ++ _g_free0 (self->collate); ++ self->collate = _tmp5_; ++ return self; ++} ++ ++ ++RygelLMSSqlOperator* rygel_lms_sql_operator_new (const gchar* name, const gchar* arg, const gchar* collate) { ++ return rygel_lms_sql_operator_construct (RYGEL_LMS_TYPE_SQL_OPERATOR, name, arg, collate); ++} ++ ++ ++RygelLMSSqlOperator* rygel_lms_sql_operator_construct_from_search_criteria_op (GType object_type, GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) { ++ RygelLMSSqlOperator * self = NULL; ++ gchar* sql = NULL; ++ GUPnPSearchCriteriaOp _tmp0_ = 0; ++ const gchar* _tmp7_ = NULL; ++ const gchar* _tmp8_ = NULL; ++ const gchar* _tmp9_ = NULL; ++ g_return_val_if_fail (arg != NULL, NULL); ++ g_return_val_if_fail (collate != NULL, NULL); ++ sql = NULL; ++ _tmp0_ = op; ++ switch (_tmp0_) { ++ case GUPNP_SEARCH_CRITERIA_OP_EQ: ++ { ++ gchar* _tmp1_ = NULL; ++ _tmp1_ = g_strdup ("="); ++ _g_free0 (sql); ++ sql = _tmp1_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_NEQ: ++ { ++ gchar* _tmp2_ = NULL; ++ _tmp2_ = g_strdup ("!="); ++ _g_free0 (sql); ++ sql = _tmp2_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_LESS: ++ { ++ gchar* _tmp3_ = NULL; ++ _tmp3_ = g_strdup ("<"); ++ _g_free0 (sql); ++ sql = _tmp3_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_LEQ: ++ { ++ gchar* _tmp4_ = NULL; ++ _tmp4_ = g_strdup ("<="); ++ _g_free0 (sql); ++ sql = _tmp4_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_GREATER: ++ { ++ gchar* _tmp5_ = NULL; ++ _tmp5_ = g_strdup (">"); ++ _g_free0 (sql); ++ sql = _tmp5_; ++ break; ++ } ++ case GUPNP_SEARCH_CRITERIA_OP_GEQ: ++ { ++ gchar* _tmp6_ = NULL; ++ _tmp6_ = g_strdup (">="); ++ _g_free0 (sql); ++ sql = _tmp6_; ++ break; ++ } ++ default: ++ { ++ g_assert_not_reached (); ++ } ++ } ++ _tmp7_ = sql; ++ _tmp8_ = arg; ++ _tmp9_ = collate; ++ self = (RygelLMSSqlOperator*) rygel_lms_sql_operator_construct (object_type, _tmp7_, _tmp8_, _tmp9_); ++ _g_free0 (sql); ++ return self; ++} ++ ++ ++RygelLMSSqlOperator* rygel_lms_sql_operator_new_from_search_criteria_op (GUPnPSearchCriteriaOp op, const gchar* arg, const gchar* collate) { ++ return rygel_lms_sql_operator_construct_from_search_criteria_op (RYGEL_LMS_TYPE_SQL_OPERATOR, op, arg, collate); ++} ++ ++ ++static gchar* rygel_lms_sql_operator_real_to_string (RygelLMSSqlOperator* self) { ++ gchar* result = NULL; ++ const gchar* _tmp0_ = NULL; ++ const gchar* _tmp1_ = NULL; ++ const gchar* _tmp2_ = NULL; ++ gchar* _tmp3_ = NULL; ++ _tmp0_ = self->arg; ++ _tmp1_ = self->name; ++ _tmp2_ = self->collate; ++ _tmp3_ = g_strdup_printf ("(%s %s ? %s)", _tmp0_, _tmp1_, _tmp2_); ++ result = _tmp3_; ++ return result; ++} ++ ++ ++gchar* rygel_lms_sql_operator_to_string (RygelLMSSqlOperator* self) { ++ g_return_val_if_fail (self != NULL, NULL); ++ return RYGEL_LMS_SQL_OPERATOR_GET_CLASS (self)->to_string (self); ++} ++ ++ ++static void rygel_lms_sql_operator_class_init (RygelLMSSqlOperatorClass * klass) { ++ rygel_lms_sql_operator_parent_class = g_type_class_peek_parent (klass); ++ ((RygelLMSSqlOperatorClass *) klass)->to_string = rygel_lms_sql_operator_real_to_string; ++ G_OBJECT_CLASS (klass)->finalize = rygel_lms_sql_operator_finalize; ++} ++ ++ ++static void rygel_lms_sql_operator_instance_init (RygelLMSSqlOperator * self) { ++} ++ ++ ++static void rygel_lms_sql_operator_finalize (GObject* obj) { ++ RygelLMSSqlOperator * self; ++ self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_LMS_TYPE_SQL_OPERATOR, RygelLMSSqlOperator); ++ _g_free0 (self->name); ++ _g_free0 (self->arg); ++ _g_free0 (self->collate); ++ G_OBJECT_CLASS (rygel_lms_sql_operator_parent_class)->finalize (obj); ++} ++ ++ ++GType rygel_lms_sql_operator_get_type (void) { ++ static volatile gsize rygel_lms_sql_operator_type_id__volatile = 0; ++ if (g_once_init_enter (&rygel_lms_sql_operator_type_id__volatile)) { ++ static const GTypeInfo g_define_type_info = { sizeof (RygelLMSSqlOperatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_lms_sql_operator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLMSSqlOperator), 0, (GInstanceInitFunc) rygel_lms_sql_operator_instance_init, NULL }; ++ GType rygel_lms_sql_operator_type_id; ++ rygel_lms_sql_operator_type_id = g_type_register_static (G_TYPE_OBJECT, "RygelLMSSqlOperator", &g_define_type_info, 0); ++ g_once_init_leave (&rygel_lms_sql_operator_type_id__volatile, rygel_lms_sql_operator_type_id); ++ } ++ return rygel_lms_sql_operator_type_id__volatile; ++} ++ ++ ++ +-- +1.8.3.1 + diff --git a/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend new file mode 100644 index 000000000..9363c3cdc --- /dev/null +++ b/meta-agl/recipes-connectivity/rygel/rygel_%.bbappend @@ -0,0 +1,8 @@ +# Disable everything but the media-export plugin, add the lms plugin +PACKAGECONFIG = "media-export lms" +PACKAGECONFIG[lms] = "--enable-lms-plugin,--disable-lms-plugin,sqlite3" + +# LightMediaScanner plugin patches +SRC_URI += "file://0001-Add-LightMediaScanner-plugin.patch \ + file://0002-lms-add-C-source-files.patch \ + " diff --git a/meta-agl/recipes-connectivity/rygel/rygel_0.26.1.bb b/meta-agl/recipes-connectivity/rygel/rygel_0.26.1.bb new file mode 100644 index 000000000..205e900e2 --- /dev/null +++ b/meta-agl/recipes-connectivity/rygel/rygel_0.26.1.bb @@ -0,0 +1,58 @@ +SUMMARY = "A UPnP AV media server and renderer" +DESCRIPTION = "Rygel is a home media solution (UPnP AV MediaServer) that \ +allow you to easily share audio, video and pictures to other devices. \ +Additionally, media player software may use Rygel to become a MediaRenderer \ +that may be controlled remotely by a UPnP or DLNA Controller." +HOMEPAGE = "http://live.gnome.org/Rygel" + +LICENSE = "LGPLv2+" +LIC_FILES_CHKSUM = "file://COPYING;md5=5f30f0716dfdd0d91eb439ebec522ec2 \ + file://src/rygel/rygel-main.vala;endline=25;md5=a4cce4d389da1c1638fe68d07ae9d811" + +DEPENDS = "libxml2 glib-2.0 gssdp gupnp gupnp-av gupnp-dlna gstreamer1.0 gstreamer1.0-plugins-base ossp-uuid libgee-0.8 libsoup-2.4 libmediaart-2.0" +RDEPENDS_${PN} = "gstreamer1.0-plugins-base-playback shared-mime-info" + +GNOME_COMPRESS_TYPE = "xz" +SRC_URI[archive.md5sum] = "f182d54913a528bb5b4fb2f291aca0fc" +SRC_URI[archive.sha256sum] = "390740609e34399b886ddb9a8f7eca25055ad72048dfdd869edf02999b1e1d8f" + +inherit gnomebase vala + +EXTRA_OECONF = "--disable-introspection --disable-tracker-plugin --with-media-engine=gstreamer" + +PACKAGECONFIG ?= "external mpris mediathek ruih media-export gst-launch gtk+3" +PACKAGECONFIG[external] = "--enable-external-plugin,--disable-external-plugin" +PACKAGECONFIG[mpris] = "--enable-mpris-plugin,--disable-mpris-plugin" +PACKAGECONFIG[mediathek] = "--enable-mediathek-plugin,--disable-mediathek-plugin" +PACKAGECONFIG[ruih] = "--enable-ruih-plugin,--disable-ruih-plugin" +PACKAGECONFIG[media-export] = "--enable-media-export-plugin,--disable-media-export-plugin,sqlite3" +PACKAGECONFIG[gst-launch] = "--enable-gst-launch-plugin,--disable-gst-launch-plugin" +PACKAGECONFIG[gtk+3] = ",--without-ui,gtk+3" + +LIBV = "2.6" + +do_install_append() { + # Remove .la files for loadable modules + rm -f ${D}/${libdir}/rygel-${LIBV}/engines/*.la + rm -f ${D}/${libdir}/rygel-${LIBV}/plugins/*.la +} + +FILES_${PN} += "${libdir}/rygel-${LIBV}/engines ${datadir}/dbus-1 ${datadir}/icons" +FILES_${PN}-dbg += "${libdir}/rygel-${LIBV}/engines/.debug ${libdir}/rygel-${LIBV}/plugins/.debug" + +PACKAGES += "${PN}-meta" +ALLOW_EMPTY_${PN}-meta = "1" + +PACKAGES_DYNAMIC = "${PN}-plugin-*" + +python populate_packages_prepend () { + rygel_libdir = d.expand('${libdir}/rygel-${LIBV}') + postinst = d.getVar('plugin_postinst', True) + pkgs = [] + + pkgs += do_split_packages(d, oe.path.join(rygel_libdir, "plugins"), 'librygel-(.*)\.so$', d.expand('${PN}-plugin-%s'), 'Rygel plugin for %s', postinst=postinst, extra_depends=d.expand('${PN}')) + pkgs += do_split_packages(d, oe.path.join(rygel_libdir, "plugins"), '(.*)\.plugin$', d.expand('${PN}-plugin-%s'), 'Rygel plugin for %s', postinst=postinst, extra_depends=d.expand('${PN}')) + + metapkg = d.getVar('PN', True) + '-meta' + d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs)) +} diff --git a/meta-agl/recipes-devtools/libgee/libgee-0.8_0.16.1.bb b/meta-agl/recipes-devtools/libgee/libgee-0.8_0.16.1.bb new file mode 100644 index 000000000..3cf16e309 --- /dev/null +++ b/meta-agl/recipes-devtools/libgee/libgee-0.8_0.16.1.bb @@ -0,0 +1,26 @@ +DESCRIPTION = "libgee is a collection library providing GObject-based interfaces \ +and classes for commonly used data structures." +HOMEPAGE = "http://live.gnome.org/Libgee" +SECTION = "libs" +DEPENDS = "glib-2.0 gobject-introspection-stub" + +BBCLASSEXTEND = "native" +LICENSE = "LGPLv2.1" +LIC_FILES_CHKSUM = "file://COPYING;md5=fbc093901857fcd118f065f900982c24" + +PE = "1" + +inherit autotools vala pkgconfig +do_configure_prepend() { + MACROS="libtool.m4 lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4" + for i in ${MACROS}; do + rm -f m4/$i + done +} + +SHRT_VER = "${@d.getVar('PV',1).split('.')[0]}.${@d.getVar('PV',1).split('.')[1]}" +SRC_URI = "http://ftp.gnome.org/pub/GNOME/sources/libgee/${SHRT_VER}/libgee-${PV}.tar.xz" +SRC_URI[md5sum] = "d30cf203784431b0fdc3216b1acd999c" +SRC_URI[sha256sum] = "d95f8ea8e78f843c71b1958fa2fb445e4a325e4821ec23d0d5108d8170e564a5" + +S = "${WORKDIR}/libgee-${PV}" diff --git a/meta-agl/recipes-ivi/images/agl-image-ivi-crosssdk.bb b/meta-agl/recipes-ivi/images/agl-image-ivi-crosssdk.bb new file mode 100644 index 000000000..104462019 --- /dev/null +++ b/meta-agl/recipes-ivi/images/agl-image-ivi-crosssdk.bb @@ -0,0 +1,12 @@ +SUMMARY = "Cross SDK of AGL Distribution for IVI profile" + +DESCRIPTION = "Basic image for baseline of AGL Distribution for IVI profile. \ +It includes the full meta-toolchain, plus developement headers and libraries \ +to form a standalone cross SDK." + +require agl-image-ivi.bb + +IMAGE_FEATURES += "dev-pkgs" +IMAGE_INSTALL += "kernel-dev" + +inherit populate_sdk diff --git a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb index 0b925c096..405c0fbe6 100644 --- a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb +++ b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-connectivity.bb @@ -11,4 +11,8 @@ PACKAGES = "\ ALLOW_EMPTY_${PN} = "1" RDEPENDS_${PN} += "\ + ofono \ + rygel \ + rygel-plugin-media-export \ + rygel-plugin-lms \ " diff --git a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb index 78508eed8..11536405e 100644 --- a/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb +++ b/meta-agl/recipes-ivi/packagegroups/packagegroup-agl-ivi-multimedia.bb @@ -11,4 +11,7 @@ PACKAGES = "\ ALLOW_EMPTY_${PN} = "1" RDEPENDS_${PN} += "\ + gstreamer1.0-plugins-base-meta \ + gstreamer1.0-plugins-good-meta \ + lightmediascanner-meta \ " diff --git a/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch new file mode 100644 index 000000000..9528bec79 --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/files/id3-plugin-support-out-of-tree-build.patch @@ -0,0 +1,11 @@ +--- a/src/plugins/Makefile.am 2015-10-25 16:12:29.331415823 +0000 ++++ b/src/plugins/Makefile.am 2015-10-25 16:14:37.593415808 +0000 +@@ -93,7 +93,7 @@ + id3_id3_la_SOURCES = id3/id3.c id3/id3v1_genres.c + id3_id3_la_LIBADD = $(PLUGINS_LIBADD) + +-id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk ++$(srcdir)/id3/id3v1_genres.c: $(srcdir)/id3/id3v1_genres.def $(srcdir)/id3/id3v1_genres_gen.awk + $(AWK) -f $(srcdir)/id3/id3v1_genres_gen.awk $(srcdir)/id3/id3v1_genres.def > $@ + + EXTRA_DIST += id3/id3v1_genres.def id3/id3v1_genres_gen.awk diff --git a/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend new file mode 100644 index 000000000..7e6381113 --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_%.bbappend @@ -0,0 +1,2 @@ +# Disable everything but the roygalty-free formats +PACKAGECONFIG = "ogg flac wave m3u pls jpeg png" diff --git a/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb new file mode 100644 index 000000000..9870fac3d --- /dev/null +++ b/meta-agl/recipes-multimedia/lightmediascanner/lightmediascanner_0.5.1.bb @@ -0,0 +1,62 @@ +SUMMARY = "Lightweight media scanner" +DESCRIPTION = "Lightweight media scanner meant to be used in not-so-powerful devices, like embedded systems or old machines." +SECTION = "libs/multimedia" + +LICENSE = "LGPLv2.1+" +LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343 \ + file://src/lib/lightmediascanner.c;endline=21;md5=6d8889bccb4c6c27e8b786342a3eb267" + +DEPENDS = "file gawk glib-2.0 sqlite3" + +PV = "0.5.1+git${SRCPV}" +SRCREV = "adfddb3486276a5ed2f5008c9e43a811e1271cc9" +SRC_URI = "git://github.com/profusion/lightmediascanner.git \ + file://id3-plugin-support-out-of-tree-build.patch \ + " + +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +EXTRA_OECONF = "--enable-static --disable-mp4" + +PACKAGECONFIG ??= "ogg flac wave id3 m3u pls asf rm jpeg png" +PACKAGECONFIG[generic] = "--enable-generic,--disable-generic,libav" +PACKAGECONFIG[ogg] = "--enable-ogg,--disable-ogg,libogg libvorbis libtheora" +PACKAGECONFIG[flac] = "--enable-flac,--disable-flac,flac" +PACKAGECONFIG[wave] = "--enable-wave,--disable-wave" +PACKAGECONFIG[id3] = "--enable-id3,--disable-id3" +PACKAGECONFIG[m3u] = "--enable-m3u,--disable-m3u" +PACKAGECONFIG[pls] = "--enable-pls,--disable-pls" +PACKAGECONFIG[asf] = "--enable-asf,--disable-asf" +PACKAGECONFIG[rm] = "--enable-rm,--disable-rm" +PACKAGECONFIG[jpeg] = "--enable-jpeg,--disable-jpeg" +PACKAGECONFIG[png] = "--enable-png,--disable-png" + +do_install_append() { + # Install "test" binary for corresponding package + install -d ${D}/${bindir} + install -m 755 ${B}/src/bin/.libs/test ${D}/${bindir}/test-lms + # Remove .la files for loadable modules + rm -f ${D}/${libdir}/${PN}/plugins/*.la +} + +FILES_${PN} += "${datadir}/dbus-1" +FILES_${PN}-dbg += "${libdir}/${PN}/plugins/.debug" + +PACKAGES_prepend = "${PN}-test " +FILES_${PN}-test_prepend = "${bindir}/test-lms " + +PACKAGES += "${PN}-meta" +ALLOW_EMPTY_${PN}-meta = "1" + +PACKAGES_DYNAMIC = "${PN}-plugin-*" + +python populate_packages_prepend () { + lms_libdir = d.expand('${libdir}/${PN}') + pkgs = [] + + pkgs += do_split_packages(d, oe.path.join(lms_libdir, "plugins"), '^(.*)\.so$', d.expand('${PN}-plugin-%s'), 'LightMediaScanner plugin for %s', prepend=True, extra_depends=d.expand('${PN}')) + metapkg = d.getVar('PN', True) + '-meta' + d.setVar('RDEPENDS_' + metapkg, ' '.join(pkgs)) +} diff --git a/meta-agl/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend b/meta-agl/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend new file mode 100644 index 000000000..2d9f558e9 --- /dev/null +++ b/meta-agl/recipes-multimedia/pulseaudio/pulseaudio_%.bbappend @@ -0,0 +1,6 @@ +# Prevent BlueZ 4 from being always pulled +PACKAGECONFIG_remove = "bluez4" + +# If Bluetooth is asked in DISTRO_FEATURES, verify if Bluez 5 is also +# explicitly specified. If it is not, fall back to BlueZ 4 +PACKAGECONFIG_append = "${@bb.utils.contains('DISTRO_FEATURES', 'bluetooth', bb.utils.contains('DISTRO_FEATURES', 'bluez5', 'bluez5', 'bluez4', d), '', d)}" diff --git a/meta-agl/recipes-support/libmediaart/libmediaart-2.0_1.9.0.bb b/meta-agl/recipes-support/libmediaart/libmediaart-2.0_1.9.0.bb new file mode 100644 index 000000000..44f135a21 --- /dev/null +++ b/meta-agl/recipes-support/libmediaart/libmediaart-2.0_1.9.0.bb @@ -0,0 +1,7 @@ +require libmediaart.inc + +SRC_URI = "${GNOME_MIRROR}/libmediaart/1.9/libmediaart-${PV}.tar.xz" +SRC_URI[md5sum] = "0b65d64398d2f3dff89534c9dfffab4f" +SRC_URI[sha256sum] = "94668adb29d4dc3115b0fd105942ebd5ca6f5f9dbb2afa8a191a73a747dd506f" + +S = "${WORKDIR}/libmediaart-${PV}" diff --git a/meta-agl/recipes-support/libmediaart/libmediaart.inc b/meta-agl/recipes-support/libmediaart/libmediaart.inc new file mode 100644 index 000000000..a117e9ba5 --- /dev/null +++ b/meta-agl/recipes-support/libmediaart/libmediaart.inc @@ -0,0 +1,14 @@ +SUMMARY = "Library tasked with managing, extracting and handling media art caches" + +LICENSE = "LGPLv2+ & GPLv2+" +LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=4fbd65380cdd255951079008b364516c \ + file://libmediaart/extract.c;endline=18;md5=dff2b6328ab067b5baadc135f9876c36 \ + file://tests/mediaarttest.c;endline=18;md5=067106eaa1f7a9d918759a096667f18e" + +DEPENDS = "glib-2.0 gdk-pixbuf" + +GNOME_COMPRESS_TYPE = "xz" + +inherit gnomebase gtk-doc + +EXTRA_OECONF = "--disable-introspection --disable-qt --enable-gdkpixbuf" diff --git a/meta-ivi-common/recipes-core/packagegroups/packagegroup-ivi-common-core-os-commonlibs.bb b/meta-ivi-common/recipes-core/packagegroups/packagegroup-ivi-common-core-os-commonlibs.bb index eb7df8de2..99a3abd31 100644 --- a/meta-ivi-common/recipes-core/packagegroups/packagegroup-ivi-common-core-os-commonlibs.bb +++ b/meta-ivi-common/recipes-core/packagegroups/packagegroup-ivi-common-core-os-commonlibs.bb @@ -12,4 +12,5 @@ PACKAGES = "\ ALLOW_EMPTY_${PN} = "1" RDEPENDS_${PN} += "\ + procps \ " diff --git a/meta-ivi-common/recipes-test/gtest/gtest/CMakeLists-gtest.pc.in-Add-pkg-config-support-to-gte.patch b/meta-ivi-common/recipes-test/gtest/gtest/CMakeLists-gtest.pc.in-Add-pkg-config-support-to-gte.patch new file mode 100644 index 000000000..1ece136b6 --- /dev/null +++ b/meta-ivi-common/recipes-test/gtest/gtest/CMakeLists-gtest.pc.in-Add-pkg-config-support-to-gte.patch @@ -0,0 +1,55 @@ +From d4b25ce723812faf78d8ee038b7cbed00cbba682 Mon Sep 17 00:00:00 2001 +From: Rodrigo Caimi <caimi@datacom.ind.br> +Date: Tue, 7 Oct 2014 15:37:10 -0300 +Subject: [PATCH] CMakeLists, gtest.pc.in: Add pkg-config support to gtest + 1.7.0 + +Signed-off-by: Rodrigo Caimi <caimi@datacom.ind.br> +--- + CMakeLists.txt | 6 ++++++ + gtest.pc.in | 9 +++++++++ + 2 files changed, 15 insertions(+) + create mode 100644 gtest.pc.in + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 281c4c2..e4354a8 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -29,6 +29,9 @@ if (COMMAND pre_project_set_up_hermetic_build) + pre_project_set_up_hermetic_build() + endif() + ++# pkg-config support ++configure_file("gtest.pc.in" "gtest.pc" @ONLY) ++ + ######################################################################## + # + # Project-wide settings +@@ -75,6 +78,9 @@ target_link_libraries(gtest_main gtest) + + install(TARGETS gtest DESTINATION lib) + install(TARGETS gtest_main DESTINATION lib) ++install(FILES "${CMAKE_CURRENT_BINARY_DIR}/gtest.pc" ++ DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig/" ++) + + ######################################################################## + # +diff --git a/gtest.pc.in b/gtest.pc.in +new file mode 100644 +index 0000000..57b1049 +--- /dev/null ++++ b/gtest.pc.in +@@ -0,0 +1,9 @@ ++Name: libgtest ++Version: 1.7.0 ++Description: Google's framework for writing C++ tests on a variety of platforms ++ ++prefix=@CMAKE_INSTALL_PREFIX@ ++includedir=${prefix}/include ++libdir=${prefix}/lib ++Cflags:-I${includedir}/gtest ++Libs: -L${libdir} -lgtest -lgtest_main +-- +1.9.1 + diff --git a/meta-ivi-common/recipes-test/gtest/gtest/cmake-Add-install-command-for-libraries-and-headers.patch b/meta-ivi-common/recipes-test/gtest/gtest/cmake-Add-install-command-for-libraries-and-headers.patch new file mode 100644 index 000000000..0c160b02a --- /dev/null +++ b/meta-ivi-common/recipes-test/gtest/gtest/cmake-Add-install-command-for-libraries-and-headers.patch @@ -0,0 +1,39 @@ +From 5318983562be6babeb5a6996e7dda4b31acfdba8 Mon Sep 17 00:00:00 2001 +From: Otavio Salvador <otavio@ossystems.com.br> +Date: Wed, 30 Jul 2014 16:49:53 -0300 +Subject: [PATCH] cmake: Add install command for libraries and headers +Organization: O.S. Systems Software LTDA. + +Upstream-Status: Inappropriate [embedded specific] + +Signed-off-by: Otavio Salvador <otavio@ossystems.com.br> +--- + CMakeLists.txt | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 57470c8..281c4c2 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -56,6 +56,8 @@ include_directories( + ${gtest_SOURCE_DIR}/include + ${gtest_SOURCE_DIR}) + ++install(DIRECTORY ${gtest_SOURCE_DIR}/include/gtest DESTINATION include) ++ + # Where Google Test's libraries can be found. + link_directories(${gtest_BINARY_DIR}/src) + +@@ -71,6 +73,9 @@ cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) + cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) + target_link_libraries(gtest_main gtest) + ++install(TARGETS gtest DESTINATION lib) ++install(TARGETS gtest_main DESTINATION lib) ++ + ######################################################################## + # + # Samples on how to link user tests with gtest or gtest_main. +-- +1.9.1 + diff --git a/meta-ivi-common/recipes-test/gtest/gtest_1.7.0.bb b/meta-ivi-common/recipes-test/gtest/gtest_1.7.0.bb new file mode 100644 index 000000000..9f148d549 --- /dev/null +++ b/meta-ivi-common/recipes-test/gtest/gtest_1.7.0.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "Google's framework for writing C++ tests" +HOMEPAGE = "http://code.google.com/p/googletest/" +SECTION = "libs" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=cbbd27594afd089daa160d3a16dd515a" + +SRC_URI = "\ + http://googletest.googlecode.com/files/${BPN}-${PV}.zip \ + file://cmake-Add-install-command-for-libraries-and-headers.patch \ + file://CMakeLists-gtest.pc.in-Add-pkg-config-support-to-gte.patch \ +" + +SRC_URI[md5sum] = "2d6ec8ccdf5c46b05ba54a9fd1d130d7" +SRC_URI[sha256sum] = "247ca18dd83f53deb1328be17e4b1be31514cedfc1e3424f672bf11fd7e0d60d" + +inherit lib_package cmake + +ALLOW_EMPTY_${PN} = "1" +ALLOW_EMPTY_${PN}-dbg = "1" + +RDEPENDS_${PN}-dev += "${PN}-staticdev" + +BBCLASSEXTEND = "nativesdk" diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend b/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend new file mode 100644 index 000000000..772f81b0f --- /dev/null +++ b/meta-ivi-common/recipes-test/wayland/wayland-fits_%.bbappend @@ -0,0 +1,5 @@ +# Disable GTK+ and EFL tests +PACKAGECONFIG = "" + +# UInput driver is necessary on QEMU +RDEPENDS_${PN}_append_qemux86-64 = " kernel-module-uinput" diff --git a/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bb b/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bb new file mode 100644 index 000000000..3a4f8a2ca --- /dev/null +++ b/meta-ivi-common/recipes-test/wayland/wayland-fits_git.bb @@ -0,0 +1,33 @@ +SUMMARY = "Wayland-fits, the Wayland Functional Integration Test Suite" +DESCRIPTION = "Wayland-fits is a fully automated functional integration \ +test suite. Its main purpose is to test the functionality and integration of \ +client-side (i.e. toolkit) and server-side (compositor) implementations of \ +the Wayland protocol." +HOMEPAGE = "https://github.com/01org/wayland-fits" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://COPYING;md5=f8d34cadaf891753c0f00c6cd48f08f5 \ + file://src/extensions/weston/weston-wfits.cpp;endline=21;md5=848c81e55cf3a30a9f6ed75f0dba7a97" + +SRC_URI = "git://github.com/01org/wayland-fits.git" +SRCREV = "f30dfa9fceb438d3687c5215093fffc21a7852fc" + +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +DEPENDS = "libcheck boost wayland weston" +RDEPENDS_${PN} = "weston" + +EXTRA_OECONF += "--enable-shared --disable-static --with-boost-libdir=${STAGING_LIBDIR}" + +PACKAGECONFIG ??= "elementary gtk+3" + +PACKAGECONFIG[elementary] = "--enable-efl-tests,--disable-efl-tests,elementary" +PACKAGECONFIG[gtk+3] = "--enable-gtk-tests,--disable-gtk-tests,gtk+3" + +do_install_append() { + rm -f ${D}/${libdir}/weston/*.la +} + +FILES_${PN} += "${bindir}/wfits ${libdir}/weston/*.so" +FILES_${PN}-dbg += "${bindir}/.debug ${libdir}/weston/.debug ${prefix}/src" diff --git a/scripts/envsetup.sh b/scripts/envsetup.sh new file mode 100644 index 000000000..27d73a7e2 --- /dev/null +++ b/scripts/envsetup.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +if [ -z $1 ]; then + echo -e "Usage: source envsetup.sh <board/device> [build dir]" + return -1 +fi + +case "$1" in + "porter") + # setup proprietary gfx drivers and multimedia packages + COPY_MM_SCRIPT=meta-renesas/meta-rcar-gen2/scripts/setup_mm_packages.sh + if [ -f $COPY_MM_SCRIPT ]; then + . $COPY_MM_SCRIPT + copy_mm_packages $1 + if [ $? -ne 0 ]; then + echo "Copying gfx drivers and multimedia packages for '$1' failed." + return -1 + fi + fi + + # template conf for R-Car2 M2 Porter board + TEMPLATECONF=$PWD/meta-renesas/meta-rcar-gen2/conf + ;; + "qemux86-64") + # template conf for QEMU x86-64 + TEMPLATECONF=$PWD/meta-agl-demo/conf + ;; + *) + # nothing to do here + echo "WARN: '$1' is not tested by AGL Distro" + if [ -z $TEMPLATECONF ]; then + TEMPLATECONF=$PWD/meta-agl-demo/conf + fi + ;; +esac + +echo "envsetup: Set '$1 as MACHINE." +export MACHINE="$1" + +echo "envsetup: Using templates for local.conf & bblayers.conf from :" +echo " '$TEMPLATECONF'" +export TEMPLATECONF + +if [ -n "$2" ]; then + BUILD_DIR="$2" +else + BUILD_DIR=build +fi + +echo "envsetup: Setup build environment for poky/oe." +echo -e + +source poky/oe-init-build-env $BUILD_DIR + +if [ -n "$DL_DIR" ]; then + BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE DL_DIR" +fi + +if [ -n "$SSTATE_DIR" ]; then + BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE SSTATE_DIR" +fi + +export BB_ENV_EXTRAWHITE + |