run migrations and schema update through new Realm apis

This commit is contained in:
Ari Lazier 2015-06-22 10:32:31 -07:00
parent 60700ba121
commit 2a0a5d234f
4 changed files with 54 additions and 15 deletions

View File

@ -351,7 +351,7 @@ bool ObjectStore::is_schema_at_version(Group *group, uint64_t version) {
if (old_version > version && old_version != NotVersioned) {
throw ObjectStoreException(old_version, version);
}
return old_version != version;
return old_version == version;
}
@ -362,7 +362,7 @@ bool ObjectStore::update_realm_with_schema(Group *group,
// Recheck the schema version after beginning the write transaction as
// another process may have done the migration after we opened the read
// transaction
bool migrating = is_schema_at_version(group, version);
bool migrating = !is_schema_at_version(group, version);
// create tables
bool changed = create_metadata_tables(group);

View File

@ -59,10 +59,9 @@ ObjectStoreException::ObjectStoreException(uint64_t old_version, uint64_t new_ve
}
ObjectStoreException::ObjectStoreException(vector<ObjectStoreException> validation_errors, const string &object_type) :
m_validation_errors(validation_errors),
m_kind(Kind::ObjectStoreValidationFailure),
m_info({{InfoKeyObjectType, object_type}}),
m_what(generate_what()) {
m_validation_errors(validation_errors), m_kind(Kind::ObjectStoreValidationFailure) {
m_info[InfoKeyObjectType] = object_type;
m_what = generate_what();
}
string ObjectStoreException::generate_what() const {
@ -88,7 +87,7 @@ std::string ObjectStoreException::populate_format_string(const std::string & for
while(regex_search(current, sm, re)) {
out_string += sm.prefix();
const string &key = sm[1];
if (key == "ValidationString") {
if (key == "ValidationErrors") {
out_string += validation_errors_string();
}
else {

View File

@ -84,13 +84,14 @@ SharedRealm Realm::get_shared_realm(Config &config)
return realm;
}
realm = make_shared<Realm>(config);
realm = SharedRealm(new Realm(config));
// we want to ensure we are only initializing a single realm at a time
lock_guard<mutex> lock(s_init_mutex);
if (!config.schema) {
// get schema from group and skip validation
realm->m_config.schema_version = ObjectStore::get_schema_version(realm->read_group());
realm->m_config.schema = make_unique<ObjectStore::Schema>(ObjectStore::schema_from_group(realm->read_group()));
}
else if (config.read_only) {
@ -107,21 +108,45 @@ SharedRealm Realm::get_shared_realm(Config &config)
realm->m_config.schema = make_unique<ObjectStore::Schema>(*existing->m_config.schema);
}
else {
// its a new realm so update/migrate if needed
ObjectStore::update_realm_with_schema(realm->read_group(), config.schema_version, *realm->m_config.schema, realm->m_config.migration_function);
// its a non-cached realm so update/migrate if needed
realm->update_schema(*realm->m_config.schema, config.schema_version);
}
s_global_cache.cache_realm(realm, realm->m_thread_id);
return realm;
}
static void check_read_write(Realm *realm) {
bool Realm::update_schema(ObjectStore::Schema &schema, uint64_t version)
{
bool changed = false;
try {
begin_transaction();
changed = ObjectStore::update_realm_with_schema(read_group(), version, schema, m_config.migration_function);
commit_transaction();
m_config.schema_version = version;
if (m_config.schema.get() != &schema) {
m_config.schema = make_unique<ObjectStore::Schema>(schema);
}
}
catch (...) {
if (is_in_transaction()) {
cancel_transaction();
}
throw;
}
return changed;
}
static void check_read_write(Realm *realm)
{
if (realm->config().read_only) {
throw RealmException(RealmException::Kind::InvalidTransaction, "Can't perform transactions on read-only Realms.");
}
}
void Realm::verify_thread() {
void Realm::verify_thread()
{
if (m_thread_id != this_thread::get_id()) {
throw RealmException(RealmException::Kind::IncorrectThread, "Realm accessed from incorrect thread.");
}

View File

@ -52,11 +52,20 @@ namespace realm {
Config(const Config& c);
};
Realm(Config &config);
Realm(const Realm& r) = delete;
// Get a cached Realm or create a new one if no cached copies exists
// Caching is done by path - mismatches for inMemory and readOnly Config properties
// will raise an exception
// If schema/schema_version is specified, update_schema is called automatically on the realm
// and a migration is performed. If not specified, the schema version and schema are dynamically
// read from the the existing Realm.
static SharedRealm get_shared_realm(Config &config);
// Updates a Realm to a given target schema/version creating tables and updating indexes as necessary
// Uses the existing migration function on the Config, and the resulting Schema and version with updated
// column mappings are set on the realms config upon success.
// returns if any changes were made
bool update_schema(ObjectStore::Schema &schema, uint64_t version);
const Config &config() const { return m_config; }
void begin_transaction();
@ -83,6 +92,9 @@ namespace realm {
const std::string DidChangeNotification = "DidChangeNotification";
private:
Realm(Config &config);
//Realm(const Realm& r) = delete;
Config m_config;
std::thread::id m_thread_id;
bool m_in_transaction;
@ -131,6 +143,9 @@ namespace realm {
IncompatibleLockFile,
InvalidTransaction,
IncorrectThread,
/** Thrown when trying to open an unitialized Realm without a target schema or with a mismatching
schema version **/
InvalidSchemaVersion
};
RealmException(Kind kind, std::string message) : m_kind(kind), m_what(message) {}