Include author and rating in private message headers.

This commit is contained in:
akwizgran
2013-04-14 21:15:23 +01:00
parent 4ff2b88955
commit da7657ff4d
15 changed files with 969 additions and 901 deletions

View File

@@ -118,7 +118,7 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
serviceConnection.waitForStartup();
long now = System.currentTimeMillis();
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(groupId);
db.getGroupMessageHeaders(groupId);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Load took " + duration + " ms");

View File

@@ -129,7 +129,7 @@ implements OnClickListener, DatabaseListener, NoBlogsDialog.Listener {
boolean postable = local.contains(g.getId());
try {
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(g.getId());
db.getGroupMessageHeaders(g.getId());
displayHeaders(g, postable, headers);
} catch(NoSuchSubscriptionException e) {
if(LOG.isLoggable(INFO))
@@ -256,7 +256,7 @@ implements OnClickListener, DatabaseListener, NoBlogsDialog.Listener {
serviceConnection.waitForStartup();
long now = System.currentTimeMillis();
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(g.getId());
db.getGroupMessageHeaders(g.getId());
boolean postable = db.getLocalGroups().contains(g);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))

View File

@@ -116,7 +116,7 @@ OnClickListener, OnItemClickListener {
serviceConnection.waitForStartup();
long now = System.currentTimeMillis();
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(groupId);
db.getGroupMessageHeaders(groupId);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Load took " + duration + " ms");

View File

@@ -124,7 +124,7 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
if(g.isRestricted()) continue;
try {
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(g.getId());
db.getGroupMessageHeaders(g.getId());
displayHeaders(g, headers);
} catch(NoSuchSubscriptionException e) {
if(LOG.isLoggable(INFO))
@@ -244,7 +244,7 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
serviceConnection.waitForStartup();
long now = System.currentTimeMillis();
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(g.getId());
db.getGroupMessageHeaders(g.getId());
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Partial load took " + duration + " ms");

View File

@@ -19,7 +19,6 @@ import net.sf.briar.android.BriarService.BriarServiceConnection;
import net.sf.briar.android.widgets.HorizontalBorder;
import net.sf.briar.api.AuthorId;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.LocalAuthor;
import net.sf.briar.api.android.DatabaseUiExecutor;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
@@ -60,7 +59,6 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
private volatile ContactId contactId = null;
private volatile AuthorId localAuthorId = null;
private volatile String localAuthorName = null;
@Override
public void onCreate(Bundle state) {
@@ -82,7 +80,7 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
adapter = new ConversationAdapter(this, contactName);
adapter = new ConversationAdapter(this);
list = new ListView(this);
// Give me all the width and all the unused height
list.setLayoutParams(MATCH_WRAP_1);
@@ -118,14 +116,12 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
try {
serviceConnection.waitForStartup();
long now = System.currentTimeMillis();
LocalAuthor localAuthor = db.getLocalAuthor(localAuthorId);
localAuthorName = localAuthor.getName();
Collection<PrivateMessageHeader> headers =
db.getPrivateMessageHeaders(contactId);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Load took " + duration + " ms");
displayHeaders(localAuthor, headers);
displayHeaders(headers);
} catch(NoSuchContactException e) {
if(LOG.isLoggable(INFO)) LOG.info("Contact removed");
finishOnUiThread();
@@ -141,11 +137,10 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
});
}
private void displayHeaders(final LocalAuthor localAuthor,
private void displayHeaders(
final Collection<PrivateMessageHeader> headers) {
runOnUiThread(new Runnable() {
public void run() {
adapter.setLocalAuthorName(localAuthor.getName());
adapter.clear();
for(PrivateMessageHeader h : headers) adapter.add(h);
adapter.sort(AscendingHeaderComparator.INSTANCE);
@@ -228,7 +223,6 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
Intent i = new Intent(this, ReadPrivateMessageActivity.class);
i.putExtra("net.sf.briar.CONTACT_ID", contactId.getInt());
i.putExtra("net.sf.briar.CONTACT_NAME", contactName);
i.putExtra("net.sf.briar.LOCAL_AUTHOR_NAME", localAuthorName);
i.putExtra("net.sf.briar.MESSAGE_ID", item.getId().getBytes());
i.putExtra("net.sf.briar.CONTENT_TYPE", item.getContentType());
i.putExtra("net.sf.briar.TIMESTAMP", item.getTimestamp());

View File

@@ -23,23 +23,13 @@ import android.widget.TextView;
class ConversationAdapter extends ArrayAdapter<PrivateMessageHeader> {
private final String contactName;
private String localAuthorName = null;
ConversationAdapter(Context ctx, String contactName) {
ConversationAdapter(Context ctx) {
super(ctx, android.R.layout.simple_expandable_list_item_1,
new ArrayList<PrivateMessageHeader>());
this.contactName = contactName;
}
void setLocalAuthorName(String localAuthorName) {
this.localAuthorName = localAuthorName;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(localAuthorName == null) throw new IllegalStateException();
PrivateMessageHeader item = getItem(position);
Context ctx = getContext();
@@ -59,8 +49,7 @@ class ConversationAdapter extends ArrayAdapter<PrivateMessageHeader> {
name.setTextSize(18);
name.setMaxLines(1);
name.setPadding(10, 10, 10, 10);
if(item.isIncoming()) name.setText(contactName);
else name.setText(localAuthorName);
name.setText(item.getAuthor().getName());
innerLayout.addView(name);
if(item.getContentType().equals("text/plain")) {

View File

@@ -180,6 +180,10 @@ public interface DatabaseComponent {
/** Returns the group with the given ID, if the user subscribes to it. */
Group getGroup(GroupId g) throws DbException;
/** Returns the headers of all messages in the given group. */
Collection<GroupMessageHeader> getGroupMessageHeaders(GroupId g)
throws DbException;
/** Returns the pseudonym with the given ID. */
LocalAuthor getLocalAuthor(AuthorId a) throws DbException;
@@ -199,10 +203,6 @@ public interface DatabaseComponent {
/** Returns the body of the message with the given ID. */
byte[] getMessageBody(MessageId m) throws DbException;
/** Returns the headers of all messages in the given group. */
Collection<GroupMessageHeader> getMessageHeaders(GroupId g)
throws DbException;
/**
* Returns the headers of all private messages to or from the given
* contact.

View File

@@ -8,35 +8,17 @@ import net.sf.briar.api.messaging.Rating;
public class GroupMessageHeader extends MessageHeader {
private final GroupId groupId;
private final Author author;
private final Rating rating;
public GroupMessageHeader(MessageId id, MessageId parent,
public GroupMessageHeader(MessageId id, MessageId parent, Author author,
String contentType, String subject, long timestamp, boolean read,
boolean starred, GroupId groupId, Author author, Rating rating) {
super(id, parent, contentType, subject, timestamp, read, starred);
boolean starred, Rating rating, GroupId groupId) {
super(id, parent, author, contentType, subject, timestamp, read,
starred, rating);
this.groupId = groupId;
this.author = author;
this.rating = rating;
}
/** Returns the ID of the group to which the message belongs. */
public GroupId getGroupId() {
return groupId;
}
/**
* Returns the message's author, or null if this is an anonymous message.
*/
public Author getAuthor() {
return author;
}
/**
* Returns the rating for the message's author, or Rating.UNRATED if this
* is an anonymous message.
*/
public Rating getRating() {
return rating;
}
}

View File

@@ -1,23 +1,30 @@
package net.sf.briar.api.db;
import net.sf.briar.api.Author;
import net.sf.briar.api.messaging.MessageId;
import net.sf.briar.api.messaging.Rating;
public abstract class MessageHeader {
private final MessageId id, parent;
private final Author author;
private final String contentType, subject;
private final long timestamp;
private final boolean read, starred;
private final Rating rating;
protected MessageHeader(MessageId id, MessageId parent, String contentType,
String subject, long timestamp, boolean read, boolean starred) {
protected MessageHeader(MessageId id, MessageId parent, Author author,
String contentType, String subject, long timestamp, boolean read,
boolean starred, Rating rating) {
this.id = id;
this.parent = parent;
this.author = author;
this.contentType = contentType;
this.subject = subject;
this.timestamp = timestamp;
this.read = read;
this.starred = starred;
this.rating = rating;
}
/** Returns the message's unique identifier. */
@@ -33,6 +40,13 @@ public abstract class MessageHeader {
return parent;
}
/**
* Returns the message's author, or null if this is an anonymous message.
*/
public Author getAuthor() {
return author;
}
/** Returns the message's content type. */
public String getContentType() {
return contentType;
@@ -57,4 +71,12 @@ public abstract class MessageHeader {
public boolean isStarred() {
return starred;
}
/**
* Returns the rating for the message's author, or Rating.UNRATED if this
* is an anonymous message.
*/
public Rating getRating() {
return rating;
}
}

View File

@@ -1,17 +1,21 @@
package net.sf.briar.api.db;
import net.sf.briar.api.Author;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.messaging.MessageId;
import net.sf.briar.api.messaging.Rating;
public class PrivateMessageHeader extends MessageHeader {
private final ContactId contactId;
private final boolean incoming;
public PrivateMessageHeader(MessageId id, MessageId parent,
public PrivateMessageHeader(MessageId id, MessageId parent, Author author,
String contentType, String subject, long timestamp, boolean read,
boolean starred, ContactId contactId, boolean incoming) {
super(id, parent, contentType, subject, timestamp, read, starred);
boolean starred, Rating rating, ContactId contactId,
boolean incoming) {
super(id, parent, author, contentType, subject, timestamp, read,
starred, rating);
this.contactId = contactId;
this.incoming = incoming;
}

View File

@@ -101,7 +101,8 @@ interface Database<T> {
* <p>
* Locking: message write.
*/
boolean addGroupMessage(T txn, Message m) throws DbException;
boolean addGroupMessage(T txn, Message m, boolean incoming)
throws DbException;
/**
* Stores a pseudonym that the user can use to sign messages.
@@ -131,7 +132,8 @@ interface Database<T> {
* <p>
* Locking: message write.
*/
boolean addPrivateMessage(T txn, Message m, ContactId c) throws DbException;
boolean addPrivateMessage(T txn, Message m, ContactId c, boolean incoming)
throws DbException;
/**
* Stores the given temporary secrets and deletes any secrets that have
@@ -272,6 +274,14 @@ interface Database<T> {
*/
Group getGroup(T txn, GroupId g) throws DbException;
/**
* Returns the headers of all messages in the given group.
* <p>
* Locking: message read, rating read.
*/
Collection<GroupMessageHeader> getGroupMessageHeaders(T txn, GroupId g)
throws DbException;
/**
* Returns the parent of the given group message, or null if either the
* message has no parent, or the parent is absent from the database, or the
@@ -333,19 +343,11 @@ interface Database<T> {
*/
byte[] getMessageBody(T txn, MessageId m) throws DbException;
/**
* Returns the headers of all messages in the given group.
* <p>
* Locking: message read, rating read.
*/
Collection<GroupMessageHeader> getMessageHeaders(T txn, GroupId g)
throws DbException;
/**
* Returns the headers of all private messages to or from the given
* contact.
* <p>
* Locking: message read.
* Locking: contact read, identity read, message read, rating read.
*/
Collection<PrivateMessageHeader> getPrivateMessageHeaders(T txn,
ContactId c) throws DbException;

File diff suppressed because it is too large Load Diff

View File

@@ -161,6 +161,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " bodyStart INT NOT NULL,"
+ " bodyLength INT NOT NULL,"
+ " raw BLOB NOT NULL,"
+ " incoming BOOLEAN NOT NULL,"
+ " sendability INT UNSIGNED," // Null for private messages
+ " contactId INT UNSIGNED," // Null for group messages
+ " read BOOLEAN NOT NULL,"
@@ -685,7 +686,7 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public boolean addGroupMessage(Connection txn, Message m)
public boolean addGroupMessage(Connection txn, Message m, boolean incoming)
throws DbException {
if(m.getGroup() == null) throw new IllegalArgumentException();
if(containsMessage(txn, m.getId())) return false;
@@ -694,9 +695,9 @@ abstract class JdbcDatabase implements Database<Connection> {
String sql = "INSERT INTO messages (messageId, parentId, groupId,"
+ " authorId, authorName, authorKey, contentType, subject,"
+ " timestamp, length, bodyStart, bodyLength, raw,"
+ " sendability, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ZERO(),"
+ " FALSE, FALSE)";
+ " incoming, sendability, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
+ " ZERO(), FALSE, FALSE)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getId().getBytes());
if(m.getParent() == null) ps.setNull(2, BINARY);
@@ -720,6 +721,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setInt(11, m.getBodyStart());
ps.setInt(12, m.getBodyLength());
ps.setBytes(13, raw);
ps.setBoolean(14, incoming);
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -803,16 +805,17 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public boolean addPrivateMessage(Connection txn, Message m, ContactId c)
throws DbException {
public boolean addPrivateMessage(Connection txn, Message m, ContactId c,
boolean incoming) throws DbException {
if(m.getGroup() != null) throw new IllegalArgumentException();
if(m.getAuthor() != null) throw new IllegalArgumentException();
if(containsMessage(txn, m.getId())) return false;
PreparedStatement ps = null;
try {
String sql = "INSERT INTO messages (messageId, parentId,"
+ " contentType, subject, timestamp, length, bodyStart,"
+ " bodyLength, raw, contactId, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, FALSE, FALSE)";
+ " bodyLength, raw, incoming, contactId, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, FALSE, FALSE)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getId().getBytes());
if(m.getParent() == null) ps.setNull(2, BINARY);
@@ -825,7 +828,8 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setInt(7, m.getBodyStart());
ps.setInt(8, m.getBodyLength());
ps.setBytes(9, raw);
ps.setInt(10, c.getInt());
ps.setBoolean(10, incoming);
ps.setInt(11, c.getInt());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -1333,6 +1337,60 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Collection<GroupMessageHeader> getGroupMessageHeaders(Connection txn,
GroupId g) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT messageId, parentId, m.authorId, authorName,"
+ " authorKey, rating, contentType, subject, timestamp,"
+ " read, starred"
+ " FROM messages AS m"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON m.authorId = r.authorId"
+ " WHERE groupId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes());
rs = ps.executeQuery();
List<GroupMessageHeader> headers =
new ArrayList<GroupMessageHeader>();
while(rs.next()) {
MessageId id = new MessageId(rs.getBytes(1));
byte[] b = rs.getBytes(2);
MessageId parent = b == null ? null : new MessageId(b);
Author author;
Rating rating;
b = rs.getBytes(3);
if(b == null) {
author = null;
rating = UNRATED;
} else {
AuthorId authorId = new AuthorId(b);
String authorName = rs.getString(4);
byte[] authorKey = rs.getBytes(5);
author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
rating = Rating.values()[rs.getByte(6)];
}
String contentType = rs.getString(7);
String subject = rs.getString(8);
long timestamp = rs.getLong(9);
boolean read = rs.getBoolean(10);
boolean starred = rs.getBoolean(11);
headers.add(new GroupMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
g));
}
rs.close();
ps.close();
return Collections.unmodifiableList(headers);
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public MessageId getGroupMessageParent(Connection txn, MessageId m)
throws DbException {
PreparedStatement ps = null;
@@ -1546,59 +1604,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Collection<GroupMessageHeader> getMessageHeaders(Connection txn,
GroupId g) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT messageId, parentId, m.authorId, authorName,"
+ " authorKey, rating, contentType, subject, timestamp,"
+ " read, starred"
+ " FROM messages AS m"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON m.authorId = r.authorId"
+ " WHERE groupId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes());
rs = ps.executeQuery();
List<GroupMessageHeader> headers =
new ArrayList<GroupMessageHeader>();
while(rs.next()) {
MessageId id = new MessageId(rs.getBytes(1));
byte[] b = rs.getBytes(2);
MessageId parent = b == null ? null : new MessageId(b);
Author author;
Rating rating;
b = rs.getBytes(3);
if(b == null) {
author = null;
rating = UNRATED;
} else {
AuthorId authorId = new AuthorId(b);
String authorName = rs.getString(4);
byte[] authorKey = rs.getBytes(5);
author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
rating = Rating.values()[rs.getByte(6)];
}
String contentType = rs.getString(7);
String subject = rs.getString(8);
long timestamp = rs.getLong(9);
boolean read = rs.getBoolean(10);
boolean starred = rs.getBoolean(11);
headers.add(new GroupMessageHeader(id, parent, contentType,
subject, timestamp, read, starred, g, author, rating));
}
rs.close();
ps.close();
return Collections.unmodifiableList(headers);
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public Collection<MessageId> getMessagesByAuthor(Connection txn, AuthorId a)
throws DbException {
PreparedStatement ps = null;
@@ -1767,13 +1772,18 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Get the incoming message headers
String sql = "SELECT m.messageId, parentId, contentType, subject,"
+ " timestamp, read, starred, seen"
+ " timestamp, read, starred, c.authorId, name, publicKey,"
+ " rating"
+ " FROM messages AS m"
+ " JOIN statuses AS s"
+ " ON m.messageId = s.messageId"
+ " AND m.contactId = s.contactId"
+ " WHERE m.contactId = ? AND groupId IS NULL";
+ " JOIN contacts AS c"
+ " ON m.contactId = c.contactId"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON c.authorId = r.authorId"
+ " WHERE m.contactId = ?"
+ " AND groupId IS NULL"
+ " AND incoming = TRUE";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
rs = ps.executeQuery();
@@ -1788,9 +1798,53 @@ abstract class JdbcDatabase implements Database<Connection> {
long timestamp = rs.getLong(5);
boolean read = rs.getBoolean(6);
boolean starred = rs.getBoolean(7);
boolean seen = rs.getBoolean(8);
headers.add(new PrivateMessageHeader(id, parent, contentType,
subject, timestamp, read, starred, c, seen));
AuthorId authorId = new AuthorId(rs.getBytes(8));
String authorName = rs.getString(9);
byte[] authorKey = rs.getBytes(10);
Author author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
Rating rating = Rating.values()[rs.getByte(11)];
headers.add(new PrivateMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
c, true));
}
rs.close();
ps.close();
// Get the outgoing message headers
sql = "SELECT m.messageId, parentId, contentType, subject,"
+ " timestamp, read, starred, a.authorId, a.name,"
+ " a.publicKey, rating"
+ " FROM messages AS m"
+ " JOIN contacts AS c"
+ " ON m.contactId = c.contactId"
+ " JOIN localAuthors AS a"
+ " ON c.localAuthorId = a.authorId"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON c.localAuthorId = r.authorId"
+ " WHERE m.contactId = ?"
+ " AND groupId IS NULL"
+ " AND incoming = FALSE";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
rs = ps.executeQuery();
while(rs.next()) {
MessageId id = new MessageId(rs.getBytes(1));
byte[] b = rs.getBytes(2);
MessageId parent = b == null ? null : new MessageId(b);
String contentType = rs.getString(3);
String subject = rs.getString(4);
long timestamp = rs.getLong(5);
boolean read = rs.getBoolean(6);
boolean starred = rs.getBoolean(7);
AuthorId authorId = new AuthorId(rs.getBytes(8));
String authorName = rs.getString(9);
byte[] authorKey = rs.getBytes(10);
Author author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
Rating rating = Rating.values()[rs.getByte(11)];
headers.add(new PrivateMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
c, false));
}
rs.close();
ps.close();

View File

@@ -172,7 +172,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
// getMessageHeaders(groupId)
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).getMessageHeaders(txn, groupId);
oneOf(database).getGroupMessageHeaders(txn, groupId);
will(returnValue(Collections.emptyList()));
// getSubscriptions()
oneOf(database).getSubscriptions(txn);
@@ -212,7 +212,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
db.getRemoteProperties(transportId));
db.subscribe(group); // First time - listeners called
db.subscribe(group); // Second time - not called
assertEquals(Collections.emptyList(), db.getMessageHeaders(groupId));
assertEquals(Collections.emptyList(),
db.getGroupMessageHeaders(groupId));
assertEquals(Arrays.asList(groupId), db.getSubscriptions());
db.unsubscribe(group);
db.removeContact(contactId);
@@ -367,7 +368,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
}});
@@ -392,7 +393,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).getContactIds(txn);
@@ -428,7 +429,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).getContactIds(txn);
@@ -467,7 +468,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(false));
}});
DatabaseComponent db = createDatabaseComponent(database, cleaner,
@@ -492,7 +494,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).addStatus(txn, contactId, messageId, false);
@@ -702,7 +705,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
} catch(NoSuchSubscriptionException expected) {}
try {
db.getMessageHeaders(groupId);
db.getGroupMessageHeaders(groupId);
fail();
} catch(NoSuchSubscriptionException expected) {}
@@ -1148,7 +1151,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// The message is stored
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
true);
will(returnValue(true));
oneOf(database).addStatus(txn, contactId, messageId, true);
// The message must be acked
@@ -1175,8 +1179,9 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).commitTransaction(txn);
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// The message is stored, but it's a duplicate
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
// The message is not stored, it's a duplicate
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
true);
will(returnValue(false));
// The message must still be acked
oneOf(database).addMessageToAck(txn, contactId, messageId);
@@ -1236,8 +1241,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsVisibleSubscription(txn, contactId,
groupId);
will(returnValue(true));
// The message is stored, but it's a duplicate
oneOf(database).addGroupMessage(txn, message);
// The message is not stored, it's a duplicate
oneOf(database).addGroupMessage(txn, message, true);
will(returnValue(false));
oneOf(database).addStatus(txn, contactId, messageId, true);
// The message must be acked
@@ -1269,7 +1274,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
groupId);
will(returnValue(true));
// The message is stored, and it's not a duplicate
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, true);
will(returnValue(true));
oneOf(database).addStatus(txn, contactId, messageId, true);
// Set the status to seen = true for all other contacts (none)
@@ -1311,7 +1316,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
groupId);
will(returnValue(true));
// The message is stored, and it's not a duplicate
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, true);
will(returnValue(true));
oneOf(database).addStatus(txn, contactId, messageId, true);
// Set the status to seen = true for all other contacts (none)
@@ -1513,7 +1518,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).getContactIds(txn);
@@ -1553,7 +1558,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(true));
oneOf(database).setReadFlag(txn, messageId, true);
oneOf(database).addStatus(txn, contactId, messageId, false);
@@ -1585,7 +1591,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
will(returnValue(txn));
oneOf(database).containsSubscription(txn, groupId);
will(returnValue(true));
oneOf(database).addGroupMessage(txn, message);
oneOf(database).addGroupMessage(txn, message, false);
will(returnValue(false));
oneOf(database).commitTransaction(txn);
// The message was not added, so the listener should not be called
@@ -1615,7 +1621,8 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
// addLocalPrivateMessage(privateMessage, contactId)
oneOf(database).addPrivateMessage(txn, privateMessage, contactId);
oneOf(database).addPrivateMessage(txn, privateMessage, contactId,
false);
will(returnValue(false));
// The message was not added, so the listener should not be called
}});

View File

@@ -110,10 +110,10 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
assertTrue(db.containsSubscription(txn, groupId));
assertFalse(db.containsMessage(txn, messageId));
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, true);
assertTrue(db.containsMessage(txn, messageId));
assertFalse(db.containsMessage(txn, messageId1));
db.addPrivateMessage(txn, privateMessage, contactId);
db.addPrivateMessage(txn, privateMessage, contactId, true);
assertTrue(db.containsMessage(txn, messageId1));
db.commitTransaction(txn);
db.close();
@@ -173,7 +173,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to a group and store a message
db.addSubscription(txn, group);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// Unsubscribing from the group should remove the message
assertTrue(db.containsMessage(txn, messageId));
@@ -192,7 +192,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId);
db.addPrivateMessage(txn, privateMessage, contactId, false);
// Removing the contact should remove the message
assertTrue(db.containsMessage(txn, messageId1));
@@ -212,7 +212,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId);
db.addPrivateMessage(txn, privateMessage, contactId, false);
// The message has no status yet, so it should not be sendable
assertFalse(db.hasSendableMessages(txn, contactId));
@@ -241,7 +241,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Add a contact and store a private message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addPrivateMessage(txn, privateMessage, contactId);
db.addPrivateMessage(txn, privateMessage, contactId, false);
db.addStatus(txn, contactId, messageId1, false);
// The message is sendable, but too large to send
@@ -273,7 +273,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The message should not be sendable
@@ -312,7 +312,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.setSendability(txn, messageId, 1);
// The message has no status yet, so it should not be sendable
@@ -349,7 +349,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.setSendability(txn, messageId, 1);
db.addStatus(txn, contactId, messageId, false);
@@ -388,7 +388,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.setSendability(txn, messageId, 1);
db.addStatus(txn, contactId, messageId, false);
@@ -419,7 +419,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.setSendability(txn, messageId, 1);
db.addStatus(txn, contactId, messageId, false);
@@ -505,7 +505,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.setSendability(txn, messageId, 1);
db.addStatus(txn, contactId, messageId, false);
@@ -545,8 +545,8 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to a group and store two messages
db.addSubscription(txn, group);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message1);
db.addGroupMessage(txn, message, false);
db.addGroupMessage(txn, message1, false);
// Check that each message is retrievable via its author
Iterator<MessageId> it =
@@ -583,10 +583,10 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to the groups and store the messages
db.addSubscription(txn, group);
db.addSubscription(txn, group1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, child1);
db.addGroupMessage(txn, child2);
db.addGroupMessage(txn, child3);
db.addGroupMessage(txn, message, false);
db.addGroupMessage(txn, child1, false);
db.addGroupMessage(txn, child2, false);
db.addGroupMessage(txn, child3, false);
// Make all the children sendable
db.setSendability(txn, childId1, 1);
db.setSendability(txn, childId2, 5);
@@ -613,8 +613,8 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to a group and store two messages
db.addSubscription(txn, group);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message1);
db.addGroupMessage(txn, message, false);
db.addGroupMessage(txn, message1, false);
// Allowing enough capacity for one message should return the older one
Iterator<MessageId> it = db.getOldMessages(txn, size).iterator();
@@ -653,7 +653,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Storing a message should reduce the free space
Connection txn = db.startTransaction();
db.addSubscription(txn, group);
db.addGroupMessage(txn, message1);
db.addGroupMessage(txn, message1, false);
db.commitTransaction(txn);
assertTrue(db.getFreeSpace() < free);
@@ -894,7 +894,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// Set the sendability to > 0 and the status to seen = true
db.setSendability(txn, messageId, 1);
@@ -919,7 +919,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// Set the sendability to 0 and the status to seen = false
db.setSendability(txn, messageId, 0);
@@ -945,7 +945,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.setRetentionTime(txn, contactId, timestamp + 1, 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// Set the sendability to > 0 and the status to seen = false
db.setSendability(txn, messageId, 1);
@@ -969,7 +969,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// Set the sendability to > 0 and the status to seen = false
db.setSendability(txn, messageId, 1);
@@ -1032,7 +1032,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// There's no contact subscription for the group
@@ -1053,7 +1053,7 @@ public class H2DatabaseTest extends BriarTestCase {
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addSubscription(txn, group);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
db.addStatus(txn, contactId, messageId, false);
// The subscription is not visible
@@ -1075,7 +1075,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// The message has already been seen by the contact
db.addStatus(txn, contactId, messageId, true);
@@ -1098,7 +1098,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
db.addVisibility(txn, contactId, groupId);
db.setSubscriptions(txn, contactId, Arrays.asList(group), 1);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// The message has not been seen by the contact
db.addStatus(txn, contactId, messageId, false);
@@ -1146,7 +1146,7 @@ public class H2DatabaseTest extends BriarTestCase {
MessageId childId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, null, group, null, contentType,
subject, timestamp, raw);
db.addGroupMessage(txn, child);
db.addGroupMessage(txn, child, false);
assertTrue(db.containsMessage(txn, childId));
assertNull(db.getGroupMessageParent(txn, childId));
@@ -1167,7 +1167,7 @@ public class H2DatabaseTest extends BriarTestCase {
MessageId parentId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, parentId, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child);
db.addGroupMessage(txn, child, false);
assertTrue(db.containsMessage(txn, childId));
assertFalse(db.containsMessage(txn, parentId));
assertNull(db.getGroupMessageParent(txn, childId));
@@ -1195,8 +1195,8 @@ public class H2DatabaseTest extends BriarTestCase {
contentType, subject, timestamp, raw);
Message parent = new TestMessage(parentId, null, group1, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child);
db.addGroupMessage(txn, parent);
db.addGroupMessage(txn, child, false);
db.addGroupMessage(txn, parent, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertNull(db.getGroupMessageParent(txn, childId));
@@ -1219,8 +1219,8 @@ public class H2DatabaseTest extends BriarTestCase {
MessageId childId = new MessageId(TestUtils.getRandomId());
Message child = new TestMessage(childId, messageId1, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child);
db.addPrivateMessage(txn, privateMessage, contactId);
db.addGroupMessage(txn, child, false);
db.addPrivateMessage(txn, privateMessage, contactId, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, messageId1));
assertNull(db.getGroupMessageParent(txn, childId));
@@ -1245,8 +1245,8 @@ public class H2DatabaseTest extends BriarTestCase {
contentType, subject, timestamp, raw);
Message parent = new TestMessage(parentId, null, group, null,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, child);
db.addGroupMessage(txn, parent);
db.addGroupMessage(txn, child, false);
db.addGroupMessage(txn, parent, false);
assertTrue(db.containsMessage(txn, childId));
assertTrue(db.containsMessage(txn, parentId));
assertEquals(parentId, db.getGroupMessageParent(txn, childId));
@@ -1271,8 +1271,8 @@ public class H2DatabaseTest extends BriarTestCase {
contentType, subject, timestamp, raw, 5, bodyLength);
Message privateMessage1 = new TestMessage(messageId1, null, null,
null, contentType, subject, timestamp, raw, 10, bodyLength);
db.addGroupMessage(txn, message1);
db.addPrivateMessage(txn, privateMessage1, contactId);
db.addGroupMessage(txn, message1, false);
db.addPrivateMessage(txn, privateMessage1, contactId, false);
// Calculate the expected message bodies
byte[] expectedBody = new byte[bodyLength];
@@ -1305,19 +1305,19 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group);
// Store a couple of messages
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
MessageId parentId = new MessageId(TestUtils.getRandomId());
long timestamp1 = System.currentTimeMillis();
Message message1 = new TestMessage(messageId1, parentId, group, author,
contentType, subject, timestamp1, raw);
db.addGroupMessage(txn, message1);
db.addGroupMessage(txn, message1, false);
// Mark one of the messages read
assertFalse(db.setReadFlag(txn, messageId, true));
// Retrieve the message headers
Collection<GroupMessageHeader> headers =
db.getMessageHeaders(txn, groupId);
db.getGroupMessageHeaders(txn, groupId);
Iterator<GroupMessageHeader> it = headers.iterator();
boolean messageFound = false, message1Found = false;
// First header (order is undefined)
@@ -1380,7 +1380,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to a group and store a message
db.addSubscription(txn, group);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// The message should be unread by default
assertFalse(db.getReadFlag(txn, messageId));
@@ -1406,7 +1406,7 @@ public class H2DatabaseTest extends BriarTestCase {
// Subscribe to a group and store a message
db.addSubscription(txn, group);
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
// The message should be unstarred by default
assertFalse(db.getStarredFlag(txn, messageId));
@@ -1437,17 +1437,17 @@ public class H2DatabaseTest extends BriarTestCase {
db.addSubscription(txn, group1);
// Store two messages in the first group
db.addGroupMessage(txn, message);
db.addGroupMessage(txn, message, false);
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
Message message1 = new TestMessage(messageId1, null, group, author,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, message1);
db.addGroupMessage(txn, message1, false);
// Store one message in the second group
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
Message message2 = new TestMessage(messageId2, null, group1, author,
contentType, subject, timestamp, raw);
db.addGroupMessage(txn, message2);
db.addGroupMessage(txn, message2, false);
// Mark one of the messages in the first group read
assertFalse(db.setReadFlag(txn, messageId, true));