From 8ec40587b2280b6a97e336ebe4e98caec543138a Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Tue, 13 Sep 2011 16:15:50 +0100 Subject: [PATCH] Check for sendable private messages as well as group messages. --- components/net/sf/briar/db/Database.java | 5 +- components/net/sf/briar/db/JdbcDatabase.java | 83 +++++++++++++++----- test/net/sf/briar/db/H2DatabaseTest.java | 1 - 3 files changed, 65 insertions(+), 24 deletions(-) diff --git a/components/net/sf/briar/db/Database.java b/components/net/sf/briar/db/Database.java index 2d9015362c..042a2a2ed9 100644 --- a/components/net/sf/briar/db/Database.java +++ b/components/net/sf/briar/db/Database.java @@ -264,9 +264,8 @@ interface Database<T> { Rating getRating(T txn, AuthorId a) throws DbException; /** - * Returns the sendability score of the given message. Messages with - * sendability scores greater than zero are eligible to be sent to - * contacts. + * Returns the sendability score of the given message. Group messages with + * sendability scores greater than zero are eligible to be sent to contacts. * <p> * Locking: messages read. */ diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java index 2ff792ff9f..13e8b13bb6 100644 --- a/components/net/sf/briar/db/JdbcDatabase.java +++ b/components/net/sf/briar/db/JdbcDatabase.java @@ -936,26 +936,47 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { + // Do we have a sendable private message with the given ID? String sql = "SELECT size, raw FROM messages" + + " JOIN statuses ON messages.messageId = statuses.messageId" + + " WHERE messages.messageId = ? AND messages.contactId = ?" + + " AND status = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, m.getBytes()); + ps.setInt(2, c.getInt()); + ps.setShort(3, (short) Status.NEW.ordinal()); + rs = ps.executeQuery(); + byte[] raw = null; + if(rs.next()) { + int size = rs.getInt(1); + Blob b = rs.getBlob(2); + raw = b.getBytes(1, size); + if(raw.length != size) throw new DbStateException(); + } + if(rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + if(raw != null) return raw; + // Do we have a sendable group message with the given ID? + sql = "SELECT size, raw FROM messages" + " JOIN contactSubscriptions" + " ON messages.groupId = contactSubscriptions.groupId" + " JOIN visibilities" + " ON messages.groupId = visibilities.groupId" - + " JOIN statuses ON messages.messageId = statuses.messageId" + + " AND contactSubscriptions.contactId = visibilities.contactId" + + " JOIN statuses" + + " ON messages.messageId = statuses.messageId" + + " AND contactSubscriptions.contactId = statuses.contactId" + " WHERE messages.messageId = ?" + " AND contactSubscriptions.contactId = ?" - + " AND visibilities.contactId = ?" - + " AND statuses.contactId = ?" + " AND timestamp >= start" - + " AND status = ? AND sendability > ZERO()"; + + " AND status = ?" + + " AND sendability > ZERO()"; ps = txn.prepareStatement(sql); ps.setBytes(1, m.getBytes()); ps.setInt(2, c.getInt()); - ps.setInt(3, c.getInt()); - ps.setInt(4, c.getInt()); - ps.setShort(5, (short) Status.NEW.ordinal()); + ps.setShort(3, (short) Status.NEW.ordinal()); rs = ps.executeQuery(); - byte[] raw = null; if(rs.next()) { int size = rs.getInt(1); Blob b = rs.getBlob(2); @@ -1091,7 +1112,7 @@ abstract class JdbcDatabase implements Database<Connection> { if(rs.next()) throw new DbStateException(); rs.close(); ps.close(); - return new MessageId(parent); + return parent == null ? null : new MessageId(parent); } catch(SQLException e) { tryToClose(rs); tryToClose(ps); @@ -1169,26 +1190,48 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { + // Do we have any sendable private messages? String sql = "SELECT size, messages.messageId FROM messages" + + " JOIN statuses ON messages.messageId = statuses.messageId" + + " WHERE messages.contactId = ? AND status = ?" + + " ORDER BY timestamp"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + ps.setShort(2, (short) Status.NEW.ordinal()); + rs = ps.executeQuery(); + Collection<MessageId> ids = new ArrayList<MessageId>(); + int total = 0; + while(rs.next()) { + int size = rs.getInt(1); + if(total + size > capacity) break; + ids.add(new MessageId(rs.getBytes(2))); + total += size; + } + rs.close(); + ps.close(); + if(LOG.isLoggable(Level.FINE)) + LOG.fine(ids.size() + " sendable private messages, " + + total + "/" + capacity + " bytes"); + if(total == capacity) return ids; + // Do we have any sendable group messages? + sql = "SELECT size, messages.messageId FROM messages" + " JOIN contactSubscriptions" + " ON messages.groupId = contactSubscriptions.groupId" + " JOIN visibilities" + " ON messages.groupId = visibilities.groupId" - + " JOIN statuses ON messages.messageId = statuses.messageId" + + " AND contactSubscriptions.contactId = visibilities.contactId" + + " JOIN statuses" + + " ON messages.messageId = statuses.messageId" + + " AND contactSubscriptions.contactId = statuses.contactId" + " WHERE contactSubscriptions.contactId = ?" - + " AND visibilities.contactId = ?" - + " AND statuses.contactId = ?" + " AND timestamp >= start" - + " AND status = ? AND sendability > ZERO()" + + " AND status = ?" + + " AND sendability > ZERO()" + " ORDER BY timestamp"; ps = txn.prepareStatement(sql); ps.setInt(1, c.getInt()); - ps.setInt(2, c.getInt()); - ps.setInt(3, c.getInt()); - ps.setShort(4, (short) Status.NEW.ordinal()); + ps.setShort(2, (short) Status.NEW.ordinal()); rs = ps.executeQuery(); - Collection<MessageId> ids = new ArrayList<MessageId>(); - int total = 0; while(rs.next()) { int size = rs.getInt(1); if(total + size > capacity) break; @@ -1198,8 +1241,8 @@ abstract class JdbcDatabase implements Database<Connection> { rs.close(); ps.close(); if(LOG.isLoggable(Level.FINE)) - LOG.fine(ids.size() + " sendable messages, " + total + "/" + - capacity + " bytes"); + LOG.fine(ids.size() + " sendable private and group messages, " + + total + "/" + capacity + " bytes"); return ids; } catch(SQLException e) { tryToClose(rs); diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java index 09e8c52f3e..ad49d1b497 100644 --- a/test/net/sf/briar/db/H2DatabaseTest.java +++ b/test/net/sf/briar/db/H2DatabaseTest.java @@ -220,7 +220,6 @@ public class H2DatabaseTest extends TestCase { db.setStatus(txn, contactId, messageId, Status.NEW); // The message should not be sendable - assertEquals(0, db.getSendability(txn, messageId)); assertFalse(db.hasSendableMessages(txn, contactId)); Iterator<MessageId> it = db.getSendableMessages(txn, contactId, ONE_MEGABYTE).iterator(); -- GitLab