mirror of
https://github.com/status-im/realm-js.git
synced 2025-02-02 09:46:28 +00:00
Add sorted() method to List
This commit is contained in:
parent
d847fbceb1
commit
5332131c14
@ -18,6 +18,7 @@ class List {}
|
||||
// Non-mutating methods:
|
||||
util.createMethods(List.prototype, objectTypes.LIST, [
|
||||
'filtered',
|
||||
'sorted',
|
||||
'snapshot',
|
||||
]);
|
||||
|
||||
|
@ -15,8 +15,8 @@ class Results {}
|
||||
|
||||
util.createMethods(Results.prototype, constants.objectTypes.RESULTS, [
|
||||
'filtered',
|
||||
'snapshot',
|
||||
'sorted',
|
||||
'snapshot',
|
||||
]);
|
||||
|
||||
function create(realmId, info) {
|
||||
|
@ -191,6 +191,7 @@ JSValueRef ListStaticResults(JSContextRef ctx, JSObjectRef function, JSObjectRef
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(thisObject);
|
||||
RJSValidateArgumentCount(argumentCount, 0);
|
||||
|
||||
return RJSResultsCreate(ctx, list->realm(), list->get_object_schema(), std::move(list->get_query()), false);
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
@ -204,10 +205,10 @@ JSValueRef ListStaticResults(JSContextRef ctx, JSObjectRef function, JSObjectRef
|
||||
JSValueRef ListFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(thisObject);
|
||||
|
||||
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
|
||||
|
||||
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
|
||||
return RJSResultsCreate(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments);
|
||||
return RJSResultsCreateFiltered(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments);
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
@ -217,7 +218,23 @@ JSValueRef ListFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef this
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list) {
|
||||
JSValueRef ListSorted(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
List *list = RJSGetInternal<List *>(thisObject);
|
||||
RJSValidateArgumentRange(argumentCount, 1, 2);
|
||||
|
||||
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
|
||||
return RJSResultsCreateSorted(ctx, sharedRealm, list->get_object_schema(), std::move(list->get_query()), argumentCount, arguments);
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
*jsException = RJSMakeError(ctx, exp);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSObjectRef RJSListCreate(JSContextRef ctx, List &list) {
|
||||
return RJSWrapObject<List *>(ctx, RJSListClass(), new List(list));
|
||||
}
|
||||
|
||||
@ -228,6 +245,7 @@ static const JSStaticFunction RJSListFuncs[] = {
|
||||
{"unshift", ListUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"splice", ListSplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"filtered", ListFiltered, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"sorted", ListSorted, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"snapshot", ListStaticResults, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -96,54 +96,8 @@ JSValueRef ResultsSorted(JSContextRef ctx, JSObjectRef function, JSObjectRef thi
|
||||
Results *results = RJSGetInternal<Results *>(thisObject);
|
||||
RJSValidateArgumentRange(argumentCount, 1, 2);
|
||||
|
||||
size_t prop_count;
|
||||
std::vector<std::string> prop_names;
|
||||
std::vector<bool> ascending;
|
||||
|
||||
if (RJSIsValueArray(ctx, arguments[0])) {
|
||||
RJSValidateArgumentCount(argumentCount, 1, "Second argument is not allowed if passed an array of sort descriptors");
|
||||
|
||||
JSObjectRef js_prop_names = RJSValidatedValueToObject(ctx, arguments[0]);
|
||||
prop_count = RJSValidatedListLength(ctx, js_prop_names);
|
||||
if (!prop_count) {
|
||||
throw std::invalid_argument("Sort descriptor array must not be empty");
|
||||
}
|
||||
|
||||
prop_names.resize(prop_count);
|
||||
ascending.resize(prop_count);
|
||||
|
||||
for (unsigned int i = 0; i < prop_count; i++) {
|
||||
JSValueRef val = RJSValidatedPropertyAtIndex(ctx, js_prop_names, i);
|
||||
|
||||
if (RJSIsValueArray(ctx, val)) {
|
||||
prop_names[i] = RJSValidatedStringForValue(ctx, RJSValidatedPropertyAtIndex(ctx, (JSObjectRef)val, 0));
|
||||
ascending[i] = !JSValueToBoolean(ctx, RJSValidatedPropertyAtIndex(ctx, (JSObjectRef)val, 1));
|
||||
}
|
||||
else {
|
||||
prop_names[i] = RJSValidatedStringForValue(ctx, val);
|
||||
ascending[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
prop_count = 1;
|
||||
prop_names.push_back(RJSValidatedStringForValue(ctx, arguments[0]));
|
||||
ascending.push_back(argumentCount == 1 ? true : !JSValueToBoolean(ctx, arguments[1]));
|
||||
}
|
||||
|
||||
std::vector<size_t> columns(prop_count);
|
||||
size_t index = 0;
|
||||
|
||||
for (std::string prop_name : prop_names) {
|
||||
const Property *prop = results->get_object_schema().property_for_name(prop_name);
|
||||
if (!prop) {
|
||||
throw std::runtime_error("Property '" + prop_name + "' does not exist on object type '" + results->get_object_schema().name + "'");
|
||||
}
|
||||
columns[index++] = prop->table_column;
|
||||
}
|
||||
|
||||
results = new Results(results->sort({std::move(columns), std::move(ascending)}));
|
||||
return RJSWrapObject<Results *>(ctx, RJSResultsClass(), results);
|
||||
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
|
||||
return RJSResultsCreateSorted(ctx, sharedRealm, results->get_object_schema(), std::move(results->get_query()), argumentCount, arguments);
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
@ -153,14 +107,13 @@ JSValueRef ResultsSorted(JSContextRef ctx, JSObjectRef function, JSObjectRef thi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
JSValueRef ResultsFiltered(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
Results *results = RJSGetInternal<Results *>(thisObject);
|
||||
|
||||
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
|
||||
|
||||
SharedRealm sharedRealm = *RJSGetInternal<SharedRealm *>(thisObject);
|
||||
return RJSResultsCreate(ctx, sharedRealm, results->get_object_schema(), std::move(results->get_query()), argumentCount, arguments);
|
||||
return RJSResultsCreateFiltered(ctx, sharedRealm, results->get_object_schema(), std::move(results->get_query()), argumentCount, arguments);
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
if (jsException) {
|
||||
@ -194,7 +147,14 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl
|
||||
return RJSWrapObject<Results *>(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, SharedRealm realm, const ObjectSchema &objectSchema, Query query, bool live) {
|
||||
Results *results = new Results(realm, objectSchema, std::move(query));
|
||||
results->set_live(live);
|
||||
|
||||
return RJSWrapObject<Results *>(ctx, RJSResultsClass(), results);
|
||||
}
|
||||
|
||||
JSObjectRef RJSResultsCreateFiltered(JSContextRef ctx, SharedRealm realm, const ObjectSchema &objectSchema, Query query, size_t argumentCount, const JSValueRef arguments[]) {
|
||||
std::string queryString = RJSValidatedStringForValue(ctx, arguments[0], "predicate");
|
||||
std::vector<JSValueRef> args(argumentCount - 1);
|
||||
for (size_t i = 1; i < argumentCount; i++) {
|
||||
@ -208,10 +168,56 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, const r
|
||||
return RJSResultsCreate(ctx, realm, objectSchema, std::move(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);
|
||||
JSObjectRef RJSResultsCreateSorted(JSContextRef ctx, SharedRealm realm, const ObjectSchema &objectSchema, Query query, size_t argumentCount, const JSValueRef arguments[]) {
|
||||
size_t prop_count;
|
||||
std::vector<std::string> prop_names;
|
||||
std::vector<bool> ascending;
|
||||
|
||||
if (RJSIsValueArray(ctx, arguments[0])) {
|
||||
RJSValidateArgumentCount(argumentCount, 1, "Second argument is not allowed if passed an array of sort descriptors");
|
||||
|
||||
JSObjectRef js_prop_names = RJSValidatedValueToObject(ctx, arguments[0]);
|
||||
prop_count = RJSValidatedListLength(ctx, js_prop_names);
|
||||
if (!prop_count) {
|
||||
throw std::invalid_argument("Sort descriptor array must not be empty");
|
||||
}
|
||||
|
||||
prop_names.resize(prop_count);
|
||||
ascending.resize(prop_count);
|
||||
|
||||
for (unsigned int i = 0; i < prop_count; i++) {
|
||||
JSValueRef val = RJSValidatedPropertyAtIndex(ctx, js_prop_names, i);
|
||||
|
||||
if (RJSIsValueArray(ctx, val)) {
|
||||
prop_names[i] = RJSValidatedStringForValue(ctx, RJSValidatedPropertyAtIndex(ctx, (JSObjectRef)val, 0));
|
||||
ascending[i] = !JSValueToBoolean(ctx, RJSValidatedPropertyAtIndex(ctx, (JSObjectRef)val, 1));
|
||||
}
|
||||
else {
|
||||
prop_names[i] = RJSValidatedStringForValue(ctx, val);
|
||||
ascending[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
RJSValidateArgumentRange(argumentCount, 1, 2);
|
||||
|
||||
prop_count = 1;
|
||||
prop_names.push_back(RJSValidatedStringForValue(ctx, arguments[0]));
|
||||
ascending.push_back(argumentCount == 1 ? true : !JSValueToBoolean(ctx, arguments[1]));
|
||||
}
|
||||
|
||||
std::vector<size_t> columns(prop_count);
|
||||
size_t index = 0;
|
||||
|
||||
for (std::string prop_name : prop_names) {
|
||||
const Property *prop = objectSchema.property_for_name(prop_name);
|
||||
if (!prop) {
|
||||
throw std::runtime_error("Property '" + prop_name + "' does not exist on object type '" + objectSchema.name + "'");
|
||||
}
|
||||
columns[index++] = prop->table_column;
|
||||
}
|
||||
|
||||
Results *results = new Results(realm, objectSchema, std::move(query), {std::move(columns), std::move(ascending)});
|
||||
return RJSWrapObject<Results *>(ctx, RJSResultsClass(), results);
|
||||
}
|
||||
|
||||
|
@ -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<JSValueRef> 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, realm::Query query, bool live = true);
|
||||
|
||||
JSObjectRef RJSResultsCreateFiltered(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, size_t argumentCount, const JSValueRef arguments[]);
|
||||
JSObjectRef RJSResultsCreateSorted(JSContextRef ctx, realm::SharedRealm realm, const realm::ObjectSchema &objectSchema, realm::Query query, size_t argumentCount, const JSValueRef arguments[]);
|
||||
|
@ -445,29 +445,54 @@ module.exports = BaseTest.extend({
|
||||
},
|
||||
|
||||
testListFiltered: function() {
|
||||
var personListSchema = {
|
||||
name: 'PersonList',
|
||||
properties: {
|
||||
list: {type: 'list', objectType: 'PersonObject'}
|
||||
}
|
||||
};
|
||||
var realm = new Realm({schema: [schemas.PersonObject, personListSchema]});
|
||||
var listObject;
|
||||
var realm = new Realm({schema: [schemas.PersonObject, schemas.PersonList]});
|
||||
var list;
|
||||
|
||||
realm.write(function() {
|
||||
listObject = realm.create('PersonList', {list: [
|
||||
var object = 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});
|
||||
|
||||
list = object.list;
|
||||
});
|
||||
|
||||
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);
|
||||
},
|
||||
|
||||
testListSorted: function() {
|
||||
var realm = new Realm({schema: [schemas.PersonObject, schemas.PersonList]});
|
||||
var list;
|
||||
|
||||
realm.write(function() {
|
||||
var object = 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});
|
||||
|
||||
list = object.list;
|
||||
});
|
||||
|
||||
var names = function(results, prop) {
|
||||
return Array.prototype.map.call(results, function(object) {
|
||||
return object.name;
|
||||
});
|
||||
};
|
||||
|
||||
var objects = list.sorted('name', true);
|
||||
TestCase.assertArraysEqual(names(objects), ['Tim', 'Bjarne', 'Ari', 'Alex']);
|
||||
|
||||
objects = list.sorted(['age', 'name']);
|
||||
TestCase.assertArraysEqual(names(objects), ['Ari', 'Tim', 'Alex', 'Bjarne']);
|
||||
},
|
||||
});
|
||||
|
@ -135,7 +135,7 @@ module.exports = BaseTest.extend({
|
||||
realm.objects('PersonObject').filtered("invalidQuery");
|
||||
});
|
||||
},
|
||||
testSort: function() {
|
||||
testResultsSorted: function() {
|
||||
var realm = new Realm({schema: [schemas.IntPrimary]});
|
||||
var objects = realm.objects('IntPrimaryObject');
|
||||
|
||||
|
@ -27,6 +27,13 @@ PersonObject.prototype.description = function() {
|
||||
};
|
||||
exports.PersonObject = PersonObject;
|
||||
|
||||
exports.PersonList = {
|
||||
name: 'PersonList',
|
||||
properties: {
|
||||
list: {type: 'list', objectType: 'PersonObject'},
|
||||
}
|
||||
};
|
||||
|
||||
exports.BasicTypes = {
|
||||
name: 'BasicTypesObject',
|
||||
properties: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user