Properly serialize args to create Realm through RPC

An exception was thrown when parsing the JSON when only a string was passed. This is better and no longer uses the Objective-C API for converting the dictionary to a JSValue.
This commit is contained in:
Scott Kyle 2015-10-15 03:00:13 -07:00
parent 7b5be78df2
commit 94521b73bb
3 changed files with 35 additions and 22 deletions

View File

@ -30,7 +30,7 @@ class Realm {
} }
} }
let realmId = this[realmKey] = rpc.createRealm(config); let realmId = this[realmKey] = rpc.createRealm(Array.from(arguments));
objects.registerConstructors(realmId, constructors); objects.registerConstructors(realmId, constructors);
} }

View File

@ -41,8 +41,12 @@ function registerTypeConverter(type, handler) {
typeConverters[type] = handler; typeConverters[type] = handler;
} }
function createRealm(config) { function createRealm(args) {
return sendRequest('create_realm', config); if (args) {
args = args.map((arg) => serialize(null, arg));
}
return sendRequest('create_realm', {arguments: args});
} }
function callRealmMethod(realmId, name, args) { function callRealmMethod(realmId, name, args) {

View File

@ -45,31 +45,40 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
self = [super init]; self = [super init];
if (self) { if (self) {
_context = JSGlobalContextCreate(NULL); _context = JSGlobalContextCreate(NULL);
_requests["/create_realm"] = [=](NSDictionary *dict) { _requests["/create_realm"] = [=](NSDictionary *dict) {
// We should have a method for serializing schema rather than relying on JSValue NSArray *args = dict[@"arguments"];
JSValueRef value = [[JSValue valueWithObject:dict NSUInteger argCount = args.count;
inContext:[JSContext contextWithJSGlobalContextRef:_context]] JSValueRef]; JSValueRef argValues[argCount];
JSValueRef ex = NULL;
RPCObjectID realmId = [self storeObject:RealmConstructor(_context, NULL, 1, &value, &ex)]; for (NSUInteger i = 0; i < argCount; i++) {
if (ex) { argValues[i] = [self valueFromDictionary:args[i]];
return @{@"error": @(RJSStringForValue(_context, ex).c_str())};
} }
JSValueRef exception = NULL;
JSObjectRef realmObject = RealmConstructor(_context, NULL, argCount, argValues, &exception);
if (exception) {
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
}
RPCObjectID realmId = [self storeObject:realmObject];
return @{@"result": @(realmId)}; return @{@"result": @(realmId)};
}; };
_requests["/begin_transaction"] = [=](NSDictionary *dict) { _requests["/begin_transaction"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue]; RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->begin_transaction(); RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->begin_transaction();
return @{}; return nil;
}; };
_requests["/cancel_transaction"] = [=](NSDictionary *dict) { _requests["/cancel_transaction"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue]; RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->cancel_transaction(); RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->cancel_transaction();
return @{}; return nil;
}; };
_requests["/commit_transaction"] = [=](NSDictionary *dict) { _requests["/commit_transaction"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue]; RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->commit_transaction(); RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->commit_transaction();
return @{}; return nil;
}; };
_requests["/call_realm_method"] = [=](NSDictionary *dict) { _requests["/call_realm_method"] = [=](NSDictionary *dict) {
NSString *name = dict[@"name"]; NSString *name = dict[@"name"];
@ -106,7 +115,7 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
RPCObjectID oid = [dict[@"id"] unsignedLongValue]; RPCObjectID oid = [dict[@"id"] unsignedLongValue];
JSValueUnprotect(_context, _objects[oid]); JSValueUnprotect(_context, _objects[oid]);
_objects.erase(oid); _objects.erase(oid);
return @{}; return nil;
}; };
_requests["/get_results_size"] = [=](NSDictionary *dict) { _requests["/get_results_size"] = [=](NSDictionary *dict) {
RPCObjectID resultsId = [dict[@"resultsId"] unsignedLongValue]; RPCObjectID resultsId = [dict[@"resultsId"] unsignedLongValue];
@ -185,26 +194,26 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
response = @{@"error": [@"exception thrown: " stringByAppendingString:@(exception.what())]}; response = @{@"error": [@"exception thrown: " stringByAppendingString:@(exception.what())]};
} }
}); });
return response; return response ?: @{};
} }
- (NSDictionary *)performObjectMethod:(const char *)name - (NSDictionary *)performObjectMethod:(const char *)name
classMethods:(const JSStaticFunction [])methods classMethods:(const JSStaticFunction [])methods
args:(NSArray *)args args:(NSArray *)args
objectId:(RPCObjectID)oid { objectId:(RPCObjectID)oid {
NSUInteger count = args.count; NSUInteger argCount = args.count;
JSValueRef argValues[count]; JSValueRef argValues[argCount];
for (NSUInteger i = 0; i < count; i++) { for (NSUInteger i = 0; i < argCount; i++) {
argValues[i] = [self valueFromDictionary:args[i]]; argValues[i] = [self valueFromDictionary:args[i]];
} }
size_t index = 0; size_t index = 0;
while (methods[index].name) { while (methods[index].name) {
if (!strcmp(methods[index].name, name)) { if (!strcmp(methods[index].name, name)) {
JSValueRef ex = NULL; JSValueRef exception = NULL;
JSValueRef ret = methods[index].callAsFunction(_context, NULL, _objects[oid], count, argValues, &ex); JSValueRef ret = methods[index].callAsFunction(_context, NULL, _objects[oid], argCount, argValues, &exception);
if (ex) { if (exception) {
return @{@"error": @(RJSStringForValue(_context, ex).c_str())}; return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
} }
return @{@"result": [self resultForJSValue:ret]}; return @{@"result": [self resultForJSValue:ret]};
} }