mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 21:29:54 +01:00
Incremental subscription updates (untested).
This commit is contained in:
@@ -125,6 +125,15 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
void addSubscription(T txn, Group g) throws DbException;
|
void addSubscription(T txn, Group g) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the given contact's subscription to the given group starting at
|
||||||
|
* the given time.
|
||||||
|
* <p>
|
||||||
|
* Locking: contact read, subscription write.
|
||||||
|
*/
|
||||||
|
void addSubscription(T txn, ContactId c, Group g, long start)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates and returns a local index for the given transport. Returns
|
* Allocates and returns a local index for the given transport. Returns
|
||||||
* null if all indices have been allocated.
|
* null if all indices have been allocated.
|
||||||
@@ -526,6 +535,16 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
void removeSubscription(T txn, GroupId g) throws DbException;
|
void removeSubscription(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes any subscriptions for the given contact with IDs between the
|
||||||
|
* given IDs. If both of the given IDs are null, all subscriptions are
|
||||||
|
* removed. If only the first is null, all subscriptions with IDs less than
|
||||||
|
* the second ID are removed. If onlt the second is null, all subscriptions
|
||||||
|
* with IDs greater than the first are removed.
|
||||||
|
*/
|
||||||
|
void removeSubscriptions(T txn, ContactId c, GroupId start, GroupId end)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the given group invisible to the given contact.
|
* Makes the given group invisible to the given contact.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -551,6 +570,13 @@ interface Database<T> {
|
|||||||
void setConnectionWindow(T txn, ContactId c, TransportIndex i,
|
void setConnectionWindow(T txn, ContactId c, TransportIndex i,
|
||||||
ConnectionWindow w) throws DbException;
|
ConnectionWindow w) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given contact's database expiry time.
|
||||||
|
* <p>
|
||||||
|
* Locking: contact read, subscription write.
|
||||||
|
*/
|
||||||
|
void setExpiryTime(T txn, ContactId c, long expiry) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the local transport properties for the given transport, replacing
|
* Sets the local transport properties for the given transport, replacing
|
||||||
* any existing properties for that transport.
|
* any existing properties for that transport.
|
||||||
@@ -611,23 +637,23 @@ interface Database<T> {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the subscriptions for the given contact, replacing any existing
|
* Records the time of the latest subscription update acknowledged by the
|
||||||
* subscriptions unless the existing subscriptions have a newer timestamp.
|
* given contact.
|
||||||
* <p>
|
|
||||||
* Locking: contact read, subscription write.
|
|
||||||
*/
|
|
||||||
void setSubscriptions(T txn, ContactId c, Map<Group, Long> subs,
|
|
||||||
long timestamp) throws DbException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Records the time of the latest subscription modification acknowledged by
|
|
||||||
* the given contact.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Locking: contact read, subscription write.
|
* Locking: contact read, subscription write.
|
||||||
*/
|
*/
|
||||||
void setSubscriptionsAcked(T txn, ContactId c, long timestamp)
|
void setSubscriptionsAcked(T txn, ContactId c, long timestamp)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the time of the latest subscription update received from the
|
||||||
|
* given contact.
|
||||||
|
* <p>
|
||||||
|
* Locking: contact read, subscription write.
|
||||||
|
*/
|
||||||
|
void setSubscriptionsReceived(T txn, ContactId c, long timestamp)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the transports for the given contact, replacing any existing
|
* Sets the transports for the given contact, replacing any existing
|
||||||
* transports unless the existing transports have a newer timestamp.
|
* transports unless the existing transports have a newer timestamp.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -1175,8 +1176,17 @@ DatabaseCleaner.Callback {
|
|||||||
try {
|
try {
|
||||||
T txn = db.startTransaction();
|
T txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
|
Map<GroupId, GroupId> holes = s.getHoles();
|
||||||
|
for(Entry<GroupId, GroupId> e : holes.entrySet()) {
|
||||||
|
GroupId start = e.getKey(), end = e.getValue();
|
||||||
|
db.removeSubscriptions(txn, c, start, end);
|
||||||
|
}
|
||||||
Map<Group, Long> subs = s.getSubscriptions();
|
Map<Group, Long> subs = s.getSubscriptions();
|
||||||
db.setSubscriptions(txn, c, subs, s.getTimestamp());
|
for(Entry<Group, Long> e : subs.entrySet()) {
|
||||||
|
db.addSubscription(txn, c, e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
db.setExpiryTime(txn, c, s.getExpiryTime());
|
||||||
|
db.setSubscriptionsReceived(txn, c, s.getTimestamp());
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
} catch(DbException e) {
|
} catch(DbException e) {
|
||||||
db.abortTransaction(txn);
|
db.abortTransaction(txn);
|
||||||
|
|||||||
@@ -735,10 +735,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
public void addSubscription(Connection txn, Group g) throws DbException {
|
public void addSubscription(Connection txn, Group g) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
// Add the group to the subscriptions table
|
|
||||||
String sql = "INSERT INTO subscriptions"
|
String sql = "INSERT INTO subscriptions"
|
||||||
+ " (groupId, groupName, groupKey, start)"
|
+ " (groupId, groupName, groupKey, start) VALUES (?, ?, ?, ?)";
|
||||||
+ " VALUES (?, ?, ?, ?)";
|
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, g.getId().getBytes());
|
ps.setBytes(1, g.getId().getBytes());
|
||||||
ps.setString(2, g.getName());
|
ps.setString(2, g.getName());
|
||||||
@@ -754,6 +752,43 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSubscription(Connection txn, ContactId c, Group g,
|
||||||
|
long start) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
// Check whether the subscription already exists
|
||||||
|
String sql = "SELECT NULL FROM contactSubscriptions"
|
||||||
|
+ " WHERE contactId = ? AND groupId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setBytes(2, g.getId().getBytes());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
boolean found = rs.next();
|
||||||
|
if(rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
if(found) return;
|
||||||
|
// Add the subscription
|
||||||
|
sql = "INSERT INTO contactSubscriptions"
|
||||||
|
+ " (contactId, groupId, groupName, groupKey, start)"
|
||||||
|
+ " VALUES (?, ?, ?, ?, ?)";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setBytes(2, g.getId().getBytes());
|
||||||
|
ps.setString(3, g.getName());
|
||||||
|
ps.setBytes(4, g.getPublicKey());
|
||||||
|
ps.setLong(5, start);
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if(affected != 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TransportIndex addTransport(Connection txn, TransportId t)
|
public TransportIndex addTransport(Connection txn, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2234,6 +2269,49 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeSubscriptions(Connection txn, ContactId c, GroupId start,
|
||||||
|
GroupId end) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
if(start == null && end == null) {
|
||||||
|
// Delete everything
|
||||||
|
String sql = "DELETE FROM contactSubscriptions"
|
||||||
|
+ " WHERE contactId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
} else if(start == null) {
|
||||||
|
// Delete everything before end
|
||||||
|
String sql = "DELETE FROM contactSubscriptions"
|
||||||
|
+ " WHERE contactId = ? AND groupId < ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setBytes(2, end.getBytes());
|
||||||
|
} else if(end == null) {
|
||||||
|
// Delete everything after start
|
||||||
|
String sql = "DELETE FROM contactSubscriptions"
|
||||||
|
+ " WHERE contactId = ? AND groupId > ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setBytes(2, start.getBytes());
|
||||||
|
} else {
|
||||||
|
// Delete everything between start and end
|
||||||
|
String sql = "DELETE FROM contactSubscriptions"
|
||||||
|
+ " WHERE contactId = ?"
|
||||||
|
+ " AND groupId > ? AND groupId < ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
ps.setBytes(2, start.getBytes());
|
||||||
|
ps.setBytes(3, end.getBytes());
|
||||||
|
}
|
||||||
|
ps.executeUpdate();
|
||||||
|
ps.close();
|
||||||
|
} catch(SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void removeVisibility(Connection txn, ContactId c, GroupId g)
|
public void removeVisibility(Connection txn, ContactId c, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2348,6 +2426,24 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setExpiryTime(Connection txn, ContactId c, long expiry)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE subscriptionTimes SET expiry = ?"
|
||||||
|
+ " WHERE contactId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setLong(1, expiry);
|
||||||
|
ps.setInt(2, c.getInt());
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if(affected > 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setLocalProperties(Connection txn, TransportId t,
|
public void setLocalProperties(Connection txn, TransportId t,
|
||||||
TransportProperties p) throws DbException {
|
TransportProperties p) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2641,66 +2737,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubscriptions(Connection txn, ContactId c,
|
|
||||||
Map<Group, Long> subs, long timestamp) throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
// Return if the timestamp isn't fresh
|
|
||||||
String sql = "SELECT received FROM subscriptionTimes"
|
|
||||||
+ " WHERE contactId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, c.getInt());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
if(!rs.next()) throw new DbStateException();
|
|
||||||
long lastTimestamp = rs.getLong(1);
|
|
||||||
if(rs.next()) throw new DbStateException();
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
if(lastTimestamp >= timestamp) return;
|
|
||||||
// Delete any existing subscriptions
|
|
||||||
sql = "DELETE FROM contactSubscriptions WHERE contactId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, c.getInt());
|
|
||||||
ps.executeUpdate();
|
|
||||||
ps.close();
|
|
||||||
// Store the new subscriptions
|
|
||||||
sql = "INSERT INTO contactSubscriptions"
|
|
||||||
+ " (contactId, groupId, groupName, groupKey, start)"
|
|
||||||
+ " VALUES (?, ?, ?, ?, ?)";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, c.getInt());
|
|
||||||
for(Entry<Group, Long> e : subs.entrySet()) {
|
|
||||||
Group g = e.getKey();
|
|
||||||
ps.setBytes(2, g.getId().getBytes());
|
|
||||||
ps.setString(3, g.getName());
|
|
||||||
ps.setBytes(4, g.getPublicKey());
|
|
||||||
ps.setLong(5, e.getValue());
|
|
||||||
ps.addBatch();
|
|
||||||
}
|
|
||||||
int[] batchAffected = ps.executeBatch();
|
|
||||||
if(batchAffected.length != subs.size())
|
|
||||||
throw new DbStateException();
|
|
||||||
for(int i = 0; i < batchAffected.length; i++) {
|
|
||||||
if(batchAffected[i] != 1) throw new DbStateException();
|
|
||||||
}
|
|
||||||
ps.close();
|
|
||||||
// Update the timestamp
|
|
||||||
sql = "UPDATE subscriptionTimes SET received = ?"
|
|
||||||
+ " WHERE contactId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setLong(1, timestamp);
|
|
||||||
ps.setInt(2, c.getInt());
|
|
||||||
int affected = ps.executeUpdate();
|
|
||||||
if(affected != 1) throw new DbStateException();
|
|
||||||
ps.close();
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubscriptionsAcked(Connection txn, ContactId c,
|
public void setSubscriptionsAcked(Connection txn, ContactId c,
|
||||||
long timestamp) throws DbException {
|
long timestamp) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2710,7 +2746,24 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setLong(1, timestamp);
|
ps.setLong(1, timestamp);
|
||||||
ps.setInt(2, c.getInt());
|
ps.setInt(2, c.getInt());
|
||||||
ps.setLong(3, timestamp);
|
int affected = ps.executeUpdate();
|
||||||
|
if(affected > 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubscriptionsReceived(Connection txn, ContactId c,
|
||||||
|
long timestamp) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE subscriptionTimes SET received = ?"
|
||||||
|
+ " WHERE contactId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setLong(1, timestamp);
|
||||||
|
ps.setInt(2, c.getInt());
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if(affected > 1) throw new DbStateException();
|
if(affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
|
|||||||
@@ -1231,7 +1231,9 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReceiveSubscriptionUpdate() throws Exception {
|
public void testReceiveSubscriptionUpdate() throws Exception {
|
||||||
final long timestamp = 1234L;
|
final GroupId start = new GroupId(TestUtils.getRandomId());
|
||||||
|
final GroupId end = new GroupId(TestUtils.getRandomId());
|
||||||
|
final long expiry = 1234L, timestamp = 5678L;
|
||||||
Mockery context = new Mockery();
|
Mockery context = new Mockery();
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Database<Object> database = context.mock(Database.class);
|
final Database<Object> database = context.mock(Database.class);
|
||||||
@@ -1247,12 +1249,19 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
|
|||||||
allowing(database).containsContact(txn, contactId);
|
allowing(database).containsContact(txn, contactId);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
// Get the contents of the update
|
// Get the contents of the update
|
||||||
|
oneOf(subscriptionUpdate).getHoles();
|
||||||
|
will(returnValue(Collections.singletonMap(start, end)));
|
||||||
oneOf(subscriptionUpdate).getSubscriptions();
|
oneOf(subscriptionUpdate).getSubscriptions();
|
||||||
will(returnValue(Collections.singletonMap(group, 0L)));
|
will(returnValue(Collections.singletonMap(group, 0L)));
|
||||||
|
oneOf(subscriptionUpdate).getExpiryTime();
|
||||||
|
will(returnValue(expiry));
|
||||||
oneOf(subscriptionUpdate).getTimestamp();
|
oneOf(subscriptionUpdate).getTimestamp();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(database).setSubscriptions(txn, contactId,
|
// Store the contents of the update
|
||||||
Collections.singletonMap(group, 0L), timestamp);
|
oneOf(database).removeSubscriptions(txn, contactId, start, end);
|
||||||
|
oneOf(database).addSubscription(txn, contactId, group, 0L);
|
||||||
|
oneOf(database).setExpiryTime(txn, contactId, expiry);
|
||||||
|
oneOf(database).setSubscriptionsReceived(txn, contactId, timestamp);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner,
|
DatabaseComponent db = createDatabaseComponent(database, cleaner,
|
||||||
shutdown, packetFactory);
|
shutdown, packetFactory);
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
private final TransportProperties properties;
|
private final TransportProperties properties;
|
||||||
private final Map<ContactId, TransportProperties> remoteProperties;
|
private final Map<ContactId, TransportProperties> remoteProperties;
|
||||||
private final Collection<Transport> remoteTransports;
|
private final Collection<Transport> remoteTransports;
|
||||||
private final Map<Group, Long> subscriptions;
|
|
||||||
private final byte[] inSecret, outSecret;
|
private final byte[] inSecret, outSecret;
|
||||||
private final Collection<byte[]> erase;
|
private final Collection<byte[]> erase;
|
||||||
|
|
||||||
@@ -128,7 +127,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
Transport remoteTransport = new Transport(transportId, remoteIndex,
|
Transport remoteTransport = new Transport(transportId, remoteIndex,
|
||||||
properties);
|
properties);
|
||||||
remoteTransports = Collections.singletonList(remoteTransport);
|
remoteTransports = Collections.singletonList(remoteTransport);
|
||||||
subscriptions = Collections.singletonMap(group, 0L);
|
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
inSecret = new byte[32];
|
inSecret = new byte[32];
|
||||||
r.nextBytes(inSecret);
|
r.nextBytes(inSecret);
|
||||||
@@ -356,7 +354,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
|
|
||||||
@@ -394,7 +392,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSendability(txn, messageId, 1);
|
db.setSendability(txn, messageId, 1);
|
||||||
|
|
||||||
@@ -447,7 +445,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertFalse(it.hasNext());
|
assertFalse(it.hasNext());
|
||||||
|
|
||||||
// The contact subscribing should make the message sendable
|
// The contact subscribing should make the message sendable
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||||
assertTrue(it.hasNext());
|
assertTrue(it.hasNext());
|
||||||
@@ -455,8 +453,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertFalse(it.hasNext());
|
assertFalse(it.hasNext());
|
||||||
|
|
||||||
// The contact unsubscribing should make the message unsendable
|
// The contact unsubscribing should make the message unsendable
|
||||||
db.setSubscriptions(txn, contactId,
|
db.removeSubscriptions(txn, contactId, null, null);
|
||||||
Collections.<Group, Long>emptyMap(), 2);
|
|
||||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||||
assertFalse(it.hasNext());
|
assertFalse(it.hasNext());
|
||||||
@@ -481,16 +478,15 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// The message is older than the contact's subscription, so it should
|
// The message is older than the contact's subscription, so it should
|
||||||
// not be sendable
|
// not be sendable
|
||||||
db.setSubscriptions(txn, contactId,
|
db.addSubscription(txn, contactId, group, timestamp + 1);
|
||||||
Collections.singletonMap(group, timestamp + 1), 1);
|
|
||||||
assertFalse(db.hasSendableMessages(txn, contactId));
|
assertFalse(db.hasSendableMessages(txn, contactId));
|
||||||
Iterator<MessageId> it =
|
Iterator<MessageId> it =
|
||||||
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||||
assertFalse(it.hasNext());
|
assertFalse(it.hasNext());
|
||||||
|
|
||||||
// Changing the contact's subscription should make the message sendable
|
// Changing the contact's subscription should make the message sendable
|
||||||
db.setSubscriptions(txn, contactId,
|
db.removeSubscriptions(txn, contactId, null, null);
|
||||||
Collections.singletonMap(group, timestamp), 2);
|
db.addSubscription(txn, contactId, group, timestamp);
|
||||||
assertTrue(db.hasSendableMessages(txn, contactId));
|
assertTrue(db.hasSendableMessages(txn, contactId));
|
||||||
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator();
|
||||||
assertTrue(it.hasNext());
|
assertTrue(it.hasNext());
|
||||||
@@ -510,7 +506,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSendability(txn, messageId, 1);
|
db.setSendability(txn, messageId, 1);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
@@ -540,7 +536,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
// Add a contact, subscribe to a group and store a message
|
// Add a contact, subscribe to a group and store a message
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSendability(txn, messageId, 1);
|
db.setSendability(txn, messageId, 1);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
@@ -675,7 +671,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSendability(txn, messageId, 1);
|
db.setSendability(txn, messageId, 1);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
@@ -714,7 +710,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSendability(txn, messageId, 1);
|
db.setSendability(txn, messageId, 1);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
@@ -1150,57 +1146,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateSubscriptions() throws Exception {
|
|
||||||
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
|
||||||
Group group1 = groupFactory.createGroup(groupId1, "Another group name",
|
|
||||||
null);
|
|
||||||
Database<Connection> db = open(false);
|
|
||||||
Connection txn = db.startTransaction();
|
|
||||||
|
|
||||||
// Add a contact with some subscriptions
|
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
|
||||||
assertEquals(Collections.singletonList(group),
|
|
||||||
db.getSubscriptions(txn, contactId));
|
|
||||||
|
|
||||||
// Update the subscriptions
|
|
||||||
Map<Group, Long> subscriptions1 = Collections.singletonMap(group1, 0L);
|
|
||||||
db.setSubscriptions(txn, contactId, subscriptions1, 2);
|
|
||||||
assertEquals(Collections.singletonList(group1),
|
|
||||||
db.getSubscriptions(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSubscriptionsNotUpdatedIfTimestampIsOld()
|
|
||||||
throws Exception {
|
|
||||||
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
|
||||||
Group group1 = groupFactory.createGroup(groupId1, "Another group name",
|
|
||||||
null);
|
|
||||||
Database<Connection> db = open(false);
|
|
||||||
Connection txn = db.startTransaction();
|
|
||||||
|
|
||||||
// Add a contact with some subscriptions
|
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 2);
|
|
||||||
assertEquals(Collections.singletonList(group),
|
|
||||||
db.getSubscriptions(txn, contactId));
|
|
||||||
|
|
||||||
// Try to update the subscriptions using a timestamp of 1
|
|
||||||
Map<Group, Long> subscriptions1 = Collections.singletonMap(group1, 0L);
|
|
||||||
db.setSubscriptions(txn, contactId, subscriptions1, 1);
|
|
||||||
|
|
||||||
// The old subscriptions should still be there
|
|
||||||
assertEquals(Collections.singletonList(group),
|
|
||||||
db.getSubscriptions(txn, contactId));
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetMessageIfSendableReturnsNullIfNotInDatabase()
|
public void testGetMessageIfSendableReturnsNullIfNotInDatabase()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -1210,7 +1155,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
// Add a contact and subscribe to a group
|
// Add a contact and subscribe to a group
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
|
|
||||||
// The message is not in the database
|
// The message is not in the database
|
||||||
assertNull(db.getMessageIfSendable(txn, contactId, messageId));
|
assertNull(db.getMessageIfSendable(txn, contactId, messageId));
|
||||||
@@ -1228,7 +1173,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
// Add a contact, subscribe to a group and store a message
|
// Add a contact, subscribe to a group and store a message
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// Set the sendability to > 0 and the status to SEEN
|
// Set the sendability to > 0 and the status to SEEN
|
||||||
@@ -1251,7 +1196,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
// Add a contact, subscribe to a group and store a message
|
// Add a contact, subscribe to a group and store a message
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// Set the sendability to 0 and the status to NEW
|
// Set the sendability to 0 and the status to NEW
|
||||||
@@ -1275,8 +1220,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
Map<Group, Long> subs = Collections.singletonMap(group, timestamp + 1);
|
db.addSubscription(txn, contactId, group, timestamp + 1);
|
||||||
db.setSubscriptions(txn, contactId, subs, 1);
|
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// Set the sendability to > 0 and the status to NEW
|
// Set the sendability to > 0 and the status to NEW
|
||||||
@@ -1299,7 +1243,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// Set the sendability to > 0 and the status to NEW
|
// Set the sendability to > 0 and the status to NEW
|
||||||
@@ -1324,7 +1268,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
|
|
||||||
// The message is not in the database
|
// The message is not in the database
|
||||||
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
|
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
|
||||||
@@ -1341,7 +1285,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact with a subscription
|
// Add a contact with a subscription
|
||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
|
|
||||||
// There's no local subscription for the group
|
// There's no local subscription for the group
|
||||||
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
|
assertFalse(db.setStatusSeenIfVisible(txn, contactId, messageId));
|
||||||
@@ -1379,7 +1323,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.setStatus(txn, contactId, messageId, Status.NEW);
|
db.setStatus(txn, contactId, messageId, Status.NEW);
|
||||||
|
|
||||||
// The subscription is not visible
|
// The subscription is not visible
|
||||||
@@ -1399,7 +1343,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// The message has already been seen by the contact
|
// The message has already been seen by the contact
|
||||||
@@ -1421,7 +1365,7 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
assertEquals(contactId, db.addContact(txn, inSecret, outSecret, erase));
|
||||||
db.addSubscription(txn, group);
|
db.addSubscription(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.setSubscriptions(txn, contactId, subscriptions, 1);
|
db.addSubscription(txn, contactId, group, 0L);
|
||||||
db.addGroupMessage(txn, message);
|
db.addGroupMessage(txn, message);
|
||||||
|
|
||||||
// The message has not been seen by the contact
|
// The message has not been seen by the contact
|
||||||
|
|||||||
Reference in New Issue
Block a user