/* Copyright (c) 2012-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Gabriel Roldan (Boundless) - initial implementation
*/
package org.locationtech.geogig.storage;
import java.io.Closeable;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.RevObject;
import org.locationtech.geogig.api.RevTag;
import org.locationtech.geogig.api.RevTree;
import org.locationtech.geogig.di.Singleton;
import org.locationtech.geogig.repository.RepositoryConnectionException;
/**
* Provides an interface for implementations of GeoGig object databases.
*/
@Singleton
public interface ObjectDatabase extends Closeable {
/**
* Opens the database. It's safe to call this method multiple times, and only the first call
* shall take effect.
*/
public void open();
/**
* Performs any setup required before first open, including setting default configuration.
*/
public void configure() throws RepositoryConnectionException;
/**
* Verify the configuration before opening the database.
*/
public void checkConfig() throws RepositoryConnectionException;
/**
* @return true if the database is open, false otherwise
*/
public boolean isOpen();
/**
* Closes the database.
*/
public void close();
/**
* Determines if the given {@link ObjectId} exists in the object database.
*
* @param id the id to search for
* @return true if the object exists, false otherwise
*/
public boolean exists(final ObjectId id);
/**
* Searches the database for {@link ObjectId}s that match the given partial id.
*
* @param partialId the partial id to search for
* @return a list of matching results
*/
public List<ObjectId> lookUp(final String partialId);
/**
* Reads an object with the given {@link ObjectId id} out of the database.
*
* @throws IllegalArgumentException if no blob exists for the given {@code id}
*/
public RevObject get(ObjectId id) throws IllegalArgumentException;
/**
* Reads an object with the given {@link ObjectId id} out of the database.
*
* @throws IllegalArgumentException if no blob exists for the given {@code id}, or the object
* found is not of the required {@code type}
*/
public <T extends RevObject> T get(ObjectId id, Class<T> type) throws IllegalArgumentException;
/**
* Reads an object with the given {@link ObjectId id} out of the database.
*
* @return the object found, or {@code null} if no object is found
*/
public @Nullable
RevObject getIfPresent(ObjectId id);
/**
* Reads an object with the given {@link ObjectId id} out of the database.
*
* @return the object found, or {@code null} if no object is found
* @throws IllegalArgumentException if the object is found but is not of the required
* {@code type}
*/
public @Nullable
<T extends RevObject> T getIfPresent(ObjectId id, Class<T> type)
throws IllegalArgumentException;
/**
* Shortcut for {@link #get(ObjectId, Class) get(id, RevTree.class)}
*/
public RevTree getTree(ObjectId id);
/**
* Shortcut for {@link #get(ObjectId, Class) get(id, RevFeature.class)}
*/
public RevFeature getFeature(ObjectId id);
/**
* Shortcut for {@link #get(ObjectId, Class) get(id, RevFeatureType.class)}
*/
public RevFeatureType getFeatureType(ObjectId id);
/**
* Shortcut for {@link #get(ObjectId, Class) get(id, RevCommit.class)}
*/
public RevCommit getCommit(ObjectId id);
/**
* Shortcut for {@link #get(ObjectId, Class) get(id, RevTag.class)}
*/
public RevTag getTag(ObjectId id);
/**
* Adds an object to the database with the given {@link ObjectId id}. If an object with the same
* id already exists, it will not be inserted.
*
* @param object the object to insert, key'ed by its {@link RevObject#getId() id}
* @return true if the object was inserted, false otherwise
*/
public boolean put(final RevObject object);
/**
* @return a newly constructed {@link ObjectInserter} for this database
*/
@Deprecated
public ObjectInserter newObjectInserter();
/**
* Deletes the object with the provided {@link ObjectId id} from the database.
*
* @param objectId the id of the object to delete
* @return true if the object was deleted, false if it was not found
*/
public boolean delete(ObjectId objectId);
/**
* Shorthand for {@link #getAll(Iterable, BulkOpListener)} with
* {@link BulkOpListener#NOOP_LISTENER} as second argument
*/
public Iterator<RevObject> getAll(final Iterable<ObjectId> ids);
/**
* Query method to retrieve a collection of objects from the database, given a collection of
* object identifiers.
* <p>
* The returned iterator may not preserve the order of the argument list of ids.
* <p>
* The {@link BulkOpListener#found(RevObject, Integer) listener.found} method is going to be
* called for each object found as the returned iterator is traversed.
* <p>
* The {@link BulkOpListener#notFound(ObjectId) listener.notFound} method is to be called for
* each object not found as the iterator is traversed.
*
* @param ids an iterable holding the list of ids to remove from the database
* @param listener a listener that gets notified of {@link BulkOpListener#deleted(ObjectId)
* deleted} and {@link BulkOpListener#notFound(ObjectId) not found} items
* @return an iterator with the objects <b>found</b> on the database, in no particular order
*/
public Iterator<RevObject> getAll(final Iterable<ObjectId> ids, BulkOpListener listener);
/**
* Shorthand for {@link #putAll(Iterator, BulkOpListener)} with
* {@link BulkOpListener#NOOP_LISTENER} as second argument
*/
public void putAll(Iterator<? extends RevObject> objects);
/**
* Requests to insert all objects into the object database
* <p>
* Objects already present (given its {@link RevObject#getId() id} shall not be inserted.
* <p>
* For each object that gets actually inserted (i.e. an object with the same id didn't
* previously exist), {@link BulkOpListener#inserted(RevObject, Integer) listener.inserted}
* method is called.
*
* @param objects the objects to request for insertion into the object database
* @param listener a listener to get notifications of actually inserted objects
*/
public void putAll(Iterator<? extends RevObject> objects, BulkOpListener listener);
/**
* Shorthand for {@link #deleteAll(Iterator, BulkOpListener)} with
* {@link BulkOpListener#NOOP_LISTENER} as second argument
*/
public long deleteAll(Iterator<ObjectId> ids);
/**
* Requests to delete all objects in the argument list of object ids from the object database.
* <p>
* For each object found and deleted, the {@link BulkOpListener#deleted(ObjectId)
* listener.deleted} method will be called
* <p>
* For each object not found, the {@link BulkOpListener#notFound(ObjectId) listener.notFound}
* method will be called
*
* @param ids the identifiers of objects to delete
* @param listener a listener to receive notifications of deleted and not found objects
* @return the number of objects actually deleted
*/
public long deleteAll(Iterator<ObjectId> ids, BulkOpListener listener);
}