From 882420ebc22e567b4c3d70175c03a10a760438c3 Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Sat, 2 Mar 2013 03:31:39 +0000
Subject: [PATCH] Added a method for getting one contact's private messages
 from the DB.

---
 .../messages/ConversationActivity.java        |  7 ++--
 .../android/messages/ConversationAdapter.java |  2 +-
 .../messages/ConversationListActivity.java    |  8 ++--
 .../messages/ConversationListAdapter.java     |  3 +-
 .../sf/briar/api/db/DatabaseComponent.java    |  7 ++++
 briar-core/src/net/sf/briar/db/Database.java  |  9 +++++
 .../sf/briar/db/DatabaseComponentImpl.java    | 19 +++++++++
 .../src/net/sf/briar/db/JdbcDatabase.java     | 39 +++++++++++++++++++
 8 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
index 1782a6ceb1..82ae8a74fe 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java
@@ -47,8 +47,8 @@ implements OnClickListener, DatabaseListener {
 	@Inject private DatabaseComponent db;
 	@Inject @DatabaseExecutor private Executor dbExecutor;
 
-	private ContactId contactId = null;
 	private ConversationAdapter adapter = null;
+	private volatile ContactId contactId = null;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -125,7 +125,7 @@ implements OnClickListener, DatabaseListener {
 					serviceConnection.waitForStartup();
 					// Load the message headers from the database
 					Collection<PrivateMessageHeader> headers =
-							db.getPrivateMessageHeaders();
+							db.getPrivateMessageHeaders(contactId);
 					if(LOG.isLoggable(INFO))
 						LOG.info("Loaded " + headers.size() + " headers");
 					// Update the conversation
@@ -147,8 +147,7 @@ implements OnClickListener, DatabaseListener {
 		runOnUiThread(new Runnable() {
 			public void run() {
 				adapter.clear();
-				for(PrivateMessageHeader h : headers)
-					if(h.getContactId().equals(contactId)) adapter.add(h);
+				for(PrivateMessageHeader h : headers) adapter.add(h);
 				adapter.sort(AscendingHeaderComparator.INSTANCE);
 			}
 		});
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java
index 6720b08dd7..67c6c629b7 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java
@@ -56,7 +56,7 @@ implements OnItemClickListener {
 
 		TextView date = new TextView(ctx);
 		date.setTextSize(14);
-		date.setPadding(5, 0, 10, 0);
+		date.setPadding(10, 0, 10, 0);
 		long then = item.getTimestamp(), now = System.currentTimeMillis();
 		date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
 		layout.addView(date);
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
index 9188d61770..f09c7dabed 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
@@ -112,20 +112,20 @@ implements OnClickListener, DatabaseListener {
 						ContactId contactId = db.addContact("Carol");
 						// Insert some fake messages to and from the contact
 						Message m = messageFactory.createPrivateMessage(null,
-								"First message's subject is quite long to test"
-								+ " line wrapping and stuff like that",
+								"First message's subject is short",
 								"First message's body".getBytes("UTF-8"));
 						db.addLocalPrivateMessage(m, contactId);
 						db.setReadFlag(m.getId(), true);
 						db.setStarredFlag(m.getId(), true);
 						Thread.sleep(1000);
 						m = messageFactory.createPrivateMessage(m.getId(),
-								"Second message's subject is short",
+								"Second message's subject is also short",
 								"Second message's body".getBytes("UTF-8"));
 						db.receiveMessage(contactId, m);
 						Thread.sleep(1000);
 						m = messageFactory.createPrivateMessage(m.getId(),
-								"Third message's subject is also short",
+								"Third message's subject is quite long to test"
+								+ " line wrapping and exciting stuff like that",
 								"Third message's body".getBytes("UTF-8"));
 						db.addLocalPrivateMessage(m, contactId);
 						db.setReadFlag(m.getId(), true);
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java b/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java
index 50a8a574a0..234af5266e 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java
@@ -53,7 +53,6 @@ implements OnItemClickListener {
 				WRAP_CONTENT, 1));
 		innerLayout.setOrientation(VERTICAL);
 		innerLayout.setGravity(LEFT);
-		innerLayout.setPadding(0, 5, 0, 5);
 
 		TextView name = new TextView(ctx);
 		name.setTextSize(18);
@@ -69,7 +68,7 @@ implements OnItemClickListener {
 
 		TextView date = new TextView(ctx);
 		date.setTextSize(14);
-		date.setPadding(5, 0, 10, 0);
+		date.setPadding(10, 0, 10, 0);
 		long then = item.getTimestamp(), now = System.currentTimeMillis();
 		date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
 		layout.addView(date);
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 e301eea38b..b930322fb4 100644
--- a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java
+++ b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java
@@ -174,6 +174,13 @@ public interface DatabaseComponent {
 	Collection<PrivateMessageHeader> getPrivateMessageHeaders()
 			throws DbException;
 
+	/**
+	 * Returns the headers of all private messages to or from the given
+	 * contact.
+	 */
+	Collection<PrivateMessageHeader> getPrivateMessageHeaders(ContactId c)
+			throws DbException;
+
 	/** Returns the user's rating for the given author. */
 	Rating getRating(AuthorId a) throws DbException;
 
diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java
index 9faecae8e9..97df26ac6e 100644
--- a/briar-core/src/net/sf/briar/db/Database.java
+++ b/briar-core/src/net/sf/briar/db/Database.java
@@ -278,6 +278,15 @@ interface Database<T> {
 	Collection<PrivateMessageHeader> getPrivateMessageHeaders(T txn)
 			throws DbException;
 
+	/**
+	 * Returns the headers of all private messages to or from the given
+	 * contact.
+	 * <p>
+	 * Locking: message read.
+	 */
+	Collection<PrivateMessageHeader> getPrivateMessageHeaders(T txn,
+			ContactId c) throws DbException;
+
 	/**
 	 * Returns the IDs of all messages signed by the given author.
 	 * <p>
diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
index 5bace6d58e..299f52bd4e 100644
--- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
@@ -946,6 +946,25 @@ DatabaseCleaner.Callback {
 		}
 	}
 
+	public Collection<PrivateMessageHeader> getPrivateMessageHeaders(
+			ContactId c) throws DbException {
+		messageLock.readLock().lock();
+		try {
+			T txn = db.startTransaction();
+			try {
+				Collection<PrivateMessageHeader> headers =
+						db.getPrivateMessageHeaders(txn, c);
+				db.commitTransaction(txn);
+				return headers;
+			} catch(DbException e) {
+				db.abortTransaction(txn);
+				throw e;
+			}
+		} finally {
+			messageLock.readLock().unlock();
+		}
+	}
+
 	public Rating getRating(AuthorId a) throws DbException {
 		ratingLock.readLock().lock();
 		try {
diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
index e7611872fe..45ec3fd7f3 100644
--- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java
+++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
@@ -1302,6 +1302,45 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
+	public Collection<PrivateMessageHeader> getPrivateMessageHeaders(
+			Connection txn, ContactId c) throws DbException {
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		try {
+			String sql = "SELECT m.messageId, parentId, subject, timestamp,"
+					+ " read, starred, seen"
+					+ " 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";
+			ps = txn.prepareStatement(sql);
+			ps.setInt(1, c.getInt());
+			rs = ps.executeQuery();
+			List<PrivateMessageHeader> headers =
+					new ArrayList<PrivateMessageHeader>();
+			while(rs.next()) {
+				MessageId id = new MessageId(rs.getBytes(1));
+				byte[] b = rs.getBytes(2);
+				MessageId parent = b == null ? null : new MessageId(b);
+				String subject = rs.getString(3);
+				long timestamp = rs.getLong(4);
+				boolean read = rs.getBoolean(5);
+				boolean starred = rs.getBoolean(6);
+				boolean seen = rs.getBoolean(7);
+				headers.add(new PrivateMessageHeader(id, parent, subject,
+						timestamp, read, starred, c, !seen));
+			}
+			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;
-- 
GitLab