super._followFetchSpecification(fetchSpec, relationshipName, sourceObjects, context);
}
@Override
public void _verifyNoChangesToReadonlyEntity(EODatabaseOperation dbOp) {
EOEntity entity = dbOp.entity();
if (entity.isReadOnly()) {
switch (dbOp.databaseOperator()) {
case 0: // '\0'
return;
case 1: // '\001'
throw new IllegalStateException("cannot insert object:" + dbOp.object() + " that corresponds to read-only entity: " + entity.name() + " in databaseContext " + this);
case 3: // '\003'
throw new IllegalStateException("cannot delete object:" + dbOp.object() + " that corresponds to read-only entity:" + entity.name() + " in databaseContext " + this);
case 2: // '\002'
if (!dbOp.dbSnapshot().equals(dbOp.newRow())) {
throw new IllegalStateException("cannot update '" + dbOp.rowDiffsForAttributes(entity.attributes()).allKeys() + "' keys on object:" + dbOp.object() + " that corresponds to read-only entity: " + entity.name() + " in databaseContext " + this);
}
return;
}
}
// HACK: ak these methods are protected, so we call them via KVC
if (dbOp.databaseOperator() == 2 && ((Boolean) NSKeyValueCoding.Utility.valueForKey(entity, "_hasNonUpdateableAttributes")).booleanValue()) {
NSArray keys = (NSArray) NSKeyValueCoding.Utility.valueForKey(entity, "dbSnapshotKeys");
NSDictionary dbSnapshot = dbOp.dbSnapshot();
NSDictionary newRow = dbOp.newRow();
for (int i = keys.count() - 1; i >= 0; i--) {
String key = (String) keys.objectAtIndex(i);
EOAttribute att = entity.attributeNamed(key);
// FIX: ak when you have single-table inheritance and in the
// child there are foreign keys that are not in the parent
// THEN, if the entity _hasNonUpdateableAttributes (public PK or
// read only props) the DB op is checked
// against the attributes. BUT this dictionary has all entries,
// even from the child (most likely NULL values)
// and the current implementation doesn't check against the case
// when the attribute isn't present in the first place.
// SO we add this check and live happily ever after
if (att != null && att._isNonUpdateable() && !dbSnapshot.objectForKey(key).equals(newRow.objectForKey(key))) {
if (att.isReadOnly()) {
throw new IllegalStateException("cannot update read-only key '" + key + "' on object:" + dbOp.object() + " of entity: " + entity.name() + " in databaseContext " + this);
}
throw new IllegalStateException("cannot update primary-key '" + key + "' from '" + dbSnapshot.objectForKey(key) + "' to '" + newRow.objectForKey(key) + "' on object:" + dbOp.object() + " of entity: " + entity.name() + " in databaseContext " + this);
}
}
}
}