Added `writeCopyTo` functionality (#1715)

* Added `writeCopyTo` functionality
* Fixes #1678
* Added optional `encryptionKey` to `writeCopyTo`
This commit is contained in:
Valerii Hiora 2018-04-03 12:50:03 +03:00 committed by Kenneth Geisshirt
parent 497de5f3ea
commit c3a83f1866
4 changed files with 95 additions and 2 deletions

View File

@ -272,6 +272,18 @@ class Realm {
* @returns {true} if compaction succeeds.
*/
compact() {}
/**
* Writes a compacted copy of the Realm to the given path.
*
* The destination file cannot already exist.
*
* Note that if this method is called from within a write transaction, the current data is written,
* not the data from the point when the previous write transaction was committed.
* @param {string} path path to save the Realm to
* @param {ArrayBuffer|ArrayBufferView} [encryptionKey] - Optional 64-byte encryption key to encrypt the new file with.
*/
writeCopyTo(path, encryptionKey) {}
}
/**

8
lib/index.d.ts vendored
View File

@ -677,6 +677,14 @@ declare class Realm {
*/
compact(): boolean;
/**
* Write a copy to destination path
* @param path destination path
* @param encryptionKey encryption key to use
* @returns void
*/
writeCopyTo(path: string, encryptionKey?: ArrayBuffer | ArrayBufferView): void;
privileges() : Realm.Permissions.Realm;
privileges(objectType: string | Realm.ObjectSchema | Function) : Realm.Permissions.Class;
privileges(obj: Realm.Object) : Realm.Permissions.Class;

View File

@ -183,6 +183,7 @@ public:
static void remove_all_listeners(ContextType, ObjectType, Arguments, ReturnValue &);
static void close(ContextType, ObjectType, Arguments, ReturnValue &);
static void compact(ContextType, ObjectType, Arguments, ReturnValue &);
static void writeCopyTo(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&);
@ -241,6 +242,7 @@ public:
{"removeAllListeners", wrap<remove_all_listeners>},
{"close", wrap<close>},
{"compact", wrap<compact>},
{"writeCopyTo", wrap<writeCopyTo>},
{"deleteModel", wrap<delete_model>},
{"privileges", wrap<privileges>},
{"_objectForObjectId", wrap<object_for_object_id>},
@ -1004,6 +1006,36 @@ void RealmClass<T>::compact(ContextType ctx, ObjectType this_object, Arguments a
return_value.set(realm->compact());
}
template<typename T>
void RealmClass<T>::writeCopyTo(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue &return_value) {
args.validate_maximum(2);
if (args.count == 0) {
throw std::runtime_error("At least path has to be provided for 'writeCopyTo'");
}
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
ValueType pathValue = args[0];
if (!Value::is_string(ctx, pathValue)) {
throw std::runtime_error("Argument to 'writeCopyTo' must be a String.");
}
std::string path = Value::validated_to_string(ctx, pathValue);
BinaryData key;
if (args.count == 2) {
ValueType key_value = args[1];
if (!Value::is_binary(ctx, key_value)) {
throw std::runtime_error("Encryption key for 'writeCopyTo' must be a Binary.");
}
auto key_data = Value::validated_to_binary(ctx, key_value);
key = { static_cast<const char *>(key_data.data()), key_data.size() };
}
realm->write_copy(path, key);
}
template<typename T>
void RealmClass<T>::object_for_object_id(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue& return_value) {
args.validate_count(2);

View File

@ -56,7 +56,7 @@ module.exports = {
const realm2 = new Realm({schema: [], path: testPath2});
TestCase.assertEqual(realm2.path, defaultDir + testPath2);
},
testRealmIsClosed: function() {
const realm = new Realm({schema: []});
TestCase.assertFalse(realm.isClosed);
@ -1200,8 +1200,49 @@ module.exports = {
testDisableFileFormatUpgrade: function() {
Realm.copyBundledRealmFiles();
TestCase.assertThrowsContaining(() => {
TestCase.assertThrowsContaining(() => {
new Realm({ path: 'dates-v3.realm', disableFormatUpgrade: true } );
}, 'The Realm file format must be allowed to be upgraded in order to proceed.');
},
testWriteCopyTo: function() {
const realm = new Realm({schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject, schemas.LinkToAllTypes]});
realm.write(() => {
realm.create('TestObject', {doubleCol: 1});
});
TestCase.assertEqual(1, realm.objects('TestObject').length);
TestCase.assertThrowsContaining(() => {
realm.writeCopyTo();
}, "At least path has to be provided for 'writeCopyTo'");
TestCase.assertThrowsContaining(() => {
realm.writeCopyTo(34);
}, "Argument to 'writeCopyTo' must be a String.");
const copyName = "testWriteCopy.realm";
realm.writeCopyTo(copyName);
const copyConfig = { path: copyName };
const realmCopy = new Realm(copyConfig);
TestCase.assertEqual(1, realmCopy.objects('TestObject').length);
realmCopy.close();
TestCase.assertThrowsContaining(() => {
realm.writeCopyTo("testWriteCopyWithInvalidKey.realm", "hello");
}, "Encryption key for 'writeCopyTo' must be a Binary.");
const encryptedCopyName = "testWriteEncryptedCopy.realm";
var encryptionKey = new Int8Array(64);
encryptionKey[0] = 1;
realm.writeCopyTo(encryptedCopyName, encryptionKey);
const encryptedCopyConfig = { path: encryptedCopyName, encryptionKey: encryptionKey };
const encryptedRealmCopy = new Realm(encryptedCopyConfig);
TestCase.assertEqual(1, encryptedRealmCopy.objects('TestObject').length);
encryptedRealmCopy.close();
realm.close();
}
};