Moved MessageHeader into DB component and added read/starred flags.

This commit is contained in:
akwizgran
2011-10-26 17:07:09 +01:00
parent 0f6b0e88c1
commit 6d91603bf7
14 changed files with 108 additions and 83 deletions

View File

@@ -16,7 +16,6 @@ import net.sf.briar.api.protocol.Batch;
import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer; import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.SubscriptionUpdate; import net.sf.briar.api.protocol.SubscriptionUpdate;

View File

@@ -1,4 +1,8 @@
package net.sf.briar.api.protocol; package net.sf.briar.api.db;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.MessageId;
public interface MessageHeader { public interface MessageHeader {
@@ -22,4 +26,10 @@ public interface MessageHeader {
/** Returns the timestamp created by the message's author. */ /** Returns the timestamp created by the message's author. */
long getTimestamp(); long getTimestamp();
/** Returns true if the message has been read. */
boolean getRead();
/** Returns true if the message has been starred. */
boolean getStarred();
} }

View File

@@ -1,6 +1,6 @@
package net.sf.briar.api.protocol; package net.sf.briar.api.protocol;
public interface Message extends MessageHeader { public interface Message {
/** /**
* The maximum length of a message body in bytes. To allow for future * The maximum length of a message body in bytes. To allow for future
@@ -19,6 +19,27 @@ public interface Message extends MessageHeader {
/** The length of the random salt in bytes. */ /** The length of the random salt in bytes. */
static final int SALT_LENGTH = 8; static final int SALT_LENGTH = 8;
/** Returns the message's unique identifier. */
MessageId getId();
/**
* Returns the message's parent, or MessageId.NONE if this is the first
* message in a thread.
*/
MessageId getParent();
/** Returns the group to which the message belongs. */
GroupId getGroup();
/** Returns the message's author. */
AuthorId getAuthor();
/** Returns the message's subject line. */
String getSubject();
/** Returns the timestamp created by the message's author. */
long getTimestamp();
/** Returns the length of the serialised message in bytes. */ /** Returns the length of the serialised message in bytes. */
int getLength(); int getLength();

View File

@@ -1,7 +0,0 @@
package net.sf.briar.api.protocol;
public interface MessageHeaderFactory {
MessageHeader createMessageHeader(MessageId id, MessageId parent,
GroupId group, AuthorId author, String subject, long timestamp);
}

View File

@@ -10,13 +10,13 @@ import net.sf.briar.api.TransportConfig;
import net.sf.briar.api.TransportId; import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.db.Status; import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow; import net.sf.briar.api.transport.ConnectionWindow;
@@ -257,7 +257,7 @@ interface Database<T> {
/** /**
* Returns the headers of all messages in the given group. * Returns the headers of all messages in the given group.
* <p> * <p>
* Locking: message read. * Locking: message read, messageFlag read.
*/ */
Collection<MessageHeader> getMessageHeaders(T txn, GroupId g) Collection<MessageHeader> getMessageHeaders(T txn, GroupId g)
throws DbException; throws DbException;

View File

@@ -27,6 +27,7 @@ import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException; 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.NoSuchContactException;
import net.sf.briar.api.db.Status; import net.sf.briar.api.db.Status;
import net.sf.briar.api.db.event.BatchReceivedEvent; import net.sf.briar.api.db.event.BatchReceivedEvent;
@@ -45,7 +46,6 @@ import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer; import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.SubscriptionUpdate; import net.sf.briar.api.protocol.SubscriptionUpdate;
@@ -789,15 +789,20 @@ DatabaseCleaner.Callback {
throws DbException { throws DbException {
messageLock.readLock().lock(); messageLock.readLock().lock();
try { try {
T txn = db.startTransaction(); messageFlagLock.readLock().lock();
try { try {
Collection<MessageHeader> headers = T txn = db.startTransaction();
db.getMessageHeaders(txn, g); try {
db.commitTransaction(txn); Collection<MessageHeader> headers =
return headers; db.getMessageHeaders(txn, g);
} catch(DbException e) { db.commitTransaction(txn);
db.abortTransaction(txn); return headers;
throw e; } catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
messageFlagLock.readLock().unlock();
} }
} finally { } finally {
messageLock.readLock().unlock(); messageLock.readLock().unlock();

View File

@@ -9,7 +9,6 @@ import net.sf.briar.api.db.DatabaseDirectory;
import net.sf.briar.api.db.DatabaseMaxSize; import net.sf.briar.api.db.DatabaseMaxSize;
import net.sf.briar.api.db.DatabasePassword; import net.sf.briar.api.db.DatabasePassword;
import net.sf.briar.api.protocol.GroupFactory; import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.transport.ConnectionWindowFactory; import net.sf.briar.api.transport.ConnectionWindowFactory;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@@ -27,10 +26,9 @@ public class DatabaseModule extends AbstractModule {
Database<Connection> getDatabase(@DatabaseDirectory File dir, Database<Connection> getDatabase(@DatabaseDirectory File dir,
@DatabasePassword Password password, @DatabaseMaxSize long maxSize, @DatabasePassword Password password, @DatabaseMaxSize long maxSize,
ConnectionWindowFactory connectionWindowFactory, ConnectionWindowFactory connectionWindowFactory,
GroupFactory groupFactory, GroupFactory groupFactory) {
MessageHeaderFactory messageHeaderFactory) {
return new H2Database(dir, password, maxSize, connectionWindowFactory, return new H2Database(dir, password, maxSize, connectionWindowFactory,
groupFactory, messageHeaderFactory); groupFactory);
} }
@Provides @Singleton @Provides @Singleton

View File

@@ -16,7 +16,6 @@ import net.sf.briar.api.db.DatabaseMaxSize;
import net.sf.briar.api.db.DatabasePassword; import net.sf.briar.api.db.DatabasePassword;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.protocol.GroupFactory; import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.transport.ConnectionWindowFactory; import net.sf.briar.api.transport.ConnectionWindowFactory;
import org.apache.commons.io.FileSystemUtils; import org.apache.commons.io.FileSystemUtils;
@@ -38,9 +37,8 @@ class H2Database extends JdbcDatabase {
H2Database(@DatabaseDirectory File dir, @DatabasePassword Password password, H2Database(@DatabaseDirectory File dir, @DatabasePassword Password password,
@DatabaseMaxSize long maxSize, @DatabaseMaxSize long maxSize,
ConnectionWindowFactory connectionWindowFactory, ConnectionWindowFactory connectionWindowFactory,
GroupFactory groupFactory, GroupFactory groupFactory) {
MessageHeaderFactory messageHeaderFactory) { super(connectionWindowFactory, groupFactory,
super(connectionWindowFactory, groupFactory, messageHeaderFactory,
"BINARY(32)", "BINARY", "INT NOT NULL AUTO_INCREMENT"); "BINARY(32)", "BINARY", "INT NOT NULL AUTO_INCREMENT");
home = new File(dir, "db"); home = new File(dir, "db");
this.password = password; this.password = password;

View File

@@ -23,6 +23,7 @@ import net.sf.briar.api.TransportConfig;
import net.sf.briar.api.TransportId; import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.db.Status; import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.BatchId;
@@ -30,8 +31,6 @@ import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupFactory; import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow; import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory; import net.sf.briar.api.transport.ConnectionWindowFactory;
@@ -241,7 +240,6 @@ abstract class JdbcDatabase implements Database<Connection> {
private final String hashType, binaryType, counterType; private final String hashType, binaryType, counterType;
private final ConnectionWindowFactory connectionWindowFactory; private final ConnectionWindowFactory connectionWindowFactory;
private final GroupFactory groupFactory; private final GroupFactory groupFactory;
private final MessageHeaderFactory messageHeaderFactory;
private final LinkedList<Connection> connections = private final LinkedList<Connection> connections =
new LinkedList<Connection>(); // Locking: self new LinkedList<Connection>(); // Locking: self
@@ -252,12 +250,10 @@ abstract class JdbcDatabase implements Database<Connection> {
protected abstract Connection createConnection() throws SQLException; protected abstract Connection createConnection() throws SQLException;
JdbcDatabase(ConnectionWindowFactory connectionWindowFactory, JdbcDatabase(ConnectionWindowFactory connectionWindowFactory,
GroupFactory groupFactory, GroupFactory groupFactory, String hashType, String binaryType,
MessageHeaderFactory messageHeaderFactory, String counterType) {
String hashType, String binaryType, String counterType) {
this.connectionWindowFactory = connectionWindowFactory; this.connectionWindowFactory = connectionWindowFactory;
this.groupFactory = groupFactory; this.groupFactory = groupFactory;
this.messageHeaderFactory = messageHeaderFactory;
this.hashType = hashType; this.hashType = hashType;
this.binaryType = binaryType; this.binaryType = binaryType;
this.counterType = counterType; this.counterType = counterType;
@@ -1115,8 +1111,10 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT messageId, parentId, authorId, subject," String sql = "SELECT messages.messageId, parentId, authorId,"
+ " timestamp FROM messages" + " subject, timestamp, read, starred"
+ " FROM messages LEFT OUTER JOIN flags"
+ " ON messages.messageId = flags.messageId"
+ " WHERE groupId = ?"; + " WHERE groupId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes()); ps.setBytes(1, g.getBytes());
@@ -1129,8 +1127,10 @@ abstract class JdbcDatabase implements Database<Connection> {
AuthorId author = new AuthorId(rs.getBytes(3)); AuthorId author = new AuthorId(rs.getBytes(3));
String subject = rs.getString(4); String subject = rs.getString(4);
long timestamp = rs.getLong(5); long timestamp = rs.getLong(5);
headers.add(messageHeaderFactory.createMessageHeader(id, parent, boolean read = rs.getBoolean(6); // False if absent
g, author, subject, timestamp)); boolean starred = rs.getBoolean(7); // False if absent
headers.add(new MessageHeaderImpl(id, parent, g, author,
subject, timestamp, read, starred));
} }
rs.close(); rs.close();
ps.close(); ps.close();

View File

@@ -1,8 +1,8 @@
package net.sf.briar.protocol; package net.sf.briar.db;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
class MessageHeaderImpl implements MessageHeader { class MessageHeaderImpl implements MessageHeader {
@@ -12,15 +12,19 @@ class MessageHeaderImpl implements MessageHeader {
private final AuthorId author; private final AuthorId author;
private final String subject; private final String subject;
private final long timestamp; private final long timestamp;
private final boolean read, starred;
MessageHeaderImpl(MessageId id, MessageId parent, GroupId group, MessageHeaderImpl(MessageId id, MessageId parent, GroupId group,
AuthorId author, String subject, long timestamp) { AuthorId author, String subject, long timestamp, boolean read,
boolean starred) {
this.id = id; this.id = id;
this.parent = parent; this.parent = parent;
this.group = group; this.group = group;
this.author = author; this.author = author;
this.subject = subject; this.subject = subject;
this.timestamp = timestamp; this.timestamp = timestamp;
this.read = read;
this.starred = starred;
} }
public MessageId getId() { public MessageId getId() {
@@ -46,4 +50,12 @@ class MessageHeaderImpl implements MessageHeader {
public long getTimestamp() { public long getTimestamp() {
return timestamp; return timestamp;
} }
public boolean getRead() {
return read;
}
public boolean getStarred() {
return starred;
}
} }

View File

@@ -1,16 +0,0 @@
package net.sf.briar.protocol;
import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.protocol.MessageId;
class MessageHeaderFactoryImpl implements MessageHeaderFactory {
public MessageHeader createMessageHeader(MessageId id, MessageId parent,
GroupId group, AuthorId author, String subject, long timestamp) {
return new MessageHeaderImpl(id, parent, group, author, subject,
timestamp);
}
}

View File

@@ -10,7 +10,6 @@ import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupFactory; import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageEncoder; import net.sf.briar.api.protocol.MessageEncoder;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer; import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.ProtocolReaderFactory; import net.sf.briar.api.protocol.ProtocolReaderFactory;
@@ -31,7 +30,6 @@ public class ProtocolModule extends AbstractModule {
bind(BatchFactory.class).to(BatchFactoryImpl.class); bind(BatchFactory.class).to(BatchFactoryImpl.class);
bind(GroupFactory.class).to(GroupFactoryImpl.class); bind(GroupFactory.class).to(GroupFactoryImpl.class);
bind(MessageEncoder.class).to(MessageEncoderImpl.class); bind(MessageEncoder.class).to(MessageEncoderImpl.class);
bind(MessageHeaderFactory.class).to(MessageHeaderFactoryImpl.class);
bind(OfferFactory.class).to(OfferFactoryImpl.class); bind(OfferFactory.class).to(OfferFactoryImpl.class);
bind(ProtocolReaderFactory.class).to(ProtocolReaderFactoryImpl.class); bind(ProtocolReaderFactory.class).to(ProtocolReaderFactoryImpl.class);
bind(RequestFactory.class).to(RequestFactoryImpl.class); bind(RequestFactory.class).to(RequestFactoryImpl.class);

View File

@@ -13,6 +13,7 @@ import net.sf.briar.api.Rating;
import net.sf.briar.api.TransportId; import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.db.NoSuchContactException; import net.sf.briar.api.db.NoSuchContactException;
import net.sf.briar.api.db.Status; import net.sf.briar.api.db.Status;
import net.sf.briar.api.db.event.ContactAddedEvent; import net.sf.briar.api.db.event.ContactAddedEvent;
@@ -28,7 +29,6 @@ import net.sf.briar.api.protocol.BatchId;
import net.sf.briar.api.protocol.Group; import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.protocol.Offer; import net.sf.briar.api.protocol.Offer;
import net.sf.briar.api.protocol.ProtocolConstants; import net.sf.briar.api.protocol.ProtocolConstants;

View File

@@ -26,6 +26,7 @@ import net.sf.briar.api.TransportId;
import net.sf.briar.api.TransportProperties; import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.crypto.Password; import net.sf.briar.api.crypto.Password;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.db.MessageHeader;
import net.sf.briar.api.db.Status; import net.sf.briar.api.db.Status;
import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.AuthorId;
import net.sf.briar.api.protocol.BatchId; import net.sf.briar.api.protocol.BatchId;
@@ -33,8 +34,6 @@ import net.sf.briar.api.protocol.Group;
import net.sf.briar.api.protocol.GroupFactory; import net.sf.briar.api.protocol.GroupFactory;
import net.sf.briar.api.protocol.GroupId; import net.sf.briar.api.protocol.GroupId;
import net.sf.briar.api.protocol.Message; import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageHeader;
import net.sf.briar.api.protocol.MessageHeaderFactory;
import net.sf.briar.api.protocol.MessageId; import net.sf.briar.api.protocol.MessageId;
import net.sf.briar.api.transport.ConnectionWindow; import net.sf.briar.api.transport.ConnectionWindow;
import net.sf.briar.api.transport.ConnectionWindowFactory; import net.sf.briar.api.transport.ConnectionWindowFactory;
@@ -63,7 +62,6 @@ public class H2DatabaseTest extends TestCase {
private final Random random = new Random(); private final Random random = new Random();
private final ConnectionWindowFactory connectionWindowFactory; private final ConnectionWindowFactory connectionWindowFactory;
private final GroupFactory groupFactory; private final GroupFactory groupFactory;
private final MessageHeaderFactory messageHeaderFactory;
private final AuthorId authorId; private final AuthorId authorId;
private final BatchId batchId; private final BatchId batchId;
@@ -90,7 +88,6 @@ public class H2DatabaseTest extends TestCase {
new TransportModule(), new TestDatabaseModule(testDir)); new TransportModule(), new TestDatabaseModule(testDir));
connectionWindowFactory = i.getInstance(ConnectionWindowFactory.class); connectionWindowFactory = i.getInstance(ConnectionWindowFactory.class);
groupFactory = i.getInstance(GroupFactory.class); groupFactory = i.getInstance(GroupFactory.class);
messageHeaderFactory = i.getInstance(MessageHeaderFactory.class);
authorId = new AuthorId(TestUtils.getRandomId()); authorId = new AuthorId(TestUtils.getRandomId());
batchId = new BatchId(TestUtils.getRandomId()); batchId = new BatchId(TestUtils.getRandomId());
contactId = new ContactId(1); contactId = new ContactId(1);
@@ -1667,6 +1664,8 @@ public class H2DatabaseTest extends TestCase {
Message message1 = new TestMessage(messageId1, parentId, groupId, Message message1 = new TestMessage(messageId1, parentId, groupId,
authorId, subject, timestamp1, raw); authorId, subject, timestamp1, raw);
db.addGroupMessage(txn, message1); db.addGroupMessage(txn, message1);
// Mark one of the messages read
assertFalse(db.setRead(txn, messageId, true));
// Retrieve the message headers // Retrieve the message headers
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId); Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
@@ -1676,10 +1675,14 @@ public class H2DatabaseTest extends TestCase {
assertTrue(it.hasNext()); assertTrue(it.hasNext());
MessageHeader header = it.next(); MessageHeader header = it.next();
if(messageId.equals(header.getId())) { if(messageId.equals(header.getId())) {
assertHeadersAreEqual(message, header); assertHeadersMatch(message, header);
assertTrue(header.getRead());
assertFalse(header.getStarred());
messageFound = true; messageFound = true;
} else if(messageId1.equals(header.getId())) { } else if(messageId1.equals(header.getId())) {
assertHeadersAreEqual(message1, header); assertHeadersMatch(message1, header);
assertFalse(header.getRead());
assertFalse(header.getStarred());
message1Found = true; message1Found = true;
} else { } else {
fail(); fail();
@@ -1688,10 +1691,14 @@ public class H2DatabaseTest extends TestCase {
assertTrue(it.hasNext()); assertTrue(it.hasNext());
header = it.next(); header = it.next();
if(messageId.equals(header.getId())) { if(messageId.equals(header.getId())) {
assertHeadersAreEqual(message, header); assertHeadersMatch(message, header);
assertTrue(header.getRead());
assertFalse(header.getStarred());
messageFound = true; messageFound = true;
} else if(messageId1.equals(header.getId())) { } else if(messageId1.equals(header.getId())) {
assertHeadersAreEqual(message1, header); assertHeadersMatch(message1, header);
assertFalse(header.getRead());
assertFalse(header.getStarred());
message1Found = true; message1Found = true;
} else { } else {
fail(); fail();
@@ -1705,6 +1712,18 @@ public class H2DatabaseTest extends TestCase {
db.close(); db.close();
} }
private void assertHeadersMatch(Message m, MessageHeader h) {
assertEquals(m.getId(), h.getId());
if(m.getParent() == null) assertNull(h.getParent());
else assertEquals(m.getParent(), h.getParent());
if(m.getGroup() == null) assertNull(h.getGroup());
else assertEquals(m.getGroup(), h.getGroup());
if(m.getAuthor() == null) assertNull(h.getAuthor());
else assertEquals(m.getAuthor(), h.getAuthor());
assertEquals(m.getSubject(), h.getSubject());
assertEquals(m.getTimestamp(), h.getTimestamp());
}
@Test @Test
public void testReadFlag() throws Exception { public void testReadFlag() throws Exception {
Database<Connection> db = open(false); Database<Connection> db = open(false);
@@ -1757,18 +1776,6 @@ public class H2DatabaseTest extends TestCase {
db.close(); db.close();
} }
private void assertHeadersAreEqual(MessageHeader h1, MessageHeader h2) {
assertEquals(h1.getId(), h2.getId());
if(h1.getParent() == null) assertNull(h2.getParent());
else assertEquals(h1.getParent(), h2.getParent());
if(h1.getGroup() == null) assertNull(h2.getGroup());
else assertEquals(h1.getGroup(), h2.getGroup());
if(h1.getAuthor() == null) assertNull(h2.getAuthor());
else assertEquals(h1.getAuthor(), h2.getAuthor());
assertEquals(h1.getSubject(), h2.getSubject());
assertEquals(h1.getTimestamp(), h2.getTimestamp());
}
@Test @Test
public void testExceptionHandling() throws Exception { public void testExceptionHandling() throws Exception {
Database<Connection> db = open(false); Database<Connection> db = open(false);
@@ -1787,7 +1794,7 @@ public class H2DatabaseTest extends TestCase {
private Database<Connection> open(boolean resume) throws Exception { private Database<Connection> open(boolean resume) throws Exception {
Database<Connection> db = new H2Database(testDir, password, MAX_SIZE, Database<Connection> db = new H2Database(testDir, password, MAX_SIZE,
connectionWindowFactory, groupFactory, messageHeaderFactory); connectionWindowFactory, groupFactory);
db.open(resume); db.open(resume);
return db; return db;
} }