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 85f8c57163a72b7a2d585540d1f8e12d5e19b672..515f8f81a4aace821656a0a513fddf234b256328 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 2cc17ca6183429dcff632600a15889be60a34d09..1081c4399785ec8c6bce1ed59b7efc7bdf9b18dd 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 5a2f8325111ddba996420ef5768102fd4c330695..855c47fa301643a34d1e182f6d13c9e630b88d2c 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 e952cf58720412f7ecca20a7f48d6a5459d70913..132f3b8de0c1a42aaad7f4257d26643236c9027f 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 {