From: Lukasz Pawlik Date: Sun, 5 Aug 2012 16:54:05 +0000 (+0200) Subject: core,tracker: Sort before slicing X-Git-Tag: RYGEL_0_15_2~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7abecff3a25b2c9482a58b18e2f92ae769528148;p=profile%2Fivi%2Frygel.git core,tracker: Sort before slicing Fixes inconsistencies in returned results. https://bugzilla.gnome.org/show_bug.cgi?id=661482 --- diff --git a/src/librygel-server/rygel-browse.vala b/src/librygel-server/rygel-browse.vala index a4b6119..b9319d4 100644 --- a/src/librygel-server/rygel-browse.vala +++ b/src/librygel-server/rygel-browse.vala @@ -110,9 +110,12 @@ internal class Rygel.Browse: Rygel.MediaQueryAction { this.requested_count, this.object_id, this.index); + var children = yield container.get_children (this.index, this.requested_count, + this.sort_criteria, this.cancellable); + debug ("Fetched %u children of container '%s' from index %u.", this.requested_count, this.object_id, diff --git a/src/librygel-server/rygel-client-hacks.vala b/src/librygel-server/rygel-client-hacks.vala index 2f6f72a..3fd9040 100644 --- a/src/librygel-server/rygel-client-hacks.vala +++ b/src/librygel-server/rygel-client-hacks.vala @@ -84,12 +84,14 @@ internal abstract class Rygel.ClientHacks : GLib.Object { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { return yield container.search (expression, offset, max_count, out total_matches, + sort_criteria, cancellable); } diff --git a/src/librygel-server/rygel-item-creator.vala b/src/librygel-server/rygel-item-creator.vala index ad29cc1..3815e85 100644 --- a/src/librygel-server/rygel-item-creator.vala +++ b/src/librygel-server/rygel-item-creator.vala @@ -235,6 +235,7 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine { 0, 1, out total_matches, + "", this.cancellable); if (result.size > 0) { this.didl_item.upnp_class = upnp_class; diff --git a/src/librygel-server/rygel-media-container.vala b/src/librygel-server/rygel-media-container.vala index 8e6f420..621f787 100644 --- a/src/librygel-server/rygel-media-container.vala +++ b/src/librygel-server/rygel-media-container.vala @@ -106,12 +106,14 @@ public abstract class Rygel.MediaContainer : MediaObject { * * @param offset zero-based index of the first item to return * @param max_count maximum number of objects to return + * @param sort_criteria sorting order of objects to return * @param cancellable optional cancellable for this operation * * @return A list of media objects. */ public async abstract MediaObjects? get_children (uint offset, uint max_count, + string sort_criteria, Cancellable? cancellable) throws Error; diff --git a/src/librygel-server/rygel-search.vala b/src/librygel-server/rygel-search.vala index b050eff..d35be7e 100644 --- a/src/librygel-server/rygel-search.vala +++ b/src/librygel-server/rygel-search.vala @@ -75,12 +75,14 @@ internal class Rygel.Search: Rygel.MediaQueryAction { this.index, this.requested_count, out this.total_matches, + this.sort_criteria, this.cancellable); } else { return yield container.search (parser.expression, this.index, this.requested_count, out this.total_matches, + this.sort_criteria, this.cancellable); } } diff --git a/src/librygel-server/rygel-searchable-container.vala b/src/librygel-server/rygel-searchable-container.vala index faf2868..60d61b0 100644 --- a/src/librygel-server/rygel-searchable-container.vala +++ b/src/librygel-server/rygel-searchable-container.vala @@ -45,6 +45,7 @@ public interface Rygel.SearchableContainer : MediaContainer { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error; @@ -68,12 +69,14 @@ public interface Rygel.SearchableContainer : MediaContainer { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { var result = new MediaObjects (); var children = yield this.get_children (0, this.child_count, + sort_criteria, cancellable); // The maximum number of results we need to be able to slice-out @@ -99,7 +102,6 @@ public interface Rygel.SearchableContainer : MediaContainer { if (limit == 0 || result.size < limit) { // Then search in the children var child_limit = (limit == 0)? 0: limit - result.size; - var child_results = yield this.search_in_children (expression, children, child_limit, @@ -158,6 +160,7 @@ public interface Rygel.SearchableContainer : MediaContainer { 0, 1, out total_matches, + "", cancellable); if (results.size > 0) { return results[0]; @@ -182,6 +185,7 @@ public interface Rygel.SearchableContainer : MediaContainer { 0, limit, out tmp, + "", cancellable); result.add_all (child_result); diff --git a/src/librygel-server/rygel-simple-container.vala b/src/librygel-server/rygel-simple-container.vala index 4b82bb4..08cb7d8 100644 --- a/src/librygel-server/rygel-simple-container.vala +++ b/src/librygel-server/rygel-simple-container.vala @@ -121,10 +121,12 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer, return unique; } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws Error { + public override async MediaObjects? get_children ( + uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws Error { uint stop = offset + max_count; stop = stop.clamp (0, this.child_count); @@ -188,12 +190,14 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer, uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { return yield this.simple_search (expression, offset, max_count, out total_matches, + sort_criteria, cancellable); } diff --git a/src/librygel-server/rygel-wmp-hacks.vala b/src/librygel-server/rygel-wmp-hacks.vala index 7e9d23d..91cae3c 100644 --- a/src/librygel-server/rygel-wmp-hacks.vala +++ b/src/librygel-server/rygel-wmp-hacks.vala @@ -35,6 +35,7 @@ internal class Rygel.WMPHacks : ClientHacks { uint offset, uint requested, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { // Drop the limit. WMP has a problem if we don't know the number of @@ -46,6 +47,7 @@ internal class Rygel.WMPHacks : ClientHacks { offset, 0, out total_matches, + sort_criteria, cancellable); } } diff --git a/src/librygel-server/rygel-xbox-hacks.vala b/src/librygel-server/rygel-xbox-hacks.vala index b2f046c..fc4e3dd 100644 --- a/src/librygel-server/rygel-xbox-hacks.vala +++ b/src/librygel-server/rygel-xbox-hacks.vala @@ -130,6 +130,7 @@ internal class Rygel.XBoxHacks : ClientHacks { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { var set_total_matches = false; @@ -159,6 +160,7 @@ internal class Rygel.XBoxHacks : ClientHacks { offset, max_count, out total_matches, + sort_criteria, cancellable); if (total_matches == 0 && set_total_matches) { total_matches = results.size; diff --git a/src/plugins/external/rygel-external-container.vala b/src/plugins/external/rygel-external-container.vala index 9f8306f..a7648a6 100644 --- a/src/plugins/external/rygel-external-container.vala +++ b/src/plugins/external/rygel-external-container.vala @@ -74,10 +74,12 @@ public class Rygel.External.Container : Rygel.MediaContainer, } } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws GLib.Error { + public override async MediaObjects? get_children ( + uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws GLib.Error { string[] filter = {}; foreach (var object_prop in MediaObjectProxy.PROPERTIES) { @@ -102,6 +104,7 @@ public class Rygel.External.Container : Rygel.MediaContainer, uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws GLib.Error { if (expression == null || !this.searchable) { @@ -110,6 +113,7 @@ public class Rygel.External.Container : Rygel.MediaContainer, offset, max_count, out total_matches, + sort_criteria, cancellable); } diff --git a/src/plugins/external/rygel-external-dummy-container.vala b/src/plugins/external/rygel-external-dummy-container.vala index 7ccb6f3..b1ba379 100644 --- a/src/plugins/external/rygel-external-dummy-container.vala +++ b/src/plugins/external/rygel-external-dummy-container.vala @@ -38,14 +38,16 @@ internal class Rygel.External.DummyContainer : MediaContainer { base (id, parent, title, (int) child_count); } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws Error { + public override async MediaObjects? get_children ( + uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws Error { return new MediaObjects (); } - public override async MediaObject? find_object (string id, + public override async MediaObject? find_object (string id, Cancellable? cancellable) throws Error { return null; 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 03e18db..3477983 100644 --- a/src/plugins/media-export/rygel-media-export-db-container.vala +++ b/src/plugins/media-export/rygel-media-export-db-container.vala @@ -47,10 +47,12 @@ public class Rygel.MediaExport.DBContainer : MediaContainer, } } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws GLib.Error { + public override async MediaObjects? get_children ( + uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws GLib.Error { return this.media_db.get_children (this, offset, max_count); } @@ -58,6 +60,7 @@ public class Rygel.MediaExport.DBContainer : MediaContainer, uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws GLib.Error { MediaObjects children = null; @@ -75,6 +78,7 @@ public class Rygel.MediaExport.DBContainer : MediaContainer, offset, max_count, out total_matches, + sort_criteria, cancellable); } else { throw error; diff --git a/src/plugins/media-export/rygel-media-export-leaf-query-container.vala b/src/plugins/media-export/rygel-media-export-leaf-query-container.vala index f363290..bd82a88 100644 --- a/src/plugins/media-export/rygel-media-export-leaf-query-container.vala +++ b/src/plugins/media-export/rygel-media-export-leaf-query-container.vala @@ -26,15 +26,18 @@ internal class Rygel.MediaExport.LeafQueryContainer : QueryContainer { base (cache, expression, id, name); } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws GLib.Error { + public override async MediaObjects? get_children + (uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws GLib.Error { uint total_matches; var children = yield this.search (null, offset, max_count, out total_matches, + sort_criteria, cancellable); foreach (var child in children) { child.parent = this; diff --git a/src/plugins/media-export/rygel-media-export-node-query-container.vala b/src/plugins/media-export/rygel-media-export-node-query-container.vala index 152eddd..1d40084 100644 --- a/src/plugins/media-export/rygel-media-export-node-query-container.vala +++ b/src/plugins/media-export/rygel-media-export-node-query-container.vala @@ -43,14 +43,17 @@ internal class Rygel.MediaExport.NodeQueryContainer : QueryContainer { // MediaContainer overrides - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws GLib.Error { + public override async MediaObjects? get_children + (uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws GLib.Error { var children = new MediaObjects (); var data = this.media_db.get_object_attribute_by_search_expression (this.attribute, this.expression, + // sort criteria offset, max_count); diff --git a/src/plugins/media-export/rygel-media-export-null-container.vala b/src/plugins/media-export/rygel-media-export-null-container.vala index f046959..6309fbc 100644 --- a/src/plugins/media-export/rygel-media-export-null-container.vala +++ b/src/plugins/media-export/rygel-media-export-null-container.vala @@ -30,10 +30,12 @@ internal class Rygel.NullContainer : MediaContainer { base.root ("MediaExport", 0); } - public override async MediaObjects? get_children (uint offset, - uint max_count, - Cancellable? cancellable) - throws Error { + public override async MediaObjects? get_children ( + uint offset, + uint max_count, + string sort_criteria, + Cancellable? cancellable) + throws Error { return new MediaObjects (); } 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 3800c62..0833f44 100644 --- a/src/plugins/media-export/rygel-media-export-query-container.vala +++ b/src/plugins/media-export/rygel-media-export-query-container.vala @@ -49,6 +49,7 @@ internal abstract class Rygel.MediaExport.QueryContainer : DBContainer { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws GLib.Error { MediaObjects children = null; diff --git a/src/plugins/media-export/rygel-media-export-root-container.vala b/src/plugins/media-export/rygel-media-export-root-container.vala index 723be32..3b15685 100644 --- a/src/plugins/media-export/rygel-media-export-root-container.vala +++ b/src/plugins/media-export/rygel-media-export-root-container.vala @@ -137,6 +137,7 @@ public class Rygel.MediaExport.RootContainer : Rygel.MediaExport.DBContainer { uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws GLib.Error { if (expression == null) { @@ -144,6 +145,7 @@ public class Rygel.MediaExport.RootContainer : Rygel.MediaExport.DBContainer { offset, max_count, out total_matches, + sort_criteria, cancellable); } @@ -165,6 +167,7 @@ public class Rygel.MediaExport.RootContainer : Rygel.MediaExport.DBContainer { if (query_container != null) { list = yield query_container.get_children (offset, max_count, + sort_criteria, cancellable); total_matches = query_container.child_count; @@ -180,6 +183,7 @@ public class Rygel.MediaExport.RootContainer : Rygel.MediaExport.DBContainer { offset, max_count, out total_matches, + sort_criteria, cancellable); } } diff --git a/src/plugins/tracker/rygel-tracker-category-all-container.vala b/src/plugins/tracker/rygel-tracker-category-all-container.vala index d33643f..a1a1185 100644 --- a/src/plugins/tracker/rygel-tracker-category-all-container.vala +++ b/src/plugins/tracker/rygel-tracker-category-all-container.vala @@ -103,12 +103,14 @@ public class Rygel.Tracker.CategoryAllContainer : SearchContainer, uint offset, uint max_count, out uint total_matches, + string sort_criteria, Cancellable? cancellable) throws Error { return yield this.simple_search (expression, offset, max_count, out total_matches, + sort_criteria, cancellable); } diff --git a/src/plugins/tracker/rygel-tracker-search-container.vala b/src/plugins/tracker/rygel-tracker-search-container.vala index 6f83584..29ed77c 100644 --- a/src/plugins/tracker/rygel-tracker-search-container.vala +++ b/src/plugins/tracker/rygel-tracker-search-container.vala @@ -35,6 +35,8 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { /* class-wide constants */ private const string MODIFIED_PROPERTY = "nfo:fileLastModified"; + private string sort_criteria = ""; + public SelectionQuery query; public ItemFactory item_factory; @@ -105,8 +107,9 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { } } - public override async MediaObjects? get_children (uint offset, - uint max_count, + public override async MediaObjects? get_children (uint offset, + uint max_count, + string sort_criteria, Cancellable? cancellable) throws GLib.Error { var expression = new RelationalExpression (); @@ -116,6 +119,8 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { uint total_matches; + this.sort_criteria = sort_criteria; + return yield this.execute_query (expression, offset, max_count, @@ -133,7 +138,8 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { var query = this.create_query (expression as RelationalExpression, (int) offset, - (int) max_count); + (int) max_count, + this.sort_criteria); if (query != null) { yield query.execute (this.resources); @@ -233,14 +239,20 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { } private SelectionQuery? create_query (RelationalExpression? expression, - int offset, - int max_count) { + int offset, + int max_count, + string sort_criteria = "") { if (expression.operand1 == "upnp:class" && !this.item_factory.upnp_class.has_prefix (expression.operand2)) { return null; } - var query = new SelectionQuery.clone (this.query); + SelectionQuery query; + if (sort_criteria == null || sort_criteria == "") { + query = new SelectionQuery.clone (this.query); + } else { + query = create_sorted_query (); + } if (expression.operand1 == "@parentID") { if (!expression.compare_string (this.id)) { @@ -257,10 +269,46 @@ public class Rygel.Tracker.SearchContainer : SimpleContainer { query.offset = offset; query.max_count = max_count; + this.sort_criteria = ""; return query; } + private SelectionQuery? create_sorted_query () { + var key_chain_map = UPnPPropertyMap.get_property_map (); + var sort_props = sort_criteria.split (","); + string order = ""; + ArrayList variables = new ArrayList (); + ArrayList filters = new ArrayList (); + + variables.add_all (this.query.variables); + filters.add_all (this.query.filters); + + foreach (string s in sort_props) { + var key = key_chain_map[s.substring(1)]; + if (key.index_of (SelectionQuery.ITEM_VARIABLE) == 0) { + continue; + } + + if (s.has_prefix("-")) { + order += "DESC (" + + key + ") "; + } else { + order += key + " "; + } + } + + if (order == "") { + order = this.query.order_by; + } + + return new SelectionQuery ( + variables, + new QueryTriplets.clone(this.query.triplets), + filters, + order); + } + private string? urn_to_utf8 (string urn) { var urn_builder = new StringBuilder (); unowned string s = urn;