Verified Commit 3bcc532b authored by akwizgran's avatar akwizgran

Add transactional DB interface.

parent a384450c
......@@ -76,6 +76,32 @@ public interface DatabaseComponent {
*/
void endTransaction(Transaction txn);
/**
* Runs the given task within a transaction.
*/
void transaction(boolean readOnly, DbRunnable<DbException> task)
throws DbException;
/**
* Runs the given task within a transaction and returns the result of the
* task.
*/
<R> R transactionWithResult(boolean readOnly,
DbCallable<R, DbException> task) throws DbException;
/**
* Runs the given task within a transaction.
*/
<E extends Exception> void throwingTransaction(boolean readOnly,
DbRunnable<E> task) throws DbException, E;
/**
* Runs the given task within a transaction and returns the result of the
* task.
*/
<R, E extends Exception> R throwingTransactionWithResult(boolean readOnly,
DbCallable<R, E> task) throws DbException, E;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* and returns an ID for the contact.
......
package org.briarproject.bramble.api.db;
public interface DbCallable<R, E extends Exception> {
R call(Transaction txn) throws DbException, E;
}
package org.briarproject.bramble.api.db;
public interface DbRunnable<E extends Exception> {
void run(Transaction txn) throws DbException, E;
}
......@@ -9,7 +9,9 @@ import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.ContactExistsException;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbCallable;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.DbRunnable;
import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.MigrationListener;
import org.briarproject.bramble.api.db.NoSuchContactException;
......@@ -166,6 +168,43 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
for (Event e : transaction.getEvents()) eventBus.broadcast(e);
}
@Override
public void transaction(boolean readOnly, DbRunnable<DbException> task)
throws DbException {
throwingTransaction(readOnly, task);
}
@Override
public <R> R transactionWithResult(boolean readOnly,
DbCallable<R, DbException> task) throws DbException {
return throwingTransactionWithResult(readOnly, task);
}
@Override
public <E extends Exception> void throwingTransaction(boolean readOnly,
DbRunnable<E> task) throws DbException, E {
final Transaction txn = startTransaction(readOnly);
try {
task.run(txn);
commitTransaction(txn);
} finally {
endTransaction(txn);
}
}
@Override
public <R, E extends Exception> R throwingTransactionWithResult(
boolean readOnly, DbCallable<R, E> task) throws DbException, E {
final Transaction txn = startTransaction(readOnly);
try {
R result = task.call(txn);
commitTransaction(txn);
return result;
} finally {
endTransaction(txn);
}
}
private T unbox(Transaction transaction) {
if (transaction.isCommitted()) throw new IllegalStateException();
return txnClass.cast(transaction.unbox());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment