mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 11:49:04 +01:00
Reset message status when contact unsubscribes from group. Dev task #68.
This commit is contained in:
@@ -703,7 +703,7 @@ interface Database<T> {
|
||||
* true, unless an update with an equal or higher version number has
|
||||
* already been received from the contact.
|
||||
* <p>
|
||||
* Locking: subscription write.
|
||||
* Locking: message write, subscription write.
|
||||
*/
|
||||
boolean setGroups(T txn, ContactId c, Collection<Group> groups,
|
||||
long version) throws DbException;
|
||||
|
||||
@@ -1500,22 +1500,27 @@ DatabaseCleaner.Callback {
|
||||
boolean updated;
|
||||
contactLock.readLock().lock();
|
||||
try {
|
||||
subscriptionLock.writeLock().lock();
|
||||
messageLock.writeLock().lock();
|
||||
try {
|
||||
T txn = db.startTransaction();
|
||||
subscriptionLock.writeLock().lock();
|
||||
try {
|
||||
if(!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
Collection<Group> groups = u.getGroups();
|
||||
long version = u.getVersion();
|
||||
updated = db.setGroups(txn, c, groups, version);
|
||||
db.commitTransaction(txn);
|
||||
} catch(DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
throw e;
|
||||
T txn = db.startTransaction();
|
||||
try {
|
||||
if(!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
Collection<Group> groups = u.getGroups();
|
||||
long version = u.getVersion();
|
||||
updated = db.setGroups(txn, c, groups, version);
|
||||
db.commitTransaction(txn);
|
||||
} catch(DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
subscriptionLock.writeLock().unlock();
|
||||
}
|
||||
} finally {
|
||||
subscriptionLock.writeLock().unlock();
|
||||
messageLock.writeLock().unlock();
|
||||
}
|
||||
} finally {
|
||||
contactLock.readLock().unlock();
|
||||
|
||||
@@ -21,10 +21,12 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -2896,8 +2898,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE statuses"
|
||||
+ " SET expiry = 0, txCount = 0"
|
||||
String sql = "UPDATE statuses SET expiry = 0, txCount = 0"
|
||||
+ " WHERE messageId = ? AND contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, m.getBytes());
|
||||
@@ -2949,6 +2950,43 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.close();
|
||||
// Return false if the update is obsolete
|
||||
if(affected == 0) return false;
|
||||
// Find any messages in groups that are being removed
|
||||
Set<GroupId> newIds = new HashSet<GroupId>();
|
||||
for(Group g : groups) newIds.add(g.getId());
|
||||
sql = "SELECT messageId, m.groupId"
|
||||
+ " FROM messages AS m"
|
||||
+ " JOIN contactGroups AS cg"
|
||||
+ " ON m.groupId = cg.groupId"
|
||||
+ " WHERE contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> removed = new ArrayList<MessageId>();
|
||||
while(rs.next()) {
|
||||
if(!newIds.contains(new GroupId(rs.getBytes(2))))
|
||||
removed.add(new MessageId(rs.getBytes(1)));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
// Reset any statuses for messages in groups that are being removed
|
||||
if(!removed.isEmpty()) {
|
||||
sql = "UPDATE statuses SET ack = FALSE, seen = FALSE,"
|
||||
+ " requested = FALSE, expiry = 0, txCount = 0"
|
||||
+ " WHERE contactId = ? AND messageId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
for(MessageId m : removed) {
|
||||
ps.setBytes(2, m.getBytes());
|
||||
ps.addBatch();
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != removed.size())
|
||||
throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] < 0) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
}
|
||||
// Delete the existing subscriptions, if any
|
||||
sql = "DELETE FROM contactGroups WHERE contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
|
||||
Reference in New Issue
Block a user