diff --git a/object_store.cpp b/object_store.cpp index 17ccd41c..908ddbec 100644 --- a/object_store.cpp +++ b/object_store.cpp @@ -140,18 +140,24 @@ static inline bool property_has_changed(Property &p1, Property &p2) { return p1.type != p2.type || p1.name != p2.name || p1.object_type != p2.object_type || p1.is_nullable != p2.is_nullable; } +static bool compare_by_name(ObjectSchema const& lft, ObjectSchema const& rgt) { + return lft.name < rgt.name; +} + void ObjectStore::verify_schema(Group *group, Schema &target_schema, bool allow_missing_tables) { + std::sort(begin(target_schema), end(target_schema), compare_by_name); + std::vector errors; for (auto &object_schema : target_schema) { - if (!table_for_object_type(group, object_schema.first)) { + if (!table_for_object_type(group, object_schema.name)) { if (!allow_missing_tables) { - errors.emplace_back(ObjectSchemaValidationException(object_schema.first, - "Missing table for object type '" + object_schema.first + "'.")); + errors.emplace_back(ObjectSchemaValidationException(object_schema.name, + "Missing table for object type '" + object_schema.name + "'.")); } continue; } - auto more_errors = verify_object_schema(group, object_schema.second, target_schema); + auto more_errors = verify_object_schema(group, object_schema, target_schema); errors.insert(errors.end(), more_errors.begin(), more_errors.end()); } if (errors.size()) { @@ -163,6 +169,12 @@ std::vector ObjectStore::verify_object_schema(G std::vector exceptions; ObjectSchema table_schema(group, target_schema.name); + ObjectSchema cmp; + auto schema_contains_table = [&](std::string const& name) { + cmp.name = name; + return std::binary_search(begin(schema), end(schema), cmp, compare_by_name); + }; + // check to see if properties are the same Property *primary = nullptr; for (auto& current_prop : table_schema.properties) { @@ -178,7 +190,7 @@ std::vector ObjectStore::verify_object_schema(G } // check object_type existence - if (current_prop.object_type.length() && schema.find(current_prop.object_type) == schema.end()) { + if (current_prop.object_type.length() && !schema_contains_table(current_prop.object_type)) { exceptions.emplace_back(MissingObjectTypeException(table_schema.name, current_prop)); } @@ -249,11 +261,11 @@ bool ObjectStore::create_tables(Group *group, Schema &target_schema, bool update std::vector to_update; for (auto& object_schema : target_schema) { bool created = false; - ObjectStore::table_for_object_type_create_if_needed(group, object_schema.first, created); + ObjectStore::table_for_object_type_create_if_needed(group, object_schema.name, created); // we will modify tables for any new objectSchema (table was created) or for all if update_existing is true if (update_existing || created) { - to_update.push_back(&object_schema.second); + to_update.push_back(&object_schema); changed = true; } } @@ -330,7 +342,7 @@ bool ObjectStore::realm_requires_update(Group *group, uint64_t version, Schema & return true; } for (auto& target_schema : schema) { - TableRef table = table_for_object_type(group, target_schema.first); + TableRef table = table_for_object_type(group, target_schema.name); if (!table) { return true; } @@ -378,7 +390,7 @@ Schema ObjectStore::schema_from_group(Group *group) { for (size_t i = 0; i < group->size(); i++) { std::string object_type = object_type_for_table_name(group->get_table_name(i)); if (object_type.length()) { - schema.emplace(object_type, std::move(ObjectSchema(group, object_type))); + schema.emplace_back(group, object_type); } } return schema; @@ -386,13 +398,13 @@ Schema ObjectStore::schema_from_group(Group *group) { bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) { for (auto &object_schema : schema) { - TableRef table = table_for_object_type(group, object_schema.first); + TableRef table = table_for_object_type(group, object_schema.name); if (!table) { continue; } - update_column_mapping(group, object_schema.second); - for (auto& property : object_schema.second.properties) { + update_column_mapping(group, object_schema); + for (auto& property : object_schema.properties) { if (property.requires_index() != table->has_search_index(property.table_column)) { return false; } @@ -404,12 +416,12 @@ bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) { bool ObjectStore::update_indexes(Group *group, Schema &schema) { bool changed = false; for (auto& object_schema : schema) { - TableRef table = table_for_object_type(group, object_schema.first); + TableRef table = table_for_object_type(group, object_schema.name); if (!table) { continue; } - for (auto& property : object_schema.second.properties) { + for (auto& property : object_schema.properties) { if (property.requires_index() == table->has_search_index(property.table_column)) { continue; } @@ -420,7 +432,7 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) { table->add_search_index(property.table_column); } catch (LogicError const&) { - throw PropertyTypeNotIndexableException(object_schema.first, property); + throw PropertyTypeNotIndexableException(object_schema.name, property); } } else { @@ -433,14 +445,14 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) { void ObjectStore::validate_primary_column_uniqueness(Group *group, Schema &schema) { for (auto& object_schema : schema) { - auto primary_prop = object_schema.second.primary_key_property(); + auto primary_prop = object_schema.primary_key_property(); if (!primary_prop) { continue; } - TableRef table = table_for_object_type(group, object_schema.first); + TableRef table = table_for_object_type(group, object_schema.name); if (table->get_distinct_view(primary_prop->table_column).size() != table->size()) { - throw DuplicatePrimaryKeyValueException(object_schema.first, *primary_prop); + throw DuplicatePrimaryKeyValueException(object_schema.name, *primary_prop); } } } diff --git a/object_store.hpp b/object_store.hpp index 86bbe3ff..42b8749e 100644 --- a/object_store.hpp +++ b/object_store.hpp @@ -19,7 +19,6 @@ #ifndef REALM_OBJECT_STORE_HPP #define REALM_OBJECT_STORE_HPP -#include #include #include #include @@ -30,8 +29,7 @@ namespace realm { class ObjectSchemaValidationException; - class Schema : public std::map { - }; + using Schema = std::vector; class ObjectStore { public: diff --git a/shared_realm.cpp b/shared_realm.cpp index c46b654e..9d4a4a7f 100644 --- a/shared_realm.cpp +++ b/shared_realm.cpp @@ -284,7 +284,7 @@ bool Realm::compact() } for (auto &object_schema : *m_config.schema) { - ObjectStore::table_for_object_type(read_group(), object_schema.first)->optimize(); + ObjectStore::table_for_object_type(read_group(), object_schema.name)->optimize(); } m_shared_group->end_read();