mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-22 23:59:54 +01:00
Added a method for getting unread message counts for all groups.
This commit is contained in:
@@ -144,6 +144,9 @@ public interface DatabaseComponent {
|
|||||||
/** Returns the set of groups to which the user subscribes. */
|
/** Returns the set of groups to which the user subscribes. */
|
||||||
Collection<Group> getSubscriptions() throws DbException;
|
Collection<Group> getSubscriptions() throws DbException;
|
||||||
|
|
||||||
|
/** Returns the number of unread messages in each subscribed group. */
|
||||||
|
Map<GroupId, Integer> getUnreadMessageCounts() throws DbException;
|
||||||
|
|
||||||
/** Returns the contacts to which the given group is visible. */
|
/** Returns the contacts to which the given group is visible. */
|
||||||
Collection<ContactId> getVisibility(GroupId g) throws DbException;
|
Collection<ContactId> getVisibility(GroupId g) throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -406,6 +406,13 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
long getTransportsSent(T txn, ContactId c) throws DbException;
|
long getTransportsSent(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of unread messages in each subscribed group.
|
||||||
|
* <p>
|
||||||
|
* Locking: message read, messageFlag read, subscription read.
|
||||||
|
*/
|
||||||
|
Map<GroupId, Integer> getUnreadMessageCounts(T txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the contacts to which the given group is visible.
|
* Returns the contacts to which the given group is visible.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -885,6 +885,34 @@ DatabaseCleaner.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<GroupId, Integer> getUnreadMessageCounts() throws DbException {
|
||||||
|
messageLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
messageFlagLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
subscriptionLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
T txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
Map<GroupId, Integer> counts =
|
||||||
|
db.getUnreadMessageCounts(txn);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
return counts;
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
subscriptionLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
messageFlagLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
messageLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<ContactId> getVisibility(GroupId g) throws DbException {
|
public Collection<ContactId> getVisibility(GroupId g) throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1709,6 +1709,33 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<GroupId, Integer> getUnreadMessageCounts(Connection txn)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT groupId, COUNT(*)"
|
||||||
|
+ " FROM messages LEFT OUTER JOIN flags"
|
||||||
|
+ " ON messages.messageId = flags.messageId"
|
||||||
|
+ " WHERE (NOT read) OR (read IS NULL)"
|
||||||
|
+ " GROUP BY groupId";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
Map<GroupId, Integer> counts = new HashMap<GroupId, Integer>();
|
||||||
|
while(rs.next()) {
|
||||||
|
GroupId g = new GroupId(rs.getBytes(1));
|
||||||
|
counts.put(g, rs.getInt(2));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return counts;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
|
|||||||
@@ -1776,6 +1776,62 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUnreadMessageCounts() throws Exception {
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
|
// Subscribe to a couple of groups
|
||||||
|
db.addSubscription(txn, group);
|
||||||
|
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
||||||
|
Group group1 = groupFactory.createGroup(groupId1, "Another group",
|
||||||
|
null);
|
||||||
|
db.addSubscription(txn, group1);
|
||||||
|
|
||||||
|
// Store two messages in the first group
|
||||||
|
db.addGroupMessage(txn, message);
|
||||||
|
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||||
|
Message message1 = new TestMessage(messageId1, null, groupId,
|
||||||
|
authorId, subject, timestamp, raw);
|
||||||
|
db.addGroupMessage(txn, message1);
|
||||||
|
|
||||||
|
// Store one message in the second group
|
||||||
|
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||||
|
Message message2 = new TestMessage(messageId2, null, groupId1,
|
||||||
|
authorId, subject, timestamp, raw);
|
||||||
|
db.addGroupMessage(txn, message2);
|
||||||
|
|
||||||
|
// Mark one of the messages in the first group read
|
||||||
|
assertFalse(db.setRead(txn, messageId, true));
|
||||||
|
|
||||||
|
// There should be one unread message in each group
|
||||||
|
Map<GroupId, Integer> counts = db.getUnreadMessageCounts(txn);
|
||||||
|
assertEquals(2, counts.size());
|
||||||
|
Integer count = counts.get(groupId);
|
||||||
|
assertNotNull(count);
|
||||||
|
assertEquals(1, count.intValue());
|
||||||
|
count = counts.get(groupId1);
|
||||||
|
assertNotNull(count);
|
||||||
|
assertEquals(1, count.intValue());
|
||||||
|
|
||||||
|
// Mark the read message unread (it will now be false rather than null)
|
||||||
|
assertTrue(db.setRead(txn, messageId, false));
|
||||||
|
|
||||||
|
// Mark the message in the second group read
|
||||||
|
assertFalse(db.setRead(txn, messageId2, true));
|
||||||
|
|
||||||
|
// There should be two unread messages in the first group, none in
|
||||||
|
// the second group
|
||||||
|
counts = db.getUnreadMessageCounts(txn);
|
||||||
|
assertEquals(1, counts.size());
|
||||||
|
count = counts.get(groupId);
|
||||||
|
assertNotNull(count);
|
||||||
|
assertEquals(2, count.intValue());
|
||||||
|
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExceptionHandling() throws Exception {
|
public void testExceptionHandling() throws Exception {
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user