mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Allow messages to be marked as temporary.
This commit is contained in:
@@ -77,7 +77,7 @@ public interface DatabaseComponent extends TransactionManager {
|
|||||||
* Stores a local message.
|
* Stores a local message.
|
||||||
*/
|
*/
|
||||||
void addLocalMessage(Transaction txn, Message m, Metadata meta,
|
void addLocalMessage(Transaction txn, Message m, Metadata meta,
|
||||||
boolean shared) throws DbException;
|
boolean shared, boolean temporary) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a pending contact.
|
* Stores a pending contact.
|
||||||
@@ -510,6 +510,12 @@ public interface DatabaseComponent extends TransactionManager {
|
|||||||
void removePendingContact(Transaction txn, PendingContactId p)
|
void removePendingContact(Transaction txn, PendingContactId p)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all temporary messages (and all associated state) from the
|
||||||
|
* database.
|
||||||
|
*/
|
||||||
|
void removeTemporaryMessages(Transaction txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a transport (and all associated state) from the database.
|
* Removes a transport (and all associated state) from the database.
|
||||||
*/
|
*/
|
||||||
@@ -538,6 +544,11 @@ public interface DatabaseComponent extends TransactionManager {
|
|||||||
void setGroupVisibility(Transaction txn, ContactId c, GroupId g,
|
void setGroupVisibility(Transaction txn, ContactId c, GroupId g,
|
||||||
Visibility v) throws DbException;
|
Visibility v) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the given message as permanent, i.e. not temporary.
|
||||||
|
*/
|
||||||
|
void setMessagePermanent(Transaction txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given message as shared.
|
* Marks the given message as shared.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
public void addLocalMessage(Transaction txn, Message m,
|
public void addLocalMessage(Transaction txn, Message m,
|
||||||
BdfDictionary metadata, boolean shared)
|
BdfDictionary metadata, boolean shared)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
db.addLocalMessage(txn, m, metadataEncoder.encode(metadata), shared);
|
db.addLocalMessage(txn, m, metadataEncoder.encode(metadata), shared,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ interface Database<T> {
|
|||||||
* if the message was created locally.
|
* if the message was created locally.
|
||||||
*/
|
*/
|
||||||
void addMessage(T txn, Message m, MessageState state, boolean shared,
|
void addMessage(T txn, Message m, MessageState state, boolean shared,
|
||||||
@Nullable ContactId sender) throws DbException;
|
boolean temporary, @Nullable ContactId sender) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a dependency between two messages, where the dependent message is
|
* Adds a dependency between two messages, where the dependent message is
|
||||||
@@ -630,6 +630,12 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
void removePendingContact(T txn, PendingContactId p) throws DbException;
|
void removePendingContact(T txn, PendingContactId p) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all temporary messages (and all associated state) from the
|
||||||
|
* database.
|
||||||
|
*/
|
||||||
|
void removeTemporaryMessages(T txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a transport (and all associated state) from the database.
|
* Removes a transport (and all associated state) from the database.
|
||||||
*/
|
*/
|
||||||
@@ -671,6 +677,11 @@ interface Database<T> {
|
|||||||
void setHandshakeKeyPair(T txn, AuthorId local, PublicKey publicKey,
|
void setHandshakeKeyPair(T txn, AuthorId local, PublicKey publicKey,
|
||||||
PrivateKey privateKey) throws DbException;
|
PrivateKey privateKey) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the given message as permanent, i.e. not temporary.
|
||||||
|
*/
|
||||||
|
void setMessagePermanent(T txn, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given message as shared.
|
* Marks the given message as shared.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -273,13 +273,14 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLocalMessage(Transaction transaction, Message m,
|
public void addLocalMessage(Transaction transaction, Message m,
|
||||||
Metadata meta, boolean shared) throws DbException {
|
Metadata meta, boolean shared, boolean temporary)
|
||||||
|
throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsGroup(txn, m.getGroupId()))
|
if (!db.containsGroup(txn, m.getGroupId()))
|
||||||
throw new NoSuchGroupException();
|
throw new NoSuchGroupException();
|
||||||
if (!db.containsMessage(txn, m.getId())) {
|
if (!db.containsMessage(txn, m.getId())) {
|
||||||
db.addMessage(txn, m, DELIVERED, shared, null);
|
db.addMessage(txn, m, DELIVERED, shared, temporary, null);
|
||||||
transaction.attach(new MessageAddedEvent(m, null));
|
transaction.attach(new MessageAddedEvent(m, null));
|
||||||
transaction.attach(new MessageStateChangedEvent(m.getId(), true,
|
transaction.attach(new MessageStateChangedEvent(m.getId(), true,
|
||||||
DELIVERED));
|
DELIVERED));
|
||||||
@@ -800,7 +801,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
db.raiseSeenFlag(txn, c, m.getId());
|
db.raiseSeenFlag(txn, c, m.getId());
|
||||||
db.raiseAckFlag(txn, c, m.getId());
|
db.raiseAckFlag(txn, c, m.getId());
|
||||||
} else {
|
} else {
|
||||||
db.addMessage(txn, m, UNKNOWN, false, c);
|
db.addMessage(txn, m, UNKNOWN, false, false, c);
|
||||||
transaction.attach(new MessageAddedEvent(m, c));
|
transaction.attach(new MessageAddedEvent(m, c));
|
||||||
}
|
}
|
||||||
transaction.attach(new MessageToAckEvent(c));
|
transaction.attach(new MessageToAckEvent(c));
|
||||||
@@ -908,6 +909,14 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
transaction.attach(new PendingContactRemovedEvent(p));
|
transaction.attach(new PendingContactRemovedEvent(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeTemporaryMessages(Transaction transaction)
|
||||||
|
throws DbException {
|
||||||
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
db.removeTemporaryMessages(txn);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeTransport(Transaction transaction, TransportId t)
|
public void removeTransport(Transaction transaction, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
@@ -967,6 +976,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMessagePermanent(Transaction transaction, MessageId m)
|
||||||
|
throws DbException {
|
||||||
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
if (!db.containsMessage(txn, m))
|
||||||
|
throw new NoSuchMessageException();
|
||||||
|
db.setMessagePermanent(txn, m);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageShared(Transaction transaction, MessageId m)
|
public void setMessageShared(Transaction transaction, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
@@ -975,8 +994,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
if (!db.containsMessage(txn, m))
|
if (!db.containsMessage(txn, m))
|
||||||
throw new NoSuchMessageException();
|
throw new NoSuchMessageException();
|
||||||
if (db.getMessageState(txn, m) != DELIVERED)
|
if (db.getMessageState(txn, m) != DELIVERED)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("Shared undelivered message");
|
||||||
"Shared undelivered message");
|
|
||||||
db.setMessageShared(txn, m);
|
db.setMessageShared(txn, m);
|
||||||
transaction.attach(new MessageSharedEvent(m));
|
transaction.attach(new MessageSharedEvent(m));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
|
|
||||||
import static java.sql.Types.BINARY;
|
import static java.sql.Types.BINARY;
|
||||||
import static java.sql.Types.BOOLEAN;
|
import static java.sql.Types.BOOLEAN;
|
||||||
@@ -97,7 +98,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
abstract class JdbcDatabase implements Database<Connection> {
|
abstract class JdbcDatabase implements Database<Connection> {
|
||||||
|
|
||||||
// Package access for testing
|
// Package access for testing
|
||||||
static final int CODE_SCHEMA_VERSION = 45;
|
static final int CODE_SCHEMA_VERSION = 46;
|
||||||
|
|
||||||
// Time period offsets for incoming transport keys
|
// Time period offsets for incoming transport keys
|
||||||
private static final int OFFSET_PREV = -1;
|
private static final int OFFSET_PREV = -1;
|
||||||
@@ -177,6 +178,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " timestamp BIGINT NOT NULL,"
|
+ " timestamp BIGINT NOT NULL,"
|
||||||
+ " state INT NOT NULL,"
|
+ " state INT NOT NULL,"
|
||||||
+ " shared BOOLEAN NOT NULL,"
|
+ " shared BOOLEAN NOT NULL,"
|
||||||
|
+ " temporary BOOLEAN NOT NULL,"
|
||||||
+ " length INT NOT NULL,"
|
+ " length INT NOT NULL,"
|
||||||
+ " raw BLOB," // Null if message has been deleted
|
+ " raw BLOB," // Null if message has been deleted
|
||||||
+ " PRIMARY KEY (messageId),"
|
+ " PRIMARY KEY (messageId),"
|
||||||
@@ -336,25 +338,26 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(JdbcDatabase.class.getName());
|
getLogger(JdbcDatabase.class.getName());
|
||||||
|
|
||||||
// Different database libraries use different names for certain types
|
|
||||||
private final MessageFactory messageFactory;
|
private final MessageFactory messageFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final DatabaseTypes dbTypes;
|
private final DatabaseTypes dbTypes;
|
||||||
|
|
||||||
// Locking: connectionsLock
|
private final Lock connectionsLock = new ReentrantLock();
|
||||||
|
private final Condition connectionsChanged = connectionsLock.newCondition();
|
||||||
|
|
||||||
|
@GuardedBy("connectionsLock")
|
||||||
private final LinkedList<Connection> connections = new LinkedList<>();
|
private final LinkedList<Connection> connections = new LinkedList<>();
|
||||||
|
|
||||||
private int openConnections = 0; // Locking: connectionsLock
|
@GuardedBy("connectionsLock")
|
||||||
private boolean closed = false; // Locking: connectionsLock
|
private int openConnections = 0;
|
||||||
|
@GuardedBy("connectionsLock")
|
||||||
|
private boolean closed = false;
|
||||||
|
|
||||||
protected abstract Connection createConnection()
|
protected abstract Connection createConnection()
|
||||||
throws DbException, SQLException;
|
throws DbException, SQLException;
|
||||||
|
|
||||||
protected abstract void compactAndClose() throws DbException;
|
protected abstract void compactAndClose() throws DbException;
|
||||||
|
|
||||||
private final Lock connectionsLock = new ReentrantLock();
|
|
||||||
private final Condition connectionsChanged = connectionsLock.newCondition();
|
|
||||||
|
|
||||||
JdbcDatabase(DatabaseTypes databaseTypes, MessageFactory messageFactory,
|
JdbcDatabase(DatabaseTypes databaseTypes, MessageFactory messageFactory,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
this.dbTypes = databaseTypes;
|
this.dbTypes = databaseTypes;
|
||||||
@@ -457,7 +460,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
new Migration41_42(dbTypes),
|
new Migration41_42(dbTypes),
|
||||||
new Migration42_43(dbTypes),
|
new Migration42_43(dbTypes),
|
||||||
new Migration43_44(dbTypes),
|
new Migration43_44(dbTypes),
|
||||||
new Migration44_45()
|
new Migration44_45(),
|
||||||
|
new Migration45_46()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,22 +781,23 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMessage(Connection txn, Message m, MessageState state,
|
public void addMessage(Connection txn, Message m, MessageState state,
|
||||||
boolean messageShared, @Nullable ContactId sender)
|
boolean shared, boolean temporary, @Nullable ContactId sender)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
String sql = "INSERT INTO messages (messageId, groupId, timestamp,"
|
String sql = "INSERT INTO messages (messageId, groupId, timestamp,"
|
||||||
+ " state, shared, length, raw)"
|
+ " state, shared, temporary, length, raw)"
|
||||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?)";
|
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, m.getId().getBytes());
|
ps.setBytes(1, m.getId().getBytes());
|
||||||
ps.setBytes(2, m.getGroupId().getBytes());
|
ps.setBytes(2, m.getGroupId().getBytes());
|
||||||
ps.setLong(3, m.getTimestamp());
|
ps.setLong(3, m.getTimestamp());
|
||||||
ps.setInt(4, state.getValue());
|
ps.setInt(4, state.getValue());
|
||||||
ps.setBoolean(5, messageShared);
|
ps.setBoolean(5, shared);
|
||||||
|
ps.setBoolean(6, temporary);
|
||||||
byte[] raw = messageFactory.getRawMessage(m);
|
byte[] raw = messageFactory.getRawMessage(m);
|
||||||
ps.setInt(6, raw.length);
|
ps.setInt(7, raw.length);
|
||||||
ps.setBytes(7, raw);
|
ps.setBytes(8, raw);
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -804,8 +809,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
boolean offered = removeOfferedMessage(txn, c, m.getId());
|
boolean offered = removeOfferedMessage(txn, c, m.getId());
|
||||||
boolean seen = offered || c.equals(sender);
|
boolean seen = offered || c.equals(sender);
|
||||||
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
|
addStatus(txn, m.getId(), c, m.getGroupId(), m.getTimestamp(),
|
||||||
raw.length, state, e.getValue(), messageShared,
|
raw.length, state, e.getValue(), shared, false, seen);
|
||||||
false, seen);
|
|
||||||
}
|
}
|
||||||
// Update denormalised column in messageDependencies if dependency
|
// Update denormalised column in messageDependencies if dependency
|
||||||
// is in same group as dependent
|
// is in same group as dependent
|
||||||
@@ -2876,6 +2880,21 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeTemporaryMessages(Connection txn) throws DbException {
|
||||||
|
Statement s = null;
|
||||||
|
try {
|
||||||
|
String sql = "DELETE FROM messages WHERE temporary = TRUE";
|
||||||
|
s = txn.createStatement();
|
||||||
|
int affected = s.executeUpdate(sql);
|
||||||
|
if (affected < 0) throw new DbStateException();
|
||||||
|
s.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(s, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeTransport(Connection txn, TransportId t)
|
public void removeTransport(Connection txn, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
@@ -3021,6 +3040,24 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMessagePermanent(Connection txn, MessageId m)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE messages SET temporary = FALSE"
|
||||||
|
+ " WHERE messageId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, m.getBytes());
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMessageShared(Connection txn, MessageId m)
|
public void setMessageShared(Connection txn, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
|
class Migration45_46 implements Migration<Connection> {
|
||||||
|
|
||||||
|
private static final Logger LOG = getLogger(Migration45_46.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStartVersion() {
|
||||||
|
return 45;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEndVersion() {
|
||||||
|
return 46;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void migrate(Connection txn) throws DbException {
|
||||||
|
Statement s = null;
|
||||||
|
try {
|
||||||
|
s = txn.createStatement();
|
||||||
|
s.execute("ALTER TABLE messages"
|
||||||
|
+ " ADD COLUMN temporary BOOLEAN NOT NULL"
|
||||||
|
+ " DEFAULT (FALSE)");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(s, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -243,7 +243,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
|||||||
try {
|
try {
|
||||||
Message m = clientHelper.createMessage(localGroup.getId(), now,
|
Message m = clientHelper.createMessage(localGroup.getId(), now,
|
||||||
body);
|
body);
|
||||||
db.addLocalMessage(txn, m, new Metadata(), false);
|
db.addLocalMessage(txn, m, new Metadata(), false, false);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
|||||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(metadata));
|
will(returnValue(metadata));
|
||||||
oneOf(db).addLocalMessage(txn, message, metadata, shared);
|
oneOf(db).addLocalMessage(txn, message, metadata, shared, false);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
clientHelper.addLocalMessage(message, dictionary, shared);
|
clientHelper.addLocalMessage(message, dictionary, shared);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@@ -120,6 +121,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
private final Contact contact;
|
private final Contact contact;
|
||||||
private final KeySetId keySetId;
|
private final KeySetId keySetId;
|
||||||
private final PendingContactId pendingContactId;
|
private final PendingContactId pendingContactId;
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
public DatabaseComponentImplTest() {
|
public DatabaseComponentImplTest() {
|
||||||
clientId = getClientId();
|
clientId = getClientId();
|
||||||
@@ -242,6 +244,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
@Test(expected = NoSuchGroupException.class)
|
@Test(expected = NoSuchGroupException.class)
|
||||||
public void testLocalMessagesAreNotStoredUnlessGroupExists()
|
public void testLocalMessagesAreNotStoredUnlessGroupExists()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
boolean shared = random.nextBoolean();
|
||||||
|
boolean temporary = random.nextBoolean();
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
@@ -253,11 +258,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
eventExecutor, shutdownManager);
|
eventExecutor, shutdownManager);
|
||||||
|
|
||||||
db.transaction(false, transaction ->
|
db.transaction(false, transaction ->
|
||||||
db.addLocalMessage(transaction, message, metadata, true));
|
db.addLocalMessage(transaction, message, metadata, shared,
|
||||||
|
temporary));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddLocalMessage() throws Exception {
|
public void testAddLocalMessage() throws Exception {
|
||||||
|
boolean shared = random.nextBoolean();
|
||||||
|
boolean temporary = random.nextBoolean();
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
@@ -265,20 +274,23 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsMessage(txn, messageId);
|
oneOf(database).containsMessage(txn, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addMessage(txn, message, DELIVERED, true, null);
|
oneOf(database).addMessage(txn, message, DELIVERED, shared,
|
||||||
|
temporary, null);
|
||||||
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
// The message was added, so the listeners should be called
|
// The message was added, so the listeners should be called
|
||||||
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
|
||||||
oneOf(eventBus)
|
oneOf(eventBus).broadcast(with(any(
|
||||||
.broadcast(with(any(MessageStateChangedEvent.class)));
|
MessageStateChangedEvent.class)));
|
||||||
oneOf(eventBus).broadcast(with(any(MessageSharedEvent.class)));
|
if (shared)
|
||||||
|
oneOf(eventBus).broadcast(with(any(MessageSharedEvent.class)));
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||||
eventExecutor, shutdownManager);
|
eventExecutor, shutdownManager);
|
||||||
|
|
||||||
db.transaction(false, transaction ->
|
db.transaction(false, transaction ->
|
||||||
db.addLocalMessage(transaction, message, metadata, true));
|
db.addLocalMessage(transaction, message, metadata, shared,
|
||||||
|
temporary));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -569,11 +581,11 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Check whether the message is in the DB (which it's not)
|
// Check whether the message is in the DB (which it's not)
|
||||||
exactly(11).of(database).startTransaction();
|
exactly(12).of(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
exactly(11).of(database).containsMessage(txn, messageId);
|
exactly(12).of(database).containsMessage(txn, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
exactly(11).of(database).abortTransaction(txn);
|
exactly(12).of(database).abortTransaction(txn);
|
||||||
// Allow other checks to pass
|
// Allow other checks to pass
|
||||||
allowing(database).containsContact(txn, contactId);
|
allowing(database).containsContact(txn, contactId);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
@@ -637,6 +649,14 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
db.transaction(false, transaction ->
|
||||||
|
db.setMessagePermanent(transaction, message.getId()));
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchMessageException expected) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.transaction(false, transaction ->
|
db.transaction(false, transaction ->
|
||||||
db.setMessageShared(transaction, message.getId()));
|
db.setMessageShared(transaction, message.getId()));
|
||||||
@@ -972,7 +992,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(VISIBLE));
|
will(returnValue(VISIBLE));
|
||||||
oneOf(database).containsMessage(txn, messageId);
|
oneOf(database).containsMessage(txn, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addMessage(txn, message, UNKNOWN, false, contactId);
|
oneOf(database).addMessage(txn, message, UNKNOWN, false, false,
|
||||||
|
contactId);
|
||||||
// Second time
|
// Second time
|
||||||
oneOf(database).containsContact(txn, contactId);
|
oneOf(database).containsContact(txn, contactId);
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
@@ -1507,6 +1528,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
public void testMessageDependencies() throws Exception {
|
public void testMessageDependencies() throws Exception {
|
||||||
int shutdownHandle = 12345;
|
int shutdownHandle = 12345;
|
||||||
MessageId messageId2 = new MessageId(getRandomId());
|
MessageId messageId2 = new MessageId(getRandomId());
|
||||||
|
boolean shared = random.nextBoolean();
|
||||||
|
boolean temporary = random.nextBoolean();
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// open()
|
// open()
|
||||||
oneOf(database).open(key, null);
|
oneOf(database).open(key, null);
|
||||||
@@ -1521,7 +1545,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsMessage(txn, messageId);
|
oneOf(database).containsMessage(txn, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addMessage(txn, message, DELIVERED, true, null);
|
oneOf(database).addMessage(txn, message, DELIVERED, shared,
|
||||||
|
temporary, null);
|
||||||
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
||||||
// addMessageDependencies()
|
// addMessageDependencies()
|
||||||
oneOf(database).containsMessage(txn, messageId);
|
oneOf(database).containsMessage(txn, messageId);
|
||||||
@@ -1544,7 +1569,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class)));
|
||||||
oneOf(eventBus).broadcast(with(any(
|
oneOf(eventBus).broadcast(with(any(
|
||||||
MessageStateChangedEvent.class)));
|
MessageStateChangedEvent.class)));
|
||||||
oneOf(eventBus).broadcast(with(any(MessageSharedEvent.class)));
|
if (shared)
|
||||||
|
oneOf(eventBus).broadcast(with(any(MessageSharedEvent.class)));
|
||||||
// endTransaction()
|
// endTransaction()
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
// close()
|
// close()
|
||||||
@@ -1555,7 +1581,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
assertFalse(db.open(key, null));
|
assertFalse(db.open(key, null));
|
||||||
db.transaction(false, transaction -> {
|
db.transaction(false, transaction -> {
|
||||||
db.addLocalMessage(transaction, message, metadata, true);
|
db.addLocalMessage(transaction, message, metadata, shared,
|
||||||
|
temporary);
|
||||||
Collection<MessageId> dependencies = new ArrayList<>(2);
|
Collection<MessageId> dependencies = new ArrayList<>(2);
|
||||||
dependencies.add(messageId1);
|
dependencies.add(messageId1);
|
||||||
dependencies.add(messageId2);
|
dependencies.add(messageId2);
|
||||||
|
|||||||
@@ -567,8 +567,9 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
MessageState state =
|
MessageState state =
|
||||||
MessageState.fromValue(random.nextInt(4));
|
MessageState.fromValue(random.nextInt(4));
|
||||||
boolean shared = random.nextBoolean();
|
boolean shared = random.nextBoolean();
|
||||||
|
boolean temporary = random.nextBoolean();
|
||||||
ContactId sender = random.nextBoolean() ? c : null;
|
ContactId sender = random.nextBoolean() ? c : null;
|
||||||
db.addMessage(txn, m, state, shared, sender);
|
db.addMessage(txn, m, state, shared, temporary, sender);
|
||||||
if (random.nextBoolean())
|
if (random.nextBoolean())
|
||||||
db.raiseRequestedFlag(txn, c, m.getId());
|
db.raiseRequestedFlag(txn, c, m.getId());
|
||||||
Metadata mm = getMetadata(METADATA_KEYS_PER_MESSAGE);
|
Metadata mm = getMetadata(METADATA_KEYS_PER_MESSAGE);
|
||||||
@@ -597,7 +598,8 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
for (int j = 0; j < MESSAGES_PER_GROUP; j++) {
|
for (int j = 0; j < MESSAGES_PER_GROUP; j++) {
|
||||||
Message m = getMessage(g.getId());
|
Message m = getMessage(g.getId());
|
||||||
messages.add(m);
|
messages.add(m);
|
||||||
db.addMessage(txn, m, DELIVERED, false, null);
|
boolean temporary = random.nextBoolean();
|
||||||
|
db.addMessage(txn, m, DELIVERED, false, temporary, null);
|
||||||
Metadata mm = getMetadata(METADATA_KEYS_PER_MESSAGE);
|
Metadata mm = getMetadata(METADATA_KEYS_PER_MESSAGE);
|
||||||
messageMeta.get(g.getId()).add(mm);
|
messageMeta.get(g.getId()).add(mm);
|
||||||
db.mergeMessageMetadata(txn, m.getId(), mm);
|
db.mergeMessageMetadata(txn, m.getId(), mm);
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
assertTrue(db.containsGroup(txn, groupId));
|
assertTrue(db.containsGroup(txn, groupId));
|
||||||
assertFalse(db.containsMessage(txn, messageId));
|
assertFalse(db.containsMessage(txn, messageId));
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
assertTrue(db.containsMessage(txn, messageId));
|
assertTrue(db.containsMessage(txn, messageId));
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -191,7 +191,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and a message
|
// Add a group and a message
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Removing the group should remove the message
|
// Removing the group should remove the message
|
||||||
assertTrue(db.containsMessage(txn, messageId));
|
assertTrue(db.containsMessage(txn, messageId));
|
||||||
@@ -213,7 +213,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The contact has not seen the message, so it should be sendable
|
// The contact has not seen the message, so it should be sendable
|
||||||
Collection<MessageId> ids =
|
Collection<MessageId> ids =
|
||||||
@@ -244,7 +244,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, UNKNOWN, true, null);
|
db.addMessage(txn, message, UNKNOWN, true, false, null);
|
||||||
|
|
||||||
// The message has not been validated, so it should not be sendable
|
// The message has not been validated, so it should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||||
@@ -288,7 +288,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The group is invisible, so the message should not be sendable
|
// The group is invisible, so the message should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||||
@@ -340,7 +340,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, false, null);
|
db.addMessage(txn, message, DELIVERED, false, false, null);
|
||||||
|
|
||||||
// The message is not shared, so it should not be sendable
|
// The message is not shared, so it should not be sendable
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||||
@@ -371,7 +371,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The message is sendable, but too large to send
|
// The message is sendable, but too large to send
|
||||||
Collection<MessageId> ids =
|
Collection<MessageId> ids =
|
||||||
@@ -402,8 +402,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
// Add some messages to ack
|
// Add some messages to ack
|
||||||
Message message1 = getMessage(groupId);
|
Message message1 = getMessage(groupId);
|
||||||
MessageId messageId1 = message1.getId();
|
MessageId messageId1 = message1.getId();
|
||||||
db.addMessage(txn, message, DELIVERED, true, contactId);
|
db.addMessage(txn, message, DELIVERED, true, false, contactId);
|
||||||
db.addMessage(txn, message1, DELIVERED, true, contactId);
|
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
// Both message IDs should be returned
|
// Both message IDs should be returned
|
||||||
Collection<MessageId> ids = db.getMessagesToAck(txn, contactId, 1234);
|
Collection<MessageId> ids = db.getMessagesToAck(txn, contactId, 1234);
|
||||||
@@ -439,7 +439,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Retrieve the message from the database and mark it as sent
|
// Retrieve the message from the database and mark it as sent
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
||||||
@@ -608,7 +608,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The group is not visible so the message should not be visible
|
// The group is not visible so the message should not be visible
|
||||||
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
|
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
|
||||||
@@ -1223,7 +1223,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and a message
|
// Add a group and a message
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Attach some metadata to the message
|
// Attach some metadata to the message
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
@@ -1294,7 +1294,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and a message
|
// Add a group and a message
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Attach some metadata to the message
|
// Attach some metadata to the message
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
@@ -1355,8 +1355,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and two messages
|
// Add a group and two messages
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
db.addMessage(txn, message1, DELIVERED, true, null);
|
db.addMessage(txn, message1, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Attach some metadata to the messages
|
// Attach some metadata to the messages
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
@@ -1459,8 +1459,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and two messages
|
// Add a group and two messages
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
db.addMessage(txn, message1, DELIVERED, true, null);
|
db.addMessage(txn, message1, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Attach some metadata to the messages
|
// Attach some metadata to the messages
|
||||||
Metadata metadata = new Metadata();
|
Metadata metadata = new Metadata();
|
||||||
@@ -1536,9 +1536,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and some messages
|
// Add a group and some messages
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, PENDING, true, contactId);
|
db.addMessage(txn, message, PENDING, true, false, contactId);
|
||||||
db.addMessage(txn, message1, PENDING, true, contactId);
|
db.addMessage(txn, message1, PENDING, true, false, contactId);
|
||||||
db.addMessage(txn, message2, INVALID, true, contactId);
|
db.addMessage(txn, message2, INVALID, true, false, contactId);
|
||||||
|
|
||||||
// Add dependencies
|
// Add dependencies
|
||||||
db.addMessageDependency(txn, message, messageId1, PENDING);
|
db.addMessageDependency(txn, message, messageId1, PENDING);
|
||||||
@@ -1589,7 +1589,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(0, dependents.size());
|
assertEquals(0, dependents.size());
|
||||||
|
|
||||||
// Add message 3
|
// Add message 3
|
||||||
db.addMessage(txn, message3, UNKNOWN, false, contactId);
|
db.addMessage(txn, message3, UNKNOWN, false, false, contactId);
|
||||||
|
|
||||||
// Message 3 has message 1 as a dependent
|
// Message 3 has message 1 as a dependent
|
||||||
dependents = db.getMessageDependents(txn, messageId3);
|
dependents = db.getMessageDependents(txn, messageId3);
|
||||||
@@ -1601,7 +1601,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(0, dependents.size());
|
assertEquals(0, dependents.size());
|
||||||
|
|
||||||
// Add message 4
|
// Add message 4
|
||||||
db.addMessage(txn, message4, UNKNOWN, false, contactId);
|
db.addMessage(txn, message4, UNKNOWN, false, false, contactId);
|
||||||
|
|
||||||
// Message 4 has message 2 as a dependent
|
// Message 4 has message 2 as a dependent
|
||||||
dependents = db.getMessageDependents(txn, messageId4);
|
dependents = db.getMessageDependents(txn, messageId4);
|
||||||
@@ -1619,7 +1619,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and a message
|
// Add a group and a message
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, PENDING, true, contactId);
|
db.addMessage(txn, message, PENDING, true, false, contactId);
|
||||||
|
|
||||||
// Add a second group
|
// Add a second group
|
||||||
Group group1 = getGroup(clientId, 123);
|
Group group1 = getGroup(clientId, 123);
|
||||||
@@ -1629,7 +1629,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
// Add a message to the second group
|
// Add a message to the second group
|
||||||
Message message1 = getMessage(groupId1);
|
Message message1 = getMessage(groupId1);
|
||||||
MessageId messageId1 = message1.getId();
|
MessageId messageId1 = message1.getId();
|
||||||
db.addMessage(txn, message1, DELIVERED, true, contactId);
|
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
// Create an ID for a missing message
|
// Create an ID for a missing message
|
||||||
MessageId messageId2 = new MessageId(getRandomId());
|
MessageId messageId2 = new MessageId(getRandomId());
|
||||||
@@ -1637,7 +1637,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
// Add another message to the first group
|
// Add another message to the first group
|
||||||
Message message3 = getMessage(groupId);
|
Message message3 = getMessage(groupId);
|
||||||
MessageId messageId3 = message3.getId();
|
MessageId messageId3 = message3.getId();
|
||||||
db.addMessage(txn, message3, DELIVERED, true, contactId);
|
db.addMessage(txn, message3, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
// Add dependencies between the messages
|
// Add dependencies between the messages
|
||||||
db.addMessageDependency(txn, message, messageId1, PENDING);
|
db.addMessageDependency(txn, message, messageId1, PENDING);
|
||||||
@@ -1680,10 +1680,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and some messages with different states
|
// Add a group and some messages with different states
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message1, UNKNOWN, true, contactId);
|
db.addMessage(txn, message1, UNKNOWN, true, false, contactId);
|
||||||
db.addMessage(txn, message2, INVALID, true, contactId);
|
db.addMessage(txn, message2, INVALID, true, false, contactId);
|
||||||
db.addMessage(txn, message3, PENDING, true, contactId);
|
db.addMessage(txn, message3, PENDING, true, false, contactId);
|
||||||
db.addMessage(txn, message4, DELIVERED, true, contactId);
|
db.addMessage(txn, message4, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
Collection<MessageId> result;
|
Collection<MessageId> result;
|
||||||
|
|
||||||
@@ -1713,10 +1713,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and some messages
|
// Add a group and some messages
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message1, DELIVERED, true, contactId);
|
db.addMessage(txn, message1, DELIVERED, true, false, contactId);
|
||||||
db.addMessage(txn, message2, DELIVERED, false, contactId);
|
db.addMessage(txn, message2, DELIVERED, false, false, contactId);
|
||||||
db.addMessage(txn, message3, DELIVERED, false, contactId);
|
db.addMessage(txn, message3, DELIVERED, false, false, contactId);
|
||||||
db.addMessage(txn, message4, DELIVERED, true, contactId);
|
db.addMessage(txn, message4, DELIVERED, true, false, contactId);
|
||||||
|
|
||||||
// Introduce dependencies between the messages
|
// Introduce dependencies between the messages
|
||||||
db.addMessageDependency(txn, message1, message2.getId(), DELIVERED);
|
db.addMessageDependency(txn, message1, message2.getId(), DELIVERED);
|
||||||
@@ -1744,7 +1744,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The message should not be sent or seen
|
// The message should not be sent or seen
|
||||||
MessageStatus status = db.getMessageStatus(txn, contactId, messageId);
|
MessageStatus status = db.getMessageStatus(txn, contactId, messageId);
|
||||||
@@ -1878,7 +1878,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// The message should be visible to the contact
|
// The message should be visible to the contact
|
||||||
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
assertTrue(db.containsVisibleMessage(txn, contactId, messageId));
|
||||||
@@ -1961,7 +1961,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
// Add a group and a message
|
// Add a group and a message
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, UNKNOWN, false, contactId);
|
db.addMessage(txn, message, UNKNOWN, false, false, contactId);
|
||||||
|
|
||||||
// Walk the message through the validation and delivery states
|
// Walk the message through the validation and delivery states
|
||||||
assertEquals(UNKNOWN, db.getMessageState(txn, messageId));
|
assertEquals(UNKNOWN, db.getMessageState(txn, messageId));
|
||||||
@@ -1988,7 +1988,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, UNKNOWN, false, null);
|
db.addMessage(txn, message, UNKNOWN, false, false, null);
|
||||||
|
|
||||||
// There should be no messages to send
|
// There should be no messages to send
|
||||||
assertEquals(Long.MAX_VALUE, db.getNextSendTime(txn, contactId));
|
assertEquals(Long.MAX_VALUE, db.getNextSendTime(txn, contactId));
|
||||||
@@ -2073,7 +2073,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Time: now
|
// Time: now
|
||||||
// Retrieve the message from the database
|
// Retrieve the message from the database
|
||||||
@@ -2118,7 +2118,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.addContact(txn, author, localAuthor.getId(), null, true));
|
db.addContact(txn, author, localAuthor.getId(), null, true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||||
db.addMessage(txn, message, DELIVERED, true, null);
|
db.addMessage(txn, message, DELIVERED, true, false, null);
|
||||||
|
|
||||||
// Time: now
|
// Time: now
|
||||||
// Retrieve the message from the database
|
// Retrieve the message from the database
|
||||||
@@ -2257,6 +2257,35 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemporaryMessages() throws Exception {
|
||||||
|
Message message1 = getMessage(groupId);
|
||||||
|
MessageId messageId1 = message1.getId();
|
||||||
|
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
|
// Add a group and two temporary messages
|
||||||
|
db.addGroup(txn, group);
|
||||||
|
db.addMessage(txn, message, DELIVERED, false, true, null);
|
||||||
|
db.addMessage(txn, message1, DELIVERED, false, true, null);
|
||||||
|
|
||||||
|
// Mark one of the messages as permanent
|
||||||
|
db.setMessagePermanent(txn, messageId);
|
||||||
|
|
||||||
|
// Remove all temporary messages
|
||||||
|
db.removeTemporaryMessages(txn);
|
||||||
|
|
||||||
|
// The permanent message should not have been removed
|
||||||
|
assertTrue(db.containsMessage(txn, messageId));
|
||||||
|
|
||||||
|
// The temporary message should have been removed
|
||||||
|
assertFalse(db.containsMessage(txn, messageId1));
|
||||||
|
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
private Database<Connection> open(boolean resume) throws Exception {
|
private Database<Connection> open(boolean resume) throws Exception {
|
||||||
return open(resume, new TestMessageFactory(), new SystemClock());
|
return open(resume, new TestMessageFactory(), new SystemClock());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
|||||||
localVersionsBody);
|
localVersionsBody);
|
||||||
will(returnValue(localVersions));
|
will(returnValue(localVersions));
|
||||||
oneOf(db).addLocalMessage(txn, localVersions, new Metadata(),
|
oneOf(db).addLocalMessage(txn, localVersions, new Metadata(),
|
||||||
false);
|
false, false);
|
||||||
// Inform contacts that client versions have changed
|
// Inform contacts that client versions have changed
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(singletonList(contact)));
|
will(returnValue(singletonList(contact)));
|
||||||
@@ -259,7 +259,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
|||||||
newLocalVersionsBody);
|
newLocalVersionsBody);
|
||||||
will(returnValue(newLocalVersions));
|
will(returnValue(newLocalVersions));
|
||||||
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
|
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
|
||||||
false);
|
false, false);
|
||||||
// Inform contacts that client versions have changed
|
// Inform contacts that client versions have changed
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(singletonList(contact)));
|
will(returnValue(singletonList(contact)));
|
||||||
@@ -355,7 +355,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
|||||||
newLocalVersionsBody);
|
newLocalVersionsBody);
|
||||||
will(returnValue(newLocalVersions));
|
will(returnValue(newLocalVersions));
|
||||||
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
|
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
|
||||||
false);
|
false, false);
|
||||||
// Inform contacts that client versions have changed
|
// Inform contacts that client versions have changed
|
||||||
oneOf(db).getContacts(txn);
|
oneOf(db).getContacts(txn);
|
||||||
will(returnValue(singletonList(contact)));
|
will(returnValue(singletonList(contact)));
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
|||||||
private MessageId createStorageId(Transaction txn) throws DbException {
|
private MessageId createStorageId(Transaction txn) throws DbException {
|
||||||
Message m = clientHelper
|
Message m = clientHelper
|
||||||
.createMessageForStoringMetadata(localGroup.getId());
|
.createMessageForStoringMetadata(localGroup.getId());
|
||||||
db.addLocalMessage(txn, m, new Metadata(), false);
|
db.addLocalMessage(txn, m, new Metadata(), false, false);
|
||||||
return m.getId();
|
return m.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
private MessageId createStorageId(Transaction txn, GroupId g)
|
private MessageId createStorageId(Transaction txn, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
Message m = clientHelper.createMessageForStoringMetadata(g);
|
Message m = clientHelper.createMessageForStoringMetadata(g);
|
||||||
db.addLocalMessage(txn, m, new Metadata(), false);
|
db.addLocalMessage(txn, m, new Metadata(), false, false);
|
||||||
return m.getId();
|
return m.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ abstract class SharingManagerImpl<S extends Shareable>
|
|||||||
private MessageId createStorageId(Transaction txn, GroupId g)
|
private MessageId createStorageId(Transaction txn, GroupId g)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
Message m = clientHelper.createMessageForStoringMetadata(g);
|
Message m = clientHelper.createMessageForStoringMetadata(g);
|
||||||
db.addLocalMessage(txn, m, new Metadata(), false);
|
db.addLocalMessage(txn, m, new Metadata(), false, false);
|
||||||
return m.getId();
|
return m.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
.createMessageForStoringMetadata(contactGroup.getId());
|
.createMessageForStoringMetadata(contactGroup.getId());
|
||||||
will(returnValue(storageMessage));
|
will(returnValue(storageMessage));
|
||||||
oneOf(db).addLocalMessage(txn, storageMessage, new Metadata(),
|
oneOf(db).addLocalMessage(txn, storageMessage, new Metadata(),
|
||||||
false);
|
false, false);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper)
|
oneOf(clientHelper)
|
||||||
.createMessageForStoringMetadata(contactGroup.getId());
|
.createMessageForStoringMetadata(contactGroup.getId());
|
||||||
will(returnValue(message));
|
will(returnValue(message));
|
||||||
oneOf(db).addLocalMessage(txn, message, new Metadata(), false);
|
oneOf(db).addLocalMessage(txn, message, new Metadata(), false,
|
||||||
|
false);
|
||||||
oneOf(sessionEncoder).encodeSession(with(any(Session.class)));
|
oneOf(sessionEncoder).encodeSession(with(any(Session.class)));
|
||||||
will(returnValue(sessionDict));
|
will(returnValue(sessionDict));
|
||||||
oneOf(clientHelper).mergeMessageMetadata(txn, message.getId(),
|
oneOf(clientHelper).mergeMessageMetadata(txn, message.getId(),
|
||||||
|
|||||||
Reference in New Issue
Block a user