From abca7c26e1d4a015a40c6d59fd9ec58ce9aee2ae Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Tue, 5 Apr 2016 17:02:01 -0700 Subject: [PATCH] Add support for the concept of computed properties. --- src/object_schema.cpp | 15 ++++++++++----- src/object_schema.hpp | 5 +++-- src/object_store.cpp | 20 ++++++++++---------- src/schema.cpp | 6 +++++- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/object_schema.cpp b/src/object_schema.cpp index f794c34a..6eb819d4 100644 --- a/src/object_schema.cpp +++ b/src/object_schema.cpp @@ -43,9 +43,9 @@ ASSERT_PROPERTY_TYPE_VALUE(Array, LinkList); ObjectSchema::ObjectSchema() = default; ObjectSchema::~ObjectSchema() = default; -ObjectSchema::ObjectSchema(std::string name, std::string primary_key, std::initializer_list properties) +ObjectSchema::ObjectSchema(std::string name, std::string primary_key, std::initializer_list persisted_properties) : name(std::move(name)) -, properties(properties) +, persisted_properties(persisted_properties) , primary_key(std::move(primary_key)) { set_primary_key_property(); @@ -55,7 +55,7 @@ ObjectSchema::ObjectSchema(const Group *group, const std::string &name) : name(n ConstTableRef table = ObjectStore::table_for_object_type(group, name); size_t count = table->get_column_count(); - properties.reserve(count); + persisted_properties.reserve(count); for (size_t col = 0; col < count; col++) { Property property; property.name = table->get_column_name(col).data(); @@ -69,7 +69,7 @@ ObjectSchema::ObjectSchema(const Group *group, const std::string &name) : name(n ConstTableRef linkTable = table->get_link_target(col); property.object_type = ObjectStore::object_type_for_table_name(linkTable->get_name().data()); } - properties.push_back(std::move(property)); + persisted_properties.push_back(std::move(property)); } primary_key = realm::ObjectStore::get_primary_key_for_object(group, name); @@ -77,7 +77,12 @@ ObjectSchema::ObjectSchema(const Group *group, const std::string &name) : name(n } Property *ObjectSchema::property_for_name(StringData name) { - for (auto& prop : properties) { + for (auto& prop : persisted_properties) { + if (StringData(prop.name) == name) { + return ∝ + } + } + for (auto& prop : computed_properties) { if (StringData(prop.name) == name) { return ∝ } diff --git a/src/object_schema.hpp b/src/object_schema.hpp index f18a5a2d..71d56d69 100644 --- a/src/object_schema.hpp +++ b/src/object_schema.hpp @@ -31,7 +31,7 @@ struct Property; class ObjectSchema { public: ObjectSchema(); - ObjectSchema(std::string name, std::string primary_key, std::initializer_list properties); + ObjectSchema(std::string name, std::string primary_key, std::initializer_list persisted_properties); ~ObjectSchema(); // create object schema from existing table @@ -39,7 +39,8 @@ public: ObjectSchema(const Group *group, const std::string &name); std::string name; - std::vector properties; + std::vector persisted_properties; + std::vector computed_properties; std::string primary_key; Property *property_for_name(StringData name); diff --git a/src/object_store.cpp b/src/object_store.cpp index c7122687..d44d9674 100644 --- a/src/object_store.cpp +++ b/src/object_store.cpp @@ -180,7 +180,7 @@ std::vector ObjectStore::verify_object_schema(O std::vector exceptions; // check to see if properties are the same - for (auto& current_prop : table_schema.properties) { + for (auto& current_prop : table_schema.persisted_properties) { auto target_prop = target_schema.property_for_name(current_prop.name); if (!target_prop) { @@ -202,7 +202,7 @@ std::vector ObjectStore::verify_object_schema(O } // check for new missing properties - for (auto& target_prop : target_schema.properties) { + for (auto& target_prop : target_schema.persisted_properties) { if (!table_schema.property_for_name(target_prop.name)) { exceptions.emplace_back(ExtraPropertyException(table_schema.name, target_prop)); } @@ -270,10 +270,10 @@ void ObjectStore::create_tables(Group *group, Schema &target_schema, bool update 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); - std::vector &target_props = target_object_schema->properties; + std::vector &target_props = target_object_schema->persisted_properties; // handle columns changing from required to optional - for (auto& current_prop : current_schema.properties) { + for (auto& current_prop : current_schema.persisted_properties) { auto target_prop = target_object_schema->property_for_name(current_prop.name); if (!target_prop || !property_can_be_migrated_to_nullable(current_prop, *target_prop)) continue; @@ -292,13 +292,13 @@ void ObjectStore::create_tables(Group *group, Schema &target_schema, bool update // remove extra columns size_t deleted = 0; - for (auto& current_prop : current_schema.properties) { + for (auto& current_prop : current_schema.persisted_properties) { current_prop.table_column -= deleted; auto target_prop = target_object_schema->property_for_name(current_prop.name); if (!target_prop || (property_has_changed(current_prop, *target_prop) && !property_can_be_migrated_to_nullable(current_prop, *target_prop))) { - if (deleted == current_schema.properties.size() - 1) { + if (deleted == current_schema.persisted_properties.size() - 1) { // We're about to remove the last column from the table. Insert a placeholder column to preserve // the number of rows in the table for the addition of new columns below. table->add_column(type_Bool, "placeholder"); @@ -377,14 +377,14 @@ bool ObjectStore::needs_update(Schema const& old_schema, Schema const& schema) { return true; } - if (matching_schema->properties.size() != target_schema.properties.size()) { + if (matching_schema->persisted_properties.size() != target_schema.persisted_properties.size()) { // If the number of properties don't match then a migration is required return false; } // Check that all of the property indexes are up to date - for (size_t i = 0, count = target_schema.properties.size(); i < count; ++i) { - if (target_schema.properties[i].is_indexed != matching_schema->properties[i].is_indexed) { + for (size_t i = 0, count = target_schema.persisted_properties.size(); i < count; ++i) { + if (target_schema.persisted_properties[i].is_indexed != matching_schema->persisted_properties[i].is_indexed) { return true; } } @@ -446,7 +446,7 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) { continue; } - for (auto& property : object_schema.properties) { + for (auto& property : object_schema.persisted_properties) { if (property.requires_index() == table->has_search_index(property.table_column)) { continue; } diff --git a/src/schema.cpp b/src/schema.cpp index 2d036041..e794fb67 100644 --- a/src/schema.cpp +++ b/src/schema.cpp @@ -66,7 +66,11 @@ void Schema::validate() const std::vector exceptions; for (auto const& object : *this) { const Property *primary = nullptr; - for (auto const& prop : object.properties) { + + std::vector all_properties = object.persisted_properties; + all_properties.insert(all_properties.end(), object.computed_properties.begin(), object.computed_properties.end()); + + for (auto const& prop : all_properties) { // check object_type existence if (!prop.object_type.empty() && find(prop.object_type) == end()) { exceptions.emplace_back(MissingObjectTypeException(object.name, prop));