diff --git a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java index 5609844f42a6c8337dbdc0b30d07b894c2b93773..06800e1c4c57e90d24f38d47edc8af33e3c0b172 100644 --- a/briar-api/src/org/briarproject/api/db/DatabaseComponent.java +++ b/briar-api/src/org/briarproject/api/db/DatabaseComponent.java @@ -39,6 +39,21 @@ public interface DatabaseComponent { /** Waits for any open transactions to finish and closes the database. */ void close() throws DbException, IOException; + /** Starts a new transaction and returns an object representing it. */ + Transaction startTransaction() throws DbException; + + /** + * Aborts the given transaction - no changes made during the transaction + * will be applied to the database. + */ + void abortTransaction(Transaction txn); + + /** + * Commits the given transaction - all changes made during the transaction + * will be applied to the database. + */ + void commitTransaction(Transaction txn) throws DbException; + /** * Stores a contact associated with the given local and remote pseudonyms, * and returns an ID for the contact. diff --git a/briar-api/src/org/briarproject/api/db/Transaction.java b/briar-api/src/org/briarproject/api/db/Transaction.java new file mode 100644 index 0000000000000000000000000000000000000000..2ea803b05ef888bc1cfe7602ee4b734c937fe79a --- /dev/null +++ b/briar-api/src/org/briarproject/api/db/Transaction.java @@ -0,0 +1,15 @@ +package org.briarproject.api.db; + +/** A wrapper around a database transaction. */ +public class Transaction { + + private final Object txn; + + public Transaction(Object txn) { + this.txn = txn; + } + + public Object unbox() { + return txn; + } +} diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java index dcf88660af85e9858c356f3fca910d7e790e0b96..b62f180902efa827fcdbb6e31cfb138a809c9c4a 100644 --- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java +++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java @@ -14,6 +14,7 @@ import org.briarproject.api.db.NoSuchLocalAuthorException; import org.briarproject.api.db.NoSuchMessageException; import org.briarproject.api.db.NoSuchTransportException; import org.briarproject.api.db.StorageStatus; +import org.briarproject.api.db.Transaction; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.GroupAddedEvent; import org.briarproject.api.event.GroupRemovedEvent; @@ -77,6 +78,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { Logger.getLogger(DatabaseComponentImpl.class.getName()); private final Database<T> db; + private final Class<T> txnClass; private final EventBus eventBus; private final ShutdownManager shutdown; private final AtomicBoolean closed = new AtomicBoolean(false); @@ -84,9 +86,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { private volatile int shutdownHandle = -1; @Inject - DatabaseComponentImpl(Database<T> db, EventBus eventBus, + DatabaseComponentImpl(Database<T> db, Class<T> txnClass, EventBus eventBus, ShutdownManager shutdown) { this.db = db; + this.txnClass = txnClass; this.eventBus = eventBus; this.shutdown = shutdown; } @@ -116,6 +119,18 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { db.close(); } + public Transaction startTransaction() throws DbException { + return new Transaction(db.startTransaction()); + } + + public void abortTransaction(Transaction txn) { + db.abortTransaction(txnClass.cast(txn.unbox())); + } + + public void commitTransaction(Transaction txn) throws DbException { + db.commitTransaction(txnClass.cast(txn.unbox())); + } + public ContactId addContact(Author remote, AuthorId local) throws DbException { T txn = db.startTransaction(); @@ -975,7 +990,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { public void setVisibleToContact(ContactId c, GroupId g, boolean visible) throws DbException { - boolean wasVisible = false; + boolean wasVisible; T txn = db.startTransaction(); try { if (!db.containsContact(txn, c)) diff --git a/briar-core/src/org/briarproject/db/DatabaseModule.java b/briar-core/src/org/briarproject/db/DatabaseModule.java index 9ac531c0775312fd735d2127144f616646e1394d..6a050ed44b9a449fc8d2e5f5ec461ef749f61043 100644 --- a/briar-core/src/org/briarproject/db/DatabaseModule.java +++ b/briar-core/src/org/briarproject/db/DatabaseModule.java @@ -51,7 +51,8 @@ public class DatabaseModule extends AbstractModule { @Provides @Singleton DatabaseComponent getDatabaseComponent(Database<Connection> db, EventBus eventBus, ShutdownManager shutdown) { - return new DatabaseComponentImpl<Connection>(db, eventBus, shutdown); + return new DatabaseComponentImpl<Connection>(db, Connection.class, + eventBus, shutdown); } @Provides @Singleton @DatabaseExecutor diff --git a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java index 70a9113f23c5de966476e7efbb867f0d94236bc7..178dee5b6a9a6730fe16dc3fe3ba00ac52c770f8 100644 --- a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java +++ b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java @@ -106,9 +106,10 @@ public class DatabaseComponentImplTest extends BriarTestCase { StorageStatus.ACTIVE); } - private <T> DatabaseComponent createDatabaseComponent(Database<T> database, + private DatabaseComponent createDatabaseComponent(Database<Object> database, EventBus eventBus, ShutdownManager shutdown) { - return new DatabaseComponentImpl<T>(database, eventBus, shutdown); + return new DatabaseComponentImpl<Object>(database, Object.class, + eventBus, shutdown); } @Test