[rygel] media-export: Let SQLite do the sorting



commit bb04821f4ee93601683f6c84f8cd9f4de7891b56
Author: Jens Georg <mail jensge org>
Date:   Sat Aug 11 18:37:43 2012 +0200

    media-export: Let SQLite do the sorting

 .../rygel-media-export-db-container.vala           |    6 ++-
 .../rygel-media-export-media-cache.vala            |   59 +++++++++++++++++---
 .../rygel-media-export-query-container.vala        |    1 +
 .../rygel-media-export-sql-factory.vala            |   20 +------
 4 files changed, 60 insertions(+), 26 deletions(-)
---
diff --git a/src/plugins/media-export/rygel-media-export-db-container.vala b/src/plugins/media-export/rygel-media-export-db-container.vala
index 3477983..61141a2 100644
--- a/src/plugins/media-export/rygel-media-export-db-container.vala
+++ b/src/plugins/media-export/rygel-media-export-db-container.vala
@@ -53,7 +53,10 @@ public class Rygel.MediaExport.DBContainer : MediaContainer,
                                                      string       sort_criteria,
                                                      Cancellable? cancellable)
                                                      throws GLib.Error {
-        return this.media_db.get_children (this, offset, max_count);
+        return this.media_db.get_children (this,
+                                           sort_criteria,
+                                           offset,
+                                           max_count);
     }
 
     public virtual async MediaObjects? search (SearchExpression? expression,
@@ -68,6 +71,7 @@ public class Rygel.MediaExport.DBContainer : MediaContainer,
         try {
             children = this.media_db.get_objects_by_search_expression
                                         (expression,
+                                         sort_criteria,
                                          this.id,
                                          offset,
                                          max_count,
diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala b/src/plugins/media-export/rygel-media-export-media-cache.vala
index 43395c5..14e909c 100644
--- a/src/plugins/media-export/rygel-media-export-media-cache.vala
+++ b/src/plugins/media-export/rygel-media-export-media-cache.vala
@@ -180,6 +180,7 @@ public class Rygel.MediaExport.MediaCache : Object {
     }
 
     public MediaObjects get_children (MediaContainer container,
+                                      string?        sort_criteria,
                                       long           offset,
                                       long           max_count)
                                       throws Error {
@@ -189,7 +190,9 @@ public class Rygel.MediaExport.MediaCache : Object {
                                 offset,
                                 max_count };
 
-        var cursor = this.exec_cursor (SQLString.GET_CHILDREN, values);
+        var sql = this.sql.make (SQLString.GET_CHILDREN);
+        var sort_order = this.translate_sort_criteria (sort_criteria);
+        var cursor = this.db.exec_cursor (sql.printf (sort_order), values);
 
         foreach (var statement in cursor) {
             children.add (this.get_object_from_statement (container,
@@ -203,6 +206,7 @@ public class Rygel.MediaExport.MediaCache : Object {
     public MediaObjects get_objects_by_search_expression
                                         (SearchExpression? expression,
                                          string?           container_id,
+                                         string?           sort_criteria,
                                          uint              offset,
                                          uint              max_count,
                                          out uint          total_matches)
@@ -215,10 +219,6 @@ public class Rygel.MediaExport.MediaCache : Object {
             debug ("Parsed search expression: %s", filter);
         }
 
-        for (int i = 0; i < args.n_values; i++) {
-            debug ("Arg %d: %s", i, args.get_nth (i).get_string ());
-        }
-
         var max_objects = modify_limit (max_count);
         total_matches = (uint) get_object_count_by_filter (filter,
                                                            args,
@@ -227,6 +227,7 @@ public class Rygel.MediaExport.MediaCache : Object {
         return this.get_objects_by_filter (filter,
                                            args,
                                            container_id,
+                                           sort_criteria,
                                            offset,
                                            max_objects);
     }
@@ -244,7 +245,10 @@ public class Rygel.MediaExport.MediaCache : Object {
         }
 
         for (int i = 0; i < args.n_values; i++) {
-            debug ("Arg %d: %s", i, args.get_nth (i).get_string ());
+            var arg = args.get_nth (i);
+            debug ("Arg %d: %s", i, arg.holds (typeof (string)) ?
+                                        arg.get_string () :
+                                        arg.strdup_contents ());
         }
 
         return this.get_object_count_by_filter (filter,
@@ -275,10 +279,10 @@ public class Rygel.MediaExport.MediaCache : Object {
         return this.db.query_value (pattern.printf (filter), args.values);
     }
 
-
     public MediaObjects get_objects_by_filter (string          filter,
                                                GLib.ValueArray args,
                                                string?         container_id,
+                                               string?         sort_criteria,
                                                long            offset,
                                                long            max_count)
                                                throws Error {
@@ -290,6 +294,12 @@ public class Rygel.MediaExport.MediaCache : Object {
         MediaContainer parent = null;
 
         debug ("Parameters to bind: %u", args.n_values);
+        for (int i = 0; i < args.n_values; i++) {
+            var arg = args.get_nth (i);
+            debug ("Arg %d: %s", i, arg.holds (typeof (string)) ?
+                                        arg.get_string () :
+                                        arg.strdup_contents ());
+        }
 
         unowned string sql;
         if (container_id != null) {
@@ -297,7 +307,10 @@ public class Rygel.MediaExport.MediaCache : Object {
         } else {
             sql = this.sql.make (SQLString.GET_OBJECTS_BY_FILTER);
         }
-        var cursor = this.db.exec_cursor (sql.printf (filter), args.values);
+
+        var sort_order = this.translate_sort_criteria (sort_criteria);
+        var cursor = this.db.exec_cursor (sql.printf (filter, sort_order),
+                                          args.values);
         foreach (var statement in cursor) {
             unowned string parent_id = statement.column_text (DetailColumn.PARENT);
 
@@ -766,6 +779,9 @@ public class Rygel.MediaExport.MediaCache : Object {
                 column = "m.genre";
                 use_collation = true;
                 break;
+            case "upnp:originalTrackNumber":
+                column = "m.track";
+                break;
             default:
                 var message = "Unsupported column %s".printf (operand);
 
@@ -845,4 +861,31 @@ public class Rygel.MediaExport.MediaCache : Object {
                              throws DatabaseError {
         return this.db.query_value (this.sql.make (id), values);
     }
+
+    private string translate_sort_criteria (string? sort_criteria) {
+        if (sort_criteria == null) {
+            return "ORDER BY o.title COLLATE CASEFOLD ASC ";
+        }
+
+        string? collate;
+        var builder = new StringBuilder("ORDER BY ");
+        var fields = sort_criteria.split (",");
+        foreach (var field in fields) {
+            try {
+                var column = this.map_operand_to_column (field[1:field.length],
+                                                         out collate);
+                if (field != fields[0]) {
+                    builder.append (",");
+                }
+                builder.append_printf ("%s %s %s ",
+                                       column,
+                                       collate,
+                                       field[0] == '-' ? "DESC" : "ASC");
+            } catch (Error error) {
+                warning ("Skipping nsupported field: %s", field);
+            }
+        }
+
+        return builder.str;
+    }
 }
diff --git a/src/plugins/media-export/rygel-media-export-query-container.vala b/src/plugins/media-export/rygel-media-export-query-container.vala
index 0833f44..99f77cd 100644
--- a/src/plugins/media-export/rygel-media-export-query-container.vala
+++ b/src/plugins/media-export/rygel-media-export-query-container.vala
@@ -70,6 +70,7 @@ internal abstract class Rygel.MediaExport.QueryContainer : DBContainer {
             children = this.media_db.get_objects_by_search_expression
                                         (combined_expression,
                                          null,
+                                         sort_criteria,
                                          offset,
                                          max_count,
                                          out total_matches);
diff --git a/src/plugins/media-export/rygel-media-export-sql-factory.vala b/src/plugins/media-export/rygel-media-export-sql-factory.vala
index 899c031..00a3764 100644
--- a/src/plugins/media-export/rygel-media-export-sql-factory.vala
+++ b/src/plugins/media-export/rygel-media-export-sql-factory.vala
@@ -117,11 +117,7 @@ internal class Rygel.MediaExport.SQLFactory : Object {
         "JOIN Closure c ON (o.upnp_id = c.descendant) " +
         "LEFT OUTER JOIN meta_data m " +
         "ON c.descendant = m.object_fk " +
-    "WHERE c.ancestor = ? AND c.depth = 1 " +
-        "ORDER BY o.type_fk ASC, " +
-                 "m.class ASC, " +
-                 "m.track ASC, " +
-                 "o.title ASC " +
+    "WHERE c.ancestor = ? AND c.depth = 1 %s" +
     "LIMIT ?,?";
 
     private const string GET_OBJECTS_BY_FILTER_STRING_WITH_ANCESTOR =
@@ -129,24 +125,14 @@ internal class Rygel.MediaExport.SQLFactory : Object {
     "FROM Object o " +
         "JOIN Closure c ON o.upnp_id = c.descendant AND c.ancestor = ? " +
         "LEFT OUTER JOIN meta_data m " +
-            "ON o.upnp_id = m.object_fk %s" +
-        "ORDER BY o.parent ASC, " +
-                 "o.type_fk ASC, " +
-                 "m.class ASC, " +
-                 "m.track ASC, " +
-                 "o.title ASC " +
+            "ON o.upnp_id = m.object_fk %s %s " +
     "LIMIT ?,?";
 
     private const string GET_OBJECTS_BY_FILTER_STRING =
     "SELECT DISTINCT " + ALL_DETAILS_STRING +
     "FROM Object o " +
         "LEFT OUTER JOIN meta_data m " +
-            "ON o.upnp_id = m.object_fk %s" +
-        "ORDER BY o.parent ASC, " +
-                 "o.type_fk ASC, " +
-                 "m.class ASC, " +
-                 "m.track ASC, " +
-                 "o.title ASC " +
+            "ON o.upnp_id = m.object_fk %s %s " +
     "LIMIT ?,?";
 
     private const string GET_OBJECT_COUNT_BY_FILTER_STRING_WITH_ANCESTOR =



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