From b78a8a60d0579a0af1c350504e02f3a66e59f025 Mon Sep 17 00:00:00 2001 From: James Stone Date: Wed, 7 Feb 2018 07:11:43 -0800 Subject: [PATCH] Hook up the sort/distinct orderings from parsed queries (#1653) * Hook up the sort/distinct orderings from parsed queries * Update changelog, better tests, fix syntax --- CHANGELOG.md | 7 ++++++- src/js_results.hpp | 4 +++- src/object-store | 2 +- tests/js/query-tests.js | 3 +++ tests/js/query-tests.json | 29 ++++++++++++++++++++++++++++- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35d4261e..0a9d425b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,12 @@ ### Enhancements * Reduced initial download times in Realms with long transaction histories. * Wait for pending notifications to complete when removing a sync listener (1648). -* Further enhancements of the query parser. +* Enabled sort and distinct in the query string. If sort or distinct are also applied outside of the query string, the conditions are stacked. + - Example syntax: `age > 20 SORT(name ASC, age DESC) DISTINCT(name)` + - The ordering for sorting can be one of the following case insensitive literals: `ASC`, `ASCENDING`, `DESC`, `DESCENDING`. + - Any number of properties can appear inside the brackets in a comma separated list. + - Any number of sort/distinct conditions can be indicated, they will be applied in the specified order. + - Sort or distinct cannot operate independently, these conditions must be attached to at least one query filter. ### Bug fixes * None. diff --git a/src/js_results.hpp b/src/js_results.hpp index 5f6a30d3..f3694d08 100644 --- a/src/js_results.hpp +++ b/src/js_results.hpp @@ -152,13 +152,15 @@ typename T::Object ResultsClass::create_filtered(ContextType ctx, const U &co auto query = collection.get_query(); auto const &realm = collection.get_realm(); auto const &object_schema = collection.get_object_schema(); + DescriptorOrdering ordering; parser::ParserResult result = parser::parse(query_string); NativeAccessor accessor(ctx, realm, object_schema); query_builder::ArgumentConverter> converter(accessor, &args.value[1], args.count - 1); query_builder::apply_predicate(query, result.predicate, converter); + query_builder::apply_ordering(ordering, query.get_table(), result.ordering); - return create_instance(ctx, collection.filter(std::move(query))); + return create_instance(ctx, collection.filter(std::move(query)).apply_ordering(std::move(ordering))); } template diff --git a/src/object-store b/src/object-store index 436c1112..dbbd3d92 160000 --- a/src/object-store +++ b/src/object-store @@ -1 +1 @@ -Subproject commit 436c1112337ee68fc65655c2a253997c5dcf458f +Subproject commit dbbd3d9212e608359fc8297fb9c29433e9a13724 diff --git a/tests/js/query-tests.js b/tests/js/query-tests.js index dcc1a1ef..9ccd43fc 100644 --- a/tests/js/query-tests.js +++ b/tests/js/query-tests.js @@ -154,5 +154,8 @@ module.exports = { }, testOptionalQueries: function() { runQuerySuite(testCases.optionalTests); + }, + testOrderingQueries: function() { + runQuerySuite(testCases.orderingTests); } }; diff --git a/tests/js/query-tests.json b/tests/js/query-tests.json index db9636cc..678e0f5b 100644 --- a/tests/js/query-tests.json +++ b/tests/js/query-tests.json @@ -377,6 +377,33 @@ ["ObjectSet", [1], "LinkTypesObject", "basicLink.dateCol == null"], ["ObjectSet", [0], "LinkTypesObject", "basicLink.dateCol != null"] ] -} +}, +"orderingTests" : { + "schema" : [ + { "name": "Person", + "properties": [ + { "name": "id", "type": "int"}, + { "name": "name", "type": "string" }, + { "name": "age", "type": "int"} + ], + "primaryKey" : "id" } + ], + "objects": [ + { "type": "Person", "value": [0, "John", 28] }, + { "type": "Person", "value": [1, "John", 37] }, + { "type": "Person", "value": [2, "Jake", 27] }, + { "type": "Person", "value": [3, "Jake", 32] }, + { "type": "Person", "value": [4, "Jake", 32] }, + { "type": "Person", "value": [5, "Johnny", 19] } + ], + "tests": [ + ["ObjectSet", [1, 3], "Person", "age > 20 SORT(age DESC) DISTINCT(name)"], + ["ObjectSet", [2, 0], "Person", "age > 20 SORT(age ASC) DISTINCT(name)"], + ["ObjectSet", [2, 0], "Person", "age > 20 SORT(age ASC, name DESC) DISTINCT(name)"], + ["ObjectSet", [2, 0], "Person", "age > 20 SORT(name DESC) SORT(age ASC) DISTINCT(name)"], + ["ObjectSet", [2, 0, 3, 1], "Person", "age > 20 SORT(age ASC, name DESC) DISTINCT(name, age)"], + ["ObjectSet", [0, 2], "Person", "age > 20 SORT(age ASC) DISTINCT(age) SORT(name DESC) DISTINCT(name)"] + ] +} }