Merge pull request #338 from realm/al-schema-version

Support getting the schema version from unopened realms
This commit is contained in:
Ari Lazier 2016-03-21 13:57:02 -07:00
commit ad32fdd3c0
5 changed files with 80 additions and 3 deletions

View File

@ -10,6 +10,7 @@
* Support relative paths when opening realms
* Support case insensitive queries
* Support for indexed bool, string, and int properties
* Added method to retrieve schemaVersion from an unopened Realm
### Bugfixes
* Fix for crash on Android when initializing the Realm module

View File

@ -103,6 +103,17 @@ class Realm {
write(callback) {}
}
/**
* Get the current schema version of the Realm at the given path.
* @param {string} path - The path to the file where the
* Realm database is stored.
* @param {ArrayBuffer|ArrayBufferView} [encryptionKey] - Required only when
* accessing encrypted Realms.
* @throws {Error} When passing an invalid or non-matching encryption key.
* @returns {number} version of the schema, or `-1` if no Realm exists at `path`.
*/
Realm.schemaVersion = function(path, encryptionKey) {};
/**
* The default path where to create and access the Realm file.
* @type {string}

View File

@ -172,6 +172,11 @@ Object.defineProperties(Realm, {
get: util.getterForProperty('defaultPath'),
set: util.setterForProperty('defaultPath'),
},
schemaVersion: {
value: function(path, encryptionKey) {
return rpc.callMethod(undefined, Realm[keys.id], 'schemaVersion', Array.from(arguments));
}
},
clearTestState: {
value: function() {
util.clearMutationListeners();

View File

@ -149,6 +149,13 @@ static bool SetDefaultPath(JSContextRef ctx, JSObjectRef object, JSStringRef pro
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;
@ -202,9 +209,7 @@ JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t a
return NULL;
}
if (config.path.size() && config.path[0] != '/') {
config.path = default_realm_file_directory() + "/" + config.path;
}
config.path = RJSNormalizePath(config.path);
ensure_directory_exists_for_file(config.path);
SharedRealm realm = Realm::get_shared_realm(config);
@ -232,6 +237,39 @@ static const JSStaticValue RealmStaticProperties[] = {
{NULL, NULL}
};
JSValueRef RealmSchemaVersion(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException) {
try {
RJSValidateArgumentRange(argumentCount, 1, 2);
Realm::Config config;
config.path = RJSNormalizePath(RJSValidatedStringForValue(ctx, arguments[0]));
if (argumentCount == 2) {
JSValueRef 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);
if (version == ObjectStore::NotVersioned) {
return JSValueMakeNumber(ctx, -1);
}
else {
return JSValueMakeNumber(ctx, version);
}
}
catch (std::exception &exp) {
if (jsException) {
*jsException = RJSMakeError(ctx, exp);
}
}
return NULL;
}
static const JSStaticFunction RealmConstructorFuncs[] = {
{"schemaVersion", RealmSchemaVersion, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL},
};
JSClassRef RJSRealmConstructorClass() {
JSClassDefinition realmConstructorDefinition = kJSClassDefinitionEmpty;
realmConstructorDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
@ -239,6 +277,7 @@ JSClassRef RJSRealmConstructorClass() {
realmConstructorDefinition.callAsConstructor = RealmConstructor;
realmConstructorDefinition.hasInstance = RealmHasInstance;
realmConstructorDefinition.staticValues = RealmStaticProperties;
realmConstructorDefinition.staticFunctions = RealmConstructorFuncs;
return JSClassCreate(&realmConstructorDefinition);
}

View File

@ -117,6 +117,27 @@ module.exports = BaseTest.extend({
TestCase.assertEqual(Realm.defaultPath, newPath, "defaultPath should have been updated");
},
testRealmSchemaVersion: function() {
TestCase.assertEqual(Realm.schemaVersion(Realm.defaultPath), -1);
var realm = new Realm({schema: []});
TestCase.assertEqual(Realm.schemaVersion(Realm.defaultPath), 0);
realm = new Realm({schema: [], schemaVersion: 2, path: 'another.realm'});
TestCase.assertEqual(Realm.schemaVersion('another.realm'), 2);
var encryptionKey = new Int8Array(64);
realm = new Realm({schema: [], schemaVersion: 3, path: 'encrypted.realm', encryptionKey: encryptionKey});
TestCase.assertEqual(Realm.schemaVersion('encrypted.realm', encryptionKey), 3);
TestCase.assertThrows(function() {
Realm.schemaVersion('encrypted.realm', encryptionKey, 'extra');
});
TestCase.assertThrows(function() {
Realm.schemaVersion('encrypted.realm', 'asdf');
});
},
testRealmCreate: function() {
var realm = new Realm({schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject]});