Removed peer moderation (may be restored after beta testing).

This commit is contained in:
akwizgran
2013-09-27 18:04:27 +01:00
parent b94954544d
commit 0a153acd02
16 changed files with 80 additions and 1020 deletions

View File

@@ -20,7 +20,6 @@ import net.sf.briar.api.messaging.GroupId;
import net.sf.briar.api.messaging.GroupStatus;
import net.sf.briar.api.messaging.Message;
import net.sf.briar.api.messaging.MessageId;
import net.sf.briar.api.messaging.Rating;
import net.sf.briar.api.messaging.RetentionAck;
import net.sf.briar.api.messaging.RetentionUpdate;
import net.sf.briar.api.messaging.SubscriptionAck;
@@ -45,7 +44,6 @@ import net.sf.briar.api.transport.TemporarySecret;
* <li> contact
* <li> identity
* <li> message
* <li> rating
* <li> retention
* <li> subscription
* <li> transport
@@ -270,7 +268,7 @@ interface Database<T> {
/**
* Returns the headers of all messages in the given group.
* <p>
* Locking: message read, rating read.
* Locking: message read.
*/
Collection<GroupMessageHeader> getGroupMessageHeaders(T txn, GroupId g)
throws DbException;
@@ -341,7 +339,7 @@ interface Database<T> {
* Returns the headers of all private messages to or from the given
* contact.
* <p>
* Locking: contact read, identity read, message read, rating read.
* Locking: contact read, identity read, message read.
*/
Collection<PrivateMessageHeader> getPrivateMessageHeaders(T txn,
ContactId c) throws DbException;
@@ -364,15 +362,6 @@ interface Database<T> {
Collection<MessageId> getMessagesToOffer(T txn, ContactId c,
int maxMessages) throws DbException;
/**
* Returns the number of children of the message identified by the given
* ID that are present in the database and have sendability scores greater
* than zero.
* <p>
* Locking: message read.
*/
int getNumberOfSendableChildren(T txn, MessageId m) throws DbException;
/**
* Returns the message identified by the given ID, in serialised form.
* <p>
@@ -398,13 +387,6 @@ interface Database<T> {
*/
Collection<MessageId> getOldMessages(T txn, int size) throws DbException;
/**
* Returns the user's rating for the given author.
* <p>
* Locking: rating read.
*/
Rating getRating(T txn, AuthorId a) throws DbException;
/**
* Returns true if the given message has been read.
* <p>
@@ -443,13 +425,6 @@ interface Database<T> {
*/
Collection<TemporarySecret> getSecrets(T txn) throws DbException;
/**
* Returns the sendability score of the given group message.
* <p>
* Locking: message read.
*/
int getSendability(T txn, MessageId m) throws DbException;
/**
* Returns the IDs of some messages that are eligible to be sent to the
* given contact, with a total length less than or equal to the given
@@ -669,13 +644,6 @@ interface Database<T> {
*/
void setLastConnected(T txn, ContactId c, long now) throws DbException;
/**
* Sets the user's rating for the given author.
* <p>
* Locking: rating write.
*/
Rating setRating(T txn, AuthorId a, Rating r) throws DbException;
/**
* Marks the given message read or unread and returns true if it was
* previously read.
@@ -714,13 +682,6 @@ interface Database<T> {
boolean setRetentionTime(T txn, ContactId c, long retention, long version)
throws DbException;
/**
* Sets the sendability score of the given message.
* <p>
* Locking: message write.
*/
void setSendability(T txn, MessageId m, int sendability) throws DbException;
/**
* Marks the given message starred or unstarred and returns true if it was
* previously starred.

View File

@@ -2,7 +2,6 @@ package net.sf.briar.db;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.sf.briar.api.messaging.Rating.GOOD;
import static net.sf.briar.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
import static net.sf.briar.db.DatabaseConstants.BYTES_PER_SWEEP;
import static net.sf.briar.db.DatabaseConstants.CRITICAL_FREE_SPACE;
@@ -52,7 +51,6 @@ import net.sf.briar.api.db.event.LocalTransportsUpdatedEvent;
import net.sf.briar.api.db.event.MessageExpiredEvent;
import net.sf.briar.api.db.event.MessageReceivedEvent;
import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
import net.sf.briar.api.db.event.RatingChangedEvent;
import net.sf.briar.api.db.event.RemoteRetentionTimeUpdatedEvent;
import net.sf.briar.api.db.event.RemoteSubscriptionsUpdatedEvent;
import net.sf.briar.api.db.event.RemoteTransportsUpdatedEvent;
@@ -68,7 +66,6 @@ import net.sf.briar.api.messaging.GroupStatus;
import net.sf.briar.api.messaging.Message;
import net.sf.briar.api.messaging.MessageId;
import net.sf.briar.api.messaging.Offer;
import net.sf.briar.api.messaging.Rating;
import net.sf.briar.api.messaging.Request;
import net.sf.briar.api.messaging.RetentionAck;
import net.sf.briar.api.messaging.RetentionUpdate;
@@ -105,8 +102,6 @@ DatabaseCleaner.Callback {
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock messageLock =
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock ratingLock =
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock retentionLock =
new ReentrantReadWriteLock(true);
private final ReentrantReadWriteLock subscriptionLock =
@@ -290,27 +285,22 @@ DatabaseCleaner.Callback {
try {
messageLock.writeLock().lock();
try {
ratingLock.readLock().lock();
subscriptionLock.readLock().lock();
try {
subscriptionLock.readLock().lock();
T txn = db.startTransaction();
try {
T txn = db.startTransaction();
try {
// Don't store the message if the user has
// unsubscribed from the group
GroupId g = m.getGroup().getId();
if(db.containsSubscription(txn, g))
added = storeGroupMessage(txn, m, null);
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
subscriptionLock.readLock().unlock();
// Don't store the message if the user has
// unsubscribed from the group
GroupId g = m.getGroup().getId();
if(db.containsSubscription(txn, g))
added = storeGroupMessage(txn, m, null);
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.readLock().unlock();
subscriptionLock.readLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
@@ -324,11 +314,10 @@ DatabaseCleaner.Callback {
/**
* If the given message is already in the database, marks it as seen by the
* sender and returns false. Otherwise stores the message, updates the
* sendability of its ancestors if necessary, marks the message as seen by
* the sender and unseen by all other contacts, and returns true.
* sender and returns false. Otherwise stores the message, marks it as seen
* by the sender and unseen by all other contacts, and returns true.
* <p>
* Locking: contact read, message write, rating read.
* Locking: contact read, message write.
* @param sender is null for a locally generated message.
*/
private boolean storeGroupMessage(T txn, Message m, ContactId sender)
@@ -341,13 +330,8 @@ DatabaseCleaner.Callback {
if(sender != null) db.addStatus(txn, sender, id, true);
if(stored) {
// Mark the message as unseen by other contacts
for(ContactId c : db.getContactIds(txn)) {
for(ContactId c : db.getContactIds(txn))
if(!c.equals(sender)) db.addStatus(txn, c, id, false);
}
// Calculate and store the message's sendability
int sendability = calculateSendability(txn, m);
db.setSendability(txn, id, sendability);
if(sendability > 0) updateAncestorSendability(txn, id, true);
// Count the bytes stored
synchronized(spaceLock) {
bytesStoredSinceLastCheck += m.getSerialised().length;
@@ -359,59 +343,6 @@ DatabaseCleaner.Callback {
return stored;
}
/**
* Calculates and returns the sendability score of a message.
* <p>
* Locking: message read, rating read.
*/
private int calculateSendability(T txn, Message m) throws DbException {
int sendability = 0;
// One point for a good rating
Author a = m.getAuthor();
if(a != null && db.getRating(txn, a.getId()) == GOOD) sendability++;
// One point per sendable child (backward inclusion)
sendability += db.getNumberOfSendableChildren(txn, m.getId());
return sendability;
}
/**
* Iteratively updates the sendability of a message's ancestors to reflect
* a change in the message's sendability. Returns the number of ancestors
* that have changed from sendable to not sendable, or vice versa.
* <p>
* Locking: message write.
* @param increment true if the message's sendability has changed from 0 to
* greater than 0, or false if it has changed from greater than 0 to 0.
*/
private int updateAncestorSendability(T txn, MessageId m, boolean increment)
throws DbException {
int affected = 0;
boolean changed = true;
while(changed) {
// Stop if the message has no parent, or the parent isn't in the
// database, or the parent belongs to a different group
MessageId parent = db.getGroupMessageParent(txn, m);
if(parent == null) break;
// Increment or decrement the parent's sendability
int parentSendability = db.getSendability(txn, parent);
if(increment) {
parentSendability++;
changed = parentSendability == 1;
if(changed) affected++;
} else {
assert parentSendability > 0;
parentSendability--;
changed = parentSendability == 0;
if(changed) affected++;
}
db.setSendability(txn, parent, parentSendability);
// Move on to the parent's parent
m = parent;
}
return affected;
}
public void addLocalPrivateMessage(Message m, ContactId c)
throws DbException {
boolean added;
@@ -967,27 +898,22 @@ DatabaseCleaner.Callback {
throws DbException {
messageLock.readLock().lock();
try {
ratingLock.readLock().lock();
subscriptionLock.readLock().lock();
try {
subscriptionLock.readLock().lock();
T txn = db.startTransaction();
try {
T txn = db.startTransaction();
try {
if(!db.containsSubscription(txn, g))
throw new NoSuchSubscriptionException();
Collection<GroupMessageHeader> headers =
db.getGroupMessageHeaders(txn, g);
db.commitTransaction(txn);
return headers;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
subscriptionLock.readLock().unlock();
if(!db.containsSubscription(txn, g))
throw new NoSuchSubscriptionException();
Collection<GroupMessageHeader> headers =
db.getGroupMessageHeaders(txn, g);
db.commitTransaction(txn);
return headers;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.readLock().unlock();
subscriptionLock.readLock().unlock();
}
} finally {
messageLock.readLock().unlock();
@@ -1111,20 +1037,15 @@ DatabaseCleaner.Callback {
try {
messageLock.readLock().lock();
try {
ratingLock.readLock().lock();
T txn = db.startTransaction();
try {
T txn = db.startTransaction();
try {
Collection<PrivateMessageHeader> headers =
db.getPrivateMessageHeaders(txn, c);
db.commitTransaction(txn);
return headers;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.readLock().unlock();
Collection<PrivateMessageHeader> headers =
db.getPrivateMessageHeaders(txn, c);
db.commitTransaction(txn);
return headers;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
messageLock.readLock().unlock();
@@ -1137,23 +1058,6 @@ DatabaseCleaner.Callback {
}
}
public Rating getRating(AuthorId a) throws DbException {
ratingLock.readLock().lock();
try {
T txn = db.startTransaction();
try {
Rating r = db.getRating(txn, a);
db.commitTransaction(txn);
return r;
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.readLock().unlock();
}
}
public boolean getReadFlag(MessageId m) throws DbException {
messageLock.readLock().lock();
try {
@@ -1463,26 +1367,21 @@ DatabaseCleaner.Callback {
try {
messageLock.writeLock().lock();
try {
ratingLock.readLock().lock();
subscriptionLock.readLock().lock();
try {
subscriptionLock.readLock().lock();
T txn = db.startTransaction();
try {
T txn = db.startTransaction();
try {
if(!db.containsContact(txn, c))
throw new NoSuchContactException();
added = storeMessage(txn, c, m);
db.addMessageToAck(txn, c, m.getId());
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
subscriptionLock.readLock().unlock();
if(!db.containsContact(txn, c))
throw new NoSuchContactException();
added = storeMessage(txn, c, m);
db.addMessageToAck(txn, c, m.getId());
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.readLock().unlock();
subscriptionLock.readLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
@@ -1502,7 +1401,7 @@ DatabaseCleaner.Callback {
* Attempts to store a message received from the given contact, and returns
* true if it was stored.
* <p>
* Locking: contact read, message write, rating read, subscription read.
* Locking: contact read, message write, subscription read.
*/
private boolean storeMessage(T txn, ContactId c, Message m)
throws DbException {
@@ -1823,35 +1722,6 @@ DatabaseCleaner.Callback {
}
}
public void setRating(AuthorId a, Rating r) throws DbException {
boolean changed;
messageLock.writeLock().lock();
try {
ratingLock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
Rating old = db.setRating(txn, a, r);
changed = (old != r);
// Update the sendability of the author's messages
if(r == GOOD && old != GOOD)
updateAuthorSendability(txn, a, true);
else if(r != GOOD && old == GOOD)
updateAuthorSendability(txn, a, false);
db.commitTransaction(txn);
} catch(DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
ratingLock.writeLock().unlock();
}
} finally {
messageLock.writeLock().unlock();
}
if(changed) callListeners(new RatingChangedEvent(a, r));
}
public boolean setReadFlag(MessageId m, boolean read) throws DbException {
messageLock.writeLock().lock();
try {
@@ -1925,31 +1795,6 @@ DatabaseCleaner.Callback {
}
}
/**
* Updates the sendability of all group messages posted by the given
* author, and the ancestors of those messages if necessary.
* <p>
* Locking: message write.
* @param increment true if the user's rating for the author has changed
* from not good to good, or false if it has changed from good to not good.
*/
private void updateAuthorSendability(T txn, AuthorId a, boolean increment)
throws DbException {
for(MessageId id : db.getGroupMessages(txn, a)) {
int sendability = db.getSendability(txn, id);
if(increment) {
db.setSendability(txn, id, sendability + 1);
if(sendability == 0)
updateAncestorSendability(txn, id, true);
} else {
assert sendability > 0;
db.setSendability(txn, id, sendability - 1);
if(sendability == 1)
updateAncestorSendability(txn, id, false);
}
}
}
public boolean setStarredFlag(MessageId m, boolean starred)
throws DbException {
messageLock.writeLock().lock();
@@ -2134,7 +1979,7 @@ DatabaseCleaner.Callback {
try {
expired = db.getOldMessages(txn, size);
if(!expired.isEmpty()) {
for(MessageId m : expired) removeMessage(txn, m);
for(MessageId m : expired) db.removeMessage(txn, m);
db.incrementRetentionVersions(txn);
if(LOG.isLoggable(INFO))
LOG.info("Expired " + expired.size() + " messages");
@@ -2155,19 +2000,6 @@ DatabaseCleaner.Callback {
return true;
}
/**
* Removes the given message (and all associated state) from the database.
* <p>
* Locking: message write.
*/
private void removeMessage(T txn, MessageId m) throws DbException {
int sendability = db.getSendability(txn, m);
// If the message is sendable, deleting it may affect its ancestors'
// sendability (backward inclusion)
if(sendability > 0) updateAncestorSendability(txn, m, false);
db.removeMessage(txn, m);
}
public boolean shouldCheckFreeSpace() {
synchronized(spaceLock) {
long now = clock.currentTimeMillis();

View File

@@ -6,7 +6,6 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.sf.briar.api.messaging.MessagingConstants.MAX_SUBSCRIPTIONS;
import static net.sf.briar.api.messaging.MessagingConstants.RETENTION_MODULUS;
import static net.sf.briar.api.messaging.Rating.UNRATED;
import static net.sf.briar.db.ExponentialBackoff.calculateExpiry;
import java.io.IOException;
@@ -45,7 +44,6 @@ import net.sf.briar.api.messaging.GroupId;
import net.sf.briar.api.messaging.GroupStatus;
import net.sf.briar.api.messaging.Message;
import net.sf.briar.api.messaging.MessageId;
import net.sf.briar.api.messaging.Rating;
import net.sf.briar.api.messaging.RetentionAck;
import net.sf.briar.api.messaging.RetentionUpdate;
import net.sf.briar.api.messaging.SubscriptionAck;
@@ -154,7 +152,6 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " bodyLength INT NOT NULL,"
+ " raw BLOB NOT NULL,"
+ " incoming BOOLEAN NOT NULL,"
+ " sendability INT UNSIGNED," // Null for private messages
+ " contactId INT UNSIGNED," // Null for group messages
+ " read BOOLEAN NOT NULL,"
+ " starred BOOLEAN NOT NULL,"
@@ -166,18 +163,12 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " REFERENCES contacts (contactId)"
+ " ON DELETE CASCADE)";
private static final String INDEX_MESSAGES_BY_PARENT =
"CREATE INDEX messagesByParent ON messages (parentId)";
private static final String INDEX_MESSAGES_BY_AUTHOR =
"CREATE INDEX messagesByAuthor ON messages (authorId)";
private static final String INDEX_MESSAGES_BY_TIMESTAMP =
"CREATE INDEX messagesByTimestamp ON messages (timestamp)";
private static final String INDEX_MESSAGES_BY_SENDABILITY =
"CREATE INDEX messagesBySendability ON messages (sendability)";
// Locking: message
private static final String CREATE_MESSAGES_TO_ACK =
"CREATE TABLE messagesToAck"
@@ -210,13 +201,6 @@ abstract class JdbcDatabase implements Database<Connection> {
private static final String INDEX_STATUSES_BY_CONTACT =
"CREATE INDEX statusesByContact ON statuses (contactId)";
// Locking: rating
private static final String CREATE_RATINGS =
"CREATE TABLE ratings"
+ " (authorId HASH NOT NULL,"
+ " rating SMALLINT NOT NULL,"
+ " PRIMARY KEY (authorId))";
// Locking: retention
private static final String CREATE_RETENTION_VERSIONS =
"CREATE TABLE retentionVersions"
@@ -403,15 +387,12 @@ abstract class JdbcDatabase implements Database<Connection> {
s.executeUpdate(insertTypeNames(CREATE_CONTACT_GROUPS));
s.executeUpdate(insertTypeNames(CREATE_GROUP_VERSIONS));
s.executeUpdate(insertTypeNames(CREATE_MESSAGES));
s.executeUpdate(INDEX_MESSAGES_BY_PARENT);
s.executeUpdate(INDEX_MESSAGES_BY_AUTHOR);
s.executeUpdate(INDEX_MESSAGES_BY_TIMESTAMP);
s.executeUpdate(INDEX_MESSAGES_BY_SENDABILITY);
s.executeUpdate(insertTypeNames(CREATE_MESSAGES_TO_ACK));
s.executeUpdate(insertTypeNames(CREATE_STATUSES));
s.executeUpdate(INDEX_STATUSES_BY_MESSAGE);
s.executeUpdate(INDEX_STATUSES_BY_CONTACT);
s.executeUpdate(insertTypeNames(CREATE_RATINGS));
s.executeUpdate(insertTypeNames(CREATE_RETENTION_VERSIONS));
s.executeUpdate(insertTypeNames(CREATE_TRANSPORTS));
s.executeUpdate(insertTypeNames(CREATE_TRANSPORT_CONFIGS));
@@ -681,8 +662,8 @@ abstract class JdbcDatabase implements Database<Connection> {
String sql = "INSERT INTO messages (messageId, parentId, groupId,"
+ " authorId, authorName, authorKey, contentType, subject,"
+ " timestamp, length, bodyStart, bodyLength, raw,"
+ " incoming, sendability, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0,"
+ " incoming, read, starred)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
+ " FALSE, FALSE)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getId().getBytes());
@@ -1307,12 +1288,10 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT messageId, parentId, m.authorId, authorName,"
+ " authorKey, rating, contentType, subject, timestamp,"
+ " read, starred"
+ " FROM messages AS m"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON m.authorId = r.authorId"
String sql = "SELECT messageId, parentId, authorId, authorName,"
+ " authorKey, contentType, subject, timestamp, read,"
+ " starred"
+ " FROM messages"
+ " WHERE groupId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, g.getBytes());
@@ -1324,27 +1303,22 @@ abstract class JdbcDatabase implements Database<Connection> {
byte[] b = rs.getBytes(2);
MessageId parent = b == null ? null : new MessageId(b);
Author author;
Rating rating;
b = rs.getBytes(3);
if(b == null) {
author = null;
rating = UNRATED;
} else {
AuthorId authorId = new AuthorId(b);
String authorName = rs.getString(4);
byte[] authorKey = rs.getBytes(5);
author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
rating = Rating.values()[rs.getByte(6)];
}
String contentType = rs.getString(7);
String subject = rs.getString(8);
long timestamp = rs.getLong(9);
boolean read = rs.getBoolean(10);
boolean starred = rs.getBoolean(11);
String contentType = rs.getString(6);
String subject = rs.getString(7);
long timestamp = rs.getLong(8);
boolean read = rs.getBoolean(9);
boolean starred = rs.getBoolean(10);
headers.add(new GroupMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
g));
contentType, subject, timestamp, read, starred, g));
}
rs.close();
ps.close();
@@ -1626,7 +1600,6 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE cg.contactId = ?"
+ " AND timestamp >= retention"
+ " AND seen = FALSE AND s.expiry < ?"
+ " AND sendability > 0"
+ " ORDER BY timestamp DESC LIMIT ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
@@ -1644,41 +1617,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public int getNumberOfSendableChildren(Connection txn, MessageId m)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
// Children in other groups should not be counted
String sql = "SELECT groupId FROM messages WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
rs = ps.executeQuery();
if(!rs.next()) throw new DbStateException();
byte[] groupId = rs.getBytes(1);
if(rs.next()) throw new DbStateException();
rs.close();
ps.close();
sql = "SELECT COUNT (messageId) FROM messages"
+ " WHERE parentId = ? AND groupId = ?"
+ " AND sendability > 0";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
ps.setBytes(2, groupId);
rs = ps.executeQuery();
if(!rs.next()) throw new DbStateException();
int count = rs.getInt(1);
if(rs.next()) throw new DbStateException();
rs.close();
ps.close();
return count;
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public Collection<MessageId> getOldMessages(Connection txn, int capacity)
throws DbException {
PreparedStatement ps = null;
@@ -1713,13 +1651,10 @@ abstract class JdbcDatabase implements Database<Connection> {
try {
// Get the incoming message headers
String sql = "SELECT m.messageId, parentId, contentType, subject,"
+ " timestamp, read, starred, c.authorId, name, publicKey,"
+ " rating"
+ " timestamp, read, starred, c.authorId, name, publicKey"
+ " FROM messages AS m"
+ " JOIN contacts AS c"
+ " ON m.contactId = c.contactId"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON c.authorId = r.authorId"
+ " WHERE m.contactId = ?"
+ " AND groupId IS NULL"
+ " AND incoming = TRUE";
@@ -1741,25 +1676,21 @@ abstract class JdbcDatabase implements Database<Connection> {
String authorName = rs.getString(9);
byte[] authorKey = rs.getBytes(10);
Author author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
Rating rating = Rating.values()[rs.getByte(11)];
headers.add(new PrivateMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
c, true));
contentType, subject, timestamp, read, starred, c,
true));
}
rs.close();
ps.close();
// Get the outgoing message headers
sql = "SELECT m.messageId, parentId, contentType, subject,"
+ " timestamp, read, starred, a.authorId, a.name,"
+ " a.publicKey, rating"
+ " a.publicKey"
+ " FROM messages AS m"
+ " JOIN contacts AS c"
+ " ON m.contactId = c.contactId"
+ " JOIN localAuthors AS a"
+ " ON c.localAuthorId = a.authorId"
+ " LEFT OUTER JOIN ratings AS r"
+ " ON c.localAuthorId = r.authorId"
+ " WHERE m.contactId = ?"
+ " AND groupId IS NULL"
+ " AND incoming = FALSE";
@@ -1779,11 +1710,9 @@ abstract class JdbcDatabase implements Database<Connection> {
String authorName = rs.getString(9);
byte[] authorKey = rs.getBytes(10);
Author author = new Author(authorId, authorName, authorKey);
// NULL == 0 == UNRATED
Rating rating = Rating.values()[rs.getByte(11)];
headers.add(new PrivateMessageHeader(id, parent, author,
contentType, subject, timestamp, read, starred, rating,
c, false));
contentType, subject, timestamp, read, starred, c,
false));
}
rs.close();
ps.close();
@@ -1795,28 +1724,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Rating getRating(Connection txn, AuthorId a) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT rating FROM ratings WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getBytes());
rs = ps.executeQuery();
Rating r;
if(rs.next()) r = Rating.values()[rs.getByte(1)];
else r = UNRATED;
if(rs.next()) throw new DbStateException();
rs.close();
ps.close();
return r;
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public byte[] getRawMessage(Connection txn, MessageId m)
throws DbException {
PreparedStatement ps = null;
@@ -1883,8 +1790,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE m.messageId = ?"
+ " AND cg.contactId = ?"
+ " AND timestamp >= retention"
+ " AND seen = FALSE AND s.expiry < ?"
+ " AND sendability > 0";
+ " AND seen = FALSE AND s.expiry < ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
ps.setInt(2, c.getInt());
@@ -2080,27 +1986,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public int getSendability(Connection txn, MessageId m) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT sendability FROM messages WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, m.getBytes());
rs = ps.executeQuery();
if(!rs.next()) throw new DbStateException();
int sendability = rs.getInt(1);
if(rs.next()) throw new DbStateException();
rs.close();
ps.close();
return sendability;
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public Collection<MessageId> getSendableMessages(Connection txn,
ContactId c, int maxLength) throws DbException {
long now = clock.currentTimeMillis();
@@ -2143,7 +2028,6 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE cg.contactId = ?"
+ " AND timestamp >= retention"
+ " AND seen = FALSE AND s.expiry < ?"
+ " AND sendability > 0"
+ " ORDER BY timestamp DESC";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
@@ -2587,7 +2471,6 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " WHERE cg.contactId = ?"
+ " AND timestamp >= retention"
+ " AND seen = FALSE AND s.expiry < ?"
+ " AND sendability > 0"
+ " LIMIT 1";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
@@ -2940,53 +2823,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public Rating setRating(Connection txn, AuthorId a, Rating r)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT rating FROM ratings WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getBytes());
rs = ps.executeQuery();
Rating old = UNRATED;
boolean exists = false;
if(rs.next()) {
old = Rating.values()[rs.getByte(1)];
exists = true;
}
if(rs.next()) throw new DbStateException();
rs.close();
ps.close();
if(old == r) return old;
if(exists) {
// A rating row exists - update it
sql = "UPDATE ratings SET rating = ? WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setByte(1, (byte) r.ordinal());
ps.setBytes(2, a.getBytes());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
} else {
// No rating row exists - create one
sql = "INSERT INTO ratings (authorId, rating)"
+ " VALUES (?, ?)";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getBytes());
ps.setByte(2, (byte) r.ordinal());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
}
return old;
} catch(SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}
}
public boolean setReadFlag(Connection txn, MessageId m, boolean read)
throws DbException {
PreparedStatement ps = null;
@@ -3181,24 +3017,6 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setSendability(Connection txn, MessageId m, int sendability)
throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE messages SET sendability = ?"
+ " WHERE messageId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, sendability);
ps.setBytes(2, m.getBytes());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
} catch(SQLException e) {
tryToClose(ps);
throw new DbException(e);
}
}
public boolean setStarredFlag(Connection txn, MessageId m, boolean starred)
throws DbException {
PreparedStatement ps = null;

View File

@@ -9,7 +9,6 @@ import static net.sf.briar.api.TransportPropertyConstants.MAX_PROPERTIES_PER_TRA
import static net.sf.briar.api.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static net.sf.briar.api.invitation.InvitationConstants.CONNECTION_TIMEOUT;
import static net.sf.briar.api.invitation.InvitationConstants.HASH_LENGTH;
import static net.sf.briar.api.messaging.Rating.GOOD;
import java.io.IOException;
import java.security.GeneralSecurityException;
@@ -263,8 +262,6 @@ abstract class Connector extends Thread {
long epoch, boolean alice) throws DbException {
// Add the contact to the database
contactId = db.addContact(remoteAuthor, localAuthor.getId());
// Add a positive rating for the contact's pseudonym
db.setRating(remoteAuthor.getId(), GOOD);
// Store the remote transport properties
db.setRemoteProperties(contactId, remoteProps);
// Create an endpoint for each transport shared with the contact

View File

@@ -3,7 +3,6 @@ package net.sf.briar.messaging.duplex;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.sf.briar.api.messaging.MessagingConstants.MAX_PACKET_LENGTH;
import static net.sf.briar.api.messaging.Rating.GOOD;
import java.io.IOException;
import java.io.InputStream;
@@ -35,7 +34,6 @@ import net.sf.briar.api.db.event.LocalTransportsUpdatedEvent;
import net.sf.briar.api.db.event.MessageExpiredEvent;
import net.sf.briar.api.db.event.MessageReceivedEvent;
import net.sf.briar.api.db.event.PrivateMessageAddedEvent;
import net.sf.briar.api.db.event.RatingChangedEvent;
import net.sf.briar.api.db.event.RemoteRetentionTimeUpdatedEvent;
import net.sf.briar.api.db.event.RemoteSubscriptionsUpdatedEvent;
import net.sf.briar.api.db.event.RemoteTransportsUpdatedEvent;
@@ -157,10 +155,6 @@ abstract class DuplexConnection implements DatabaseListener {
if(canSendOffer.getAndSet(false))
dbExecutor.execute(new GenerateOffer());
}
} else if(e instanceof RatingChangedEvent) {
RatingChangedEvent r = (RatingChangedEvent) e;
if(r.getRating() == GOOD && canSendOffer.getAndSet(false))
dbExecutor.execute(new GenerateOffer());
} else if(e instanceof RemoteRetentionTimeUpdatedEvent) {
dbExecutor.execute(new GenerateRetentionAck());
} else if(e instanceof RemoteSubscriptionsUpdatedEvent) {