validate primary keys after migrations

This commit is contained in:
Ari Lazier 2015-06-04 18:14:53 -07:00
parent 1ccf9f6192
commit 3c9953f4c6
3 changed files with 27 additions and 5 deletions

View File

@ -18,6 +18,9 @@
#include "object_store.hpp"
#include <realm/link_view.hpp>
#include <realm/table_view.hpp>
using namespace realm;
using namespace std;
@ -289,18 +292,19 @@ bool ObjectStore::update_realm_with_schema(realm::Group *group,
}
}
changed = changed | update_indexes(group, schema);
changed = update_indexes(group, schema) | changed;
if (!migrating) {
return changed;
}
// apply the migration block if provided and there's any old data
// to be migrated
if (get_schema_version(group) != realm::ObjectStore::NotVersioned) {
migration();
}
validate_primary_column_uniqueness(group, schema);
set_schema_version(group, version);
return true;
}
@ -325,7 +329,7 @@ bool ObjectStore::are_indexes_up_to_date(Group *group, Schema &schema) {
validate_schema_and_update_column_mapping(group, object_schema); // FIXME we just need the column mapping
for (auto &property:object_schema.properties) {
if (property.is_indexed != table->has_search_index(property.table_column)) {
if (property.requires_index() != table->has_search_index(property.table_column)) {
return false;
}
}
@ -342,12 +346,12 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {
}
for (auto &property:object_schema.properties) {
if (property.is_indexed == table->has_search_index(property.table_column)) {
if (property.requires_index() == table->has_search_index(property.table_column)) {
continue;
}
changed = true;
if (property.is_indexed) {
if (property.requires_index()) {
try {
table->add_search_index(property.table_column);
}
@ -364,3 +368,16 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {
return changed;
}
void ObjectStore::validate_primary_column_uniqueness(Group *group, Schema &schema) {
for (auto &object_schema:schema) {
auto primary_prop = object_schema.primary_key_property();
if (primary_prop == object_schema.properties.end()) {
continue;
}
realm::TableRef table = table_for_object_type(group, object_schema.name);
if (table->get_distinct_view(primary_prop->table_column).size() != table->size()) {
throw ObjectStoreException(ObjectStoreException::RealmDuplicatePrimaryKeyValue, {{"object_type", object_schema.name}, {"property_name", primary_prop->name}});
}
}
}

View File

@ -89,6 +89,9 @@ namespace realm {
// returns if any indexes were changed
static bool update_indexes(Group *group, Schema &schema);
// validates that all primary key properties have unique values
static void validate_primary_column_uniqueness(Group *group, Schema &schema);
friend ObjectSchema;
};
@ -98,6 +101,7 @@ namespace realm {
// thrown when calling update_realm_to_schema and the realm version is greater than the given version
RealmVersionGreaterThanSchemaVersion,
RealmPropertyTypeNotIndexable, // object_type, property_name, property_type
RealmDuplicatePrimaryKeyValue, // object_type, property_name
};
typedef std::map<std::string, std::string> Dict;

View File

@ -54,6 +54,7 @@ namespace realm {
bool is_indexed;
size_t table_column;
bool requires_index() { return is_primary | is_indexed; }
};
static inline const char *string_for_property_type(PropertyType type) {