Moved subscription updates to the client layer.

This commit is contained in:
akwizgran
2016-02-01 15:13:36 +00:00
parent 54272c8836
commit 18db17bf5b
30 changed files with 1286 additions and 646 deletions

View File

@@ -598,13 +598,6 @@ interface Database<T> {
void setReorderingWindow(T txn, ContactId c, TransportId t,
long rotationPeriod, long base, byte[] bitmap) throws DbException;
/**
* Makes a group visible or invisible to future contacts by default.
* <p>
* Locking: write.
*/
void setVisibleToAll(T txn, GroupId g, boolean all) throws DbException;
/**
* Updates the transmission count and expiry time of the given message
* with respect to the given contact, using the latency of the transport

View File

@@ -223,6 +223,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (added) {
eventBus.broadcast(new MessageAddedEvent(m, null));
eventBus.broadcast(new MessageValidatedEvent(m, c, true, true));
if (shared) eventBus.broadcast(new MessageSharedEvent(m));
}
}
@@ -801,6 +802,28 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
}
}
public boolean isVisibleToContact(ContactId c, GroupId g)
throws DbException {
lock.readLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
if (!db.containsGroup(txn, g))
throw new NoSuchGroupException();
boolean visible = db.containsVisibleGroup(txn, c, g);
db.commitTransaction(txn);
return visible;
} catch (DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
lock.readLock().unlock();
}
}
public void mergeGroupMetadata(GroupId g, Metadata meta)
throws DbException {
lock.writeLock().lock();
@@ -900,7 +923,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
duplicate = db.containsMessage(txn, m.getId());
visible = db.containsVisibleGroup(txn, c, m.getGroupId());
if (visible) {
if (!duplicate) addMessage(txn, m, UNKNOWN, true, c);
if (!duplicate) addMessage(txn, m, UNKNOWN, false, c);
db.raiseAckFlag(txn, c, m.getId());
}
db.commitTransaction(txn);
@@ -1162,7 +1185,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (!db.containsGroup(txn, g))
throw new NoSuchGroupException();
// Use HashSets for O(1) lookups, O(n) overall running time
HashSet<ContactId> now = new HashSet<ContactId>(visible);
Collection<ContactId> now = new HashSet<ContactId>(visible);
Collection<ContactId> before = db.getVisibility(txn, g);
before = new HashSet<ContactId>(before);
// Set the group's visibility for each current contact
@@ -1177,8 +1200,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
affected.add(c);
}
}
// Make the group invisible to future contacts
db.setVisibleToAll(txn, g, false);
db.commitTransaction(txn);
} catch (DbException e) {
db.abortTransaction(txn);
@@ -1191,27 +1212,20 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void setVisibleToAll(GroupId g, boolean all) throws DbException {
Collection<ContactId> affected = new ArrayList<ContactId>();
public void setVisibleToContact(ContactId c, GroupId g, boolean visible)
throws DbException {
boolean wasVisible = false;
lock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
if (!db.containsGroup(txn, g))
throw new NoSuchGroupException();
// Make the group visible or invisible to future contacts
db.setVisibleToAll(txn, g, all);
if (all) {
// Make the group visible to all current contacts
Collection<ContactId> before = db.getVisibility(txn, g);
before = new HashSet<ContactId>(before);
for (ContactId c : db.getContactIds(txn)) {
if (!before.contains(c)) {
db.addVisibility(txn, c, g);
affected.add(c);
}
}
}
wasVisible = db.containsVisibleGroup(txn, c, g);
if (visible && !wasVisible) db.addVisibility(txn, c, g);
else if (!visible && wasVisible) db.removeVisibility(txn, c, g);
db.commitTransaction(txn);
} catch (DbException e) {
db.abortTransaction(txn);
@@ -1220,8 +1234,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
if (!affected.isEmpty())
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
if (visible != wasVisible) {
eventBus.broadcast(new GroupVisibilityUpdatedEvent(
Collections.singletonList(c)));
}
}
public void updateTransportKeys(Map<ContactId, TransportKeys> keys)

View File

@@ -66,8 +66,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
*/
abstract class JdbcDatabase implements Database<Connection> {
private static final int SCHEMA_VERSION = 19;
private static final int MIN_SCHEMA_VERSION = 19;
private static final int SCHEMA_VERSION = 20;
private static final int MIN_SCHEMA_VERSION = 20;
private static final String CREATE_SETTINGS =
"CREATE TABLE settings"
@@ -104,7 +104,6 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " (groupId HASH NOT NULL,"
+ " clientId HASH NOT NULL,"
+ " descriptor BINARY NOT NULL,"
+ " visibleToAll BOOLEAN NOT NULL,"
+ " PRIMARY KEY (groupId))";
private static final String CREATE_GROUP_METADATA =
@@ -511,30 +510,6 @@ abstract class JdbcDatabase implements Database<Connection> {
if (rows != 1) throw new DbStateException();
ps.close();
}
// Make groups that are visible to everyone visible to this contact
sql = "SELECT groupId FROM groups WHERE visibleToAll = TRUE";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
ids = new ArrayList<byte[]>();
while (rs.next()) ids.add(rs.getBytes(1));
rs.close();
ps.close();
if (!ids.isEmpty()) {
sql = "INSERT INTO groupVisibilities (contactId, groupId)"
+ " VALUES (?, ?)";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
for (byte[] id : ids) {
ps.setBytes(2, id);
ps.addBatch();
}
int[] batchAffected = ps.executeBatch();
if (batchAffected.length != ids.size())
throw new DbStateException();
for (int rows : batchAffected)
if (rows != 1) throw new DbStateException();
ps.close();
}
return c;
} catch (SQLException e) {
tryToClose(rs);
@@ -546,9 +521,8 @@ abstract class JdbcDatabase implements Database<Connection> {
public void addGroup(Connection txn, Group g) throws DbException {
PreparedStatement ps = null;
try {
String sql = "INSERT INTO groups"
+ " (groupId, clientId, descriptor, visibleToAll)"
+ " VALUES (?, ?, ?, FALSE)";
String sql = "INSERT INTO groups (groupId, clientId, descriptor)"
+ " VALUES (?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getId().getBytes());
ps.setBytes(2, g.getClientId().getBytes());
@@ -2137,23 +2111,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setVisibleToAll(Connection txn, GroupId g, boolean all)
throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE groups SET visibleToAll = ? WHERE groupId = ?";
ps = txn.prepareStatement(sql);
ps.setBoolean(1, all);
ps.setBytes(2, g.getBytes());
int affected = ps.executeUpdate();
if (affected < 0 || affected > 1) throw new DbStateException();
ps.close();
} catch (SQLException e) {
tryToClose(ps);
throw new DbException(e);
}
}
public void updateExpiryTime(Connection txn, ContactId c, MessageId m,
int maxLatency) throws DbException {
PreparedStatement ps = null;