From 282aad3ce420be1559629ed4aaf512191b81c421 Mon Sep 17 00:00:00 2001
From: bontric <benjohnwie@gmail.com>
Date: Mon, 24 Sep 2018 18:10:58 +0200
Subject: [PATCH] Add "hasMessagesOrAcksToSend" function which checks whether
 messages or acks need to be send to a given ContactId

---
 .../bramble/api/db/DatabaseComponent.java     | 10 +++++++
 .../org/briarproject/bramble/db/Database.java |  9 ++++++
 .../bramble/db/DatabaseComponentImpl.java     | 12 +++++++-
 .../briarproject/bramble/db/JdbcDatabase.java | 30 +++++++++++++++++++
 4 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
index 85f8c5716..515f8f81a 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java
@@ -437,6 +437,16 @@ public interface DatabaseComponent {
 	 */
 	long getNextSendTime(Transaction txn, ContactId c) throws DbException;
 
+
+	/**
+	 * Checks whether messages or ACKs need to be delivered
+	 * to the given contact at the current time
+	 * <p />
+	 * Read-only.
+	 */
+	boolean hasMessagesOrAcksToSend(Transaction transaction,
+			ContactId c) throws DbException;
+
 	/**
 	 * Returns all settings in the given namespace.
 	 * <p/>
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
index 2cc17ca61..1081c4399 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java
@@ -505,6 +505,14 @@ interface Database<T> {
 	 */
 	long getNextSendTime(T txn, ContactId c) throws DbException;
 
+	/**
+	 * Checks whether messages or ACKs need to be delivered
+	 * to the given contact at the current time
+	 * <p />
+	 * Read-only.
+	 */
+	boolean hasMessagesToSend(T txn, ContactId c) throws DbException;
+
 	/**
 	 * Returns the IDs of some messages that are eligible to be sent to the
 	 * given contact and have been requested by the contact, up to the given
@@ -689,4 +697,5 @@ interface Database<T> {
 	 * Updates the given transport keys following key rotation.
 	 */
 	void updateTransportKeys(T txn, KeySet ks) throws DbException;
+
 }
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
index 5a2f83251..855c47fa3 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java
@@ -304,6 +304,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		db.deleteMessageMetadata(txn, m);
 	}
 
+	@Override
+	public boolean hasMessagesOrAcksToSend(Transaction transaction,
+			ContactId c) throws DbException {
+		T txn = unbox(transaction);
+		if (!db.containsContact(txn, c))
+			throw new NoSuchContactException();
+		return db.hasMessagesToSend(txn, c);
+	}
+
 	@Nullable
 	@Override
 	public Ack generateAck(Transaction transaction, ContactId c,
@@ -425,7 +434,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 	}
 
 	@Override
-	public ContactType getContactType(Transaction transaction, ContactId contactId) throws DbException {
+	public ContactType getContactType(Transaction transaction,
+			ContactId contactId) throws DbException {
 		T txn = unbox(transaction);
 		return db.getContactType(txn, contactId);
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
index e952cf587..132f3b8de 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java
@@ -2186,6 +2186,36 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
+	public boolean hasMessagesToSend(Connection txn, ContactId c)
+			throws DbException {
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		long now = clock.currentTimeMillis();
+		try {
+			String sql = "SELECT messageId FROM statuses"
+					+ " WHERE contactId = ?"
+					+ " AND ((ack = TRUE) OR (state = ?"
+					+ " AND groupShared = TRUE AND messageShared = TRUE"
+					+ " AND deleted = FALSE AND seen = FALSE"
+					+ " AND expiry < ?))"
+					+ " LIMIT 1";
+			ps = txn.prepareStatement(sql);
+			ps.setInt(1, c.getInt());
+			ps.setInt(2, DELIVERED.getValue());
+			ps.setLong(3, now);
+			rs = ps.executeQuery();
+			List<MessageId> ids = new ArrayList<>();
+			while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
+			rs.close();
+			ps.close();
+			return ids.size() > 0;
+		} catch (SQLException e) {
+			tryToClose(rs);
+			tryToClose(ps);
+			throw new DbException(e);
+		}
+	}
+
 	@Override
 	public Collection<MessageId> getRequestedMessagesToSend(Connection txn,
 			ContactId c, int maxLength) throws DbException {
-- 
GitLab