Merge pull request #60 from realm/al-os
First pass at object_store refactor
This commit is contained in:
commit
4cf19d0e87
|
@ -21,8 +21,8 @@
|
|||
02601F121BA10228007C91FF /* transact_log_handler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 02601F101BA10228007C91FF /* transact_log_handler.hpp */; };
|
||||
0270BC4C1B7CFC0D00010E03 /* RealmJS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC3E1B7CFC0D00010E03 /* RealmJS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
0270BC4D1B7CFC0D00010E03 /* RealmJS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */; };
|
||||
0270BC4E1B7CFC0D00010E03 /* RJSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC401B7CFC0D00010E03 /* RJSArray.cpp */; };
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSArray.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC411B7CFC0D00010E03 /* RJSArray.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC4E1B7CFC0D00010E03 /* RJSList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC401B7CFC0D00010E03 /* RJSList.cpp */; };
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSList.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC411B7CFC0D00010E03 /* RJSList.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC421B7CFC0D00010E03 /* RJSObject.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC511B7CFC0D00010E03 /* RJSObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC431B7CFC0D00010E03 /* RJSObject.mm */; };
|
||||
0270BC521B7CFC0D00010E03 /* RJSRealm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC441B7CFC0D00010E03 /* RJSRealm.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
|
@ -33,7 +33,6 @@
|
|||
0270BC571B7CFC0D00010E03 /* RJSSchema.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC491B7CFC0D00010E03 /* RJSSchema.mm */; };
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC4A1B7CFC0D00010E03 /* RJSUtil.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC591B7CFC0D00010E03 /* RJSUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC4B1B7CFC0D00010E03 /* RJSUtil.mm */; };
|
||||
0270BC671B7CFC1C00010E03 /* object_accessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC5C1B7CFC1C00010E03 /* object_accessor.cpp */; };
|
||||
0270BC681B7CFC1C00010E03 /* object_accessor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC5D1B7CFC1C00010E03 /* object_accessor.hpp */; };
|
||||
0270BC691B7CFC1C00010E03 /* object_schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC5E1B7CFC1C00010E03 /* object_schema.cpp */; };
|
||||
0270BC6A1B7CFC1C00010E03 /* object_schema.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC5F1B7CFC1C00010E03 /* object_schema.hpp */; };
|
||||
|
@ -54,6 +53,8 @@
|
|||
0270BCD11B7D067300010E03 /* RealmReactModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0270BCD01B7D067300010E03 /* RealmReactModule.m */; };
|
||||
02B29A311B7CF86D008A7E6B /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CB11AE99CEC009B348C /* RealmJS.framework */; };
|
||||
02B58CCE1AE99D4D009B348C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */; };
|
||||
02C0864E1BCDB27000942F9C /* list.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C0864C1BCDB27000942F9C /* list.cpp */; settings = {ASSET_TAGS = (); }; };
|
||||
02C0864F1BCDB27000942F9C /* list.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 02C0864D1BCDB27000942F9C /* list.hpp */; settings = {ASSET_TAGS = (); }; };
|
||||
02D456DA1B7E59A500EE1299 /* ArrayTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02D456D91B7E59A500EE1299 /* ArrayTests.js */; };
|
||||
02D8D1F71B601984006DB49D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
@ -143,8 +144,8 @@
|
|||
02601F101BA10228007C91FF /* transact_log_handler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = transact_log_handler.hpp; path = "src/object-store/transact_log_handler.hpp"; sourceTree = "<group>"; };
|
||||
0270BC3E1B7CFC0D00010E03 /* RealmJS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmJS.h; path = src/RealmJS.h; sourceTree = "<group>"; };
|
||||
0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmJS.mm; path = src/RealmJS.mm; sourceTree = "<group>"; };
|
||||
0270BC401B7CFC0D00010E03 /* RJSArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RJSArray.cpp; path = src/RJSArray.cpp; sourceTree = "<group>"; };
|
||||
0270BC411B7CFC0D00010E03 /* RJSArray.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RJSArray.hpp; path = src/RJSArray.hpp; sourceTree = "<group>"; };
|
||||
0270BC401B7CFC0D00010E03 /* RJSList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RJSList.cpp; path = src/RJSList.cpp; sourceTree = "<group>"; };
|
||||
0270BC411B7CFC0D00010E03 /* RJSList.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RJSList.hpp; path = src/RJSList.hpp; sourceTree = "<group>"; };
|
||||
0270BC421B7CFC0D00010E03 /* RJSObject.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RJSObject.hpp; path = src/RJSObject.hpp; sourceTree = "<group>"; };
|
||||
0270BC431B7CFC0D00010E03 /* RJSObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RJSObject.mm; path = src/RJSObject.mm; sourceTree = "<group>"; };
|
||||
0270BC441B7CFC0D00010E03 /* RJSRealm.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RJSRealm.hpp; path = src/RJSRealm.hpp; sourceTree = "<group>"; };
|
||||
|
@ -156,7 +157,6 @@
|
|||
0270BC4A1B7CFC0D00010E03 /* RJSUtil.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RJSUtil.hpp; path = src/RJSUtil.hpp; sourceTree = "<group>"; };
|
||||
0270BC4B1B7CFC0D00010E03 /* RJSUtil.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RJSUtil.mm; path = src/RJSUtil.mm; sourceTree = "<group>"; };
|
||||
0270BC5A1B7CFC1300010E03 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = src/Info.plist; sourceTree = "<group>"; };
|
||||
0270BC5C1B7CFC1C00010E03 /* object_accessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = object_accessor.cpp; path = "src/object-store/object_accessor.cpp"; sourceTree = "<group>"; };
|
||||
0270BC5D1B7CFC1C00010E03 /* object_accessor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = object_accessor.hpp; path = "src/object-store/object_accessor.hpp"; sourceTree = "<group>"; };
|
||||
0270BC5E1B7CFC1C00010E03 /* object_schema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = object_schema.cpp; path = "src/object-store/object_schema.cpp"; sourceTree = "<group>"; };
|
||||
0270BC5F1B7CFC1C00010E03 /* object_schema.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = object_schema.hpp; path = "src/object-store/object_schema.hpp"; sourceTree = "<group>"; };
|
||||
|
@ -183,6 +183,8 @@
|
|||
02B58CB11AE99CEC009B348C /* RealmJS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RealmJS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
02B58CBC1AE99CEC009B348C /* RealmJSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RealmJSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
02C0864C1BCDB27000942F9C /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = list.cpp; path = "src/object-store/list.cpp"; sourceTree = "<group>"; };
|
||||
02C0864D1BCDB27000942F9C /* list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = list.hpp; path = "src/object-store/list.hpp"; sourceTree = "<group>"; };
|
||||
02D456D91B7E59A500EE1299 /* ArrayTests.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ArrayTests.js; path = tests/ArrayTests.js; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
@ -219,7 +221,6 @@
|
|||
0270BC3D1B7CFBFD00010E03 /* RealmJS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0270BC5C1B7CFC1C00010E03 /* object_accessor.cpp */,
|
||||
0270BC5D1B7CFC1C00010E03 /* object_accessor.hpp */,
|
||||
0270BC5E1B7CFC1C00010E03 /* object_schema.cpp */,
|
||||
0270BC5F1B7CFC1C00010E03 /* object_schema.hpp */,
|
||||
|
@ -234,6 +235,8 @@
|
|||
02601F021BA0F0C4007C91FF /* external_commit_helper.hpp */,
|
||||
02601F051BA0F0CD007C91FF /* index_set.cpp */,
|
||||
02601F061BA0F0CD007C91FF /* index_set.hpp */,
|
||||
02C0864C1BCDB27000942F9C /* list.cpp */,
|
||||
02C0864D1BCDB27000942F9C /* list.hpp */,
|
||||
02601F0B1BA0F3A7007C91FF /* schema.cpp */,
|
||||
02601F0C1BA0F3A7007C91FF /* schema.hpp */,
|
||||
02601F0F1BA10228007C91FF /* transact_log_handler.cpp */,
|
||||
|
@ -243,8 +246,8 @@
|
|||
0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */,
|
||||
02258FB11BC6E2D00075F13A /* RealmRPC.h */,
|
||||
02258FB21BC6E2D00075F13A /* RealmRPC.mm */,
|
||||
0270BC401B7CFC0D00010E03 /* RJSArray.cpp */,
|
||||
0270BC411B7CFC0D00010E03 /* RJSArray.hpp */,
|
||||
0270BC401B7CFC0D00010E03 /* RJSList.cpp */,
|
||||
0270BC411B7CFC0D00010E03 /* RJSList.hpp */,
|
||||
0270BC421B7CFC0D00010E03 /* RJSObject.hpp */,
|
||||
0270BC431B7CFC0D00010E03 /* RJSObject.mm */,
|
||||
0270BC441B7CFC0D00010E03 /* RJSRealm.hpp */,
|
||||
|
@ -337,7 +340,7 @@
|
|||
files = (
|
||||
0270BC4C1B7CFC0D00010E03 /* RealmJS.h in Headers */,
|
||||
02258FB31BC6E2D00075F13A /* RealmRPC.h in Headers */,
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSArray.hpp in Headers */,
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSList.hpp in Headers */,
|
||||
0270BC541B7CFC0D00010E03 /* RJSResults.hpp in Headers */,
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */,
|
||||
0270BC561B7CFC0D00010E03 /* RJSSchema.hpp in Headers */,
|
||||
|
@ -353,6 +356,7 @@
|
|||
02601F041BA0F0C4007C91FF /* external_commit_helper.hpp in Headers */,
|
||||
02601F091BA0F0CD007C91FF /* index_set.hpp in Headers */,
|
||||
0270BC6D1B7CFC1C00010E03 /* property.hpp in Headers */,
|
||||
02C0864F1BCDB27000942F9C /* list.hpp in Headers */,
|
||||
0270BC6F1B7CFC1C00010E03 /* results.hpp in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -563,11 +567,11 @@
|
|||
02601F111BA10228007C91FF /* transact_log_handler.cpp in Sources */,
|
||||
0270BC591B7CFC0D00010E03 /* RJSUtil.mm in Sources */,
|
||||
0270BC551B7CFC0D00010E03 /* RJSResults.mm in Sources */,
|
||||
02C0864E1BCDB27000942F9C /* list.cpp in Sources */,
|
||||
02601F031BA0F0C4007C91FF /* external_commit_helper.cpp in Sources */,
|
||||
0270BC6B1B7CFC1C00010E03 /* object_store.cpp in Sources */,
|
||||
0270BC701B7CFC1C00010E03 /* shared_realm.cpp in Sources */,
|
||||
0270BC671B7CFC1C00010E03 /* object_accessor.cpp in Sources */,
|
||||
0270BC4E1B7CFC0D00010E03 /* RJSArray.cpp in Sources */,
|
||||
0270BC4E1B7CFC0D00010E03 /* RJSList.cpp in Sources */,
|
||||
0270BC531B7CFC0D00010E03 /* RJSRealm.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RJSArray.hpp"
|
||||
#include "RJSList.hpp"
|
||||
#include "RJSObject.hpp"
|
||||
#include "RJSUtil.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
|
@ -24,60 +24,32 @@
|
|||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
||||
size_t ObjectArray::size() {
|
||||
return link_view->size();
|
||||
static inline List * RJSVerifiedList(JSObjectRef object) {
|
||||
List *list = RJSGetInternal<List *>(object);
|
||||
list->verify_attached();
|
||||
return list;
|
||||
}
|
||||
|
||||
Row ObjectArray::get(std::size_t row_ndx) {
|
||||
verify_valid_row(row_ndx);
|
||||
return link_view->get(row_ndx);
|
||||
}
|
||||
|
||||
void ObjectArray::set(std::size_t row_ndx, std::size_t target_row_ndx) {
|
||||
verify_valid_row(row_ndx);
|
||||
link_view->set(row_ndx, target_row_ndx);
|
||||
}
|
||||
|
||||
void ObjectArray::verify_valid_row(std::size_t row_ndx) {
|
||||
size_t size = link_view->size();
|
||||
if (row_ndx >= size) {
|
||||
throw std::out_of_range(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." + std::to_string(size) + ".");
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectArray::verify_attached() {
|
||||
if (!link_view->is_attached()) {
|
||||
throw std::runtime_error("Tableview is not attached");
|
||||
}
|
||||
link_view->sync_if_needed();
|
||||
}
|
||||
|
||||
static inline ObjectArray * RJSVerifiedArray(JSObjectRef object) {
|
||||
ObjectArray *array = RJSGetInternal<ObjectArray *>(object);
|
||||
array->verify_attached();
|
||||
return array;
|
||||
}
|
||||
|
||||
static inline ObjectArray * RJSVerifiedMutableArray(JSObjectRef object) {
|
||||
ObjectArray *array = RJSVerifiedArray(object);
|
||||
if (!array->realm->is_in_transaction()) {
|
||||
static inline List * RJSVerifiedMutableList(JSObjectRef object) {
|
||||
List *list = RJSVerifiedList(object);
|
||||
if (!list->realm->is_in_transaction()) {
|
||||
throw std::runtime_error("Can only mutate lists within a transaction.");
|
||||
}
|
||||
return array;
|
||||
return list;
|
||||
}
|
||||
|
||||
JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
|
||||
JSValueRef ListGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
|
||||
try {
|
||||
// index subscripting
|
||||
ObjectArray *array = RJSVerifiedArray(object);
|
||||
size_t size = array->size();
|
||||
List *list = RJSVerifiedList(object);
|
||||
size_t size = list->size();
|
||||
|
||||
std::string indexStr = RJSStringForJSString(propertyName);
|
||||
if (indexStr == "length") {
|
||||
return JSValueMakeNumber(ctx, size);
|
||||
}
|
||||
|
||||
return RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(RJSValidatedPositiveIndex(indexStr))));
|
||||
return RJSObjectCreate(ctx, Object(list->realm, list->object_schema, list->get(RJSValidatedPositiveIndex(indexStr))));
|
||||
}
|
||||
catch (std::out_of_range &exp) {
|
||||
// getters for nonexistent properties in JS should always return undefined
|
||||
|
@ -95,15 +67,15 @@ JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
|
|||
}
|
||||
}
|
||||
|
||||
bool ArraySetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
|
||||
bool ListSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(object);
|
||||
List *list = RJSVerifiedMutableList(object);
|
||||
std::string indexStr = RJSStringForJSString(propertyName);
|
||||
if (indexStr == "length") {
|
||||
throw std::runtime_error("The 'length' property is readonly.");
|
||||
}
|
||||
|
||||
array->set(RJSValidatedPositiveIndex(indexStr), RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(value), array->object_schema.name, false));
|
||||
list->set(RJSValidatedPositiveIndex(indexStr), RJSAccessor::to_object_index(ctx, list->realm, const_cast<JSValueRef &>(value), list->object_schema.name, false));
|
||||
return true;
|
||||
}
|
||||
catch (std::invalid_argument &exp) {
|
||||
|
@ -118,9 +90,9 @@ bool ArraySetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef property
|
|||
}
|
||||
}
|
||||
|
||||
void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
|
||||
ObjectArray *array = RJSVerifiedArray(object);
|
||||
size_t size = array->size();
|
||||
void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
|
||||
List *list = RJSVerifiedList(object);
|
||||
size_t size = list->size();
|
||||
|
||||
char str[32];
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
|
@ -131,9 +103,9 @@ void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccu
|
|||
}
|
||||
}
|
||||
|
||||
JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
JSValueRef ListPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(thisObject);
|
||||
List *array = RJSVerifiedMutableList(thisObject);
|
||||
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
|
||||
for (size_t i = 0; i < argumentCount; i++) {
|
||||
array->link_view->add(RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
|
||||
|
@ -148,18 +120,18 @@ JSValueRef ArrayPush(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObj
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
JSValueRef ListPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(thisObject);
|
||||
List *list = RJSVerifiedMutableList(thisObject);
|
||||
RJSValidateArgumentCount(argumentCount, 0);
|
||||
|
||||
size_t size = array->size();
|
||||
size_t size = list->size();
|
||||
if (size == 0) {
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
size_t index = size - 1;
|
||||
JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
|
||||
array->link_view->remove(index);
|
||||
JSValueRef obj = RJSObjectCreate(ctx, Object(list->realm, list->object_schema, list->get(index)));
|
||||
list->link_view->remove(index);
|
||||
return obj;
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
|
@ -170,9 +142,9 @@ JSValueRef ArrayPop(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObje
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
JSValueRef ListUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(thisObject);
|
||||
List *array = RJSVerifiedMutableList(thisObject);
|
||||
RJSValidateArgumentCountIsAtLeast(argumentCount, 1);
|
||||
for (size_t i = 0; i < argumentCount; i++) {
|
||||
array->link_view->insert(i, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
|
||||
|
@ -187,15 +159,15 @@ JSValueRef ArrayUnshift(JSContextRef ctx, JSObjectRef function, JSObjectRef this
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
JSValueRef ListShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(thisObject);
|
||||
List *list = RJSVerifiedMutableList(thisObject);
|
||||
RJSValidateArgumentCount(argumentCount, 0);
|
||||
if (array->size() == 0) {
|
||||
if (list->size() == 0) {
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
JSValueRef obj = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(0)));
|
||||
array->link_view->remove(0);
|
||||
JSValueRef obj = RJSObjectCreate(ctx, Object(list->realm, list->object_schema, list->get(0)));
|
||||
list->link_view->remove(0);
|
||||
return obj;
|
||||
}
|
||||
catch (std::exception &exp) {
|
||||
|
@ -206,10 +178,10 @@ JSValueRef ArrayShift(JSContextRef ctx, JSObjectRef function, JSObjectRef thisOb
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
JSValueRef ListSplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
|
||||
try {
|
||||
ObjectArray *array = RJSVerifiedMutableArray(thisObject);
|
||||
size_t size = array->size();
|
||||
List *list = RJSVerifiedMutableList(thisObject);
|
||||
size_t size = list->size();
|
||||
|
||||
RJSValidateArgumentCountIsAtLeast(argumentCount, 2);
|
||||
long index = std::min<long>(RJSValidatedValueToNumber(ctx, arguments[0]), size);
|
||||
|
@ -222,11 +194,11 @@ JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisO
|
|||
|
||||
std::vector<JSObjectRef> removedObjects(remove);
|
||||
for (size_t i = 0; i < remove; i++) {
|
||||
removedObjects[i] = RJSObjectCreate(ctx, Object(array->realm, array->object_schema, array->get(index)));
|
||||
array->link_view->remove(index);
|
||||
removedObjects[i] = RJSObjectCreate(ctx, Object(list->realm, list->object_schema, list->get(index)));
|
||||
list->link_view->remove(index);
|
||||
}
|
||||
for (size_t i = 2; i < argumentCount; i++) {
|
||||
array->link_view->insert(index + i - 2, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(arguments[i]), array->object_schema.name, false));
|
||||
list->link_view->insert(index + i - 2, RJSAccessor::to_object_index(ctx, list->realm, const_cast<JSValueRef &>(arguments[i]), list->object_schema.name, false));
|
||||
}
|
||||
return JSObjectMakeArray(ctx, remove, removedObjects.data(), jsException);
|
||||
}
|
||||
|
@ -238,20 +210,20 @@ JSValueRef ArraySplice(JSContextRef ctx, JSObjectRef function, JSObjectRef thisO
|
|||
return NULL;
|
||||
}
|
||||
|
||||
JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array) {
|
||||
return RJSWrapObject<ObjectArray *>(ctx, RJSArrayClass(), array);
|
||||
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list) {
|
||||
return RJSWrapObject<List *>(ctx, RJSListClass(), new List(list));
|
||||
}
|
||||
|
||||
const JSStaticFunction RJSArrayFuncs[] = {
|
||||
{"push", ArrayPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"pop", ArrayPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"shift", ArrayShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"unshift", ArrayUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"splice", ArraySplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
const JSStaticFunction RJSListFuncs[] = {
|
||||
{"push", ListPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"pop", ListPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"shift", ListShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"unshift", ListUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"splice", ListSplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
JSClassRef RJSArrayClass() {
|
||||
static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, ArraySetProperty, RJSArrayFuncs, NULL, ArrayPropertyNames);
|
||||
return s_arrayClass;
|
||||
JSClassRef RJSListClass() {
|
||||
static JSClassRef s_listClass = RJSCreateWrapperClass<Object>("RealmList", ListGetProperty, ListSetProperty, RJSListFuncs, NULL, ListPropertyNames);
|
||||
return s_listClass;
|
||||
}
|
|
@ -16,4 +16,12 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "object_accessor.hpp"
|
||||
#import "RJSUtil.hpp"
|
||||
#import "shared_realm.hpp"
|
||||
#import "list.hpp"
|
||||
|
||||
extern const JSStaticFunction RJSListFuncs[];
|
||||
JSClassRef RJSListClass();
|
||||
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list);
|
||||
|
||||
JSValueRef ListGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException);
|
|
@ -20,7 +20,7 @@
|
|||
#import "RJSObject.hpp"
|
||||
#import "RJSResults.hpp"
|
||||
#import "RJSSchema.hpp"
|
||||
#import "RJSArray.hpp"
|
||||
#import "RJSList.hpp"
|
||||
|
||||
#import "object_store.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
|
@ -29,49 +29,15 @@ using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
|||
using namespace realm;
|
||||
|
||||
JSValueRef ObjectGetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef* exception) {
|
||||
Object *obj = RJSGetInternal<Object *>(jsObject);
|
||||
|
||||
std::string propName = RJSStringForJSString(jsPropertyName);
|
||||
ObjectSchema &objectSchema = obj->object_schema;
|
||||
Property *prop = objectSchema.property_for_name(propName);
|
||||
if (!prop) {
|
||||
try {
|
||||
Object *obj = RJSGetInternal<Object *>(jsObject);
|
||||
return obj->get_property_value<JSValueRef>(ctx, RJSStringForJSString(jsPropertyName));
|
||||
} catch (std::exception &ex) {
|
||||
if (exception) {
|
||||
*exception = RJSMakeError(ctx, ex);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (prop->type) {
|
||||
case PropertyTypeBool:
|
||||
return JSValueMakeBoolean(ctx, obj->row.get_bool(prop->table_column));
|
||||
case PropertyTypeInt:
|
||||
return JSValueMakeNumber(ctx, obj->row.get_int(prop->table_column));
|
||||
case PropertyTypeFloat:
|
||||
return JSValueMakeNumber(ctx, obj->row.get_float(prop->table_column));
|
||||
case PropertyTypeDouble:
|
||||
return JSValueMakeNumber(ctx, obj->row.get_double(prop->table_column));
|
||||
case PropertyTypeString:
|
||||
return RJSValueForString(ctx, obj->row.get_string(prop->table_column));
|
||||
case PropertyTypeData:
|
||||
return RJSValueForString(ctx, (std::string)obj->row.get_binary(prop->table_column));
|
||||
case PropertyTypeAny:
|
||||
*exception = RJSMakeError(ctx, "'Any' type not supported");
|
||||
return NULL;
|
||||
case PropertyTypeDate: {
|
||||
JSValueRef time = JSValueMakeNumber(ctx, obj->row.get_datetime(prop->table_column).get_datetime());
|
||||
return JSObjectMakeDate(ctx, 1, &time, exception);
|
||||
}
|
||||
case PropertyTypeObject: {
|
||||
auto linkObjectSchema = obj->realm->config().schema->find(prop->object_type);
|
||||
TableRef table = ObjectStore::table_for_object_type(obj->realm->read_group(), linkObjectSchema->name);
|
||||
if (obj->row.is_null_link(prop->table_column)) {
|
||||
return JSValueMakeNull(ctx);
|
||||
}
|
||||
return RJSObjectCreate(ctx, Object(obj->realm, *linkObjectSchema, table->get(obj->row.get_link(prop->table_column))));
|
||||
}
|
||||
case PropertyTypeArray: {
|
||||
auto arrayObjectSchema = obj->realm->config().schema->find(prop->object_type);
|
||||
return RJSArrayCreate(ctx, new ObjectArray(obj->realm, *arrayObjectSchema, static_cast<LinkViewRef>(obj->row.get_linklist(prop->table_column))));
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ObjectSetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef value, JSValueRef* exception) {
|
||||
|
@ -133,6 +99,9 @@ template<> JSValueRef RJSAccessor::default_value_for_property(JSContextRef ctx,
|
|||
template<> bool RJSAccessor::is_null(JSContextRef ctx, JSValueRef &val) {
|
||||
return JSValueIsUndefined(ctx, val) || JSValueIsNull(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::null_value(JSContextRef ctx) {
|
||||
return JSValueMakeNull(ctx);
|
||||
}
|
||||
|
||||
template<> bool RJSAccessor::to_bool(JSContextRef ctx, JSValueRef &val) {
|
||||
if (!JSValueIsBoolean(ctx, val)) {
|
||||
|
@ -140,22 +109,37 @@ template<> bool RJSAccessor::to_bool(JSContextRef ctx, JSValueRef &val) {
|
|||
}
|
||||
return JSValueToBoolean(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_bool(JSContextRef ctx, bool b) {
|
||||
return JSValueMakeBoolean(ctx, b);
|
||||
}
|
||||
|
||||
template<> long long RJSAccessor::to_long(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedValueToNumber(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_long(JSContextRef ctx, long long l) {
|
||||
return JSValueMakeNumber(ctx, l);
|
||||
}
|
||||
|
||||
template<> float RJSAccessor::to_float(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedValueToNumber(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_float(JSContextRef ctx, float f) {
|
||||
return JSValueMakeNumber(ctx, f);
|
||||
}
|
||||
|
||||
template<> double RJSAccessor::to_double(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedValueToNumber(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_double(JSContextRef ctx, double d) {
|
||||
return JSValueMakeNumber(ctx, d);
|
||||
}
|
||||
|
||||
template<> std::string RJSAccessor::to_string(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedStringForValue(ctx, val);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_string(JSContextRef ctx, StringData s) {
|
||||
return RJSValueForString(ctx, s);
|
||||
}
|
||||
|
||||
template<> DateTime RJSAccessor::to_datetime(JSContextRef ctx, JSValueRef &val) {
|
||||
JSObjectRef object = RJSValidatedValueToObject(ctx, val, "Property must be a Date");
|
||||
|
@ -176,6 +160,10 @@ template<> DateTime RJSAccessor::to_datetime(JSContextRef ctx, JSValueRef &val)
|
|||
|
||||
return DateTime(utc);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_datetime(JSContextRef ctx, DateTime dt) {
|
||||
JSValueRef time = JSValueMakeNumber(ctx, dt.get_datetime());
|
||||
return JSObjectMakeDate(ctx, 1, &time, NULL);
|
||||
}
|
||||
|
||||
extern JSObjectRef RJSDictForPropertyArray(JSContextRef ctx, ObjectSchema &object_schema, JSObjectRef array);
|
||||
|
||||
|
@ -193,11 +181,16 @@ template<> size_t RJSAccessor::to_object_index(JSContextRef ctx, SharedRealm &re
|
|||
Object child = Object::create<JSValueRef>(ctx, realm, *object_schema, (JSValueRef)object, try_update);
|
||||
return child.row.get_index();
|
||||
}
|
||||
|
||||
template<> size_t RJSAccessor::array_size(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedArrayLength(ctx, RJSValidatedValueToObject(ctx, val));
|
||||
template<> JSValueRef RJSAccessor::from_object(JSContextRef ctx, Object object) {
|
||||
return RJSObjectCreate(ctx, object);
|
||||
}
|
||||
|
||||
template<> JSValueRef RJSAccessor::array_value_at_index(JSContextRef ctx, JSValueRef &val, size_t index) {
|
||||
template<> size_t RJSAccessor::list_size(JSContextRef ctx, JSValueRef &val) {
|
||||
return RJSValidatedListLength(ctx, RJSValidatedValueToObject(ctx, val));
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::list_value_at_index(JSContextRef ctx, JSValueRef &val, size_t index) {
|
||||
return RJSValidatedObjectAtIndex(ctx, RJSValidatedValueToObject(ctx, val), (unsigned int)index);
|
||||
}
|
||||
template<> JSValueRef RJSAccessor::from_list(JSContextRef ctx, List list) {
|
||||
return RJSListCreate(ctx, list);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#import "RJSRealm.hpp"
|
||||
#import "RJSObject.hpp"
|
||||
#import "RJSResults.hpp"
|
||||
#import "RJSArray.hpp"
|
||||
#import "RJSList.hpp"
|
||||
#import "RJSSchema.hpp"
|
||||
|
||||
#import "shared_realm.hpp"
|
||||
|
@ -221,7 +221,7 @@ JSValueRef RealmObjects(JSContextRef ctx, JSObjectRef function, JSObjectRef this
|
|||
|
||||
JSObjectRef RJSDictForPropertyArray(JSContextRef ctx, ObjectSchema &object_schema, JSObjectRef array) {
|
||||
// copy to dictionary
|
||||
if (object_schema.properties.size() != RJSValidatedArrayLength(ctx, array)) {
|
||||
if (object_schema.properties.size() != RJSValidatedListLength(ctx, array)) {
|
||||
throw std::runtime_error("Array must contain values for all object properties");
|
||||
}
|
||||
|
||||
|
@ -280,10 +280,10 @@ JSValueRef RealmDelete(JSContextRef ctx, JSObjectRef function, JSObjectRef thisO
|
|||
|
||||
if (RJSIsValueArray(ctx, arguments[0]) ||
|
||||
JSValueIsObjectOfClass(ctx, arguments[0], RJSResultsClass()) ||
|
||||
JSValueIsObjectOfClass(ctx, arguments[0], RJSArrayClass()))
|
||||
JSValueIsObjectOfClass(ctx, arguments[0], RJSListClass()))
|
||||
{
|
||||
JSObjectRef array = RJSValidatedValueToObject(ctx, arguments[0]);
|
||||
size_t length = RJSValidatedArrayLength(ctx, array);
|
||||
size_t length = RJSValidatedListLength(ctx, array);
|
||||
for (long i = length-1; i >= 0; i--) {
|
||||
JSValueRef object = RJSValidatedObjectAtIndex(ctx, array, (unsigned int)i);
|
||||
RealmDelete(ctx, function, thisObject, 1, &object, jsException);
|
||||
|
|
|
@ -127,7 +127,7 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
|||
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
||||
objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);
|
||||
|
||||
size_t numProperties = RJSValidatedArrayLength(ctx, propertiesObject);
|
||||
size_t numProperties = RJSValidatedListLength(ctx, propertiesObject);
|
||||
for (unsigned int p = 0; p < numProperties; p++) {
|
||||
JSObjectRef property = RJSValidatedObjectAtIndex(ctx, propertiesObject, p);
|
||||
objectSchema.properties.emplace_back(RJSParseProperty(ctx, property));
|
||||
|
@ -163,7 +163,7 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
|||
|
||||
realm::Schema RJSParseSchema(JSContextRef ctx, JSObjectRef jsonObject) {
|
||||
std::vector<ObjectSchema> schema;
|
||||
size_t length = RJSValidatedArrayLength(ctx, jsonObject);
|
||||
size_t length = RJSValidatedListLength(ctx, jsonObject);
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
JSObjectRef jsonObjectSchema = RJSValidatedObjectAtIndex(ctx, jsonObject, i);
|
||||
ObjectSchema objectSchema = RJSParseObjectSchema(ctx, jsonObjectSchema);
|
||||
|
|
|
@ -161,7 +161,7 @@ static inline std::string RJSValidatedStringProperty(JSContextRef ctx, JSObjectR
|
|||
return RJSValidatedStringForValue(ctx, propertyValue);
|
||||
}
|
||||
|
||||
static inline size_t RJSValidatedArrayLength(JSContextRef ctx, JSObjectRef object) {
|
||||
static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object) {
|
||||
JSValueRef exception = NULL;
|
||||
static JSStringRef lengthString = JSStringCreateWithUTF8CString("length");
|
||||
JSValueRef lengthValue = JSObjectGetProperty(ctx, object, lengthString, &exception);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "RealmJS.h"
|
||||
#include "RJSObject.hpp"
|
||||
#include "RJSResults.hpp"
|
||||
#include "RJSArray.hpp"
|
||||
#include "RJSList.hpp"
|
||||
#include "RJSRealm.hpp"
|
||||
#include "RJSUtil.hpp"
|
||||
|
||||
|
@ -140,7 +140,7 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
|||
|
||||
JSValueRef exception = NULL;
|
||||
static JSStringRef lengthPropertyName = JSStringCreateWithUTF8CString("length");
|
||||
JSValueRef lengthValue = ArrayGetProperty(_context, _objects[listId], lengthPropertyName, &exception);
|
||||
JSValueRef lengthValue = ListGetProperty(_context, _objects[listId], lengthPropertyName, &exception);
|
||||
size_t length = JSValueToNumber(_context, lengthValue, &exception);
|
||||
|
||||
if (exception) {
|
||||
|
@ -154,7 +154,7 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
|||
|
||||
JSValueRef exception = NULL;
|
||||
JSStringRef indexPropertyName = JSStringCreateWithUTF8CString(std::to_string(index).c_str());
|
||||
JSValueRef objectValue = ArrayGetProperty(_context, _objects[listId], indexPropertyName, &exception);
|
||||
JSValueRef objectValue = ListGetProperty(_context, _objects[listId], indexPropertyName, &exception);
|
||||
JSStringRelease(indexPropertyName);
|
||||
|
||||
if (exception) {
|
||||
|
@ -166,7 +166,7 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
|||
_requests["/call_list_method"] = [=](NSDictionary *dict) {
|
||||
NSString *name = dict[@"name"];
|
||||
return [self performObjectMethod:name.UTF8String
|
||||
classMethods:RJSArrayFuncs
|
||||
classMethods:RJSListFuncs
|
||||
args:dict[@"arguments"]
|
||||
objectId:[dict[@"listId"] unsignedLongValue]];
|
||||
};
|
||||
|
@ -249,14 +249,14 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
|||
@"schema": [self objectSchemaToJSONObject:object->object_schema]
|
||||
};
|
||||
}
|
||||
else if (JSValueIsObjectOfClass(_context, value, RJSArrayClass())) {
|
||||
realm::ObjectArray *array = RJSGetInternal<realm::ObjectArray *>(jsObject);
|
||||
else if (JSValueIsObjectOfClass(_context, value, RJSListClass())) {
|
||||
realm::List *list = RJSGetInternal<realm::List *>(jsObject);
|
||||
RPCObjectID oid = [self storeObject:jsObject];
|
||||
return @{
|
||||
@"type": @(RJSTypeGet(realm::PropertyTypeArray).c_str()),
|
||||
@"id": @(oid),
|
||||
@"size": @(array->link_view->size()),
|
||||
@"schema": [self objectSchemaToJSONObject:array->object_schema]
|
||||
@"size": @(list->link_view->size()),
|
||||
@"schema": [self objectSchemaToJSONObject:list->object_schema]
|
||||
};
|
||||
}
|
||||
else if (JSValueIsObjectOfClass(_context, value, RJSResultsClass())) {
|
||||
|
@ -270,7 +270,7 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
|||
};
|
||||
}
|
||||
else if (RJSIsValueArray(_context, value)) {
|
||||
size_t length = RJSValidatedArrayLength(_context, jsObject);
|
||||
size_t length = RJSValidatedListLength(_context, jsObject);
|
||||
NSMutableArray *array = [NSMutableArray new];
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
[array addObject:[self resultForJSValue:JSObjectGetPropertyAtIndex(_context, jsObject, i, NULL)]];
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "list.hpp"
|
||||
#import <stdexcept>
|
||||
|
||||
using namespace realm;
|
||||
|
||||
size_t List::size() {
|
||||
return link_view->size();
|
||||
}
|
||||
|
||||
Row List::get(std::size_t row_ndx) {
|
||||
verify_valid_row(row_ndx);
|
||||
return link_view->get(row_ndx);
|
||||
}
|
||||
|
||||
void List::set(std::size_t row_ndx, std::size_t target_row_ndx) {
|
||||
verify_valid_row(row_ndx);
|
||||
link_view->set(row_ndx, target_row_ndx);
|
||||
}
|
||||
|
||||
void List::verify_valid_row(std::size_t row_ndx) {
|
||||
size_t size = link_view->size();
|
||||
if (row_ndx >= size) {
|
||||
throw std::out_of_range(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." + std::to_string(size) + ".");
|
||||
}
|
||||
}
|
||||
|
||||
void List::verify_attached() {
|
||||
if (!link_view->is_attached()) {
|
||||
throw std::runtime_error("Tableview is not attached");
|
||||
}
|
||||
link_view->sync_if_needed();
|
||||
}
|
|
@ -16,13 +16,15 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "RJSUtil.hpp"
|
||||
#ifndef REALM_LIST_HPP
|
||||
#define REALM_LIST_HPP
|
||||
|
||||
#import "shared_realm.hpp"
|
||||
#import <realm/link_view.hpp>
|
||||
|
||||
namespace realm {
|
||||
struct ObjectArray {
|
||||
ObjectArray(SharedRealm &r, ObjectSchema &s, LinkViewRef l) : realm(r), object_schema(s), link_view(l) {}
|
||||
struct List {
|
||||
List(SharedRealm &r, ObjectSchema &s, LinkViewRef l) : realm(r), object_schema(s), link_view(l) {}
|
||||
// FIXME - all should be const
|
||||
SharedRealm realm;
|
||||
ObjectSchema &object_schema;
|
||||
|
@ -36,8 +38,5 @@ namespace realm {
|
|||
};
|
||||
}
|
||||
|
||||
extern const JSStaticFunction RJSArrayFuncs[];
|
||||
JSClassRef RJSArrayClass();
|
||||
JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array);
|
||||
|
||||
JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException);
|
||||
#endif /* REALM_LIST_HPP */
|
|
@ -21,43 +21,9 @@
|
|||
|
||||
#include <string>
|
||||
#include "shared_realm.hpp"
|
||||
#include "list.hpp"
|
||||
|
||||
namespace realm {
|
||||
template<typename ValueType, typename ContextType>
|
||||
class NativeAccessor {
|
||||
public:
|
||||
//
|
||||
// Value converters - template specializations must be implemented for each platform
|
||||
//
|
||||
static bool dict_has_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
|
||||
static ValueType dict_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
|
||||
|
||||
static bool has_default_value_for_property(ContextType ctx, const ObjectSchema &object_schema, const std::string &prop_name);
|
||||
static ValueType default_value_for_property(ContextType ctx, const ObjectSchema &object_schema, const std::string &prop_name);
|
||||
|
||||
static bool to_bool(ContextType ctx, ValueType &val);
|
||||
static long long to_long(ContextType ctx, ValueType &val);
|
||||
static float to_float(ContextType ctx, ValueType &val);
|
||||
static double to_double(ContextType ctx, ValueType &val);
|
||||
static std::string to_string(ContextType ctx, ValueType &val);
|
||||
static DateTime to_datetime(ContextType ctx, ValueType &val);
|
||||
|
||||
static bool is_null(ContextType ctx, ValueType &val);
|
||||
|
||||
// convert value to persisted object
|
||||
// for existing objects return the existing row index
|
||||
// for new/updated objects return the row index
|
||||
static size_t to_object_index(ContextType ctx, SharedRealm &realm, ValueType &val, std::string &type, bool try_update);
|
||||
|
||||
// array value acessors
|
||||
static size_t array_size(ContextType ctx, ValueType &val);
|
||||
static ValueType array_value_at_index(ContextType ctx, ValueType &val, size_t index);
|
||||
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
static Mixed to_mixed(ContextType ctx, ValueType &val) { throw std::runtime_error("'Any' type is unsupported"); }
|
||||
};
|
||||
|
||||
class Object {
|
||||
public:
|
||||
|
@ -67,10 +33,13 @@ namespace realm {
|
|||
ObjectSchema &object_schema;
|
||||
Row row;
|
||||
|
||||
// property setter
|
||||
// property getter/setter
|
||||
template<typename ValueType, typename ContextType>
|
||||
inline void set_property_value(ContextType ctx, std::string prop_name, ValueType value, bool try_update);
|
||||
|
||||
template<typename ValueType, typename ContextType>
|
||||
inline ValueType get_property_value(ContextType ctx, std::string prop_name);
|
||||
|
||||
// create an Object from a native representation
|
||||
template<typename ValueType, typename ContextType>
|
||||
static inline Object create(ContextType ctx, SharedRealm realm, ObjectSchema &object_schema, ValueType value, bool try_update);
|
||||
|
@ -78,6 +47,53 @@ namespace realm {
|
|||
private:
|
||||
template<typename ValueType, typename ContextType>
|
||||
inline void set_property_value_impl(ContextType ctx, Property &property, ValueType value, bool try_update);
|
||||
template<typename ValueType, typename ContextType>
|
||||
inline ValueType get_property_value_impl(ContextType ctx, Property &property);
|
||||
};
|
||||
|
||||
//
|
||||
// Value converters - template specializations must be implemented for each platform in order to call templated methods on Object
|
||||
//
|
||||
template<typename ValueType, typename ContextType>
|
||||
class NativeAccessor {
|
||||
public:
|
||||
static bool dict_has_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
|
||||
static ValueType dict_value_for_key(ContextType ctx, ValueType dict, const std::string &prop_name);
|
||||
|
||||
static bool has_default_value_for_property(ContextType ctx, const ObjectSchema &object_schema, const std::string &prop_name);
|
||||
static ValueType default_value_for_property(ContextType ctx, const ObjectSchema &object_schema, const std::string &prop_name);
|
||||
|
||||
static bool to_bool(ContextType, ValueType &);
|
||||
static ValueType from_bool(ContextType, bool);
|
||||
static long long to_long(ContextType, ValueType &);
|
||||
static ValueType from_long(ContextType, long long);
|
||||
static float to_float(ContextType, ValueType &);
|
||||
static ValueType from_float(ContextType, float);
|
||||
static double to_double(ContextType, ValueType &);
|
||||
static ValueType from_double(ContextType, double);
|
||||
static std::string to_string(ContextType, ValueType &);
|
||||
static ValueType from_string(ContextType, StringData);
|
||||
static DateTime to_datetime(ContextType, ValueType &);
|
||||
static ValueType from_datetime(ContextType, DateTime);
|
||||
|
||||
static bool is_null(ContextType, ValueType &);
|
||||
static ValueType null_value(ContextType);
|
||||
|
||||
// convert value to persisted object
|
||||
// for existing objects return the existing row index
|
||||
// for new/updated objects return the row index
|
||||
static size_t to_object_index(ContextType ctx, SharedRealm &realm, ValueType &val, std::string &type, bool try_update);
|
||||
static ValueType from_object(ContextType ctx, Object);
|
||||
|
||||
// list value acessors
|
||||
static size_t list_size(ContextType ctx, ValueType &val);
|
||||
static ValueType list_value_at_index(ContextType ctx, ValueType &val, size_t index);
|
||||
static ValueType from_list(ContextType ctx, List);
|
||||
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
static Mixed to_mixed(ContextType ctx, ValueType &val) { throw std::runtime_error("'Any' type is unsupported"); }
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -93,6 +109,16 @@ namespace realm {
|
|||
set_property_value_impl(ctx, *prop, value, try_update);
|
||||
};
|
||||
|
||||
template <typename ValueType, typename ContextType>
|
||||
inline ValueType Object::get_property_value(ContextType ctx, std::string prop_name)
|
||||
{
|
||||
Property *prop = object_schema.property_for_name(prop_name);
|
||||
if (!prop) {
|
||||
throw std::runtime_error("Setting invalid property '" + prop_name + "' on object '" + object_schema.name + "'.");
|
||||
}
|
||||
return get_property_value_impl<ValueType>(ctx, *prop);
|
||||
};
|
||||
|
||||
template <typename ValueType, typename ContextType>
|
||||
inline void Object::set_property_value_impl(ContextType ctx, Property &property, ValueType value, bool try_update)
|
||||
{
|
||||
|
@ -140,9 +166,9 @@ namespace realm {
|
|||
case PropertyTypeArray: {
|
||||
realm::LinkViewRef link_view = row.get_linklist(column);
|
||||
link_view->clear();
|
||||
size_t count = Accessor::array_size(ctx, value);
|
||||
size_t count = Accessor::list_size(ctx, value);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ValueType element = Accessor::array_value_at_index(ctx, value, i);
|
||||
ValueType element = Accessor::list_value_at_index(ctx, value, i);
|
||||
link_view->add(Accessor::to_object_index(ctx, realm, element, property.object_type, try_update));
|
||||
}
|
||||
break;
|
||||
|
@ -150,6 +176,44 @@ namespace realm {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename ValueType, typename ContextType>
|
||||
inline ValueType Object::get_property_value_impl(ContextType ctx, Property &property)
|
||||
{
|
||||
using Accessor = NativeAccessor<ValueType, ContextType>;
|
||||
|
||||
size_t column = property.table_column;
|
||||
switch (property.type) {
|
||||
case PropertyTypeBool:
|
||||
return Accessor::from_bool(ctx, row.get_bool(column));
|
||||
case PropertyTypeInt:
|
||||
return Accessor::from_long(ctx, row.get_int(column));
|
||||
case PropertyTypeFloat:
|
||||
return Accessor::from_float(ctx, row.get_float(column));
|
||||
case PropertyTypeDouble:
|
||||
return Accessor::from_double(ctx, row.get_double(column));
|
||||
case PropertyTypeString:
|
||||
return Accessor::from_string(ctx, row.get_string(column));
|
||||
case PropertyTypeData:
|
||||
return Accessor::from_string(ctx, (std::string)row.get_binary(column));
|
||||
case PropertyTypeAny:
|
||||
throw "Any not supported";
|
||||
case PropertyTypeDate:
|
||||
return Accessor::from_datetime(ctx, row.get_datetime(column));
|
||||
case PropertyTypeObject: {
|
||||
auto linkObjectSchema = realm->config().schema->find(property.object_type);
|
||||
TableRef table = ObjectStore::table_for_object_type(realm->read_group(), linkObjectSchema->name);
|
||||
if (row.is_null_link(property.table_column)) {
|
||||
return Accessor::null_value(ctx);
|
||||
}
|
||||
return Accessor::from_object(ctx, std::move(Object(realm, *linkObjectSchema, table->get(row.get_link(column)))));
|
||||
}
|
||||
case PropertyTypeArray: {
|
||||
auto arrayObjectSchema = realm->config().schema->find(property.object_type);
|
||||
return Accessor::from_list(ctx, std::move(List(realm, *arrayObjectSchema, static_cast<LinkViewRef>(row.get_linklist(column)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ValueType, typename ContextType>
|
||||
inline Object Object::create(ContextType ctx, SharedRealm realm, ObjectSchema &object_schema, ValueType value, bool try_update)
|
||||
{
|
||||
|
|
|
@ -243,9 +243,9 @@ static JSClassRef s_globalClass;
|
|||
}
|
||||
@end
|
||||
|
||||
@interface RJSArrayTests : RealmJSTests
|
||||
@interface RJSListTests : RealmJSTests
|
||||
@end
|
||||
@implementation RJSArrayTests
|
||||
@implementation RJSListTests
|
||||
+ (NSString *)jsSuiteName {
|
||||
return @"ArrayTests";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue