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; }
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; }
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; } }