Reset using a single db query

This commit is contained in:
Daniel Lublin
2021-12-09 12:52:43 +01:00
parent 3eb3dbde09
commit 93a03d7e15
5 changed files with 15 additions and 23 deletions

View File

@@ -473,8 +473,8 @@ public interface DatabaseComponent extends TransactionManager {
/** /**
* Reset the transmission count, expiry time and ETA of all messages that * Reset the transmission count, expiry time and ETA of all messages that
* are eligible to be sent to the given contact. Messages are selected in * are eligible to be sent to the given contact. This includes messages that
* the same way as {@link #getUnackedMessagesToSend(Transaction, ContactId)} * have already been sent and are not yet due for retransmission.
*/ */
void resetUnackedMessagesToSend(Transaction txn, ContactId c) void resetUnackedMessagesToSend(Transaction txn, ContactId c)
throws DbException; throws DbException;

View File

@@ -758,11 +758,11 @@ interface Database<T> {
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException; void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
/** /**
* Resets the transmission count, expiry time and ETA of the given messages * Resets the transmission count, expiry time and ETA of all messages that
* with respect to the given contact. * are eligible to be sent to the given contact. This includes messages that
* have already been sent and are not yet due for retransmission.
*/ */
void resetExpiryTimeAndEta(T txn, ContactId c, Collection<MessageId> ids) void resetUnackedMessagesToSend(T txn, ContactId c) throws DbException;
throws DbException;
/** /**
* Sets the cleanup timer duration for the given message. This does not * Sets the cleanup timer duration for the given message. This does not

View File

@@ -756,10 +756,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsContact(txn, c)) if (!db.containsContact(txn, c))
throw new NoSuchContactException(); throw new NoSuchContactException();
Collection<MessageId> unackedToSend = db.resetUnackedMessagesToSend(txn, c);
new ArrayList<>(db.getUnackedMessagesToSend(txn, c).keySet());
if (unackedToSend.isEmpty()) return;
db.resetExpiryTimeAndEta(txn, c, unackedToSend);
} }
@Override @Override

View File

@@ -3291,26 +3291,21 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
@Override @Override
public void resetExpiryTimeAndEta(Connection txn, ContactId c, public void resetUnackedMessagesToSend(Connection txn, ContactId c)
Collection<MessageId> ids)
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
String sql = "UPDATE statuses SET expiry = 0, txCount = 0, eta = 0" String sql = "UPDATE statuses SET expiry = 0, txCount = 0, eta = 0"
+ " WHERE contactId = ? AND messageId = ?"; + " WHERE contactId = ? AND state = ?"
+ " AND groupShared = TRUE AND messageShared = TRUE"
+ " AND deleted = FALSE AND seen = FALSE";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt()); ps.setInt(1, c.getInt());
for (MessageId m : ids) { ps.setInt(2, DELIVERED.getValue());
ps.setBytes(2, m.getBytes()); int affected = ps.executeUpdate();
ps.addBatch(); if (affected < 0) {
}
int[] batchAffected = ps.executeBatch();
if (batchAffected.length != ids.size()) {
throw new DbStateException(); throw new DbStateException();
} }
for (int rows : batchAffected) {
if (rows < 0 || rows > 1) throw new DbStateException();
}
ps.close(); ps.close();
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(ps, LOG, WARNING); tryToClose(ps, LOG, WARNING);

View File

@@ -2233,7 +2233,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertTrue(ids.isEmpty()); assertTrue(ids.isEmpty());
// Reset the retransmission times // Reset the retransmission times
db.resetExpiryTimeAndEta(txn, contactId, singletonList(messageId)); db.resetUnackedMessagesToSend(txn, contactId);
// The message should have infinitely short expiry // The message should have infinitely short expiry
assertEquals(0, db.getNextSendTime(txn, contactId)); assertEquals(0, db.getNextSendTime(txn, contactId));