support sorting by a single property

This commit is contained in:
Ari Lazier 2015-09-03 15:46:31 -07:00
parent cc0f821a99
commit 870fe78aad
4 changed files with 85 additions and 6 deletions

View File

@ -59,6 +59,32 @@ void ResultsPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAc
}
}
JSValueRef SortByProperty(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try {
Results *results = RJSGetInternal<Results *>(thisObject);
RJSValidateArgumentRange(argumentCount, 1, 2);
std::string propName = RJSValidatedStringForValue(ctx, arguments[0]);
Property *prop = results->object_schema.property_for_name(propName);
if (!prop) {
throw std::runtime_error("Property '" + propName + "' does not exist on object type '" + results->object_schema.name + "'");
}
bool ascending = true;
if (argumentCount == 2) {
ascending = RJSValidatedValueToBool(ctx, arguments[1]);
}
SortOrder sort = {{prop->table_column}, {ascending}};
results->setSort(sort);
}
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);
return RJSWrapObject<Results *>(ctx, RJSResultsClass(), new Results(realm, realm->config().schema->at(className), table->where()));
@ -83,6 +109,10 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl
JSClassRef RJSResultsClass() {
static JSClassRef s_objectClass = RJSCreateWrapperClass<Object>("Results", ResultsGetProperty, NULL, NULL, NULL, ResultsPropertyNames);
const JSStaticFunction resultsFuncs[] = {
{"sortByProperty", SortByProperty, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL},
};
static JSClassRef s_objectClass = RJSCreateWrapperClass<Object>("Results", ResultsGetProperty, NULL, resultsFuncs, NULL, ResultsPropertyNames);
return s_objectClass;
}

View File

@ -21,17 +21,26 @@
using namespace realm;
Results::Results(SharedRealm &r, ObjectSchema &o, Query q) :
Results::Results(SharedRealm &r, ObjectSchema &o, Query q, SortOrder s) :
realm(r), object_schema(o), backing_query(q), table_view(backing_query.find_all())
{
setSort(std::move(s));
}
size_t Results::size() {
size_t Results::size()
{
verify_attached();
return table_view.size();
}
Row Results::get(std::size_t row_ndx) {
void Results::setSort(SortOrder s)
{
sort_order = std::make_unique<SortOrder>(std::move(s));
table_view.sort(sort_order->columnIndices, sort_order->ascending);
}
Row Results::get(std::size_t row_ndx)
{
verify_attached();
if (row_ndx >= table_view.size()) {
throw std::range_error(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." +
@ -40,7 +49,8 @@ Row Results::get(std::size_t row_ndx) {
return table_view.get(row_ndx);
}
void Results::verify_attached() {
void Results::verify_attached()
{
if (!table_view.is_attached()) {
throw std::runtime_error("Tableview is not attached");
}

View File

@ -23,8 +23,19 @@
#import <realm/table_view.hpp>
namespace realm {
struct SortOrder {
std::vector<size_t> columnIndices;
std::vector<bool> ascending;
explicit operator bool() const {
return !columnIndices.empty();
}
};
static SortOrder s_defaultSort = {{}, {}};
struct Results {
Results(SharedRealm &r, ObjectSchema &o, Query q);
Results(SharedRealm &r, ObjectSchema &o, Query q, SortOrder s = s_defaultSort);
size_t size();
Row get(std::size_t row_ndx);
void verify_attached();
@ -33,6 +44,9 @@ namespace realm {
ObjectSchema &object_schema;
Query backing_query;
TableView table_view;
std::unique_ptr<SortOrder> sort_order;
void setSort(SortOrder s);
};
}

View File

@ -74,4 +74,29 @@ var ResultsTests = {
}
TestCase.assertEqual(1, count);
},
testSort: function() {
var realm = new Realm({schema: [TestObjectSchema]});
var objects = realm.objects('TestObject');
realm.write(function() {
realm.create('TestObject', [2]);
realm.create('TestObject', [3]);
realm.create('TestObject', [1]);
realm.create('TestObject', [4]);
realm.create('TestObject', [0]);
});
objects.sortByProperty('doubleCol');
TestCase.assertEqual(objects[0].doubleCol, 0);
TestCase.assertEqual(objects[1].doubleCol, 1);
TestCase.assertEqual(objects[2].doubleCol, 2);
TestCase.assertEqual(objects[3].doubleCol, 3);
TestCase.assertEqual(objects[4].doubleCol, 4);
objects.sortByProperty('doubleCol', false);
TestCase.assertEqual(objects[0].doubleCol, 4);
TestCase.assertEqual(objects[1].doubleCol, 3);
TestCase.assertEqual(objects[2].doubleCol, 2);
TestCase.assertEqual(objects[3].doubleCol, 1);
TestCase.assertEqual(objects[4].doubleCol, 0);
},
}