diff --git a/src/js_realm.hpp b/src/js_realm.hpp index 72ce3b31..6fc662df 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -186,6 +186,7 @@ public: static void compact(ContextType, ObjectType, Arguments, ReturnValue &); static void delete_model(ContextType, ObjectType, Arguments, ReturnValue &); static void object_for_object_id(ContextType, ObjectType, Arguments, ReturnValue&); + static void privileges(ContextType, ObjectType, Arguments, ReturnValue&); // properties static void get_empty(ContextType, ObjectType, ReturnValue &); @@ -242,6 +243,7 @@ public: {"close", wrap}, {"compact", wrap}, {"deleteModel", wrap}, + {"privileges", wrap}, {"_objectForObjectId", wrap}, #if REALM_ENABLE_SYNC {"_waitForDownload", wrap}, @@ -291,7 +293,8 @@ public: return name; } - static const ObjectSchema& validated_object_schema_for_value(ContextType ctx, const SharedRealm &realm, const ValueType &value, std::string& object_type) { + static const ObjectSchema& validated_object_schema_for_value(ContextType ctx, const SharedRealm &realm, const ValueType &value) { + std::string object_type; if (Value::is_constructor(ctx, value)) { FunctionType constructor = Value::to_constructor(ctx, value); @@ -541,7 +544,7 @@ void RealmClass::constructor(ContextType ctx, ObjectType this_object, size_t template SharedRealm RealmClass::create_shared_realm(ContextType ctx, realm::Realm::Config config, bool schema_updated, - ObjectDefaultsMap && defaults, ConstructorMap && constructors) { + ObjectDefaultsMap&& defaults, ConstructorMap&& constructors) { config.execution_context = Context::get_execution_context_id(ctx); SharedRealm realm; @@ -551,9 +554,6 @@ SharedRealm RealmClass::create_shared_realm(ContextType ctx, realm::Realm::Co catch (const RealmFileException& ex) { handleRealmFileException(ctx, config, ex); } - catch (...) { - throw; - } GlobalContextType global_context = Context::get_global_context(ctx); if (!realm->m_binding_context) { @@ -790,10 +790,8 @@ void RealmClass::objects(ContextType ctx, ObjectType this_object, Arguments a args.validate_maximum(1); SharedRealm realm = *get_internal>(this_object); - std::string object_type; - validated_object_schema_for_value(ctx, realm, args[0], object_type); - - return_value.set(ResultsClass::create_instance(ctx, realm, object_type)); + auto& object_schema = validated_object_schema_for_value(ctx, realm, args[0]); + return_value.set(ResultsClass::create_instance(ctx, realm, object_schema.name)); } template @@ -802,7 +800,7 @@ void RealmClass::object_for_primary_key(ContextType ctx, ObjectType this_obje SharedRealm realm = *get_internal>(this_object); std::string object_type; - auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0], object_type); + auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0]); NativeAccessor accessor(ctx, realm, object_schema); auto realm_object = realm::Object::get_for_primary_key(accessor, realm, object_schema, args[1]); @@ -820,8 +818,7 @@ void RealmClass::create(ContextType ctx, ObjectType this_object, Arguments ar SharedRealm realm = *get_internal>(this_object); realm->verify_open(); - std::string object_type; - auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0], object_type); + auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0]); ObjectType object = Value::validated_to_object(ctx, args[1], "properties"); if (Value::is_array(ctx, args[1])) { @@ -1011,21 +1008,67 @@ void RealmClass::object_for_object_id(ContextType ctx, ObjectType this_object if (!sync::has_object_ids(realm->read_group())) throw std::logic_error("Realm._objectForObjectId() can only be used with synced Realms."); - std::string object_type = Value::validated_to_string(ctx, args[0]); - validated_object_schema_for_value(ctx, realm, args[0], object_type); - + auto& object_schema = validated_object_schema_for_value(ctx, realm, args[0]); std::string object_id_string = Value::validated_to_string(ctx, args[1]); auto object_id = sync::ObjectID::from_string(object_id_string); const Group& group = realm->read_group(); - size_t ndx = sync::row_for_object_id(group, *ObjectStore::table_for_object_type(group, object_type), object_id); + size_t ndx = sync::row_for_object_id(group, *ObjectStore::table_for_object_type(group, object_schema.name), object_id); if (ndx != realm::npos) { - return_value.set(RealmObjectClass::create_instance(ctx, realm::Object(realm, object_type, ndx))); + return_value.set(RealmObjectClass::create_instance(ctx, realm::Object(realm, object_schema.name, ndx))); } #else throw std::logic_error("Realm._objectForObjectId() can only be used with synced Realms."); #endif // REALM_ENABLE_SYNC } +template +void RealmClass::privileges(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) { + args.validate_maximum(1); + + using Privilege = realm::ComputedPrivileges; + auto has_privilege = [](Privilege actual, Privilege expected) { + return (static_cast(actual) & static_cast(expected)) == static_cast(expected); + }; + + SharedRealm realm = *get_internal>(this_object); + if (args.count == 0) { + auto p = realm->get_privileges(); + ObjectType object = Object::create_empty(ctx); + Object::set_property(ctx, object, "read", Value::from_boolean(ctx, has_privilege(p, Privilege::Read))); + Object::set_property(ctx, object, "update", Value::from_boolean(ctx,has_privilege(p, Privilege::Update))); + Object::set_property(ctx, object, "modifySchema", Value::from_boolean(ctx, has_privilege(p, Privilege::ModifySchema))); + Object::set_property(ctx, object, "setPermissions", Value::from_boolean(ctx, has_privilege(p, Privilege::SetPermissions))); + return_value.set(object); + return; + } + + if (Value::is_object(ctx, args[0])) { + auto arg = Value::to_object(ctx, args[0]); + if (Object::template is_instance>(ctx, arg)) { + auto obj = get_internal>(arg); + auto p = realm->get_privileges(obj->row()); + + ObjectType object = Object::create_empty(ctx); + Object::set_property(ctx, object, "read", Value::from_boolean(ctx, has_privilege(p, Privilege::Read))); + Object::set_property(ctx, object, "update", Value::from_boolean(ctx,has_privilege(p, Privilege::Update))); + Object::set_property(ctx, object, "delete", Value::from_boolean(ctx,has_privilege(p, Privilege::Delete))); + Object::set_property(ctx, object, "setPermissions", Value::from_boolean(ctx, has_privilege(p, Privilege::SetPermissions))); + return_value.set(object); + return; + } + } + + auto& object_schema = validated_object_schema_for_value(ctx, realm, args[0]); + auto p = realm->get_privileges(object_schema.name); + ObjectType object = Object::create_empty(ctx); + Object::set_property(ctx, object, "read", Value::from_boolean(ctx, has_privilege(p, Privilege::Read))); + Object::set_property(ctx, object, "update", Value::from_boolean(ctx,has_privilege(p, Privilege::Update))); + Object::set_property(ctx, object, "create", Value::from_boolean(ctx, has_privilege(p, Privilege::Create))); + Object::set_property(ctx, object, "subscribe", Value::from_boolean(ctx, has_privilege(p, Privilege::Query))); + Object::set_property(ctx, object, "setPermissions", Value::from_boolean(ctx, has_privilege(p, Privilege::SetPermissions))); + return_value.set(object); +} + } // js } // realm