diff --git a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java index c8a8b3a02fc8944a7a78008043804084b76555f6..0932c53595947a76de7d3f89d0014370b04ea1f6 100644 --- a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java +++ b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java @@ -174,6 +174,9 @@ public interface DatabaseComponent { /** Returns the contacts to which the given group is visible. */ Collection<ContactId> getVisibility(GroupId g) throws DbException; + /** Returns the subscriptions that are visible to the given contact. */ + Collection<GroupId> getVisibleSubscriptions(ContactId c) throws DbException; + /** Returns true if any messages are sendable to the given contact. */ boolean hasSendableMessages(ContactId c) throws DbException; diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java index eaf7b6a143199af17e8d37e05272ef9f51340377..9fa585ff380f004daa4bb661c3bb6c2fd64daafa 100644 --- a/briar-core/src/net/sf/briar/db/Database.java +++ b/briar-core/src/net/sf/briar/db/Database.java @@ -441,6 +441,14 @@ interface Database<T> { */ Collection<ContactId> getVisibility(T txn, GroupId g) throws DbException; + /** + * Returns the subscriptions that are visible to the given contact. + * <p> + * Locking: contact read, subscription read. + */ + Collection<GroupId> getVisibleSubscriptions(T txn, ContactId c) + throws DbException; + /** * Returns true if any messages are sendable to the given contact. * <p> diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java index 0c96b0fa87fd52bdb7ef4020d9cf5e8429eb8fb4..87777852ed103512434501aa3e28a7b89f7b6435 100644 --- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java +++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java @@ -982,6 +982,32 @@ DatabaseCleaner.Callback { } } + public Collection<GroupId> getVisibleSubscriptions(ContactId c) + throws DbException { + contactLock.readLock().lock(); + try { + subscriptionLock.readLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsContact(txn, c)) + throw new NoSuchContactException(); + Collection<GroupId> visible = + db.getVisibleSubscriptions(txn, c); + db.commitTransaction(txn); + return visible; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + subscriptionLock.readLock().unlock(); + } + } finally { + contactLock.readLock().unlock(); + } + } + public boolean hasSendableMessages(ContactId c) throws DbException { contactLock.readLock().lock(); try { diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java index c6ba2bb27d9bf463f181ffb1d26bd8ac6c369007..e3a8637e42d15c39bedb6e6dba0d7979014f9402 100644 --- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java +++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java @@ -1854,7 +1854,7 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT transportId, key, value, localVersion" + String sql = "SELECT tp.transportId, key, value, localVersion" + " FROM transportProperties AS tp" + " JOIN transportVersions AS tv" + " ON tp.transportId = tv.transportId" @@ -1937,6 +1937,28 @@ abstract class JdbcDatabase implements Database<Connection> { } } + public Collection<GroupId> getVisibleSubscriptions(Connection txn, + ContactId c) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT groupId FROM groupVisibilities" + + " WHERE contactId = ?"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + rs = ps.executeQuery(); + List<GroupId> visible = new ArrayList<GroupId>(); + while(rs.next()) visible.add(new GroupId(rs.getBytes(1))); + rs.close(); + ps.close(); + return Collections.unmodifiableList(visible); + } catch(SQLException e) { + tryToClose(rs); + tryToClose(ps); + throw new DbException(e); + } + } + public boolean hasSendableMessages(Connection txn, ContactId c) throws DbException { PreparedStatement ps = null;