Added support for in-memory realms (#1304)
* Added support for in-memory realms
This commit is contained in:
parent
03bc224374
commit
208aa8ee46
|
@ -9,6 +9,7 @@ X.Y.Z Release notes
|
||||||
* Added additional parameter for `Realm.open` and `Realm.openAsync` for download progress notifications
|
* Added additional parameter for `Realm.open` and `Realm.openAsync` for download progress notifications
|
||||||
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
* Added `Realm.deleteFile` for deleting a Realm (#363).
|
||||||
* Added `Realm.deleteModel` for deleting a Realm model in a migration (#573).
|
* Added `Realm.deleteModel` for deleting a Realm model in a migration (#573).
|
||||||
|
* Added support for in-memory Realms.
|
||||||
* `Realm.Sync.User.login`, `Realm.Sync.User.register`, and `Realm.Sync.User.registerWithProvider` return Promises and deprecate the callback style for them. Callbacks will continue to work for backward compatibility.
|
* `Realm.Sync.User.login`, `Realm.Sync.User.register`, and `Realm.Sync.User.registerWithProvider` return Promises and deprecate the callback style for them. Callbacks will continue to work for backward compatibility.
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
|
@ -278,6 +278,11 @@ Realm.defaultPath;
|
||||||
* will be skipped if another process is accessing it.
|
* will be skipped if another process is accessing it.
|
||||||
* @property {string} [path={@link Realm.defaultPath}] - The path to the file where the
|
* @property {string} [path={@link Realm.defaultPath}] - The path to the file where the
|
||||||
* Realm database should be stored.
|
* Realm database should be stored.
|
||||||
|
* @property {boolean} [inMemory=false] - Specifies if this Realm should be opened in-memory. This
|
||||||
|
* still requires a path (can be the default path) to identify the Realm so other processes can
|
||||||
|
* open the same Realm. The file will also be used as swap space if the Realm becomes bigger than
|
||||||
|
* what fits in memory, but it is not persistent and will be removed when the last instance
|
||||||
|
* is closed.
|
||||||
* @property {boolean} [readOnly=false] - Specifies if this Realm should be opened as read-only.
|
* @property {boolean} [readOnly=false] - Specifies if this Realm should be opened as read-only.
|
||||||
* @property {Array<Realm~ObjectClass|Realm~ObjectSchema>} [schema] - Specifies all the
|
* @property {Array<Realm~ObjectClass|Realm~ObjectSchema>} [schema] - Specifies all the
|
||||||
* object types in this Realm. **Required** when first creating a Realm at this `path`.
|
* object types in this Realm. **Required** when first creating a Realm at this `path`.
|
||||||
|
|
|
@ -55,6 +55,7 @@ function setupRealm(realm, realmId) {
|
||||||
'empty',
|
'empty',
|
||||||
'path',
|
'path',
|
||||||
'readOnly',
|
'readOnly',
|
||||||
|
'inMemory',
|
||||||
'schema',
|
'schema',
|
||||||
'schemaVersion',
|
'schemaVersion',
|
||||||
'syncSession',
|
'syncSession',
|
||||||
|
|
|
@ -80,6 +80,7 @@ declare namespace Realm {
|
||||||
shouldCompactOnLaunch?: (totalBytes: number, usedBytes: number) => boolean;
|
shouldCompactOnLaunch?: (totalBytes: number, usedBytes: number) => boolean;
|
||||||
path?: string;
|
path?: string;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
|
inMemory?: boolean;
|
||||||
schema?: ObjectClass[] | ObjectSchema[];
|
schema?: ObjectClass[] | ObjectSchema[];
|
||||||
schemaVersion?: number;
|
schemaVersion?: number;
|
||||||
sync?: Realm.Sync.SyncConfiguration;
|
sync?: Realm.Sync.SyncConfiguration;
|
||||||
|
|
|
@ -187,6 +187,7 @@ public:
|
||||||
static void get_path(ContextType, ObjectType, ReturnValue &);
|
static void get_path(ContextType, ObjectType, ReturnValue &);
|
||||||
static void get_schema_version(ContextType, ObjectType, ReturnValue &);
|
static void get_schema_version(ContextType, ObjectType, ReturnValue &);
|
||||||
static void get_schema(ContextType, ObjectType, ReturnValue &);
|
static void get_schema(ContextType, ObjectType, ReturnValue &);
|
||||||
|
static void get_in_memory(ContextType, ObjectType, ReturnValue &);
|
||||||
static void get_read_only(ContextType, ObjectType, ReturnValue &);
|
static void get_read_only(ContextType, ObjectType, ReturnValue &);
|
||||||
static void get_is_in_transaction(ContextType, ObjectType, ReturnValue &);
|
static void get_is_in_transaction(ContextType, ObjectType, ReturnValue &);
|
||||||
#if REALM_ENABLE_SYNC
|
#if REALM_ENABLE_SYNC
|
||||||
|
@ -243,6 +244,7 @@ public:
|
||||||
{"path", {wrap<get_path>, nullptr}},
|
{"path", {wrap<get_path>, nullptr}},
|
||||||
{"schemaVersion", {wrap<get_schema_version>, nullptr}},
|
{"schemaVersion", {wrap<get_schema_version>, nullptr}},
|
||||||
{"schema", {wrap<get_schema>, nullptr}},
|
{"schema", {wrap<get_schema>, nullptr}},
|
||||||
|
{"inMemory", {wrap<get_in_memory>, nullptr}},
|
||||||
{"readOnly", {wrap<get_read_only>, nullptr}},
|
{"readOnly", {wrap<get_read_only>, nullptr}},
|
||||||
{"isInTransaction", {wrap<get_is_in_transaction>, nullptr}},
|
{"isInTransaction", {wrap<get_is_in_transaction>, nullptr}},
|
||||||
#if REALM_ENABLE_SYNC
|
#if REALM_ENABLE_SYNC
|
||||||
|
@ -380,6 +382,12 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
||||||
else if (config.path.empty()) {
|
else if (config.path.empty()) {
|
||||||
config.path = js::default_path();
|
config.path = js::default_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const String in_memory_string = "inMemory";
|
||||||
|
ValueType in_memory_value = Object::get_property(ctx, object, in_memory_string);
|
||||||
|
if (!Value::is_undefined(ctx, in_memory_value) && Value::validated_to_boolean(ctx, in_memory_value, "inMemory")) {
|
||||||
|
config.in_memory = true;
|
||||||
|
}
|
||||||
|
|
||||||
static const String read_only_string = "readOnly";
|
static const String read_only_string = "readOnly";
|
||||||
ValueType read_only_value = Object::get_property(ctx, object, read_only_string);
|
ValueType read_only_value = Object::get_property(ctx, object, read_only_string);
|
||||||
|
@ -606,6 +614,11 @@ void RealmClass<T>::get_schema(ContextType ctx, ObjectType object, ReturnValue &
|
||||||
return_value.set(Schema<T>::object_for_schema(ctx, schema));
|
return_value.set(Schema<T>::object_for_schema(ctx, schema));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void RealmClass<T>::get_in_memory(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
||||||
|
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().in_memory);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void RealmClass<T>::get_read_only(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
void RealmClass<T>::get_read_only(ContextType ctx, ObjectType object, ReturnValue &return_value) {
|
||||||
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().read_only());
|
return_value.set(get_internal<T, RealmClass<T>>(object)->get()->config().read_only());
|
||||||
|
|
|
@ -161,6 +161,36 @@ module.exports = {
|
||||||
}]});
|
}]});
|
||||||
}, "Property 'InvalidObject.link' declared as origin of linking objects property 'InvalidObject.linkingObjects' links to type 'IntObject'")
|
}, "Property 'InvalidObject.link' declared as origin of linking objects property 'InvalidObject.linkingObjects' links to type 'IntObject'")
|
||||||
},
|
},
|
||||||
|
|
||||||
|
testRealmConstructorInMemory: function() {
|
||||||
|
// open in-memory realm instance
|
||||||
|
const realm1 = new Realm({inMemory: true, schema: [schemas.TestObject]});
|
||||||
|
realm1.write(function() {
|
||||||
|
realm1.create('TestObject', [1])
|
||||||
|
});
|
||||||
|
TestCase.assertEqual(realm1.inMemory, true);
|
||||||
|
|
||||||
|
// open a second instance of the same realm and check that they share data
|
||||||
|
const realm2 = new Realm({inMemory: true});
|
||||||
|
const objects = realm2.objects('TestObject');
|
||||||
|
TestCase.assertEqual(objects.length, 1);
|
||||||
|
TestCase.assertEqual(objects[0].doubleCol, 1.0);
|
||||||
|
TestCase.assertEqual(realm2.inMemory, true);
|
||||||
|
|
||||||
|
// Close both realms (this should delete the realm since there are no more
|
||||||
|
// references to it.
|
||||||
|
realm1.close();
|
||||||
|
realm2.close();
|
||||||
|
|
||||||
|
// Open the same in-memory realm again and verify that it is now empty
|
||||||
|
const realm3 = new Realm({inMemory: true});
|
||||||
|
TestCase.assertEqual(realm3.schema.length, 0);
|
||||||
|
|
||||||
|
// try to open the same realm in persistent mode (should fail as you cannot mix modes)
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
const realm4 = new Realm({});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
testRealmConstructorReadOnly: function() {
|
testRealmConstructorReadOnly: function() {
|
||||||
var realm = new Realm({schema: [schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.TestObject]});
|
||||||
|
|
Loading…
Reference in New Issue