Example #1
0
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.name);
        if (!table) {
            continue;
        }

        for (auto& property : object_schema.persisted_properties) {
            if (property.requires_index() == table->has_search_index(property.table_column)) {
                continue;
            }

            changed = true;
            if (property.requires_index()) {
                try {
                    table->add_search_index(property.table_column);
                }
                catch (LogicError const&) {
                    throw PropertyTypeNotIndexableException(object_schema.name, property);
                }
            }
            else {
                table->remove_search_index(property.table_column);
            }
        }
    }
    return changed;
}
Example #2
0
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.name);
        if (!table) {
            continue;
        }

        for (auto& property : object_schema.properties) {
            if (property.requires_index() == table->has_search_index(property.table_column)) {
                continue;
            }

            changed = true;
            if (property.requires_index()) {
                try {
                    table->add_search_index(property.table_column);
                }
                catch (LogicError const&) {
                    throw ObjectStoreException(ObjectStoreException::Kind::RealmPropertyTypeNotIndexable, {
                        {"object_type", object_schema.name},
                        {"property_name", property.name},
                        {"property_type", string_for_property_type(property.type)}
                    });
                }
            }
            else {
                table->remove_search_index(property.table_column);
            }
        }
    }
    return changed;
}
Example #3
0
void ObjectStore::rename_property(Group *group, Schema& passed_schema, StringData object_type, StringData old_name, StringData new_name) {
    TableRef table = table_for_object_type(group, object_type);
    if (!table) {
        throw PropertyRenameMissingNewObjectTypeException(object_type);
    }
    ObjectSchema matching_schema(group, object_type);
    Property *old_property = matching_schema.property_for_name(old_name);
    if (old_property == nullptr) {
        throw PropertyRenameMissingOldPropertyException(old_name, new_name);
    }
    auto passed_object_schema = passed_schema.find(object_type);
    if (passed_object_schema == passed_schema.end()) {
        throw PropertyRenameMissingNewObjectTypeException(object_type);
    }
    Property *new_property = matching_schema.property_for_name(new_name);
    if (new_property == nullptr) {
        // new property not in new schema, which means we're probably renaming
        // to an intermediate property in a multi-version migration.
        // this is safe because the migration will fail schema validation unless
        // this property is renamed again.
        new_property = matching_schema.property_for_name(old_name);
        new_property->name = new_name;
        table->rename_column(old_property->table_column, new_name);
        return;
    }
    if (old_property->type != new_property->type ||
        old_property->object_type != new_property->object_type) {
        throw PropertyRenameTypeMismatchException(*old_property, *new_property);
    }
    if (passed_object_schema->property_for_name(old_name) != nullptr) {
        throw PropertyRenameOldStillExistsException(old_name, new_name);
    }
    size_t column_to_remove = new_property->table_column;
    table->rename_column(old_property->table_column, new_name);
    table->remove_column(column_to_remove);
    // update table_column for each property since it may have shifted
    for (auto& current_prop : passed_object_schema->persisted_properties) {
        auto target_prop = matching_schema.property_for_name(current_prop.name);
        current_prop.table_column = target_prop->table_column;
    }
    // update index for new column
    if (new_property->requires_index() && !old_property->requires_index()) {
        table->add_search_index(old_property->table_column);
    } else if (!new_property->requires_index() && old_property->requires_index()) {
        table->remove_search_index(old_property->table_column);
    }
    old_property->name = new_name;
    // update nullability for column
    if (property_can_be_migrated_to_nullable(*old_property, *new_property)) {
        new_property->table_column = old_property->table_column;
        old_property->table_column = old_property->table_column + 1;

        table->insert_column(new_property->table_column, DataType(new_property->type), new_property->name, new_property->is_nullable);
        copy_property_values(*old_property, *new_property, *table);
        table->remove_column(old_property->table_column);

        old_property->table_column = new_property->table_column;
    }
}