use of org.locationtech.geogig.storage.StagingDatabase in project GeoGig by boundlessgeo.
the class RevParseTest method testResolveToMultipleIds.
@Test
public void testResolveToMultipleIds() {
StagingDatabase mockIndexDb = mock(StagingDatabase.class);
Context mockCommands = mock(Context.class);
RefParse mockRefParse = mock(RefParse.class);
when(mockRefParse.setName(anyString())).thenReturn(mockRefParse);
when(mockCommands.command(eq(RefParse.class))).thenReturn(mockRefParse);
Optional<Ref> ref = Optional.absent();
when(mockRefParse.call()).thenReturn(ref);
List<ObjectId> oIds = Arrays.asList(ObjectId.forString("Object 1"), ObjectId.forString("Object 2"));
when(mockIndexDb.lookUp(anyString())).thenReturn(oIds);
when(mockCommands.stagingDatabase()).thenReturn(mockIndexDb);
RevParse command = new RevParse();
command.setContext(mockCommands);
exception.expect(IllegalArgumentException.class);
command.setRefSpec(commitId1.toString().substring(0, commitId1.toString().length() - 2)).call();
}
use of org.locationtech.geogig.storage.StagingDatabase in project GeoGig by boundlessgeo.
the class JEConflictsTest method testConflicts.
@Test
public void testConflicts() {
StagingDatabase db = geogig.getRepository().stagingDatabase();
List<Conflict> conflicts = db.getConflicts(null, null);
assertTrue(conflicts.isEmpty());
Conflict conflict = new Conflict(idP1, ObjectId.forString("ancestor"), ObjectId.forString("ours"), ObjectId.forString("theirs"));
Conflict conflict2 = new Conflict(idP2, ObjectId.forString("ancestor2"), ObjectId.forString("ours2"), ObjectId.forString("theirs2"));
db.addConflict(null, conflict);
Optional<Conflict> returnedConflict = db.getConflict(null, idP1);
assertTrue(returnedConflict.isPresent());
assertEquals(conflict, returnedConflict.get());
db.removeConflict(null, idP1);
conflicts = db.getConflicts(null, null);
assertTrue(conflicts.isEmpty());
db.addConflict(null, conflict);
db.addConflict(null, conflict2);
assertEquals(2, db.getConflicts(null, null).size());
db.removeConflicts(null);
conflicts = db.getConflicts(null, null);
assertTrue(conflicts.isEmpty());
final String NS = "ns";
db.addConflict(NS, conflict);
db.addConflict(null, conflict2);
returnedConflict = db.getConflict(NS, idP1);
assertTrue(returnedConflict.isPresent());
assertEquals(conflict, returnedConflict.get());
assertEquals(1, db.getConflicts(NS, null).size());
db.removeConflict(NS, idP1);
conflicts = db.getConflicts(NS, null);
assertTrue(conflicts.isEmpty());
db.addConflict(NS, conflict);
db.addConflict(NS, conflict2);
assertEquals(2, db.getConflicts(NS, null).size());
assertEquals(1, db.getConflicts(null, null).size());
db.removeConflicts(NS);
conflicts = db.getConflicts(NS, null);
assertTrue(conflicts.isEmpty());
conflicts = db.getConflicts(null, null);
assertFalse(conflicts.isEmpty());
}
use of org.locationtech.geogig.storage.StagingDatabase in project GeoGig by boundlessgeo.
the class ApplyPatchOp method applyPatch.
private void applyPatch(Patch patch) {
final WorkingTree workTree = workingTree();
final StagingDatabase indexDb = stagingDatabase();
if (reverse) {
patch = patch.reversed();
}
List<FeatureInfo> removed = patch.getRemovedFeatures();
for (FeatureInfo feature : removed) {
workTree.delete(NodeRef.parentPath(feature.getPath()), NodeRef.nodeFromPath(feature.getPath()));
}
List<FeatureInfo> added = patch.getAddedFeatures();
for (FeatureInfo feature : added) {
workTree.insert(NodeRef.parentPath(feature.getPath()), feature.getFeature());
}
List<FeatureDiff> diffs = patch.getModifiedFeatures();
for (FeatureDiff diff : diffs) {
String path = diff.getPath();
DepthSearch depthSearch = new DepthSearch(indexDb);
Optional<NodeRef> noderef = depthSearch.find(workTree.getTree(), path);
RevFeatureType oldRevFeatureType = command(RevObjectParse.class).setObjectId(noderef.get().getMetadataId()).call(RevFeatureType.class).get();
String refSpec = Ref.WORK_HEAD + ":" + path;
RevFeature feature = command(RevObjectParse.class).setRefSpec(refSpec).call(RevFeature.class).get();
RevFeatureType newRevFeatureType = getFeatureType(diff, feature, oldRevFeatureType);
ImmutableList<Optional<Object>> values = feature.getValues();
ImmutableList<PropertyDescriptor> oldDescriptors = oldRevFeatureType.sortedDescriptors();
ImmutableList<PropertyDescriptor> newDescriptors = newRevFeatureType.sortedDescriptors();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder((SimpleFeatureType) newRevFeatureType.type());
Map<Name, Optional<?>> attrs = Maps.newHashMap();
for (int i = 0; i < oldDescriptors.size(); i++) {
PropertyDescriptor descriptor = oldDescriptors.get(i);
if (newDescriptors.contains(descriptor)) {
Optional<Object> value = values.get(i);
attrs.put(descriptor.getName(), value);
}
}
Set<Entry<PropertyDescriptor, AttributeDiff>> featureDiffs = diff.getDiffs().entrySet();
for (Iterator<Entry<PropertyDescriptor, AttributeDiff>> iterator = featureDiffs.iterator(); iterator.hasNext(); ) {
Entry<PropertyDescriptor, AttributeDiff> entry = iterator.next();
if (!entry.getValue().getType().equals(TYPE.REMOVED)) {
Optional<?> oldValue = attrs.get(entry.getKey().getName());
attrs.put(entry.getKey().getName(), entry.getValue().applyOn(oldValue));
}
}
Set<Entry<Name, Optional<?>>> entries = attrs.entrySet();
for (Iterator<Entry<Name, Optional<?>>> iterator = entries.iterator(); iterator.hasNext(); ) {
Entry<Name, Optional<?>> entry = iterator.next();
featureBuilder.set(entry.getKey(), entry.getValue().orNull());
}
SimpleFeature featureToInsert = featureBuilder.buildFeature(NodeRef.nodeFromPath(path));
workTree.insert(NodeRef.parentPath(path), featureToInsert);
}
ImmutableList<FeatureTypeDiff> alteredTrees = patch.getAlteredTrees();
for (FeatureTypeDiff diff : alteredTrees) {
Optional<RevFeatureType> featureType;
if (diff.getOldFeatureType().isNull()) {
featureType = patch.getFeatureTypeFromId(diff.getNewFeatureType());
workTree.createTypeTree(diff.getPath(), featureType.get().type());
} else if (diff.getNewFeatureType().isNull()) {
workTree.delete(diff.getPath());
} else {
featureType = patch.getFeatureTypeFromId(diff.getNewFeatureType());
workTree.updateTypeTree(diff.getPath(), featureType.get().type());
}
}
}
use of org.locationtech.geogig.storage.StagingDatabase in project GeoGig by boundlessgeo.
the class Index method stage.
/**
* Stages the changes indicated by the {@link DiffEntry} iterator.
*
* @param progress the progress listener for the process
* @param unstaged an iterator for the unstaged changes
* @param numChanges number of unstaged changes
*/
@Override
public void stage(final ProgressListener progress, final Iterator<DiffEntry> unstaged, final long numChanges) {
int i = 0;
progress.started();
final RevTree currentIndexHead = getTree();
Map<String, RevTreeBuilder> parentTress = Maps.newHashMap();
Map<String, ObjectId> parentMetadataIds = Maps.newHashMap();
Set<String> removedTrees = Sets.newHashSet();
StagingDatabase database = getDatabase();
while (unstaged.hasNext()) {
final DiffEntry diff = unstaged.next();
final String fullPath = diff.oldPath() == null ? diff.newPath() : diff.oldPath();
final String parentPath = NodeRef.parentPath(fullPath);
/*
* TODO: revisit, ideally the list of diff entries would come with one single entry for
* the whole removed tree instead of that one and every single children of it.
*/
if (removedTrees.contains(parentPath)) {
continue;
}
if (null == parentPath) {
// it is the root tree that's been changed, update head and ignore anything else
ObjectId newRoot = diff.newObjectId();
updateStageHead(newRoot);
progress.setProgress(100f);
progress.complete();
return;
}
RevTreeBuilder parentTree = getParentTree(currentIndexHead, parentPath, parentTress, parentMetadataIds);
i++;
progress.setProgress((float) (i * 100) / numChanges);
NodeRef oldObject = diff.getOldObject();
NodeRef newObject = diff.getNewObject();
if (newObject == null) {
// Delete
parentTree.remove(oldObject.name());
if (TYPE.TREE.equals(oldObject.getType())) {
removedTrees.add(oldObject.path());
}
} else if (oldObject == null) {
// Add
Node node = newObject.getNode();
parentTree.put(node);
parentMetadataIds.put(newObject.path(), newObject.getMetadataId());
} else {
// Modify
Node node = newObject.getNode();
parentTree.put(node);
}
database.removeConflict(null, fullPath);
}
ObjectId newRootTree = currentIndexHead.getId();
for (Map.Entry<String, RevTreeBuilder> entry : parentTress.entrySet()) {
String changedTreePath = entry.getKey();
RevTreeBuilder changedTreeBuilder = entry.getValue();
RevTree changedTree = changedTreeBuilder.build();
ObjectId parentMetadataId = parentMetadataIds.get(changedTreePath);
if (NodeRef.ROOT.equals(changedTreePath)) {
// root
database.put(changedTree);
newRootTree = changedTree.getId();
} else {
// parentMetadataId = parentMetadataId == null ?
Supplier<RevTreeBuilder> rootTreeSupplier = getTreeSupplier();
newRootTree = context.command(WriteBack.class).setAncestor(rootTreeSupplier).setChildPath(changedTreePath).setMetadataId(parentMetadataId).setToIndex(true).setTree(changedTree).call();
}
updateStageHead(newRootTree);
}
progress.complete();
}
use of org.locationtech.geogig.storage.StagingDatabase in project GeoGig by boundlessgeo.
the class ExportOp method _call.
/**
* Executes the export operation using the parameters that have been specified.
*
* @return a FeatureCollection with the specified features
*/
@Override
protected SimpleFeatureStore _call() {
final StagingDatabase database = stagingDatabase();
if (filterFeatureTypeId != null) {
RevObject filterType = database.getIfPresent(filterFeatureTypeId);
checkArgument(filterType instanceof RevFeatureType, "Provided filter feature type is does not exist");
}
final SimpleFeatureStore targetStore = getTargetStore();
final String refspec = resolveRefSpec();
final String treePath = refspec.substring(refspec.indexOf(':') + 1);
final RevTree rootTree = resolveRootTree(refspec);
final NodeRef typeTreeRef = resolTypeTreeRef(refspec, treePath, rootTree);
final ObjectId defaultMetadataId = typeTreeRef.getMetadataId();
final RevTree typeTree = database.getTree(typeTreeRef.objectId());
final ProgressListener progressListener = getProgressListener();
progressListener.started();
progressListener.setDescription("Exporting from " + path + " to " + targetStore.getName().getLocalPart() + "... ");
FeatureCollection<SimpleFeatureType, SimpleFeature> asFeatureCollection = new BaseFeatureCollection<SimpleFeatureType, SimpleFeature>() {
@Override
public FeatureIterator<SimpleFeature> features() {
final Iterator<SimpleFeature> plainFeatures = getFeatures(typeTree, database, defaultMetadataId, progressListener);
Iterator<SimpleFeature> adaptedFeatures = adaptToArguments(plainFeatures, defaultMetadataId);
Iterator<Optional<Feature>> transformed = Iterators.transform(adaptedFeatures, ExportOp.this.function);
Iterator<SimpleFeature> filtered = Iterators.filter(Iterators.transform(transformed, new Function<Optional<Feature>, SimpleFeature>() {
@Override
public SimpleFeature apply(Optional<Feature> input) {
return (SimpleFeature) (input.isPresent() ? input.get() : null);
}
}), Predicates.notNull());
return new DelegateFeatureIterator<SimpleFeature>(filtered);
}
};
// add the feature collection to the feature store
final Transaction transaction;
if (transactional) {
transaction = new DefaultTransaction("create");
} else {
transaction = Transaction.AUTO_COMMIT;
}
try {
targetStore.setTransaction(transaction);
try {
targetStore.addFeatures(asFeatureCollection);
transaction.commit();
} catch (final Exception e) {
if (transactional) {
transaction.rollback();
}
Throwables.propagateIfInstanceOf(e, GeoToolsOpException.class);
throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD);
} finally {
transaction.close();
}
} catch (IOException e) {
throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD);
}
progressListener.complete();
return targetStore;
}
Aggregations