mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Nudge the database API in the direction of sanity.
This commit is contained in:
@@ -8,7 +8,7 @@ import net.sf.briar.api.serial.Writer;
|
|||||||
/**
|
/**
|
||||||
* Type-safe wrapper for an integer that uniquely identifies a transport plugin.
|
* Type-safe wrapper for an integer that uniquely identifies a transport plugin.
|
||||||
*/
|
*/
|
||||||
public class TransportId implements Writable, Comparable<TransportId> {
|
public class TransportId implements Writable {
|
||||||
|
|
||||||
public static final int MIN_ID = 0;
|
public static final int MIN_ID = 0;
|
||||||
public static final int MAX_ID = 65535;
|
public static final int MAX_ID = 65535;
|
||||||
@@ -38,10 +38,4 @@ public class TransportId implements Writable, Comparable<TransportId> {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(TransportId t) {
|
|
||||||
if(id < t.id) return -1;
|
|
||||||
if(id > t.id) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ public interface DatabaseComponent {
|
|||||||
void generateTransportUpdate(ContactId c, TransportWriter t) throws
|
void generateTransportUpdate(ContactId c, TransportWriter t) throws
|
||||||
DbException, IOException;
|
DbException, IOException;
|
||||||
|
|
||||||
|
/** Returns the configuration for the given transport. */
|
||||||
|
TransportConfig getConfig(TransportId t) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an outgoing connection number for the given contact and
|
* Returns an outgoing connection number for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
@@ -124,8 +127,8 @@ public interface DatabaseComponent {
|
|||||||
/** Returns the user's rating for the given author. */
|
/** Returns the user's rating for the given author. */
|
||||||
Rating getRating(AuthorId a) throws DbException;
|
Rating getRating(AuthorId a) throws DbException;
|
||||||
|
|
||||||
/** Returns all remote transport properties. */
|
/** Returns all remote transport properties for the given transport. */
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>> getRemoteTransports()
|
Map<ContactId, TransportProperties> getRemoteProperties(TransportId t)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/** Returns the secret shared with the given contact. */
|
/** Returns the secret shared with the given contact. */
|
||||||
@@ -134,9 +137,6 @@ public interface DatabaseComponent {
|
|||||||
/** Returns the set of groups to which the user subscribes. */
|
/** Returns the set of groups to which the user subscribes. */
|
||||||
Collection<Group> getSubscriptions() throws DbException;
|
Collection<Group> getSubscriptions() throws DbException;
|
||||||
|
|
||||||
/** Returns the configuration for the given transport. */
|
|
||||||
TransportConfig getTransportConfig(TransportId t) throws DbException;
|
|
||||||
|
|
||||||
/** Returns the contacts to which the given group is visible. */
|
/** Returns the contacts to which the given group is visible. */
|
||||||
Collection<ContactId> getVisibility(GroupId g) throws DbException;
|
Collection<ContactId> getVisibility(GroupId g) throws DbException;
|
||||||
|
|
||||||
@@ -171,6 +171,12 @@ public interface DatabaseComponent {
|
|||||||
/** Removes a contact (and all associated state) from the database. */
|
/** Removes a contact (and all associated state) from the database. */
|
||||||
void removeContact(ContactId c) throws DbException;
|
void removeContact(ContactId c) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the configuration for the given transport, replacing any existing
|
||||||
|
* configuration for that transport.
|
||||||
|
*/
|
||||||
|
void setConfig(TransportId t, TransportConfig c) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the connection reordering window for the given contact and
|
* Sets the connection reordering window for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
@@ -178,26 +184,19 @@ public interface DatabaseComponent {
|
|||||||
void setConnectionWindow(ContactId c, TransportId t, ConnectionWindow w)
|
void setConnectionWindow(ContactId c, TransportId t, ConnectionWindow w)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the local transport properties for the given transport, replacing
|
||||||
|
* any existing properties for that transport.
|
||||||
|
*/
|
||||||
|
void setLocalProperties(TransportId t, TransportProperties p)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/** Records the user's rating for the given author. */
|
/** Records the user's rating for the given author. */
|
||||||
void setRating(AuthorId a, Rating r) throws DbException;
|
void setRating(AuthorId a, Rating r) throws DbException;
|
||||||
|
|
||||||
/** Records the given messages as having been seen by the given contact. */
|
/** Records the given messages as having been seen by the given contact. */
|
||||||
void setSeen(ContactId c, Collection<MessageId> seen) throws DbException;
|
void setSeen(ContactId c, Collection<MessageId> seen) throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the configuration for the given transport, replacing any existing
|
|
||||||
* configuration for that transport.
|
|
||||||
*/
|
|
||||||
void setTransportConfig(TransportId t, TransportConfig config)
|
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the transport properties for the given transport, replacing any
|
|
||||||
* existing properties for that transport.
|
|
||||||
*/
|
|
||||||
void setTransportProperties(TransportId t, TransportProperties properties)
|
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the given group visible to the given set of contacts and invisible
|
* Makes the given group visible to the given set of contacts and invisible
|
||||||
* to any other contacts.
|
* to any other contacts.
|
||||||
|
|||||||
@@ -170,6 +170,13 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<BatchId> getBatchesToAck(T txn, ContactId c) throws DbException;
|
Collection<BatchId> getBatchesToAck(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configuration for the given transport.
|
||||||
|
* <p>
|
||||||
|
* Locking: transports read.
|
||||||
|
*/
|
||||||
|
TransportConfig getConfig(T txn, TransportId t) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates and returns a connection number for the given contact and
|
* Allocates and returns a connection number for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
@@ -280,12 +287,12 @@ interface Database<T> {
|
|||||||
Rating getRating(T txn, AuthorId a) throws DbException;
|
Rating getRating(T txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all remote transport properties.
|
* Returns all remote properties for the given transport.
|
||||||
* <p>
|
* <p>
|
||||||
* Locking: contacts read, transports read.
|
* Locking: contacts read, transports read.
|
||||||
*/
|
*/
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>>
|
Map<ContactId, TransportProperties> getRemoteProperties(T txn,
|
||||||
getRemoteTransports(T txn) throws DbException;
|
TransportId t) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sendability score of the given group message.
|
* Returns the sendability score of the given group message.
|
||||||
@@ -335,13 +342,6 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
|
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configuration for the given transport.
|
|
||||||
* <p>
|
|
||||||
* Locking: transports read.
|
|
||||||
*/
|
|
||||||
TransportConfig getTransportConfig(T txn, TransportId t) throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the contacts to which the given group is visible.
|
* Returns the contacts to which the given group is visible.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -414,6 +414,15 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
void removeSubscription(T txn, GroupId g) throws DbException;
|
void removeSubscription(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the configuration for the given transport, replacing any existing
|
||||||
|
* configuration for that transport.
|
||||||
|
* <p>
|
||||||
|
* Locking: transports write.
|
||||||
|
*/
|
||||||
|
void setConfig(T txn, TransportId t, TransportConfig config)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the connection reordering window for the given contact and
|
* Sets the connection reordering window for the given contact and
|
||||||
* transport.
|
* transport.
|
||||||
@@ -423,6 +432,15 @@ interface Database<T> {
|
|||||||
void setConnectionWindow(T txn, ContactId c, TransportId t,
|
void setConnectionWindow(T txn, ContactId c, TransportId t,
|
||||||
ConnectionWindow w) throws DbException;
|
ConnectionWindow w) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the local transport properties for the given transport, replacing
|
||||||
|
* any existing properties for that transport.
|
||||||
|
* <p>
|
||||||
|
* Locking: transports write.
|
||||||
|
*/
|
||||||
|
void setLocalProperties(T txn, TransportId t, TransportProperties p)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the user's rating for the given author.
|
* Sets the user's rating for the given author.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -475,24 +493,6 @@ interface Database<T> {
|
|||||||
void setSubscriptionTimestamp(T txn, ContactId c, long timestamp)
|
void setSubscriptionTimestamp(T txn, ContactId c, long timestamp)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the configuration for the given transport, replacing any existing
|
|
||||||
* configuration for that transport.
|
|
||||||
* <p>
|
|
||||||
* Locking: transports write.
|
|
||||||
*/
|
|
||||||
void setTransportConfig(T txn, TransportId t, TransportConfig config)
|
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the transport properties for the given transport, replacing any
|
|
||||||
* existing properties for that transport.
|
|
||||||
* <p>
|
|
||||||
* Locking: transports write.
|
|
||||||
*/
|
|
||||||
void setTransportProperties(T txn, TransportId t,
|
|
||||||
TransportProperties properties) throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the transport properties for the given contact, replacing any
|
* Sets the transport properties for the given contact, replacing any
|
||||||
* existing properties unless the existing properties have a newer
|
* existing properties unless the existing properties have a newer
|
||||||
|
|||||||
@@ -636,6 +636,23 @@ DatabaseCleaner.Callback {
|
|||||||
LOG.fine("Added " + transports.size() + " transports to update");
|
LOG.fine("Added " + transports.size() + " transports to update");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransportConfig getConfig(TransportId t) throws DbException {
|
||||||
|
transportLock.readLock().lock();
|
||||||
|
try {
|
||||||
|
T txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
TransportConfig config = db.getConfig(txn, t);
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
return config;
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transportLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long getConnectionNumber(ContactId c, TransportId t)
|
public long getConnectionNumber(ContactId c, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
@@ -737,18 +754,18 @@ DatabaseCleaner.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<TransportId, Map<ContactId, TransportProperties>>
|
public Map<ContactId, TransportProperties> getRemoteProperties(
|
||||||
getRemoteTransports() throws DbException {
|
TransportId t) throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
transportLock.readLock().lock();
|
transportLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
T txn = db.startTransaction();
|
T txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>>
|
Map<ContactId, TransportProperties> properties =
|
||||||
transports = db.getRemoteTransports(txn);
|
db.getRemoteProperties(txn, t);
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
return transports;
|
return properties;
|
||||||
} catch(DbException e) {
|
} catch(DbException e) {
|
||||||
db.abortTransaction(txn);
|
db.abortTransaction(txn);
|
||||||
throw e;
|
throw e;
|
||||||
@@ -796,24 +813,6 @@ DatabaseCleaner.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportConfig getTransportConfig(TransportId t)
|
|
||||||
throws DbException {
|
|
||||||
transportLock.readLock().lock();
|
|
||||||
try {
|
|
||||||
T txn = db.startTransaction();
|
|
||||||
try {
|
|
||||||
TransportConfig config = db.getTransportConfig(txn, t);
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
return config;
|
|
||||||
} catch(DbException e) {
|
|
||||||
db.abortTransaction(txn);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
transportLock.readLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ContactId> getVisibility(GroupId g) throws DbException {
|
public Collection<ContactId> getVisibility(GroupId g) throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -1105,6 +1104,30 @@ DatabaseCleaner.Callback {
|
|||||||
callListeners(Event.CONTACTS_UPDATED);
|
callListeners(Event.CONTACTS_UPDATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConfig(TransportId t, TransportConfig config)
|
||||||
|
throws DbException {
|
||||||
|
boolean changed = false;
|
||||||
|
transportLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
T txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
TransportConfig old = db.getConfig(txn, t);
|
||||||
|
if(!config.equals(old)) {
|
||||||
|
db.setConfig(txn, t, config);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transportLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
// Call the listeners outside the lock
|
||||||
|
if(changed) callListeners(Event.TRANSPORTS_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
public void setConnectionWindow(ContactId c, TransportId t,
|
public void setConnectionWindow(ContactId c, TransportId t,
|
||||||
ConnectionWindow w) throws DbException {
|
ConnectionWindow w) throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
@@ -1127,6 +1150,30 @@ DatabaseCleaner.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLocalProperties(TransportId t,
|
||||||
|
TransportProperties properties) throws DbException {
|
||||||
|
boolean changed = false;
|
||||||
|
transportLock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
T txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
TransportProperties old = db.getLocalTransports(txn).get(t);
|
||||||
|
if(!properties.equals(old)) {
|
||||||
|
db.setLocalProperties(txn, t, properties);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
} catch(DbException e) {
|
||||||
|
db.abortTransaction(txn);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
transportLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
// Call the listeners outside the lock
|
||||||
|
if(changed) callListeners(Event.TRANSPORTS_UPDATED);
|
||||||
|
}
|
||||||
|
|
||||||
public void setRating(AuthorId a, Rating r) throws DbException {
|
public void setRating(AuthorId a, Rating r) throws DbException {
|
||||||
messageLock.writeLock().lock();
|
messageLock.writeLock().lock();
|
||||||
try {
|
try {
|
||||||
@@ -1221,56 +1268,6 @@ DatabaseCleaner.Callback {
|
|||||||
+ indirect + " indirectly");
|
+ indirect + " indirectly");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransportConfig(TransportId t, TransportConfig config)
|
|
||||||
throws DbException {
|
|
||||||
boolean changed = false;
|
|
||||||
transportLock.writeLock().lock();
|
|
||||||
try {
|
|
||||||
T txn = db.startTransaction();
|
|
||||||
try {
|
|
||||||
TransportConfig old = db.getTransportConfig(txn, t);
|
|
||||||
if(!config.equals(old)) {
|
|
||||||
db.setTransportConfig(txn, t, config);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} catch(DbException e) {
|
|
||||||
db.abortTransaction(txn);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
transportLock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
// Call the listeners outside the lock
|
|
||||||
if(changed) callListeners(Event.TRANSPORTS_UPDATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransportProperties(TransportId t,
|
|
||||||
TransportProperties properties) throws DbException {
|
|
||||||
boolean changed = false;
|
|
||||||
transportLock.writeLock().lock();
|
|
||||||
try {
|
|
||||||
T txn = db.startTransaction();
|
|
||||||
try {
|
|
||||||
Map<TransportId, TransportProperties> transports =
|
|
||||||
db.getLocalTransports(txn);
|
|
||||||
TransportProperties old = transports.get(t);
|
|
||||||
if(!properties.equals(old)) {
|
|
||||||
db.setTransportProperties(txn, t, properties);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
} catch(DbException e) {
|
|
||||||
db.abortTransaction(txn);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
transportLock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
// Call the listeners outside the lock
|
|
||||||
if(changed) callListeners(Event.TRANSPORTS_UPDATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisibility(GroupId g, Collection<ContactId> visible)
|
public void setVisibility(GroupId g, Collection<ContactId> visible)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
contactLock.readLock().lock();
|
contactLock.readLock().lock();
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -811,6 +810,28 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransportConfig getConfig(Connection txn, TransportId t)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT key, value FROM transportConfig"
|
||||||
|
+ " WHERE transportId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, t.getInt());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
TransportConfig config = new TransportConfig();
|
||||||
|
while(rs.next()) config.put(rs.getString(1), rs.getString(2));
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return config;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long getConnectionNumber(Connection txn, ContactId c,
|
public long getConnectionNumber(Connection txn, ContactId c,
|
||||||
TransportId t) throws DbException {
|
TransportId t) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -918,6 +939,34 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
} else return f.length();
|
} else return f.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessageId getGroupMessageParent(Connection txn, MessageId m)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT m1.parentId FROM messages AS m1"
|
||||||
|
+ " JOIN messages AS m2"
|
||||||
|
+ " ON m1.parentId = m2.messageId"
|
||||||
|
+ " AND m1.groupId = m2.groupId"
|
||||||
|
+ " WHERE m1.messageId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, m.getBytes());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
MessageId parent = null;
|
||||||
|
if(rs.next()) {
|
||||||
|
parent = new MessageId(rs.getBytes(1));
|
||||||
|
if(rs.next()) throw new DbStateException();
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return parent;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Map<TransportId, TransportProperties> getLocalTransports(
|
public Map<TransportId, TransportProperties> getLocalTransports(
|
||||||
Connection txn) throws DbException {
|
Connection txn) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -928,7 +977,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
Map<TransportId, TransportProperties> transports =
|
Map<TransportId, TransportProperties> transports =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
new HashMap<TransportId, TransportProperties>();
|
||||||
TransportProperties properties = null;
|
TransportProperties properties = null;
|
||||||
TransportId lastId = null;
|
TransportId lastId = null;
|
||||||
while(rs.next()) {
|
while(rs.next()) {
|
||||||
@@ -1164,34 +1213,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MessageId getGroupMessageParent(Connection txn, MessageId m)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT m1.parentId FROM messages AS m1"
|
|
||||||
+ " JOIN messages AS m2"
|
|
||||||
+ " ON m1.parentId = m2.messageId"
|
|
||||||
+ " AND m1.groupId = m2.groupId"
|
|
||||||
+ " WHERE m1.messageId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setBytes(1, m.getBytes());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
MessageId parent = null;
|
|
||||||
if(rs.next()) {
|
|
||||||
parent = new MessageId(rs.getBytes(1));
|
|
||||||
if(rs.next()) throw new DbStateException();
|
|
||||||
}
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return parent;
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rating getRating(Connection txn, AuthorId a) throws DbException {
|
public Rating getRating(Connection txn, AuthorId a) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -1214,61 +1235,32 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<TransportId, Map<ContactId, TransportProperties>>
|
public Map<ContactId, TransportProperties> getRemoteProperties(
|
||||||
getRemoteTransports(Connection txn) throws DbException {
|
Connection txn, TransportId t) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT transportId, contactId, key, value"
|
String sql = "SELECT contactId, key, value FROM contactTransports"
|
||||||
+ " FROM contactTransports"
|
+ " WHERE transportId = ?"
|
||||||
+ " ORDER BY transportId";
|
+ " ORDER BY contactId";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, t.getInt());
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>> transports =
|
Map<ContactId, TransportProperties> properties =
|
||||||
new TreeMap<TransportId, Map<ContactId, TransportProperties>>();
|
new HashMap<ContactId, TransportProperties>();
|
||||||
Map<ContactId, TransportProperties> contacts = null;
|
TransportProperties p = null;
|
||||||
TransportProperties properties = null;
|
|
||||||
TransportId lastTransportId = null;
|
|
||||||
ContactId lastContactId = null;
|
ContactId lastContactId = null;
|
||||||
while(rs.next()) {
|
while(rs.next()) {
|
||||||
TransportId transportId = new TransportId(rs.getInt(1));
|
ContactId contactId = new ContactId(rs.getInt(1));
|
||||||
if(!transportId.equals(lastTransportId)) {
|
|
||||||
contacts = new HashMap<ContactId, TransportProperties>();
|
|
||||||
transports.put(transportId, contacts);
|
|
||||||
lastContactId = null;
|
|
||||||
}
|
|
||||||
ContactId contactId = new ContactId(rs.getInt(2));
|
|
||||||
if(!contactId.equals(lastContactId)) {
|
if(!contactId.equals(lastContactId)) {
|
||||||
properties = new TransportProperties();
|
p = new TransportProperties();
|
||||||
contacts.put(contactId, properties);
|
properties.put(contactId, p);
|
||||||
}
|
}
|
||||||
properties.put(rs.getString(3), rs.getString(4));
|
p.put(rs.getString(2), rs.getString(3));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
return transports;
|
return properties;
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getSharedSecret(Connection txn, ContactId c)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT secret FROM contacts WHERE contactId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, c.getInt());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
if(!rs.next()) throw new DbStateException();
|
|
||||||
byte[] secret = rs.getBytes(1);
|
|
||||||
if(rs.next()) throw new DbStateException();
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return secret;
|
|
||||||
} catch(SQLException e) {
|
} catch(SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs);
|
||||||
tryToClose(ps);
|
tryToClose(ps);
|
||||||
@@ -1415,6 +1407,28 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getSharedSecret(Connection txn, ContactId c)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT secret FROM contacts WHERE contactId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
if(!rs.next()) throw new DbStateException();
|
||||||
|
byte[] secret = rs.getBytes(1);
|
||||||
|
if(rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return secret;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<Group> getSubscriptions(Connection txn)
|
public Collection<Group> getSubscriptions(Connection txn)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1469,28 +1483,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportConfig getTransportConfig(Connection txn,
|
|
||||||
TransportId t) throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT key, value FROM transportConfig"
|
|
||||||
+ " WHERE transportId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, t.getInt());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
TransportConfig config = new TransportConfig();
|
|
||||||
while(rs.next()) config.put(rs.getString(1), rs.getString(2));
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return config;
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
public Collection<ContactId> getVisibility(Connection txn, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1778,6 +1770,44 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConfig(Connection txn, TransportId t, TransportConfig config)
|
||||||
|
throws DbException {
|
||||||
|
setTransportDetails(txn, t, config, "transportConfig");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTransportDetails(Connection txn, TransportId t,
|
||||||
|
Map<String, String> details, String table) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
// Delete any existing details for the given transport
|
||||||
|
String sql = "DELETE FROM " + table + " WHERE transportId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, t.getInt());
|
||||||
|
ps.executeUpdate();
|
||||||
|
ps.close();
|
||||||
|
// Store the new details
|
||||||
|
sql = "INSERT INTO " + table + " (transportId, key, value)"
|
||||||
|
+ " VALUES (?, ?, ?)";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, t.getInt());
|
||||||
|
for(Entry<String, String> e : details.entrySet()) {
|
||||||
|
ps.setString(2, e.getKey());
|
||||||
|
ps.setString(3, e.getValue());
|
||||||
|
ps.addBatch();
|
||||||
|
}
|
||||||
|
int[] batchAffected = ps.executeBatch();
|
||||||
|
if(batchAffected.length != details.size())
|
||||||
|
throw new DbStateException();
|
||||||
|
for(int i = 0; i < batchAffected.length; i++) {
|
||||||
|
if(batchAffected[i] != 1) throw new DbStateException();
|
||||||
|
}
|
||||||
|
ps.close();
|
||||||
|
} catch(SQLException e) {
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setConnectionWindow(Connection txn, ContactId c,
|
public void setConnectionWindow(Connection txn, ContactId c,
|
||||||
TransportId t, ConnectionWindow w) throws DbException {
|
TransportId t, ConnectionWindow w) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1826,6 +1856,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLocalProperties(Connection txn, TransportId t,
|
||||||
|
TransportProperties properties) throws DbException {
|
||||||
|
setTransportDetails(txn, t, properties, "transports");
|
||||||
|
}
|
||||||
|
|
||||||
public Rating setRating(Connection txn, AuthorId a, Rating r)
|
public Rating setRating(Connection txn, AuthorId a, Rating r)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2051,49 +2086,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransportConfig(Connection txn, TransportId t,
|
|
||||||
TransportConfig config) throws DbException {
|
|
||||||
setTransportDetails(txn, t, config, "transportConfig");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTransportDetails(Connection txn, TransportId t,
|
|
||||||
Map<String, String> details, String table) throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
try {
|
|
||||||
// Delete any existing details for the given transport
|
|
||||||
String sql = "DELETE FROM " + table + " WHERE transportId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, t.getInt());
|
|
||||||
ps.executeUpdate();
|
|
||||||
ps.close();
|
|
||||||
// Store the new details
|
|
||||||
sql = "INSERT INTO " + table + " (transportId, key, value)"
|
|
||||||
+ " VALUES (?, ?, ?)";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, t.getInt());
|
|
||||||
for(Entry<String, String> e : details.entrySet()) {
|
|
||||||
ps.setString(2, e.getKey());
|
|
||||||
ps.setString(3, e.getValue());
|
|
||||||
ps.addBatch();
|
|
||||||
}
|
|
||||||
int[] batchAffected = ps.executeBatch();
|
|
||||||
if(batchAffected.length != details.size())
|
|
||||||
throw new DbStateException();
|
|
||||||
for(int i = 0; i < batchAffected.length; i++) {
|
|
||||||
if(batchAffected[i] != 1) throw new DbStateException();
|
|
||||||
}
|
|
||||||
ps.close();
|
|
||||||
} catch(SQLException e) {
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransportProperties(Connection txn, TransportId t,
|
|
||||||
TransportProperties properties) throws DbException {
|
|
||||||
setTransportDetails(txn, t, properties, "transports");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransports(Connection txn, ContactId c,
|
public void setTransports(Connection txn, ContactId c,
|
||||||
Map<TransportId, TransportProperties> transports, long timestamp)
|
Map<TransportId, TransportProperties> transports, long timestamp)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package net.sf.briar.protocol;
|
package net.sf.briar.protocol;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import net.sf.briar.api.FormatException;
|
import net.sf.briar.api.FormatException;
|
||||||
import net.sf.briar.api.TransportId;
|
import net.sf.briar.api.TransportId;
|
||||||
@@ -40,7 +40,7 @@ class TransportReader implements ObjectReader<TransportUpdate> {
|
|||||||
if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE)
|
if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
Map<TransportId, TransportProperties> transports =
|
Map<TransportId, TransportProperties> transports =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
new HashMap<TransportId, TransportProperties>();
|
||||||
for(Transport t : l) {
|
for(Transport t : l) {
|
||||||
if(transports.put(t.id, t.properties) != null)
|
if(transports.put(t.id, t.properties) != null)
|
||||||
throw new FormatException(); // Duplicate transport ID
|
throw new FormatException(); // Duplicate transport ID
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
private final Group group;
|
private final Group group;
|
||||||
private final TransportId transportId;
|
private final TransportId transportId;
|
||||||
private final Map<TransportId, TransportProperties> transports;
|
private final Map<TransportId, TransportProperties> transports;
|
||||||
private final Map<TransportId, Map<ContactId, TransportProperties>>
|
private final Map<ContactId, TransportProperties> remoteProperties;
|
||||||
remoteTransports;
|
|
||||||
private final byte[] secret;
|
private final byte[] secret;
|
||||||
|
|
||||||
public DatabaseComponentTest() {
|
public DatabaseComponentTest() {
|
||||||
@@ -81,8 +80,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
TransportProperties p =
|
TransportProperties p =
|
||||||
new TransportProperties(Collections.singletonMap("foo", "bar"));
|
new TransportProperties(Collections.singletonMap("foo", "bar"));
|
||||||
transports = Collections.singletonMap(transportId, p);
|
transports = Collections.singletonMap(transportId, p);
|
||||||
remoteTransports = Collections.singletonMap(transportId,
|
remoteProperties = Collections.singletonMap(contactId, p);
|
||||||
Collections.singletonMap(contactId, p));
|
|
||||||
secret = new byte[123];
|
secret = new byte[123];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,9 +126,9 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).getSharedSecret(txn, contactId);
|
oneOf(database).getSharedSecret(txn, contactId);
|
||||||
will(returnValue(secret));
|
will(returnValue(secret));
|
||||||
// getRemoteTransports()
|
// getTransportProperties(transportId)
|
||||||
oneOf(database).getRemoteTransports(txn);
|
oneOf(database).getRemoteProperties(txn, transportId);
|
||||||
will(returnValue(remoteTransports));
|
will(returnValue(remoteProperties));
|
||||||
// subscribe(group)
|
// subscribe(group)
|
||||||
oneOf(group).getId();
|
oneOf(group).getId();
|
||||||
will(returnValue(groupId));
|
will(returnValue(groupId));
|
||||||
@@ -176,7 +174,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
assertEquals(connectionWindow,
|
assertEquals(connectionWindow,
|
||||||
db.getConnectionWindow(contactId, transportId));
|
db.getConnectionWindow(contactId, transportId));
|
||||||
assertEquals(secret, db.getSharedSecret(contactId));
|
assertEquals(secret, db.getSharedSecret(contactId));
|
||||||
assertEquals(remoteTransports, db.getRemoteTransports());
|
assertEquals(remoteProperties, db.getRemoteProperties(transportId));
|
||||||
db.subscribe(group); // First time - check listeners are called
|
db.subscribe(group); // First time - check listeners are called
|
||||||
db.subscribe(group); // Second time - check listeners aren't called
|
db.subscribe(group); // Second time - check listeners aren't called
|
||||||
assertEquals(Collections.singletonList(groupId), db.getSubscriptions());
|
assertEquals(Collections.singletonList(groupId), db.getSubscriptions());
|
||||||
@@ -1289,7 +1287,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
oneOf(database).getLocalTransports(txn);
|
oneOf(database).getLocalTransports(txn);
|
||||||
will(returnValue(Collections.singletonMap(transportId,
|
will(returnValue(Collections.singletonMap(transportId,
|
||||||
properties)));
|
properties)));
|
||||||
oneOf(database).setTransportProperties(txn, transportId,
|
oneOf(database).setLocalProperties(txn, transportId,
|
||||||
properties1);
|
properties1);
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
|
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
|
||||||
@@ -1297,7 +1295,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransportProperties(transportId, properties1);
|
db.setLocalProperties(transportId, properties1);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -1323,7 +1321,7 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransportProperties(transportId, properties);
|
db.setLocalProperties(transportId, properties);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -1342,16 +1340,16 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).getTransportConfig(txn, transportId);
|
oneOf(database).getConfig(txn, transportId);
|
||||||
will(returnValue(config));
|
will(returnValue(config));
|
||||||
oneOf(database).setTransportConfig(txn, transportId, config1);
|
oneOf(database).setConfig(txn, transportId, config1);
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
|
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransportConfig(transportId, config1);
|
db.setConfig(transportId, config1);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
@@ -1369,14 +1367,14 @@ public abstract class DatabaseComponentTest extends TestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).getTransportConfig(txn, transportId);
|
oneOf(database).getConfig(txn, transportId);
|
||||||
will(returnValue(config));
|
will(returnValue(config));
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
DatabaseComponent db = createDatabaseComponent(database, cleaner);
|
||||||
|
|
||||||
db.addListener(listener);
|
db.addListener(listener);
|
||||||
db.setTransportConfig(transportId, config);
|
db.setConfig(transportId, config);
|
||||||
|
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -73,9 +72,9 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
private final Message message, privateMessage;
|
private final Message message, privateMessage;
|
||||||
private final Group group;
|
private final Group group;
|
||||||
private final TransportId transportId;
|
private final TransportId transportId;
|
||||||
|
private final TransportProperties properties;
|
||||||
private final Map<TransportId, TransportProperties> transports;
|
private final Map<TransportId, TransportProperties> transports;
|
||||||
private final Map<TransportId, Map<ContactId, TransportProperties>>
|
private final Map<ContactId, TransportProperties> remoteProperties;
|
||||||
remoteTransports;
|
|
||||||
private final Map<Group, Long> subscriptions;
|
private final Map<Group, Long> subscriptions;
|
||||||
private final byte[] secret;
|
private final byte[] secret;
|
||||||
|
|
||||||
@@ -102,11 +101,10 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
new TestMessage(privateMessageId, null, null, null, timestamp, raw);
|
new TestMessage(privateMessageId, null, null, null, timestamp, raw);
|
||||||
group = groupFactory.createGroup(groupId, "Group name", null);
|
group = groupFactory.createGroup(groupId, "Group name", null);
|
||||||
transportId = new TransportId(0);
|
transportId = new TransportId(0);
|
||||||
TransportProperties p =
|
properties = new TransportProperties(
|
||||||
new TransportProperties(Collections.singletonMap("foo", "bar"));
|
Collections.singletonMap("foo", "bar"));
|
||||||
transports = Collections.singletonMap(transportId, p);
|
transports = Collections.singletonMap(transportId, properties);
|
||||||
remoteTransports = Collections.singletonMap(transportId,
|
remoteProperties = Collections.singletonMap(contactId, properties);
|
||||||
Collections.singletonMap(contactId, p));
|
|
||||||
subscriptions = Collections.singletonMap(group, 0L);
|
subscriptions = Collections.singletonMap(group, 0L);
|
||||||
secret = new byte[123];
|
secret = new byte[123];
|
||||||
}
|
}
|
||||||
@@ -140,7 +138,8 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
db = open(true);
|
db = open(true);
|
||||||
txn = db.startTransaction();
|
txn = db.startTransaction();
|
||||||
assertTrue(db.containsContact(txn, contactId));
|
assertTrue(db.containsContact(txn, contactId));
|
||||||
assertEquals(remoteTransports, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
assertTrue(db.containsSubscription(txn, groupId));
|
assertTrue(db.containsSubscription(txn, groupId));
|
||||||
assertTrue(db.containsMessage(txn, messageId));
|
assertTrue(db.containsMessage(txn, messageId));
|
||||||
byte[] raw1 = db.getMessage(txn, messageId);
|
byte[] raw1 = db.getMessage(txn, messageId);
|
||||||
@@ -160,7 +159,8 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
db = open(true);
|
db = open(true);
|
||||||
txn = db.startTransaction();
|
txn = db.startTransaction();
|
||||||
assertFalse(db.containsContact(txn, contactId));
|
assertFalse(db.containsContact(txn, contactId));
|
||||||
assertEquals(Collections.emptyMap(), db.getRemoteTransports(txn));
|
assertEquals(Collections.emptyMap(),
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
assertFalse(db.containsSubscription(txn, groupId));
|
assertFalse(db.containsSubscription(txn, groupId));
|
||||||
assertFalse(db.containsMessage(txn, messageId));
|
assertFalse(db.containsMessage(txn, messageId));
|
||||||
assertFalse(db.containsMessage(txn, privateMessageId));
|
assertFalse(db.containsMessage(txn, privateMessageId));
|
||||||
@@ -991,47 +991,40 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateTransportProperties() throws Exception {
|
public void testUpdateTransportProperties() throws Exception {
|
||||||
TransportProperties properties =
|
|
||||||
new TransportProperties(Collections.singletonMap("foo", "bar"));
|
|
||||||
TransportProperties properties1 =
|
|
||||||
new TransportProperties(Collections.singletonMap("baz", "bam"));
|
|
||||||
|
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact with some transport properties
|
// Add a contact with some transport properties
|
||||||
assertEquals(contactId, db.addContact(txn, transports, secret));
|
assertEquals(contactId, db.addContact(txn, transports, secret));
|
||||||
assertEquals(remoteTransports, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
// Replace the transport properties
|
// Replace the transport properties
|
||||||
TransportId transportId1 = new TransportId(1);
|
TransportProperties properties1 =
|
||||||
|
new TransportProperties(Collections.singletonMap("baz", "bam"));
|
||||||
Map<TransportId, TransportProperties> transports1 =
|
Map<TransportId, TransportProperties> transports1 =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
Collections.singletonMap(transportId, properties1);
|
||||||
transports1.put(transportId, properties);
|
Map<ContactId, TransportProperties> remoteProperties1 =
|
||||||
transports1.put(transportId1, properties1);
|
Collections.singletonMap(contactId, properties1);
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>> remoteTransports1
|
|
||||||
= new TreeMap<TransportId, Map<ContactId, TransportProperties>>();
|
|
||||||
remoteTransports1.put(transportId, Collections.singletonMap(contactId,
|
|
||||||
properties));
|
|
||||||
remoteTransports1.put(transportId1, Collections.singletonMap(contactId,
|
|
||||||
properties1));
|
|
||||||
db.setTransports(txn, contactId, transports1, 1);
|
db.setTransports(txn, contactId, transports1, 1);
|
||||||
assertEquals(remoteTransports1, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties1,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
// Remove the transport properties
|
// Remove the transport properties
|
||||||
db.setTransports(txn, contactId,
|
db.setTransports(txn, contactId,
|
||||||
Collections.<TransportId, TransportProperties>emptyMap(), 2);
|
Collections.<TransportId, TransportProperties>emptyMap(), 2);
|
||||||
assertEquals(Collections.emptyMap(), db.getRemoteTransports(txn));
|
assertEquals(Collections.emptyMap(),
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
// Set the local transport properties
|
// Set the local transport properties
|
||||||
for(Entry<TransportId, TransportProperties> e : transports.entrySet()) {
|
for(Entry<TransportId, TransportProperties> e : transports.entrySet()) {
|
||||||
db.setTransportProperties(txn, e.getKey(), e.getValue());
|
db.setLocalProperties(txn, e.getKey(), e.getValue());
|
||||||
}
|
}
|
||||||
assertEquals(transports, db.getLocalTransports(txn));
|
assertEquals(transports, db.getLocalTransports(txn));
|
||||||
|
|
||||||
// Remove the local transport properties
|
// Remove the local transport properties
|
||||||
for(TransportId t : transports.keySet()) {
|
for(TransportId t : transports.keySet()) {
|
||||||
db.setTransportProperties(txn, t, new TransportProperties());
|
db.setLocalProperties(txn, t, new TransportProperties());
|
||||||
}
|
}
|
||||||
assertEquals(Collections.emptyMap(), db.getLocalTransports(txn));
|
assertEquals(Collections.emptyMap(), db.getLocalTransports(txn));
|
||||||
|
|
||||||
@@ -1051,17 +1044,17 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Set the transport config
|
// Set the transport config
|
||||||
db.setTransportConfig(txn, transportId, config);
|
db.setConfig(txn, transportId, config);
|
||||||
assertEquals(config, db.getTransportConfig(txn, transportId));
|
assertEquals(config, db.getConfig(txn, transportId));
|
||||||
|
|
||||||
// Update the transport config
|
// Update the transport config
|
||||||
db.setTransportConfig(txn, transportId, config1);
|
db.setConfig(txn, transportId, config1);
|
||||||
assertEquals(config1, db.getTransportConfig(txn, transportId));
|
assertEquals(config1, db.getConfig(txn, transportId));
|
||||||
|
|
||||||
// Remove the transport config
|
// Remove the transport config
|
||||||
db.setTransportConfig(txn, transportId, new TransportConfig());
|
db.setConfig(txn, transportId, new TransportConfig());
|
||||||
assertEquals(Collections.emptyMap(),
|
assertEquals(Collections.emptyMap(),
|
||||||
db.getTransportConfig(txn, transportId));
|
db.getConfig(txn, transportId));
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -1069,45 +1062,35 @@ public class H2DatabaseTest extends TestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransportsNotUpdatedIfTimestampIsOld() throws Exception {
|
public void testTransportsNotUpdatedIfTimestampIsOld() throws Exception {
|
||||||
TransportProperties properties =
|
|
||||||
new TransportProperties(Collections.singletonMap("foo", "bar"));
|
|
||||||
TransportProperties properties1 =
|
|
||||||
new TransportProperties(Collections.singletonMap("baz", "bam"));
|
|
||||||
TransportProperties properties2 =
|
|
||||||
new TransportProperties(Collections.singletonMap("quux", "etc"));
|
|
||||||
|
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact with some transport properties
|
// Add a contact with some transport properties
|
||||||
assertEquals(contactId, db.addContact(txn, transports, secret));
|
assertEquals(contactId, db.addContact(txn, transports, secret));
|
||||||
assertEquals(remoteTransports, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
// Replace the transport properties using a timestamp of 2
|
// Replace the transport properties using a timestamp of 2
|
||||||
TransportId transportId1 = new TransportId(1);
|
TransportProperties properties1 =
|
||||||
|
new TransportProperties(Collections.singletonMap("baz", "bam"));
|
||||||
Map<TransportId, TransportProperties> transports1 =
|
Map<TransportId, TransportProperties> transports1 =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
Collections.singletonMap(transportId, properties1);
|
||||||
transports1.put(transportId, properties);
|
Map<ContactId, TransportProperties> remoteProperties1 =
|
||||||
transports1.put(transportId1, properties1);
|
Collections.singletonMap(contactId, properties1);
|
||||||
Map<TransportId, Map<ContactId, TransportProperties>> remoteTransports1
|
|
||||||
= new TreeMap<TransportId, Map<ContactId, TransportProperties>>();
|
|
||||||
remoteTransports1.put(transportId, Collections.singletonMap(contactId,
|
|
||||||
properties));
|
|
||||||
remoteTransports1.put(transportId1, Collections.singletonMap(contactId,
|
|
||||||
properties1));
|
|
||||||
db.setTransports(txn, contactId, transports1, 2);
|
db.setTransports(txn, contactId, transports1, 2);
|
||||||
assertEquals(remoteTransports1, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties1,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
// Try to replace the transport properties using a timestamp of 1
|
// Try to replace the transport properties using a timestamp of 1
|
||||||
TransportId transportId2 = new TransportId(2);
|
TransportProperties properties2 =
|
||||||
|
new TransportProperties(Collections.singletonMap("quux", "etc"));
|
||||||
Map<TransportId, TransportProperties> transports2 =
|
Map<TransportId, TransportProperties> transports2 =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
Collections.singletonMap(transportId, properties2);
|
||||||
transports2.put(transportId1, properties1);
|
|
||||||
transports2.put(transportId2, properties2);
|
|
||||||
db.setTransports(txn, contactId, transports2, 1);
|
db.setTransports(txn, contactId, transports2, 1);
|
||||||
|
|
||||||
// The old properties should still be there
|
// The old properties should still be there
|
||||||
assertEquals(remoteTransports1, db.getRemoteTransports(txn));
|
assertEquals(remoteProperties1,
|
||||||
|
db.getRemoteProperties(txn, transportId));
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import net.sf.briar.TestUtils;
|
import net.sf.briar.TestUtils;
|
||||||
@@ -193,7 +192,7 @@ public class ConstantsTest extends TestCase {
|
|||||||
// Create the maximum number of plugins, each with the maximum number
|
// Create the maximum number of plugins, each with the maximum number
|
||||||
// of maximum-length properties
|
// of maximum-length properties
|
||||||
Map<TransportId, TransportProperties> transports =
|
Map<TransportId, TransportProperties> transports =
|
||||||
new TreeMap<TransportId, TransportProperties>();
|
new HashMap<TransportId, TransportProperties>();
|
||||||
for(int i = 0; i < TransportUpdate.MAX_PLUGINS_PER_UPDATE; i++) {
|
for(int i = 0; i < TransportUpdate.MAX_PLUGINS_PER_UPDATE; i++) {
|
||||||
TransportProperties p = new TransportProperties();
|
TransportProperties p = new TransportProperties();
|
||||||
for(int j = 0; j < TransportUpdate.MAX_PROPERTIES_PER_PLUGIN; j++) {
|
for(int j = 0; j < TransportUpdate.MAX_PROPERTIES_PER_PLUGIN; j++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user