Added support for in-memory realms (#1304)

* Added support for in-memory realms
This commit is contained in:
astigsen 2017-09-13 11:42:23 -07:00 committed by Kenneth Geisshirt
parent 03bc224374
commit 208aa8ee46
6 changed files with 51 additions and 0 deletions

View File

@ -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

View File

@ -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`.

View File

@ -55,6 +55,7 @@ function setupRealm(realm, realmId) {
'empty', 'empty',
'path', 'path',
'readOnly', 'readOnly',
'inMemory',
'schema', 'schema',
'schemaVersion', 'schemaVersion',
'syncSession', 'syncSession',

1
lib/index.d.ts vendored
View File

@ -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;

View File

@ -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());

View File

@ -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]});