Contact manager hooks. #209

This commit is contained in:
akwizgran
2016-01-19 19:16:35 +00:00
parent 33ef09a6bf
commit 82cf12040f
29 changed files with 333 additions and 195 deletions

View File

@@ -631,7 +631,19 @@ interface Database<T> {
*/
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
/** Marks the given message as valid or invalid. */
/**
* Sets the status of the given contact.
* <p>
* Locking: write.
*/
void setContactStatus(T txn, ContactId c, Contact.Status s)
throws DbException;
/**
* Marks the given message as valid or invalid.
* <p>
* Locking: write.
*/
void setMessageValidity(T txn, MessageId m, boolean valid)
throws DbException;

View File

@@ -16,7 +16,6 @@ import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.event.ContactAddedEvent;
import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalAuthorAddedEvent;
@@ -147,7 +146,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
public ContactId addContact(Author remote, AuthorId local)
throws DbException {
ContactId c;
lock.writeLock().lock();
try {
T txn = db.startTransaction();
@@ -156,8 +154,9 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
throw new ContactExistsException();
if (!db.containsLocalAuthor(txn, local))
throw new NoSuchLocalAuthorException();
c = db.addContact(txn, remote, local);
ContactId c = db.addContact(txn, remote, local);
db.commitTransaction(txn);
return c;
} catch (DbException e) {
db.abortTransaction(txn);
throw e;
@@ -165,8 +164,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
eventBus.broadcast(new ContactAddedEvent(c));
return c;
}
public void addContactGroup(ContactId c, Group g) throws DbException {
@@ -1219,7 +1216,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
eventBus.broadcast(new ContactRemovedEvent(c));
}
public void removeGroup(Group g) throws DbException {
@@ -1287,6 +1283,25 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
eventBus.broadcast(new TransportRemovedEvent(t));
}
public void setContactStatus(ContactId c, Contact.Status s)
throws DbException {
lock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
db.setContactStatus(txn, c, s);
db.commitTransaction(txn);
} catch (DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
lock.writeLock().unlock();
}
}
public void setMessageValidity(Message m, ClientId c, boolean valid)
throws DbException {
lock.writeLock().lock();

View File

@@ -50,8 +50,12 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.contact.Contact.Status.ADDING;
import static org.briarproject.api.db.Metadata.REMOVE;
import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.sync.ValidationManager.Status.INVALID;
import static org.briarproject.api.sync.ValidationManager.Status.UNKNOWN;
import static org.briarproject.api.sync.ValidationManager.Status.VALID;
import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
/**
@@ -60,12 +64,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
*/
abstract class JdbcDatabase implements Database<Connection> {
private static final int SCHEMA_VERSION = 14;
private static final int MIN_SCHEMA_VERSION = 14;
private static final int VALIDATION_UNKNOWN = 0;
private static final int VALIDATION_INVALID = 1;
private static final int VALIDATION_VALID = 2;
private static final int SCHEMA_VERSION = 15;
private static final int MIN_SCHEMA_VERSION = 15;
private static final String CREATE_SETTINGS =
"CREATE TABLE settings"
@@ -90,6 +90,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " name VARCHAR NOT NULL,"
+ " publicKey BINARY NOT NULL,"
+ " localAuthorId HASH NOT NULL,"
+ " status INT NOT NULL,"
+ " PRIMARY KEY (contactId),"
+ " UNIQUE (authorId),"
+ " FOREIGN KEY (localAuthorId)"
@@ -533,13 +534,14 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
// Create a contact row
String sql = "INSERT INTO contacts"
+ " (authorId, name, publicKey, localAuthorId)"
+ " VALUES (?, ?, ?, ?)";
+ " (authorId, name, publicKey, localAuthorId, status)"
+ " VALUES (?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getId().getBytes());
ps.setString(2, remote.getName());
ps.setBytes(3, remote.getPublicKey());
ps.setBytes(4, local.getBytes());
ps.setInt(5, ADDING.getValue());
int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException();
ps.close();
@@ -747,7 +749,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.setBytes(2, m.getGroupId().getBytes());
ps.setLong(3, m.getTimestamp());
ps.setBoolean(4, local);
ps.setInt(5, local ? VALIDATION_VALID : VALIDATION_UNKNOWN);
ps.setInt(5, local ? VALID.getValue() : UNKNOWN.getValue());
byte[] raw = m.getRaw();
ps.setInt(6, raw.length);
ps.setBytes(7, raw);
@@ -1192,7 +1194,8 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT authorId, name, publicKey, localAuthorId"
String sql = "SELECT authorId, name, publicKey, localAuthorId,"
+ " status"
+ " FROM contacts"
+ " WHERE contactId = ?";
ps = txn.prepareStatement(sql);
@@ -1203,10 +1206,11 @@ abstract class JdbcDatabase implements Database<Connection> {
String name = rs.getString(2);
byte[] publicKey = rs.getBytes(3);
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
Contact.Status status = Contact.Status.fromValue(rs.getInt(5));
rs.close();
ps.close();
Author author = new Author(authorId, name, publicKey);
return new Contact(c, author, localAuthorId);
return new Contact(c, author, localAuthorId, status);
} catch (SQLException e) {
tryToClose(rs);
tryToClose(ps);
@@ -1240,7 +1244,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ResultSet rs = null;
try {
String sql = "SELECT contactId, authorId, name, publicKey,"
+ " localAuthorId"
+ " localAuthorId, status"
+ " FROM contacts";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
@@ -1252,7 +1256,9 @@ abstract class JdbcDatabase implements Database<Connection> {
byte[] publicKey = rs.getBytes(4);
Author author = new Author(authorId, name, publicKey);
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
contacts.add(new Contact(contactId, author, localAuthorId));
Contact.Status status = Contact.Status.fromValue(rs.getInt(6));
contacts.add(new Contact(contactId, author, localAuthorId,
status));
}
rs.close();
ps.close();
@@ -1612,7 +1618,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " ORDER BY timestamp DESC LIMIT ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, VALIDATION_VALID);
ps.setInt(2, VALID.getValue());
ps.setLong(3, now);
ps.setInt(4, maxMessages);
rs = ps.executeQuery();
@@ -1674,7 +1680,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " ORDER BY timestamp DESC";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, VALIDATION_VALID);
ps.setInt(2, VALID.getValue());
ps.setLong(3, now);
rs = ps.executeQuery();
List<MessageId> ids = new ArrayList<MessageId>();
@@ -1704,7 +1710,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " JOIN groups AS g ON m.groupId = g.groupId"
+ " WHERE valid = ? AND clientId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, VALIDATION_UNKNOWN);
ps.setInt(1, UNKNOWN.getValue());
ps.setBytes(2, c.getBytes());
rs = ps.executeQuery();
List<MessageId> ids = new ArrayList<MessageId>();
@@ -1799,7 +1805,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " ORDER BY timestamp DESC";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setInt(2, VALIDATION_VALID);
ps.setInt(2, VALID.getValue());
ps.setLong(3, now);
rs = ps.executeQuery();
List<MessageId> ids = new ArrayList<MessageId>();
@@ -1846,7 +1852,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ResultSet rs = null;
try {
String sql = "SELECT c.contactId, authorId, c.name, publicKey,"
+ " localAuthorId"
+ " localAuthorId, status"
+ " FROM contacts AS c"
+ " JOIN contactGroups AS cg"
+ " ON c.contactId = cg.contactId"
@@ -1862,7 +1868,9 @@ abstract class JdbcDatabase implements Database<Connection> {
byte[] publicKey = rs.getBytes(4);
Author author = new Author(authorId, name, publicKey);
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
contacts.add(new Contact(contactId, author, localAuthorId));
Contact.Status status = Contact.Status.fromValue(rs.getInt(6));
contacts.add(new Contact(contactId, author, localAuthorId,
status));
}
rs.close();
ps.close();
@@ -2687,13 +2695,30 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setContactStatus(Connection txn, ContactId c, Contact.Status s)
throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE contacts SET status = ? WHERE contactId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, s.getValue());
ps.setInt(2, c.getInt());
int affected = ps.executeUpdate();
if (affected < 0 || affected > 1) throw new DbStateException();
ps.close();
} catch (SQLException e) {
tryToClose(ps);
throw new DbException(e);
}
}
public void setMessageValidity(Connection txn, MessageId m, boolean valid)
throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE messages SET valid = ? WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, valid ? VALIDATION_VALID : VALIDATION_INVALID);
ps.setInt(1, valid ? VALID.getValue() : INVALID.getValue());
ps.setBytes(2, m.getBytes());
int affected = ps.executeUpdate();
if (affected < 0) throw new DbStateException();