move static methods and constructor

This commit is contained in:
Ari Lazier 2016-03-30 13:09:05 -07:00
parent 0282e98232
commit 2baec5bec6
3 changed files with 120 additions and 117 deletions

View File

@ -19,10 +19,12 @@
#pragma once #pragma once
#include "js_util.hpp" #include "js_util.hpp"
#include "js_schema.hpp"
#include "shared_realm.hpp" #include "shared_realm.hpp"
#include "binding_context.hpp" #include "binding_context.hpp"
#include "object_accessor.hpp" #include "object_accessor.hpp"
#include "results.hpp" #include "results.hpp"
#include "platform.hpp"
#include <map> #include <map>
#include <set> #include <set>
@ -127,6 +129,7 @@ public:
using ReturnType = typename T::Return; using ReturnType = typename T::Return;
using ExceptionType = typename T::Exception; using ExceptionType = typename T::Exception;
// member methods
static void Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void Create(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void Delete(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
@ -136,6 +139,10 @@ public:
static void RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void RemoveListener(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject); static void Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
// constructor methods
static void Constructor(ContextType ctx, ObjectType constructor, size_t argumentCount, const ValueType arguments[], ObjectType &returnObject);
static void SchemaVersion(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static std::string validated_notification_name(JSContextRef ctx, JSValueRef value) { static std::string validated_notification_name(JSContextRef ctx, JSValueRef value) {
std::string name = RJSValidatedStringForValue(ctx, value); std::string name = RJSValidatedStringForValue(ctx, value);
@ -161,8 +168,104 @@ public:
return RJSValidatedStringForValue(ctx, value, "objectType"); return RJSValidatedStringForValue(ctx, value, "objectType");
} }
static std::string RJSNormalizePath(std::string path) {
if (path.size() && path[0] != '/') {
return default_realm_file_directory() + "/" + path;
}
return path;
}
}; };
template<typename T>
void Realm<T>::Constructor(ContextType ctx, ObjectType constructor, size_t argumentCount, const ValueType arguments[], ObjectType &returnObject) {
using RJSAccessor = realm::NativeAccessor<ValueType, ContextType>;
realm::Realm::Config config;
std::map<std::string, ObjectDefaults> defaults;
std::map<std::string, ObjectType> constructors;
if (argumentCount == 0) {
config.path = default_path();
}
else if (argumentCount == 1) {
ValueType value = arguments[0];
if (ValueIsString(ctx, value)) {
config.path = RJSValidatedStringForValue(ctx, value, "path");
}
else if (ValueIsObject(ctx, value)) {
JSObjectRef object = RJSValidatedValueToObject(ctx, value);
static JSStringRef pathString = JSStringCreateWithUTF8CString("path");
JSValueRef pathValue = RJSValidatedPropertyValue(ctx, object, pathString);
if (!JSValueIsUndefined(ctx, pathValue)) {
config.path = RJSValidatedStringForValue(ctx, pathValue, "path");
}
else {
config.path = js::default_path();
}
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
JSValueRef schemaValue = RJSValidatedPropertyValue(ctx, object, schemaString);
if (!JSValueIsUndefined(ctx, schemaValue)) {
config.schema.reset(new Schema(RJSParseSchema(ctx, RJSValidatedValueToObject(ctx, schemaValue), defaults, constructors)));
}
static JSStringRef schemaVersionString = JSStringCreateWithUTF8CString("schemaVersion");
JSValueRef versionValue = RJSValidatedPropertyValue(ctx, object, schemaVersionString);
if (JSValueIsNumber(ctx, versionValue)) {
config.schema_version = RJSValidatedValueToNumber(ctx, versionValue);
}
else {
config.schema_version = 0;
}
static JSStringRef encryptionKeyString = JSStringCreateWithUTF8CString("encryptionKey");
JSValueRef encryptionKeyValue = RJSValidatedPropertyValue(ctx, object, encryptionKeyString);
if (!JSValueIsUndefined(ctx, encryptionKeyValue)) {
std::string encryptionKey = RJSAccessor::to_binary(ctx, encryptionKeyValue);
config.encryption_key = std::vector<char>(encryptionKey.begin(), encryptionKey.end());;
}
}
}
else {
throw std::runtime_error("Invalid arguments when constructing 'Realm'");
}
config.path = RJSNormalizePath(config.path);
ensure_directory_exists_for_file(config.path);
SharedRealm realm = realm::Realm::get_shared_realm(config);
auto delegate = new RealmDelegate<T>(realm, JSContextGetGlobalContext(ctx));
if (!realm->m_binding_context) {
realm->m_binding_context.reset(delegate);
}
delegate->m_defaults = defaults;
delegate->m_constructors = constructors;
returnObject = WrapObject(ctx, realm_class(), new SharedRealm(realm));
}
template<typename T>
void Realm<T>::SchemaVersion(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
RJSValidateArgumentRange(argumentCount, 1, 2);
realm::Realm::Config config;
config.path = RJSNormalizePath(RJSValidatedStringForValue(ctx, arguments[0]));
if (argumentCount == 2) {
auto encryptionKeyValue = arguments[1];
std::string encryptionKey = RJSAccessor::to_binary(ctx, encryptionKeyValue);
config.encryption_key = std::vector<char>(encryptionKey.begin(), encryptionKey.end());
}
auto version = realm::Realm::get_schema_version(config);
if (version == ObjectStore::NotVersioned) {
RJSSetReturnNumber(ctx, returnObject, -1);
}
else {
RJSSetReturnNumber(ctx, returnObject, version);
}
}
template<typename T> template<typename T>
void Realm<T>::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) { void Realm<T>::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {

View File

@ -33,18 +33,21 @@
#include "js_compat.hpp" #include "js_compat.hpp"
#include "schema.hpp" #include "schema.hpp"
#define WRAP_EXCEPTION(METHOD, EXCEPTION, ARGS...) \
try { METHOD(ARGS); } \
catch(std::exception &e) { RJSSetException(ctx, EXCEPTION, e); }
#define WRAP_CLASS_METHOD(CLASS_NAME, METHOD_NAME) \ #define WRAP_CLASS_METHOD(CLASS_NAME, METHOD_NAME) \
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { \ JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* ex) { \
JSValueRef returnObject = NULL; \ JSValueRef returnObject = NULL; \
try { CLASS_NAME::METHOD_NAME(ctx, thisObject, argumentCount, arguments, returnObject); } \ WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, thisObject, argumentCount, arguments, returnObject); \
catch(std::exception &ex) { RJSSetException(ctx, *jsException, ex); } \
return returnObject; \ return returnObject; \
} }
#define WRAP_METHOD(METHOD_NAME) \ #define WRAP_CONSTRUCTOR(CLASS_NAME, METHOD_NAME) \
JSValueRef METHOD_NAME(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) { \ JSObjectRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* ex) { \
JSValueRef returnObject = NULL; \ JSObjectRef returnObject = NULL; \
METHOD_NAME(ctx, thisObject, argumentCount, arguments, returnObject, *jsException); \ WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, constructor, argumentCount, arguments, returnObject); \
return returnObject; \ return returnObject; \
} }
@ -313,3 +316,4 @@ static bool RJSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassR
return JSValueIsObjectOfClass(ctx, value, jsClass); return JSValueIsObjectOfClass(ctx, value, jsClass);
} }

View File

@ -52,86 +52,6 @@ static bool SetDefaultPath(JSContextRef ctx, JSObjectRef object, JSStringRef pro
return true; return true;
} }
inline std::string RJSNormalizePath(std::string path) {
if (path.size() && path[0] != '/') {
return default_realm_file_directory() + "/" + path;
}
return path;
}
JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try {
Realm::Config config;
std::map<std::string, realm::ObjectDefaults> defaults;
std::map<std::string, JSObjectRef> constructors;
if (argumentCount == 0) {
config.path = js::default_path();
}
else if (argumentCount == 1) {
JSValueRef value = arguments[0];
if (JSValueIsString(ctx, value)) {
config.path = RJSValidatedStringForValue(ctx, value, "path");
}
else if (JSValueIsObject(ctx, value)) {
JSObjectRef object = RJSValidatedValueToObject(ctx, value);
static JSStringRef pathString = JSStringCreateWithUTF8CString("path");
JSValueRef pathValue = RJSValidatedPropertyValue(ctx, object, pathString);
if (!JSValueIsUndefined(ctx, pathValue)) {
config.path = RJSValidatedStringForValue(ctx, pathValue, "path");
}
else {
config.path = js::default_path();
}
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
JSValueRef schemaValue = RJSValidatedPropertyValue(ctx, object, schemaString);
if (!JSValueIsUndefined(ctx, schemaValue)) {
config.schema.reset(new Schema(RJSParseSchema(ctx, RJSValidatedValueToObject(ctx, schemaValue), defaults, constructors)));
}
static JSStringRef schemaVersionString = JSStringCreateWithUTF8CString("schemaVersion");
JSValueRef versionValue = RJSValidatedPropertyValue(ctx, object, schemaVersionString);
if (JSValueIsNumber(ctx, versionValue)) {
config.schema_version = RJSValidatedValueToNumber(ctx, versionValue);
}
else {
config.schema_version = 0;
}
static JSStringRef encryptionKeyString = JSStringCreateWithUTF8CString("encryptionKey");
JSValueRef encryptionKeyValue = RJSValidatedPropertyValue(ctx, object, encryptionKeyString);
if (!JSValueIsUndefined(ctx, encryptionKeyValue)) {
std::string encryptionKey = RJSAccessor::to_binary(ctx, encryptionKeyValue);
config.encryption_key = std::vector<char>(encryptionKey.begin(), encryptionKey.end());;
}
}
}
else {
*jsException = RJSMakeError(ctx, "Invalid arguments when constructing 'Realm'");
return NULL;
}
config.path = RJSNormalizePath(config.path);
ensure_directory_exists_for_file(config.path);
SharedRealm realm = Realm::get_shared_realm(config);
auto delegate = new js::RealmDelegate<jsc::Types>(realm, JSContextGetGlobalContext(ctx));
if (!realm->m_binding_context) {
realm->m_binding_context.reset(delegate);
}
delegate->m_defaults = defaults;
delegate->m_constructors = constructors;
return js::WrapObject(ctx, RJSRealmClass(), new SharedRealm(realm));
}
catch (std::exception &ex) {
if (jsException) {
*jsException = RJSMakeError(ctx, ex);
}
return NULL;
}
}
bool RealmHasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef value, JSValueRef* exception) { bool RealmHasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef value, JSValueRef* exception) {
return JSValueIsObjectOfClass(ctx, value, RJSRealmClass()); return JSValueIsObjectOfClass(ctx, value, RJSRealmClass());
} }
@ -141,36 +61,13 @@ static const JSStaticValue RealmStaticProperties[] = {
{NULL, NULL} {NULL, NULL}
}; };
template<typename ContextType, typename ObjectType, typename ValueType, typename ReturnType, typename ExceptionType>
void RealmSchemaVersion(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject, ExceptionType &exceptionObject) {
try {
RJSValidateArgumentRange(argumentCount, 1, 2);
Realm::Config config;
config.path = RJSNormalizePath(RJSValidatedStringForValue(ctx, arguments[0]));
if (argumentCount == 2) {
auto encryptionKeyValue = arguments[1];
std::string encryptionKey = RJSAccessor::to_binary(ctx, encryptionKeyValue);
config.encryption_key = std::vector<char>(encryptionKey.begin(), encryptionKey.end());
}
auto version = Realm::get_schema_version(config); using RJSRealm = realm::js::Realm<realm::jsc::Types>;
if (version == ObjectStore::NotVersioned) { WRAP_CONSTRUCTOR(RJSRealm, Constructor);
RJSSetReturnNumber(ctx, returnObject, -1); WRAP_CLASS_METHOD(RJSRealm, SchemaVersion)
}
else {
RJSSetReturnNumber(ctx, returnObject, version);
}
}
catch (std::exception &exp) {
RJSSetException(ctx, exceptionObject, exp);
}
}
WRAP_METHOD(RealmSchemaVersion)
static const JSStaticFunction RealmConstructorFuncs[] = { static const JSStaticFunction RealmConstructorFuncs[] = {
{"schemaVersion", RealmSchemaVersion, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, {"schemaVersion", RJSRealmSchemaVersion, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL}, {NULL, NULL},
}; };
@ -178,7 +75,7 @@ JSClassRef RJSRealmConstructorClass() {
JSClassDefinition realmConstructorDefinition = kJSClassDefinitionEmpty; JSClassDefinition realmConstructorDefinition = kJSClassDefinitionEmpty;
realmConstructorDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; realmConstructorDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
realmConstructorDefinition.className = "RealmConstructor"; realmConstructorDefinition.className = "RealmConstructor";
realmConstructorDefinition.callAsConstructor = RealmConstructor; realmConstructorDefinition.callAsConstructor = RJSRealmConstructor;
realmConstructorDefinition.hasInstance = RealmHasInstance; realmConstructorDefinition.hasInstance = RealmHasInstance;
realmConstructorDefinition.staticValues = RealmStaticProperties; realmConstructorDefinition.staticValues = RealmStaticProperties;
realmConstructorDefinition.staticFunctions = RealmConstructorFuncs; realmConstructorDefinition.staticFunctions = RealmConstructorFuncs;
@ -198,7 +95,6 @@ JSValueRef RealmGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
return NULL; return NULL;
} }
using RJSRealm = realm::js::Realm<realm::jsc::Types>;
WRAP_CLASS_METHOD(RJSRealm, Objects) WRAP_CLASS_METHOD(RJSRealm, Objects)
WRAP_CLASS_METHOD(RJSRealm, Create) WRAP_CLASS_METHOD(RJSRealm, Create)
WRAP_CLASS_METHOD(RJSRealm, Delete) WRAP_CLASS_METHOD(RJSRealm, Delete)