diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java index 7d07e6775d9b087b44465917a32dfefc0e308fcf..46e944a70226381bad9a24e2a8dc373d6a3c5835 100644 --- a/components/net/sf/briar/db/Database.java +++ b/components/net/sf/briar/db/Database.java @@ -105,10 +105,6 @@ interface Database<T> { */ void addSubscription(T txn, GroupId g) throws DbException; - // FIXME: Replace these two methods with a setSubscriptions() method - void addSubscription(T txn, ContactId c, GroupId g) throws DbException; - void clearSubscriptions(T txn, ContactId c) throws DbException; - /** * Returns true iff the database contains the given contact. * <p> @@ -314,6 +310,14 @@ interface Database<T> { */ void setStatus(T txn, ContactId c, MessageId m, Status s) throws DbException; + /** + * Sets the subscriptions for the given contact, replacing any existing + * subscriptions. + * <p> + * Locking: contacts read, subscriptions write. + */ + void setSubscriptions(T txn, ContactId c, Set<GroupId> subs) throws DbException; + /** * Sets the local transport details, replacing any existing transport * details. diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java index 7a973296c96f937d57122d6829f27b3be4312e12..adbc6a6c3101b8433888455ebe390fe14d8657b6 100644 --- a/components/net/sf/briar/db/JdbcDatabase.java +++ b/components/net/sf/briar/db/JdbcDatabase.java @@ -526,43 +526,6 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public void addSubscription(Connection txn, ContactId c, GroupId g) - throws DbException { - PreparedStatement ps = null; - try { - String sql = "INSERT INTO contactSubscriptions" - + " (contactId, groupId)" - + " VALUES (?, ?)"; - ps = txn.prepareStatement(sql); - ps.setInt(1, c.getInt()); - ps.setBytes(2, g.getBytes()); - int rowsAffected = ps.executeUpdate(); - assert rowsAffected == 1; - ps.close(); - } catch(SQLException e) { - tryToClose(ps); - tryToClose(txn); - throw new DbException(e); - } - } - - public void clearSubscriptions(Connection txn, ContactId c) - throws DbException { - PreparedStatement ps = null; - try { - String sql = "DELETE FROM contactSubscriptions" - + " WHERE contactId = ?"; - ps = txn.prepareStatement(sql); - ps.setInt(1, c.getInt()); - ps.executeUpdate(); - ps.close(); - } catch(SQLException e) { - tryToClose(ps); - tryToClose(txn); - throw new DbException(e); - } - } - public boolean containsContact(Connection txn, ContactId c) throws DbException { PreparedStatement ps = null; @@ -1327,6 +1290,38 @@ abstract class JdbcDatabase implements Database<Connection> { } } + public void setSubscriptions(Connection txn, ContactId c, Set<GroupId> subs) + throws DbException { + PreparedStatement ps = null; + try { + // Delete any existing subscriptions + String sql = "DELETE FROM contactSubscriptions WHERE contactId = ?"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + ps.executeUpdate(); + ps.close(); + // Store the new subscriptions + sql = "INSERT INTO contactSubscriptions (contactId, groupId)" + + " VALUES (?, ?)"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + for(GroupId g : subs) { + ps.setBytes(2, g.getBytes()); + ps.addBatch(); + } + int[] rowsAffectedArray = ps.executeBatch(); + assert rowsAffectedArray.length == subs.size(); + for(int i = 0; i < rowsAffectedArray.length; i++) { + assert rowsAffectedArray[i] == 1; + } + ps.close(); + } catch(SQLException e) { + tryToClose(ps); + tryToClose(txn); + throw new DbException(e); + } + } + public void setTransports(Connection txn, Map<String, String> transports) throws DbException { PreparedStatement ps = null; diff --git a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java index 7d6100d0b58161fea83398fc8d81843f5fd0f496..a31f5c5a8ed2bb21a361882d92af7649d8181840 100644 --- a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java +++ b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java @@ -473,10 +473,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { try { Txn txn = db.startTransaction(); try { - // FIXME: Replace clearSubs and addSub with setSubs - db.clearSubscriptions(txn, c); Set<GroupId> subs = h.getSubscriptions(); - for(GroupId sub : subs) db.addSubscription(txn, c, sub); + db.setSubscriptions(txn, c, subs); if(LOG.isLoggable(Level.FINE)) LOG.fine("Received " + subs.size() + " subscriptions"); db.commitTransaction(txn); diff --git a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java index 403dc153637e2a519ba9323b6cc0be10c3943af3..5e115e9d95b8e56cb8231d1244999ab34f846bb0 100644 --- a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java +++ b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java @@ -354,10 +354,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { synchronized(subscriptionLock) { Txn txn = db.startTransaction(); try { - // FIXME: Replace clearSubs and addSub with setSubs - db.clearSubscriptions(txn, c); Set<GroupId> subs = h.getSubscriptions(); - for(GroupId sub : subs) db.addSubscription(txn, c, sub); + db.setSubscriptions(txn, c, subs); if(LOG.isLoggable(Level.FINE)) LOG.fine("Received " + subs.size() + " subscriptions"); db.commitTransaction(txn); diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java index 298bace357d9c06c67f93c6ed1a49ba0e614d811..17f92cebb4f916890c55dbf6ded339143bd6a87e 100644 --- a/test/net/sf/briar/db/DatabaseComponentTest.java +++ b/test/net/sf/briar/db/DatabaseComponentTest.java @@ -548,10 +548,9 @@ public abstract class DatabaseComponentTest extends TestCase { will(returnValue(acks)); oneOf(database).removeAckedBatch(txn, contactId, batchId); // Subscriptions - oneOf(database).clearSubscriptions(txn, contactId); oneOf(header).getSubscriptions(); will(returnValue(subs)); - oneOf(database).addSubscription(txn, contactId, groupId); + oneOf(database).setSubscriptions(txn, contactId, subs); // Transports oneOf(header).getTransports(); will(returnValue(transports)); diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java index 4408ab6791fc32f242c8ec1f7d7415fbec4cd477..c830a6a2b9116b876748390ee0b4aa50163917e7 100644 --- a/test/net/sf/briar/db/H2DatabaseTest.java +++ b/test/net/sf/briar/db/H2DatabaseTest.java @@ -211,7 +211,7 @@ public class H2DatabaseTest extends TestCase { Connection txn = db.startTransaction(); assertEquals(contactId, db.addContact(txn, null)); db.addSubscription(txn, groupId); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); db.addMessage(txn, message); db.setStatus(txn, contactId, messageId, Status.NEW); db.commitTransaction(txn); @@ -253,7 +253,7 @@ public class H2DatabaseTest extends TestCase { Connection txn = db.startTransaction(); assertEquals(contactId, db.addContact(txn, null)); db.addSubscription(txn, groupId); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); db.addMessage(txn, message); db.setSendability(txn, messageId, 1); db.commitTransaction(txn); @@ -315,7 +315,7 @@ public class H2DatabaseTest extends TestCase { // The contact subscribing should make the message sendable txn = db.startTransaction(); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertTrue(it.hasNext()); assertEquals(messageId, it.next()); @@ -323,7 +323,7 @@ public class H2DatabaseTest extends TestCase { // The contact unsubscribing should make the message unsendable txn = db.startTransaction(); - db.clearSubscriptions(txn, contactId); + db.setSubscriptions(txn, contactId, Collections.<GroupId>emptySet()); it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); assertFalse(it.hasNext()); db.commitTransaction(txn); @@ -342,7 +342,7 @@ public class H2DatabaseTest extends TestCase { Connection txn = db.startTransaction(); assertEquals(contactId, db.addContact(txn, null)); db.addSubscription(txn, groupId); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); db.addMessage(txn, message); db.setSendability(txn, messageId, 1); db.setStatus(txn, contactId, messageId, Status.NEW); @@ -408,7 +408,7 @@ public class H2DatabaseTest extends TestCase { Connection txn = db.startTransaction(); assertEquals(contactId, db.addContact(txn, null)); db.addSubscription(txn, groupId); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); db.addMessage(txn, message); db.setSendability(txn, messageId, 1); db.setStatus(txn, contactId, messageId, Status.NEW); @@ -451,7 +451,7 @@ public class H2DatabaseTest extends TestCase { Connection txn = db.startTransaction(); assertEquals(contactId, db.addContact(txn, null)); db.addSubscription(txn, groupId); - db.addSubscription(txn, contactId, groupId); + db.setSubscriptions(txn, contactId, Collections.singleton(groupId)); db.addMessage(txn, message); db.setSendability(txn, messageId, 1); db.setStatus(txn, contactId, messageId, Status.NEW);