From e91ef42ebbed712b739190fbc967ad30923b9acc Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:06:42 -0800 Subject: [PATCH 1/8] add filtered method --- src/js_realm.cpp | 15 ++------------- src/js_results.cpp | 31 +++++++++++++++++++++++++++++++ tests/lib/query-tests.js | 24 +++++++++++++++--------- tests/lib/realm-tests.js | 36 ++---------------------------------- tests/lib/results-tests.js | 38 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 56 deletions(-) diff --git a/src/js_realm.cpp b/src/js_realm.cpp index 11d9fbc6..c2196ce5 100644 --- a/src/js_realm.cpp +++ b/src/js_realm.cpp @@ -226,21 +226,10 @@ JSValueRef RealmGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr JSValueRef RealmObjects(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { try { - RJSValidateArgumentCountIsAtLeast(argumentCount, 1); + RJSValidateArgumentCount(1, argumentCount); std::string className = RJSValidatedStringForValue(ctx, arguments[0], "objectType"); SharedRealm sharedRealm = *RJSGetInternal(thisObject); - - if (argumentCount == 1) { - return RJSResultsCreate(ctx, sharedRealm, className); - } - else { - std::string query = RJSValidatedStringForValue(ctx, arguments[1], "predicate"); - std::vector args; - for (size_t i = 2; i < argumentCount; i++) { - args.push_back(arguments[i]); - } - return RJSResultsCreate(ctx, sharedRealm, className, query, args); - } + return RJSResultsCreate(ctx, sharedRealm, className); } catch (std::exception &exp) { if (jsException) { diff --git a/src/js_results.cpp b/src/js_results.cpp index fb242ce3..f05d7b57 100644 --- a/src/js_results.cpp +++ b/src/js_results.cpp @@ -117,6 +117,36 @@ JSValueRef ResultsSortByProperty(JSContextRef ctx, JSObjectRef function, JSObjec return NULL; } + +JSValueRef ResultsFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { + try { + Results *results = RJSGetInternal(thisObject); + + RJSValidateArgumentCountIsAtLeast(argumentCount, 1); + SharedRealm sharedRealm = *RJSGetInternal(thisObject); + + std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); + std::vector args; + for (size_t i = 1; i < argumentCount; i++) { + args.push_back(arguments[i]); + } + + parser::Predicate predicate = parser::parse(queryString); + query_builder::ArgumentConverter arguments(ctx, args); + Query query = results->get_query(); + query_builder::apply_predicate(query, predicate, arguments, *sharedRealm->config().schema, + results->get_object_schema().name); + + return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), query); + } + catch (std::exception &exp) { + if (jsException) { + *jsException = RJSMakeError(ctx, exp); + } + } + return NULL; +} + JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string className) { TableRef table = ObjectStore::table_for_object_type(realm->read_group(), className); auto object_schema = realm->config().schema->find(className); @@ -151,6 +181,7 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, const ObjectSc static const JSStaticFunction RJSResultsFuncs[] = { {"snapshot", ResultsStaticCopy, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"sortByProperty", ResultsSortByProperty, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"filtered", ResultsFiltered, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL}, }; diff --git a/tests/lib/query-tests.js b/tests/lib/query-tests.js index 7ad8d6a5..2dd9fd60 100644 --- a/tests/lib/query-tests.js +++ b/tests/lib/query-tests.js @@ -46,10 +46,9 @@ function runQuerySuite(suite) { } }); - var args; function getArgs(startArg) { - args = test.slice(startArg, startArg + 2); - for (var i = startArg + 2; i < test.length; i++) { + var args = [test[startArg]]; + for (var i = startArg + 1; i < test.length; i++) { var arg = test[i]; if (Array.isArray(arg)) { // aray arguments correspond to [objectAtIndex, propertyName] @@ -65,14 +64,20 @@ function runQuerySuite(suite) { for (var index in suite.tests) { var test = suite.tests[index]; if (test[0] == "QueryCount") { - var length = realm.objects.apply(realm, getArgs(2)).length; - TestCase.assertEqual(test[1], length, "Query '" + args[1] + "' on type '" + args[0] + "' expected " + test[1] + " results, got " + length); + var type = test[2]; + var args = getArgs(3); + var objects = realm.objects(type); + var length = objects.filtered.apply(objects, args).length; + TestCase.assertEqual(test[1], length, "Query '" + args[0] + "' on type '" + type + "' expected " + test[1] + " results, got " + length); } else if (test[0] == "ObjectSet") { - var results = realm.objects.apply(realm, getArgs(2)); - TestCase.assertEqual(test[1].length, results.length, "Query '" + args[1] + "' on type '" + args[0] + "' expected " + test[1].length + " results, got " + results.length); + var type = test[2]; + var args = getArgs(3); + var objects = realm.objects(type); + var results = objects.filtered.apply(objects, args); + TestCase.assertEqual(test[1].length, results.length, "Query '" + args[0] + "' on type '" + type+ "' expected " + test[1].length + " results, got " + results.length); - var objSchema = suite.schema.find(function(el) { return el.name == args[0] }); + var objSchema = suite.schema.find(function(el) { return el.name == type }); var primary = objSchema.primaryKey; if (!primary) { throw "Primary key required for object comparison"; @@ -84,7 +89,8 @@ function runQuerySuite(suite) { } else if (test[0] == "QueryThrows") { TestCase.assertThrows(function() { - realm.objects.apply(realm, getArgs(1)); + var args = getArgs(2); + realm.objects.apply(realm, args); }, "Expected exception not thrown for query: " + JSON.stringify(args)); } else if (test[0] != "Disabled") { diff --git a/tests/lib/realm-tests.js b/tests/lib/realm-tests.js index 42649448..c19736e2 100644 --- a/tests/lib/realm-tests.js +++ b/tests/lib/realm-tests.js @@ -290,7 +290,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(objects[0].doubleCol, 7, "wrong property value"); TestCase.assertEqual(objects[1].doubleCol, 8, "wrong property value"); - var threeObjects = realm.objects('TestObject', "doubleCol < 5"); + var threeObjects = realm.objects('TestObject').filtered("doubleCol < 5"); TestCase.assertEqual(threeObjects.length, 3, "wrong results count"); realm.delete(threeObjects); TestCase.assertEqual(objects.length, 4, 'wrong object count'); @@ -341,40 +341,8 @@ module.exports = BaseTest.extend({ realm.objects('InvalidClass'); }); TestCase.assertThrows(function() { - realm.objects('PersonObject', 'invalid query'); + realm.objects('PersonObject', 'truepredicate'); }); - TestCase.assertThrows(function() { - realm.objects('PersonObject', []); - }); - - TestCase.assertEqual(realm.objects('PersonObject', "truepredicate").length, 4); - TestCase.assertEqual(realm.objects('PersonObject').length, 4); - TestCase.assertEqual(realm.objects('PersonObject', 'age = 11').length, 1); - TestCase.assertEqual(realm.objects('PersonObject', 'age = 11')[0].name, 'Tim'); - TestCase.assertEqual(realm.objects('PersonObject', 'age = 12').length, 2); - TestCase.assertEqual(realm.objects('PersonObject', 'age = 13').length, 0); - TestCase.assertEqual(realm.objects('PersonObject', 'age < 12').length, 2); - TestCase.assertEqual(realm.objects('PersonObject', 'age > 10 && age < 13').length, 3); - TestCase.assertEqual(realm.objects('PersonObject', 'age >= 11 && age < 13').length, 3); - TestCase.assertEqual(realm.objects('PersonObject', 'name = "Tim"').length, 1); - TestCase.assertEqual(realm.objects('PersonObject', 'name = \'Tim\'').length, 1); - TestCase.assertEqual(realm.objects('PersonObject', 'married == TRUE').length, 1); - TestCase.assertEqual(realm.objects('PersonObject', 'married == false').length, 3); - - TestCase.assertEqual(realm.objects('PersonObject', 'name = $0', 'Tim').length, 1); - TestCase.assertEqual(realm.objects('PersonObject', 'age > $1 && age < $0', 13, 10).length, 3); - TestCase.assertThrows(function() { - realm.objects('PersonObject', 'age > $2 && age < $0', 13, 10) - }); - - realm.write(function() { - realm.create('DefaultValuesObject', {'dateCol': new Date(3)}); - realm.create('DefaultValuesObject', {'dateCol': new Date(4)}); - realm.create('DefaultValuesObject', {'dateCol': new Date(5)}); - }); - - TestCase.assertEqual(realm.objects('DefaultValuesObject', 'dateCol > $0', new Date(4)).length, 1); - TestCase.assertEqual(realm.objects('DefaultValuesObject', 'dateCol <= $0', new Date(4)).length, 2); }, testNotifications: function() { diff --git a/tests/lib/results-tests.js b/tests/lib/results-tests.js index 26d088a5..9e0cc86a 100644 --- a/tests/lib/results-tests.js +++ b/tests/lib/results-tests.js @@ -91,6 +91,44 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(count, 1); TestCase.assertEqual(keys.length, 1); }, + testResultsFiltered: function() { + var realm = new Realm({schema: [schemas.PersonObject, schemas.DefaultValues, schemas.TestObject]}); + realm.write(function() { + realm.create('PersonObject', {name: 'Ari', age: 10}); + realm.create('PersonObject', {name: 'Tim', age: 11}); + realm.create('PersonObject', {name: 'Bjarne', age: 12}); + realm.create('PersonObject', {name: 'Alex', age: 12, married: true}); + }); + + TestCase.assertEqual(realm.objects('PersonObject').filtered("truepredicate").length, 4); + TestCase.assertEqual(realm.objects('PersonObject').length, 4); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age = 11').length, 1); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age = 11')[0].name, 'Tim'); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age = 12').length, 2); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age = 13').length, 0); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age < 12').length, 2); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age > 10 && age < 13').length, 3); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age >= 11 && age < 13').length, 3); + TestCase.assertEqual(realm.objects('PersonObject').filtered('name = "Tim"').length, 1); + TestCase.assertEqual(realm.objects('PersonObject').filtered('name = \'Tim\'').length, 1); + TestCase.assertEqual(realm.objects('PersonObject').filtered('married == TRUE').length, 1); + TestCase.assertEqual(realm.objects('PersonObject').filtered('married == false').length, 3); + + TestCase.assertEqual(realm.objects('PersonObject').filtered('name = $0', 'Tim').length, 1); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age > $1 && age < $0', 13, 10).length, 3); + TestCase.assertThrows(function() { + realm.objects('PersonObject').filtered('age > $2 && age < $0', 13, 10) + }); + + realm.write(function() { + realm.create('DefaultValuesObject', {'dateCol': new Date(3)}); + realm.create('DefaultValuesObject', {'dateCol': new Date(4)}); + realm.create('DefaultValuesObject', {'dateCol': new Date(5)}); + }); + + TestCase.assertEqual(realm.objects('DefaultValuesObject').filtered('dateCol > $0', new Date(4)).length, 1); + TestCase.assertEqual(realm.objects('DefaultValuesObject').filtered('dateCol <= $0', new Date(4)).length, 2); + }, testSort: function() { var realm = new Realm({schema: [schemas.TestObject]}); var objects = realm.objects('TestObject'); From d838d61de44a3aa43c88f2b80d87b64d8413cb99 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:09:39 -0800 Subject: [PATCH 2/8] test query refinement --- tests/lib/results-tests.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/lib/results-tests.js b/tests/lib/results-tests.js index 9e0cc86a..9431fcfd 100644 --- a/tests/lib/results-tests.js +++ b/tests/lib/results-tests.js @@ -108,6 +108,8 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(realm.objects('PersonObject').filtered('age = 13').length, 0); TestCase.assertEqual(realm.objects('PersonObject').filtered('age < 12').length, 2); TestCase.assertEqual(realm.objects('PersonObject').filtered('age > 10 && age < 13').length, 3); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age > 10').filtered('age < 13').length, 3); + TestCase.assertEqual(realm.objects('PersonObject').filtered('age >= 11 && age < 13').length, 3); TestCase.assertEqual(realm.objects('PersonObject').filtered('name = "Tim"').length, 1); TestCase.assertEqual(realm.objects('PersonObject').filtered('name = \'Tim\'').length, 1); From 6d02614eaab7e697edf1145b447b58db5ff31a01 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:24:08 -0800 Subject: [PATCH 3/8] add List.filtered --- src/js_list.cpp | 32 ++++++++++++++++++++++++++++++++ tests/lib/list-tests.js | 27 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/js_list.cpp b/src/js_list.cpp index b99f4be0..c5d35c71 100644 --- a/src/js_list.cpp +++ b/src/js_list.cpp @@ -8,6 +8,9 @@ #include "js_util.hpp" #include "object_accessor.hpp" +#include "parser.hpp" +#include "query_builder.hpp" + #include using RJSAccessor = realm::NativeAccessor; @@ -200,6 +203,34 @@ JSValueRef ListStaticResults(JSContextRef ctx, JSObjectRef function, JSObjectRef return NULL; } +JSValueRef ListFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { + try { + List *list = RJSGetInternal(thisObject); + + RJSValidateArgumentCountIsAtLeast(argumentCount, 1); + SharedRealm sharedRealm = *RJSGetInternal(thisObject); + + std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); + std::vector args; + for (size_t i = 1; i < argumentCount; i++) { + args.push_back(arguments[i]); + } + + parser::Predicate predicate = parser::parse(queryString); + query_builder::ArgumentConverter arguments(ctx, args); + Query query = list->get_query(); + query_builder::apply_predicate(query, predicate, arguments, *sharedRealm->config().schema, list->get_object_schema().name); + + return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), query); + } + catch (std::exception &exp) { + if (jsException) { + *jsException = RJSMakeError(ctx, exp); + } + } + return NULL; +} + JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list) { return RJSWrapObject(ctx, RJSListClass(), new List(list)); } @@ -210,6 +241,7 @@ static const JSStaticFunction RJSListFuncs[] = { {"shift", ListShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"unshift", ListUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"splice", ListSplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {"filtered", ListFiltered, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"snapshot", ListStaticResults, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {NULL, NULL}, }; diff --git a/tests/lib/list-tests.js b/tests/lib/list-tests.js index 0bea2ce0..6876cddd 100644 --- a/tests/lib/list-tests.js +++ b/tests/lib/list-tests.js @@ -443,4 +443,31 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(arrayCopy[0], null); }); }, + + testListFiltered: function() { + var personListSchema = { + name: 'PersonList', + properties: { + list: {type: 'list', objectType: 'PersonObject'} + } + }; + var realm = new Realm({schema: [schemas.PersonObject, personListSchema]}); + var listObject; + realm.write(function() { + listObject = realm.create('PersonList', {list: [ + {name: 'Ari', age: 10}, + {name: 'Tim', age: 11}, + {name: 'Bjarne', age: 12}, + {name: 'Alex', age: 12, married: true} + ]}); + realm.create('PersonObject', {name: 'NotInList', age: 10}); + }); + + var list = listObject.list; + TestCase.assertEqual(list.filtered("truepredicate").length, 4); + TestCase.assertEqual(list.filtered('age = 11')[0].name, 'Tim'); + TestCase.assertEqual(list.filtered('age = 12').length, 2); + TestCase.assertEqual(list.filtered('age > 10 && age < 13').length, 3); + TestCase.assertEqual(list.filtered('age > 10').filtered('age < 13').length, 3); + }, }); From 6374a04ed40d1176d06e69f84b3e200aadb9fc02 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:27:10 -0800 Subject: [PATCH 4/8] chrome support for filtered --- lib/lists.js | 1 + lib/results.js | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/lists.js b/lib/lists.js index 3be63612..66dbd08f 100644 --- a/lib/lists.js +++ b/lib/lists.js @@ -17,6 +17,7 @@ class List {} // Non-mutating methods: util.createMethods(List.prototype, objectTypes.LIST, [ + 'filtered', 'snapshot', ]); diff --git a/lib/results.js b/lib/results.js index befc590f..7dbbf75e 100644 --- a/lib/results.js +++ b/lib/results.js @@ -14,6 +14,7 @@ module.exports = { class Results {} util.createMethods(Results.prototype, constants.objectTypes.RESULTS, [ + 'filtered', 'snapshot', 'sortByProperty', ]); From e578b05058dfbec2f3ee827849314a696fa338a4 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:39:29 -0800 Subject: [PATCH 5/8] pr feedback --- src/js_list.cpp | 14 ++------------ src/js_results.cpp | 28 ++++++++++++++++------------ src/js_results.hpp | 2 ++ 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/js_list.cpp b/src/js_list.cpp index c5d35c71..673bcb0b 100644 --- a/src/js_list.cpp +++ b/src/js_list.cpp @@ -6,8 +6,8 @@ #include "js_object.hpp" #include "js_results.hpp" #include "js_util.hpp" -#include "object_accessor.hpp" +#include "object_accessor.hpp" #include "parser.hpp" #include "query_builder.hpp" @@ -210,18 +210,8 @@ JSValueRef ListFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef this RJSValidateArgumentCountIsAtLeast(argumentCount, 1); SharedRealm sharedRealm = *RJSGetInternal(thisObject); - std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); - std::vector args; - for (size_t i = 1; i < argumentCount; i++) { - args.push_back(arguments[i]); - } - - parser::Predicate predicate = parser::parse(queryString); - query_builder::ArgumentConverter arguments(ctx, args); Query query = list->get_query(); - query_builder::apply_predicate(query, predicate, arguments, *sharedRealm->config().schema, list->get_object_schema().name); - - return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), query); + return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), query, argumentCount, arguments); } catch (std::exception &exp) { if (jsException) { diff --git a/src/js_results.cpp b/src/js_results.cpp index f05d7b57..8fae5e7f 100644 --- a/src/js_results.cpp +++ b/src/js_results.cpp @@ -125,19 +125,8 @@ JSValueRef ResultsFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef t RJSValidateArgumentCountIsAtLeast(argumentCount, 1); SharedRealm sharedRealm = *RJSGetInternal(thisObject); - std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); - std::vector args; - for (size_t i = 1; i < argumentCount; i++) { - args.push_back(arguments[i]); - } - - parser::Predicate predicate = parser::parse(queryString); - query_builder::ArgumentConverter arguments(ctx, args); Query query = results->get_query(); - query_builder::apply_predicate(query, predicate, arguments, *sharedRealm->config().schema, - results->get_object_schema().name); - - return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), query); + return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), query, argumentCount, arguments); } catch (std::exception &exp) { if (jsException) { @@ -171,6 +160,21 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl return RJSWrapObject(ctx, RJSResultsClass(), new Results(realm, *object_schema, std::move(query))); } +JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query &query, size_t argumentCount, const JSValueRef arguments[]) { + std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); + std::vector args(argumentCount-1); + for (size_t i = 1; i < argumentCount; i++) { + args[i-1] = arguments[i]; + } + + parser::Predicate predicate = parser::parse(queryString); + query_builder::ArgumentConverter queryArgs(ctx, args); + query_builder::apply_predicate(query, predicate, queryArgs, *realm->config().schema, + objectSchema.name); + + return RJSResultsCreate(ctx, realm, objectSchema, query); +} + JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, const ObjectSchema &objectSchema, const Query &query, bool live) { Results *results = new Results(realm, objectSchema, query); results->set_live(live); diff --git a/src/js_results.hpp b/src/js_results.hpp index 8f6c212b..cc4f0a8e 100644 --- a/src/js_results.hpp +++ b/src/js_results.hpp @@ -16,4 +16,6 @@ namespace realm { JSClassRef RJSResultsClass(); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className, std::string query, std::vector args); +JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query &query, size_t argumentCount, const JSValueRef arguments[]); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, const realm::Query &query, bool live = true); + From 1d01a1db73b261cdf1cb1d75b73f20153da580d5 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:48:27 -0800 Subject: [PATCH 6/8] don't copy query unnecessarily --- src/js_list.cpp | 8 ++------ src/js_results.cpp | 17 +++++++---------- src/js_results.hpp | 4 ++-- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/js_list.cpp b/src/js_list.cpp index 673bcb0b..ba5878c8 100644 --- a/src/js_list.cpp +++ b/src/js_list.cpp @@ -191,9 +191,7 @@ JSValueRef ListStaticResults(JSContextRef ctx, JSObjectRef function, JSObjectRef try { List *list = RJSGetInternal(thisObject); RJSValidateArgumentCount(argumentCount, 0); - - Query query = list->get_query(); - return RJSResultsCreate(ctx, list->realm(), list->get_object_schema(), query, false); + return RJSResultsCreate(ctx, list->realm(), list->get_object_schema(), std::move(list->get_query()), false); } catch (std::exception &exp) { if (jsException) { @@ -209,9 +207,7 @@ JSValueRef ListFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef this RJSValidateArgumentCountIsAtLeast(argumentCount, 1); SharedRealm sharedRealm = *RJSGetInternal(thisObject); - - Query query = list->get_query(); - return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), query, argumentCount, arguments); + return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments); } catch (std::exception &exp) { if (jsException) { diff --git a/src/js_results.cpp b/src/js_results.cpp index 8fae5e7f..8f154b8c 100644 --- a/src/js_results.cpp +++ b/src/js_results.cpp @@ -124,9 +124,7 @@ JSValueRef ResultsFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef t RJSValidateArgumentCountIsAtLeast(argumentCount, 1); SharedRealm sharedRealm = *RJSGetInternal(thisObject); - - Query query = results->get_query(); - return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), query, argumentCount, arguments); + return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), std::move(results->get_query()), argumentCount, arguments); } catch (std::exception &exp) { if (jsException) { @@ -160,23 +158,22 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl return RJSWrapObject(ctx, RJSResultsClass(), new Results(realm, *object_schema, std::move(query))); } -JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query &query, size_t argumentCount, const JSValueRef arguments[]) { +JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, size_t argumentCount, const JSValueRef arguments[]) { std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); - std::vector args(argumentCount-1); + std::vector args( argumentCount - 1 ); for (size_t i = 1; i < argumentCount; i++) { args[i-1] = arguments[i]; } parser::Predicate predicate = parser::parse(queryString); query_builder::ArgumentConverter queryArgs(ctx, args); - query_builder::apply_predicate(query, predicate, queryArgs, *realm->config().schema, - objectSchema.name); + query_builder::apply_predicate(query, predicate, queryArgs, *realm->config().schema, objectSchema.name); - return RJSResultsCreate(ctx, realm, objectSchema, query); + return RJSResultsCreate(ctx, realm, objectSchema, std::move(query)); } -JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, const ObjectSchema &objectSchema, const Query &query, bool live) { - Results *results = new Results(realm, objectSchema, query); +JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, const ObjectSchema &objectSchema, Query query, bool live) { + Results *results = new Results(realm, objectSchema, std::move(query)); results->set_live(live); return RJSWrapObject(ctx, RJSResultsClass(), results); diff --git a/src/js_results.hpp b/src/js_results.hpp index cc4f0a8e..61ef0d07 100644 --- a/src/js_results.hpp +++ b/src/js_results.hpp @@ -16,6 +16,6 @@ namespace realm { JSClassRef RJSResultsClass(); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className, std::string query, std::vector args); -JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query &query, size_t argumentCount, const JSValueRef arguments[]); -JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, const realm::Query &query, bool live = true); +JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, size_t argumentCount, const JSValueRef arguments[]); +JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, bool live = true); From b3486c0d0e5c19471d89cd800a91e166b9ab4071 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 20:51:03 -0800 Subject: [PATCH 7/8] final fixes --- src/js_results.cpp | 2 +- tests/lib/results-tests.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/js_results.cpp b/src/js_results.cpp index 8f154b8c..aca93769 100644 --- a/src/js_results.cpp +++ b/src/js_results.cpp @@ -160,7 +160,7 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, size_t argumentCount, const JSValueRef arguments[]) { std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate"); - std::vector args( argumentCount - 1 ); + std::vector args(argumentCount - 1); for (size_t i = 1; i < argumentCount; i++) { args[i-1] = arguments[i]; } diff --git a/tests/lib/results-tests.js b/tests/lib/results-tests.js index 9431fcfd..dd71f71a 100644 --- a/tests/lib/results-tests.js +++ b/tests/lib/results-tests.js @@ -130,6 +130,10 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(realm.objects('DefaultValuesObject').filtered('dateCol > $0', new Date(4)).length, 1); TestCase.assertEqual(realm.objects('DefaultValuesObject').filtered('dateCol <= $0', new Date(4)).length, 2); + + TestCase.assertThrows(function() { + realm.objects('PersonObject').filtered("invalidQuery"); + }); }, testSort: function() { var realm = new Realm({schema: [schemas.TestObject]}); From eb43699d414e61f38dd151adfcf2bd6ad94a01a1 Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Wed, 17 Feb 2016 21:23:43 -0800 Subject: [PATCH 8/8] fix for examples --- examples/ReactExample/components/todo-app.js | 5 +++-- examples/ReactNativeBenchmarks/benchmarks.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/ReactExample/components/todo-app.js b/examples/ReactExample/components/todo-app.js index 375163ae..e0878651 100644 --- a/examples/ReactExample/components/todo-app.js +++ b/examples/ReactExample/components/todo-app.js @@ -52,9 +52,10 @@ export default class TodoApp extends Component { } render() { + let objects = realm.objects('Todo'); let extraItems = [ - {name: 'Complete', items: realm.objects('Todo', 'done = true')}, - {name: 'Incomplete', items: realm.objects('Todo', 'done = false')}, + {name: 'Complete', items: objects.filtered('done = true')}, + {name: 'Incomplete', items: objects.filtered('Todo', 'done = false')}, ]; let route = { diff --git a/examples/ReactNativeBenchmarks/benchmarks.js b/examples/ReactNativeBenchmarks/benchmarks.js index 638607c4..e8481a2f 100644 --- a/examples/ReactNativeBenchmarks/benchmarks.js +++ b/examples/ReactNativeBenchmarks/benchmarks.js @@ -135,12 +135,12 @@ class RealmTests extends Tests { } async querycount() { - let objects = this.realm.objects('TestObject', 'int = 0 and double < ' + numBatchTestObjects / 2); + let objects = this.realm.objects('TestObject').filtered('int = 0 and double < ' + numBatchTestObjects / 2); return objects.length; } async queryenum() { - let objects = this.realm.objects('TestObject', 'int = 0 and double < ' + numBatchTestObjects / 2); + let objects = this.realm.objects('TestObject').filtered('int = 0 and double < ' + numBatchTestObjects / 2); let len = objects.length; for (let i = 0; i < len; i++) { var obj = objects[i];