use of com.torodb.core.transaction.metainf.MutableMetaDocPart in project torodb by torodb.
the class SnapshotMerger method merge.
private void merge(MetaDatabase newStructure, ImmutableMetaDatabase oldStructure, ImmutableMetaDatabase.Builder parentBuilder, MutableMetaCollection newCol, MetaElementState newState) throws UnmergeableException {
ImmutableMetaCollection byName = oldStructure.getMetaCollectionByName(newCol.getName());
ImmutableMetaCollection byId = oldStructure.getMetaCollectionByIdentifier(newCol.getIdentifier());
switch(newState) {
default:
case NOT_CHANGED:
case NOT_EXISTENT:
throw new AssertionError("A modification was expected, but the new state is " + newState);
case ADDED:
case MODIFIED:
{
if (byName != byId) {
throw createUnmergeableException(oldStructure, newCol, byName, byId);
}
if (byName == null && byId == null) {
parentBuilder.put(newCol.immutableCopy());
return;
}
assert byName != null;
assert byId != null;
ImmutableMetaCollection.Builder childBuilder = new ImmutableMetaCollection.Builder(byId);
for (MutableMetaDocPart modifiedDocPart : newCol.getModifiedMetaDocParts()) {
merge(newStructure, oldStructure, newCol, byId, childBuilder, modifiedDocPart);
}
for (Tuple2<MutableMetaIndex, MetaElementState> modifiedIndex : newCol.getModifiedMetaIndexes()) {
merge(oldStructure, newCol, byId, childBuilder, modifiedIndex.v1(), modifiedIndex.v2());
}
parentBuilder.put(childBuilder);
break;
}
case REMOVED:
{
if (byName != byId) {
/*
* The backend transaction will remove by id, but it is referencing another name on the
* current snapshot, so the final state will be inconsistent. It is better to fail.
*/
throw createUnmergeableException(oldStructure, newCol, byName, byId);
}
if (byName == null && byId == null) {
/*
* it has been removed on another transaction or created and removed on the current one.
* No change must be done
*/
return;
}
assert byName != null;
assert byId != null;
/*
* In this case, we can delegate on the backend transaction check. If it thinks everything
* is fine, we can remove the element. If it thinks there is an error, then we have to
* rollback the transaction.
*/
parentBuilder.remove(byName);
}
}
}
use of com.torodb.core.transaction.metainf.MutableMetaDocPart in project torodb by torodb.
the class SnapshotMergerTest method testIdempotency.
/**
* Fails if the checker do not allow idempotency
*
* @throws Exception
*/
@Test
public void testIdempotency() throws Exception {
SnapshotMerger merger;
MutableMetaSnapshot changedSnapshot = new WrapperMutableMetaSnapshot(new ImmutableMetaSnapshot(Collections.emptyMap()));
MutableMetaDocPart metaDocPart = changedSnapshot.addMetaDatabase("dbName1", "dbId1").addMetaCollection("colName1", "colId1").addMetaDocPart(tableRefFactory.createRoot(), "docPartId1");
metaDocPart.addMetaField("fieldName1", "fieldId1", FieldType.INTEGER);
metaDocPart.addMetaScalar("scalarId1", FieldType.INTEGER);
merger = new SnapshotMerger(currentSnapshot, changedSnapshot);
merger.merge();
}
Aggregations