Add support for the concept of computed properties.

This commit is contained in:
Mark Rowe 2016-04-05 17:02:01 -07:00 committed by Thomas Goyne
parent 64e733e4d7
commit abca7c26e1
4 changed files with 28 additions and 18 deletions

View File

@ -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<Property> properties)
ObjectSchema::ObjectSchema(std::string name, std::string primary_key, std::initializer_list<Property> 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 &prop;
}
}
for (auto& prop : computed_properties) {
if (StringData(prop.name) == name) {
return &prop;
}

View File

@ -31,7 +31,7 @@ struct Property;
class ObjectSchema {
public:
ObjectSchema();
ObjectSchema(std::string name, std::string primary_key, std::initializer_list<Property> properties);
ObjectSchema(std::string name, std::string primary_key, std::initializer_list<Property> 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<Property> properties;
std::vector<Property> persisted_properties;
std::vector<Property> computed_properties;
std::string primary_key;
Property *property_for_name(StringData name);

View File

@ -180,7 +180,7 @@ std::vector<ObjectSchemaValidationException> ObjectStore::verify_object_schema(O
std::vector<ObjectSchemaValidationException> 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<ObjectSchemaValidationException> 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<Property> &target_props = target_object_schema->properties;
std::vector<Property> &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;
}

View File

@ -66,7 +66,11 @@ void Schema::validate() const
std::vector<ObjectSchemaValidationException> exceptions;
for (auto const& object : *this) {
const Property *primary = nullptr;
for (auto const& prop : object.properties) {
std::vector<Property> 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));