From 9f124ab37e6136ea0d11fb898ace40322a767e8a Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Fri, 5 Jun 2015 18:47:19 -0700 Subject: [PATCH] don't verify when not told to, reuse tables in cases it isn't inconvinient --- object_schema.cpp | 10 ++++++++-- object_schema.hpp | 6 +++++- object_store.cpp | 38 +++++++++++++++++++------------------- object_store.hpp | 5 +++-- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/object_schema.cpp b/object_schema.cpp index e4cbc195..ca18d17e 100644 --- a/object_schema.cpp +++ b/object_schema.cpp @@ -22,8 +22,13 @@ using namespace realm; using namespace std; -ObjectSchema::ObjectSchema(realm::Group *group, const std::string &name) : name(name) { - TableRef table = ObjectStore::table_for_object_type(group, name); +ObjectSchema::ObjectSchema(Group *group, const std::string &name, Table *table) : name(name) { + TableRef tableRef; + if (!table) { + tableRef = ObjectStore::table_for_object_type(group, name); + table = tableRef.get(); + } + size_t count = table->get_column_count(); for (size_t col = 0; col < count; col++) { Property property; @@ -63,3 +68,4 @@ Property *ObjectSchema::property_for_name(const std::string &name) { } return nullptr; } + diff --git a/object_schema.hpp b/object_schema.hpp index 54ee2a14..485ceb09 100644 --- a/object_schema.hpp +++ b/object_schema.hpp @@ -24,12 +24,16 @@ #include "property.hpp" #include +#include namespace realm { class ObjectSchema { public: ObjectSchema() {} - ObjectSchema(Group *group, const std::string &name); + + // create object schema from existing table + // if no table is provided it is looked up in the group + ObjectSchema(Group *group, const std::string &name, Table *table = nullptr); std::string name; std::vector properties; diff --git a/object_store.cpp b/object_store.cpp index b8021c33..4c08f406 100644 --- a/object_store.cpp +++ b/object_store.cpp @@ -128,9 +128,9 @@ realm::TableRef ObjectStore::table_for_object_type_create_if_needed(realm::Group return group->get_or_add_table(table_name_for_object_type(object_type), &created); } -std::vector ObjectStore::validate_schema(realm::Group *group, ObjectSchema &target_schema) { +std::vector ObjectStore::validate_schema(realm::Group *group, ObjectSchema &target_schema, Table *cached_table) { vector validation_errors; - ObjectSchema table_schema(group, target_schema.name); + ObjectSchema table_schema(group, target_schema.name, cached_table); // check to see if properties are the same for (auto& current_prop:table_schema.properties) { @@ -211,11 +211,10 @@ bool ObjectStore::create_tables(realm::Group *group, ObjectStore::Schema &target } // second pass adds/removes columns for out of date tables - for (auto target_schema:to_update) { - TableRef table = ObjectStore::table_for_object_type(group, target_schema->name); - - ObjectSchema current_schema(group, target_schema->name); - vector &target_props = target_schema->properties; + for (auto target_object_schema:to_update) { + TableRef table = table_for_object_type(group, target_object_schema->name); + ObjectSchema current_schema(group, target_object_schema->name, table.get()); + vector &target_props = target_object_schema->properties; // add missing columns for (auto target_prop:target_props) { @@ -244,7 +243,7 @@ bool ObjectStore::create_tables(realm::Group *group, ObjectStore::Schema &target return (j.table_column < i.table_column); }); for (auto& current_prop:current_schema.properties) { - auto target_prop_iter = target_schema->property_for_name(current_prop.name); + auto target_prop_iter = target_object_schema->property_for_name(current_prop.name); if (!target_prop_iter || property_has_changed(current_prop, *target_prop_iter)) { table->remove_column(current_prop.table_column); changed = true; @@ -252,16 +251,16 @@ bool ObjectStore::create_tables(realm::Group *group, ObjectStore::Schema &target } // update table metadata - if (target_schema->primary_key.length()) { + if (target_object_schema->primary_key.length()) { // if there is a primary key set, check if it is the same as the old key - if (!current_schema.primary_key.length() || current_schema.primary_key != target_schema->primary_key) { - realm::ObjectStore::set_primary_key_for_object(group, target_schema->name, target_schema->primary_key); + if (!current_schema.primary_key.length() || current_schema.primary_key != target_object_schema->primary_key) { + realm::ObjectStore::set_primary_key_for_object(group, target_object_schema->name, target_object_schema->primary_key); changed = true; } } else if (current_schema.primary_key.length()) { // there is no primary key, so if there was one nil out - realm::ObjectStore::set_primary_key_for_object(group, target_schema->name, ""); + realm::ObjectStore::set_primary_key_for_object(group, target_object_schema->name, ""); changed = true; } } @@ -288,13 +287,14 @@ bool ObjectStore::update_realm_with_schema(realm::Group *group, bool migrating = is_migration_required(group, version); // create tables - bool changed = create_metadata_tables(group) | create_tables(group, schema, migrating); - for (auto& target_schema:schema) { - TableRef table = table_for_object_type(group, target_schema.name); + bool changed = create_metadata_tables(group); + changed = create_tables(group, schema, migrating) | changed; + for (auto& target_schema:schema) { // read-only realms may be missing tables entirely + TableRef table = table_for_object_type(group, target_schema.name); if (table) { - auto errors = validate_schema(group, target_schema); + auto errors = validate_schema(group, target_schema, table.get()); if (errors.size()) { throw ObjectStoreValidationException(errors, target_schema.name); } @@ -309,7 +309,7 @@ bool ObjectStore::update_realm_with_schema(realm::Group *group, // apply the migration block if provided and there's any old data if (get_schema_version(group) != realm::ObjectStore::NotVersioned) { - migration(); + migration(group, schema); } validate_primary_column_uniqueness(group, schema); @@ -387,9 +387,9 @@ void ObjectStore::validate_primary_column_uniqueness(Group *group, Schema &schem continue; } - realm::TableRef table = table_for_object_type(group, object_schema.name); + TableRef table = table_for_object_type(group, object_schema.name); if (table->get_distinct_view(primary_prop->table_column).size() != table->size()) { throw ObjectStoreException(ObjectStoreException::RealmDuplicatePrimaryKeyValue, {{"object_type", object_schema.name}, {"property_name", primary_prop->name}}); } } -} \ No newline at end of file +} diff --git a/object_store.hpp b/object_store.hpp index f067c605..88722b31 100644 --- a/object_store.hpp +++ b/object_store.hpp @@ -36,8 +36,9 @@ namespace realm { // verify a target schema against its table, setting the table_column property on each schema object // updates the column mapping on the target_schema + // if no table is provided it is fetched from the group // returns array of validation errors - static std::vector validate_schema(Group *group, ObjectSchema &target_schema); + static std::vector validate_schema(Group *group, ObjectSchema &target_schema, Table *cached_table = nullptr); // updates the target_column member for all properties based on the column indexes in the passed in group static void update_column_mapping(Group *group, ObjectSchema &target_schema); @@ -47,8 +48,8 @@ namespace realm { // passed in schema ar updated with the correct column mapping // optionally runs migration function/lambda if schema is out of date // NOTE: must be performed within a write transaction - typedef std::function MigrationFunction; typedef std::vector Schema; + typedef std::function MigrationFunction; static bool update_realm_with_schema(Group *group, uint64_t version, Schema &schema, MigrationFunction migration); // get a table for an object type