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 5bd99e5371acc70c8f9b260bd2b5401271e394bf..80df25c16b6724a5c8bad31f6a352e2e1dcd7ccd 100644 --- a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java +++ b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java @@ -152,12 +152,21 @@ public interface DatabaseComponent { /** Returns the local transport properties for the given transport. */ TransportProperties getLocalProperties(TransportId t) throws DbException; + /** Returns the body of the message with the given ID. */ + byte[] getMessageBody(MessageId m) throws DbException; + + /** Returns the header of the message with the given ID. */ + MessageHeader getMessageHeader(MessageId m) throws DbException; + /** Returns the headers of all messages in the given group. */ Collection<MessageHeader> getMessageHeaders(GroupId g) throws DbException; /** Returns the user's rating for the given author. */ Rating getRating(AuthorId a) throws DbException; + /** Returns true if the given message has been read. */ + boolean getReadFlag(MessageId m) throws DbException; + /** Returns all remote transport properties for the given transport. */ Map<ContactId, TransportProperties> getRemoteProperties(TransportId t) throws DbException; @@ -165,6 +174,9 @@ public interface DatabaseComponent { /** Returns all temporary secrets. */ Collection<TemporarySecret> getSecrets() throws DbException; + /** Returns true if the given message has been starred. */ + boolean getStarredFlag(MessageId m) throws DbException; + /** Returns the set of groups to which the user subscribes. */ Collection<Group> getSubscriptions() throws DbException; @@ -251,9 +263,21 @@ public interface DatabaseComponent { /** Records the user's rating for the given author. */ void setRating(AuthorId a, Rating r) throws DbException; + /** + * Marks the given message read or unread and returns true if it was + * previously read. + */ + boolean setReadFlag(MessageId m, boolean read) throws DbException; + /** Records the given messages as having been seen by the given contact. */ void setSeen(ContactId c, Collection<MessageId> seen) throws DbException; + /** + * Marks the given message starred or unstarred and returns true if it was + * previously starred. + */ + boolean setStarredFlag(MessageId m, boolean starred) throws DbException; + /** * Makes the given group visible to the given set of contacts and invisible * to any other contacts. diff --git a/briar-api/src/net/sf/briar/api/db/NoSuchMessageException.java b/briar-api/src/net/sf/briar/api/db/NoSuchMessageException.java new file mode 100644 index 0000000000000000000000000000000000000000..ef24e15a7d4a68d4bba3a34bad94e48ec2ca0744 --- /dev/null +++ b/briar-api/src/net/sf/briar/api/db/NoSuchMessageException.java @@ -0,0 +1,11 @@ +package net.sf.briar.api.db; + +/** + * Thrown when a database operation is attempted for a message that is not in + * the database. This exception may occur due to concurrent updates and does + * not indicate a database error. + */ +public class NoSuchMessageException extends DbException { + + private static final long serialVersionUID = 9191508339698803848L; +} diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java index ea1b8e65cb262d24232bab3deb91034b8c60941b..e0bd85aa003ed8171f2c29602b9e86de3e02ed23 100644 --- a/briar-core/src/net/sf/briar/db/Database.java +++ b/briar-core/src/net/sf/briar/db/Database.java @@ -234,18 +234,18 @@ interface Database<T> { throws DbException; /** - * Returns the message identified by the given ID, in serialised form. + * Returns the body of the message identified by the given ID. * <p> * Locking: message read. */ - byte[] getMessage(T txn, MessageId m) throws DbException; + byte[] getMessageBody(T txn, MessageId m) throws DbException; /** - * Returns the body of the message identified by the given ID. + * Returns the header of the message identified by the given ID. * <p> * Locking: message read. */ - byte[] getMessageBody(T txn, MessageId m) throws DbException; + MessageHeader getMessageHeader(T txn, MessageId m) throws DbException; /** * Returns the headers of all messages in the given group. @@ -255,16 +255,6 @@ interface Database<T> { Collection<MessageHeader> getMessageHeaders(T txn, GroupId g) throws DbException; - /** - * Returns the message identified by the given ID, in raw format, or null - * if the message is not present in the database or is not sendable to the - * given contact. - * <p> - * Locking: contact read, message read, subscription read. - */ - byte[] getMessageIfSendable(T txn, ContactId c, MessageId m) - throws DbException; - /** * Returns the IDs of all messages signed by the given author. * <p> @@ -300,6 +290,23 @@ interface Database<T> { */ int getNumberOfSendableChildren(T txn, MessageId m) throws DbException; + /** + * Returns the message identified by the given ID, in serialised form. + * <p> + * Locking: message read. + */ + byte[] getRawMessage(T txn, MessageId m) throws DbException; + + /** + * Returns the message identified by the given ID, in serialised form, or + * null if the message is not present in the database or is not sendable to + * the given contact. + * <p> + * Locking: contact read, message read, subscription read. + */ + byte[] getRawMessageIfSendable(T txn, ContactId c, MessageId m) + throws DbException; + /** * Returns the IDs of the oldest messages in the database, with a total * size less than or equal to the given size. @@ -569,7 +576,7 @@ interface Database<T> { * <p> * Locking: message write. */ - boolean setRead(T txn, MessageId m, boolean read) throws DbException; + boolean setReadFlag(T txn, MessageId m, boolean read) throws DbException; /** * Updates the remote transport properties for the given contact and the @@ -605,7 +612,8 @@ interface Database<T> { * <p> * Locking: message write. */ - boolean setStarred(T txn, MessageId m, boolean starred) throws DbException; + boolean setStarredFlag(T txn, MessageId m, boolean starred) + throws DbException; /** * Sets the status of the given message with respect to the given contact. diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java index 251373efe79cfb9f28cdb5772a6ae6c62ad0d3d5..faa69037a2d464876f39db10aa7ba08fde30687b 100644 --- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java +++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java @@ -29,6 +29,7 @@ import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.MessageHeader; import net.sf.briar.api.db.NoSuchContactException; +import net.sf.briar.api.db.NoSuchMessageException; import net.sf.briar.api.db.NoSuchSubscriptionException; import net.sf.briar.api.db.NoSuchTransportException; import net.sf.briar.api.db.event.ContactAddedEvent; @@ -503,7 +504,7 @@ DatabaseCleaner.Callback { throw new NoSuchContactException(); ids = db.getSendableMessages(txn, c, maxLength); for(MessageId m : ids) { - messages.add(db.getMessage(txn, m)); + messages.add(db.getRawMessage(txn, m)); } db.commitTransaction(txn); } catch(DbException e) { @@ -555,7 +556,7 @@ DatabaseCleaner.Callback { Iterator<MessageId> it = requested.iterator(); while(it.hasNext()) { MessageId m = it.next(); - byte[] raw = db.getMessageIfSendable(txn, c, m); + byte[] raw = db.getRawMessageIfSendable(txn, c, m); if(raw != null) { if(raw.length > maxLength) break; messages.add(raw); @@ -828,6 +829,44 @@ DatabaseCleaner.Callback { } } + public byte[] getMessageBody(MessageId m) throws DbException { + messageLock.readLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + byte[] body = db.getMessageBody(txn, m); + db.commitTransaction(txn); + return body; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.readLock().unlock(); + } + } + + public MessageHeader getMessageHeader(MessageId m) throws DbException { + messageLock.readLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + MessageHeader h = db.getMessageHeader(txn, m); + db.commitTransaction(txn); + return h; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.readLock().unlock(); + } + } + public Collection<MessageHeader> getMessageHeaders(GroupId g) throws DbException { messageLock.readLock().lock(); @@ -866,6 +905,25 @@ DatabaseCleaner.Callback { } } + public boolean getReadFlag(MessageId m) throws DbException { + messageLock.readLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + boolean read = db.getReadFlag(txn, m); + db.commitTransaction(txn); + return read; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.readLock().unlock(); + } + } + public Map<ContactId, TransportProperties> getRemoteProperties( TransportId t) throws DbException { contactLock.readLock().lock(); @@ -918,6 +976,25 @@ DatabaseCleaner.Callback { } } + public boolean getStarredFlag(MessageId m) throws DbException { + messageLock.readLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + boolean starred = db.getStarredFlag(txn, m); + db.commitTransaction(txn); + return starred; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.readLock().unlock(); + } + } + public Collection<Group> getSubscriptions() throws DbException { subscriptionLock.readLock().lock(); try { @@ -1494,6 +1571,25 @@ DatabaseCleaner.Callback { if(changed) callListeners(new RatingChangedEvent(a, r)); } + public boolean setReadFlag(MessageId m, boolean read) throws DbException { + messageLock.writeLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + boolean wasRead = db.setReadFlag(txn, m, read); + db.commitTransaction(txn); + return wasRead; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.writeLock().unlock(); + } + } + public void setSeen(ContactId c, Collection<MessageId> seen) throws DbException { contactLock.readLock().lock(); @@ -1506,9 +1602,8 @@ DatabaseCleaner.Callback { try { if(!db.containsContact(txn, c)) throw new NoSuchContactException(); - for(MessageId m : seen) { + for(MessageId m : seen) db.setStatusSeenIfVisible(txn, c, m); - } db.commitTransaction(txn); } catch(DbException e) { db.abortTransaction(txn); @@ -1550,6 +1645,26 @@ DatabaseCleaner.Callback { } } + public boolean setStarredFlag(MessageId m, boolean starred) + throws DbException { + messageLock.writeLock().lock(); + try { + T txn = db.startTransaction(); + try { + if(!db.containsMessage(txn, m)) + throw new NoSuchMessageException(); + boolean wasStarred = db.setStarredFlag(txn, m, starred); + db.commitTransaction(txn); + return wasStarred; + } catch(DbException e) { + db.abortTransaction(txn); + throw e; + } + } finally { + messageLock.writeLock().unlock(); + } + } + public void setVisibility(GroupId g, Collection<ContactId> visible) throws DbException { Collection<ContactId> affected = new ArrayList<ContactId>(); diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java index fced9675b2f80a2b072796344faf3bbd502223bb..897d7c4733c960c23c606c1a1427e73f0d3e73c1 100644 --- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java +++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java @@ -1074,22 +1074,25 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public byte[] getMessage(Connection txn, MessageId m) throws DbException { + public byte[] getMessageBody(Connection txn, MessageId m) + throws DbException { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT length, raw FROM messages WHERE messageId = ?"; + String sql = "SELECT bodyStart, bodyLength, raw FROM messages" + + " WHERE messageId = ?"; ps = txn.prepareStatement(sql); ps.setBytes(1, m.getBytes()); rs = ps.executeQuery(); if(!rs.next()) throw new DbStateException(); - int length = rs.getInt(1); - byte[] raw = rs.getBlob(2).getBytes(1, length); - if(raw.length != length) throw new DbStateException(); + int bodyStart = rs.getInt(1); + int bodyLength = rs.getInt(2); + // Bytes are indexed from 1 rather than 0 + byte[] body = rs.getBlob(3).getBytes(bodyStart + 1, bodyLength); if(rs.next()) throw new DbStateException(); rs.close(); ps.close(); - return raw; + return body; } catch(SQLException e) { tryToClose(rs); tryToClose(ps); @@ -1097,25 +1100,33 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public byte[] getMessageBody(Connection txn, MessageId m) + public MessageHeader getMessageHeader(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT bodyStart, bodyLength, raw FROM messages" + String sql = "SELECT parentId, authorId, groupId, subject," + + " timestamp, read, starred" + + " FROM messages" + " WHERE messageId = ?"; ps = txn.prepareStatement(sql); ps.setBytes(1, m.getBytes()); rs = ps.executeQuery(); if(!rs.next()) throw new DbStateException(); - int bodyStart = rs.getInt(1); - int bodyLength = rs.getInt(2); - // Bytes are indexed from 1 rather than 0 - byte[] body = rs.getBlob(3).getBytes(bodyStart + 1, bodyLength); + byte[] b = rs.getBytes(1); + MessageId parent = b == null ? null : new MessageId(b); + AuthorId author = new AuthorId(rs.getBytes(2)); + b = rs.getBytes(3); + GroupId group = b == null ? null : new GroupId(b); + String subject = rs.getString(4); + long timestamp = rs.getLong(5); + boolean read = rs.getBoolean(6); + boolean starred = rs.getBoolean(7); if(rs.next()) throw new DbStateException(); rs.close(); ps.close(); - return body; + return new MessageHeaderImpl(m, parent, group, author, subject, + timestamp, read, starred); } catch(SQLException e) { tryToClose(rs); tryToClose(ps); @@ -1128,9 +1139,9 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT m.messageId, parentId, authorId," - + " subject, timestamp, read, starred" - + " FROM messages AS m" + String sql = "SELECT messageId, parentId, authorId, subject," + + " timestamp, read, starred" + + " FROM messages" + " WHERE groupId = ?"; ps = txn.prepareStatement(sql); ps.setBytes(1, g.getBytes()); @@ -1143,8 +1154,8 @@ abstract class JdbcDatabase implements Database<Connection> { AuthorId author = new AuthorId(rs.getBytes(3)); String subject = rs.getString(4); long timestamp = rs.getLong(5); - boolean read = rs.getBoolean(6); // False if absent - boolean starred = rs.getBoolean(7); // False if absent + boolean read = rs.getBoolean(6); + boolean starred = rs.getBoolean(7); headers.add(new MessageHeaderImpl(id, parent, g, author, subject, timestamp, read, starred)); } @@ -1158,70 +1169,6 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public byte[] getMessageIfSendable(Connection txn, ContactId c, MessageId m) - throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - // Do we have a sendable private message with the given ID? - String sql = "SELECT length, raw FROM messages AS m" - + " JOIN statuses AS s" - + " ON m.messageId = s.messageId" - + " WHERE m.messageId = ? AND m.contactId = ?" - + " AND status = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, m.getBytes()); - ps.setInt(2, c.getInt()); - ps.setShort(3, (short) Status.NEW.ordinal()); - rs = ps.executeQuery(); - byte[] raw = null; - if(rs.next()) { - int length = rs.getInt(1); - raw = rs.getBlob(2).getBytes(1, length); - if(raw.length != length) throw new DbStateException(); - } - if(rs.next()) throw new DbStateException(); - rs.close(); - ps.close(); - if(raw != null) return raw; - // Do we have a sendable group message with the given ID? - sql = "SELECT length, raw FROM messages AS m" - + " JOIN contactGroups AS cg" - + " ON m.groupId = cg.groupId" - + " JOIN groupVisibilities AS gv" - + " ON m.groupId = gv.groupId" - + " AND cg.contactId = gv.contactId" - + " JOIN retentionVersions AS rv" - + " ON cg.contactId = rv.contactId" - + " JOIN statuses AS s" - + " ON m.messageId = s.messageId" - + " AND cg.contactId = s.contactId" - + " WHERE m.messageId = ?" - + " AND cg.contactId = ?" - + " AND timestamp >= retention" - + " AND status = ?" - + " AND sendability > ZERO()"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, m.getBytes()); - ps.setInt(2, c.getInt()); - ps.setShort(3, (short) Status.NEW.ordinal()); - rs = ps.executeQuery(); - if(rs.next()) { - int length = rs.getInt(1); - raw = rs.getBlob(2).getBytes(1, length); - if(raw.length != length) throw new DbStateException(); - } - if(rs.next()) throw new DbStateException(); - rs.close(); - ps.close(); - return raw; - } catch(SQLException e) { - tryToClose(rs); - tryToClose(ps); - throw new DbException(e); - } - } - public Collection<MessageId> getMessagesByAuthor(Connection txn, AuthorId a) throws DbException { PreparedStatement ps = null; @@ -1406,6 +1353,94 @@ abstract class JdbcDatabase implements Database<Connection> { } } + public byte[] getRawMessage(Connection txn, MessageId m) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT length, raw FROM messages WHERE messageId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, m.getBytes()); + rs = ps.executeQuery(); + if(!rs.next()) throw new DbStateException(); + int length = rs.getInt(1); + byte[] raw = rs.getBlob(2).getBytes(1, length); + if(raw.length != length) throw new DbStateException(); + if(rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + return raw; + } catch(SQLException e) { + tryToClose(rs); + tryToClose(ps); + throw new DbException(e); + } + } + + public byte[] getRawMessageIfSendable(Connection txn, ContactId c, + MessageId m) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + // Do we have a sendable private message with the given ID? + String sql = "SELECT length, raw FROM messages AS m" + + " JOIN statuses AS s" + + " ON m.messageId = s.messageId" + + " WHERE m.messageId = ? AND m.contactId = ?" + + " AND status = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, m.getBytes()); + ps.setInt(2, c.getInt()); + ps.setShort(3, (short) Status.NEW.ordinal()); + rs = ps.executeQuery(); + byte[] raw = null; + if(rs.next()) { + int length = rs.getInt(1); + raw = rs.getBlob(2).getBytes(1, length); + if(raw.length != length) throw new DbStateException(); + } + if(rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + if(raw != null) return raw; + // Do we have a sendable group message with the given ID? + sql = "SELECT length, raw FROM messages AS m" + + " JOIN contactGroups AS cg" + + " ON m.groupId = cg.groupId" + + " JOIN groupVisibilities AS gv" + + " ON m.groupId = gv.groupId" + + " AND cg.contactId = gv.contactId" + + " JOIN retentionVersions AS rv" + + " ON cg.contactId = rv.contactId" + + " JOIN statuses AS s" + + " ON m.messageId = s.messageId" + + " AND cg.contactId = s.contactId" + + " WHERE m.messageId = ?" + + " AND cg.contactId = ?" + + " AND timestamp >= retention" + + " AND status = ?" + + " AND sendability > ZERO()"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, m.getBytes()); + ps.setInt(2, c.getInt()); + ps.setShort(3, (short) Status.NEW.ordinal()); + rs = ps.executeQuery(); + if(rs.next()) { + int length = rs.getInt(1); + raw = rs.getBlob(2).getBytes(1, length); + if(raw.length != length) throw new DbStateException(); + } + if(rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + return raw; + } catch(SQLException e) { + tryToClose(rs); + tryToClose(ps); + throw new DbException(e); + } + } + public boolean getReadFlag(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; ResultSet rs = null; @@ -2415,7 +2450,7 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public boolean setRead(Connection txn, MessageId m, boolean read) + public boolean setReadFlag(Connection txn, MessageId m, boolean read) throws DbException { PreparedStatement ps = null; ResultSet rs = null; @@ -2543,7 +2578,7 @@ abstract class JdbcDatabase implements Database<Connection> { } } - public boolean setStarred(Connection txn, MessageId m, boolean starred) + public boolean setStarredFlag(Connection txn, MessageId m, boolean starred) throws DbException { PreparedStatement ps = null; ResultSet rs = null; diff --git a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java index c7322c84ab37e77339d34d229d4af2e3c2a4f054..0286a9798f597ac1e96af5e957c764798705417c 100644 --- a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java +++ b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java @@ -689,9 +689,9 @@ public abstract class DatabaseComponentTest extends BriarTestCase { // Get the sendable messages oneOf(database).getSendableMessages(txn, contactId, size * 2); will(returnValue(sendable)); - oneOf(database).getMessage(txn, messageId); + oneOf(database).getRawMessage(txn, messageId); will(returnValue(raw)); - oneOf(database).getMessage(txn, messageId1); + oneOf(database).getRawMessage(txn, messageId1); will(returnValue(raw1)); // Record the outstanding messages oneOf(database).addOutstandingMessages(txn, contactId, sendable); @@ -723,11 +723,11 @@ public abstract class DatabaseComponentTest extends BriarTestCase { allowing(database).containsContact(txn, contactId); will(returnValue(true)); // Try to get the requested messages - oneOf(database).getMessageIfSendable(txn, contactId, messageId); + oneOf(database).getRawMessageIfSendable(txn, contactId, messageId); will(returnValue(null)); // Message is not sendable - oneOf(database).getMessageIfSendable(txn, contactId, messageId1); + oneOf(database).getRawMessageIfSendable(txn, contactId, messageId1); will(returnValue(raw1)); // Message is sendable - oneOf(database).getMessageIfSendable(txn, contactId, messageId2); + oneOf(database).getRawMessageIfSendable(txn, contactId, messageId2); will(returnValue(null)); // Message is not sendable // Record the outstanding messages oneOf(database).addOutstandingMessages(txn, contactId, diff --git a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java index fa7b1ec7dcd0f0e486677e3e6021b6114ee99aff..05fa70c6fb34fa7bcc07b50b750ad7e7dd841704 100644 --- a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java +++ b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java @@ -111,10 +111,10 @@ public class H2DatabaseTest extends BriarTestCase { assertTrue(db.containsContact(txn, contactId)); assertTrue(db.containsSubscription(txn, groupId)); assertTrue(db.containsMessage(txn, messageId)); - byte[] raw1 = db.getMessage(txn, messageId); + byte[] raw1 = db.getRawMessage(txn, messageId); assertArrayEquals(raw, raw1); assertTrue(db.containsMessage(txn, messageId1)); - raw1 = db.getMessage(txn, messageId1); + raw1 = db.getRawMessage(txn, messageId1); assertArrayEquals(raw, raw1); // Delete the records db.removeMessage(txn, messageId); @@ -892,7 +892,7 @@ public class H2DatabaseTest extends BriarTestCase { db.setSubscriptions(txn, contactId, Arrays.asList(group), 1L); // The message is not in the database - assertNull(db.getMessageIfSendable(txn, contactId, messageId)); + assertNull(db.getRawMessageIfSendable(txn, contactId, messageId)); db.commitTransaction(txn); db.close(); @@ -914,7 +914,7 @@ public class H2DatabaseTest extends BriarTestCase { db.setStatus(txn, contactId, messageId, Status.SEEN); // The message is not sendable because its status is SEEN - assertNull(db.getMessageIfSendable(txn, contactId, messageId)); + assertNull(db.getRawMessageIfSendable(txn, contactId, messageId)); db.commitTransaction(txn); db.close(); @@ -937,7 +937,7 @@ public class H2DatabaseTest extends BriarTestCase { db.setStatus(txn, contactId, messageId, Status.NEW); // The message is not sendable because its sendability is 0 - assertNull(db.getMessageIfSendable(txn, contactId, messageId)); + assertNull(db.getRawMessageIfSendable(txn, contactId, messageId)); db.commitTransaction(txn); db.close(); @@ -962,7 +962,7 @@ public class H2DatabaseTest extends BriarTestCase { db.setStatus(txn, contactId, messageId, Status.NEW); // The message is not sendable because it's too old - assertNull(db.getMessageIfSendable(txn, contactId, messageId)); + assertNull(db.getRawMessageIfSendable(txn, contactId, messageId)); db.commitTransaction(txn); db.close(); @@ -985,7 +985,7 @@ public class H2DatabaseTest extends BriarTestCase { db.setStatus(txn, contactId, messageId, Status.NEW); // The message is sendable so it should be returned - byte[] b = db.getMessageIfSendable(txn, contactId, messageId); + byte[] b = db.getRawMessageIfSendable(txn, contactId, messageId); assertArrayEquals(raw, b); db.commitTransaction(txn); @@ -1280,8 +1280,8 @@ public class H2DatabaseTest extends BriarTestCase { System.arraycopy(raw, 10, expectedBody1, 0, bodyLength); // Retrieve the raw messages - assertArrayEquals(raw, db.getMessage(txn, messageId)); - assertArrayEquals(raw, db.getMessage(txn, messageId1)); + assertArrayEquals(raw, db.getRawMessage(txn, messageId)); + assertArrayEquals(raw, db.getRawMessage(txn, messageId1)); // Retrieve the message bodies byte[] body = db.getMessageBody(txn, messageId); @@ -1310,7 +1310,7 @@ public class H2DatabaseTest extends BriarTestCase { authorId, subject, timestamp1, raw); db.addGroupMessage(txn, message1); // Mark one of the messages read - assertFalse(db.setRead(txn, messageId, true)); + assertFalse(db.setReadFlag(txn, messageId, true)); // Retrieve the message headers Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId); @@ -1381,13 +1381,13 @@ public class H2DatabaseTest extends BriarTestCase { // The message should be unread by default assertFalse(db.getReadFlag(txn, messageId)); // Marking the message read should return the old value - assertFalse(db.setRead(txn, messageId, true)); - assertTrue(db.setRead(txn, messageId, true)); + assertFalse(db.setReadFlag(txn, messageId, true)); + assertTrue(db.setReadFlag(txn, messageId, true)); // The message should be read assertTrue(db.getReadFlag(txn, messageId)); // Marking the message unread should return the old value - assertTrue(db.setRead(txn, messageId, false)); - assertFalse(db.setRead(txn, messageId, false)); + assertTrue(db.setReadFlag(txn, messageId, false)); + assertFalse(db.setReadFlag(txn, messageId, false)); // Unsubscribe from the group db.removeSubscription(txn, groupId); @@ -1407,13 +1407,13 @@ public class H2DatabaseTest extends BriarTestCase { // The message should be unstarred by default assertFalse(db.getStarredFlag(txn, messageId)); // Starring the message should return the old value - assertFalse(db.setStarred(txn, messageId, true)); - assertTrue(db.setStarred(txn, messageId, true)); + assertFalse(db.setStarredFlag(txn, messageId, true)); + assertTrue(db.setStarredFlag(txn, messageId, true)); // The message should be starred assertTrue(db.getStarredFlag(txn, messageId)); // Unstarring the message should return the old value - assertTrue(db.setStarred(txn, messageId, false)); - assertFalse(db.setStarred(txn, messageId, false)); + assertTrue(db.setStarredFlag(txn, messageId, false)); + assertFalse(db.setStarredFlag(txn, messageId, false)); // Unsubscribe from the group db.removeSubscription(txn, groupId); @@ -1446,7 +1446,7 @@ public class H2DatabaseTest extends BriarTestCase { db.addGroupMessage(txn, message2); // Mark one of the messages in the first group read - assertFalse(db.setRead(txn, messageId, true)); + assertFalse(db.setReadFlag(txn, messageId, true)); // There should be one unread message in each group Map<GroupId, Integer> counts = db.getUnreadMessageCounts(txn); @@ -1459,10 +1459,10 @@ public class H2DatabaseTest extends BriarTestCase { assertEquals(1, count.intValue()); // Mark the read message unread (it will now be false rather than null) - assertTrue(db.setRead(txn, messageId, false)); + assertTrue(db.setReadFlag(txn, messageId, false)); // Mark the message in the second group read - assertFalse(db.setRead(txn, messageId2, true)); + assertFalse(db.setReadFlag(txn, messageId2, true)); // There should be two unread messages in the first group, none in // the second group @@ -1812,7 +1812,7 @@ public class H2DatabaseTest extends BriarTestCase { Connection txn = db.startTransaction(); try { // Ask for a nonexistent message - an exception should be thrown - db.getMessage(txn, messageId); + db.getRawMessage(txn, messageId); fail(); } catch(DbException expected) { // It should be possible to abort the transaction without error