mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Merge branch 'message-status-cleanup' into 'master'
Database efficiency improvements Some tweaks to the DB schema to improve efficiency: * Only keep status rows for messages that are visible - this saves space and avoids the need to join the groupVisibilities table when selecting messages to offer or send * Use adjacent columns for the composite primary key on the settings table This MR depends on !101. See merge request !102
This commit is contained in:
@@ -125,7 +125,7 @@ public class ContactListFragment extends BaseEventFragment {
|
|||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
List<ContactListItem> contacts =
|
List<ContactListItem> contacts =
|
||||||
new ArrayList<ContactListItem>();
|
new ArrayList<ContactListItem>();
|
||||||
for (Contact c : contactManager.getContacts()) {
|
for (Contact c : contactManager.getActiveContacts()) {
|
||||||
try {
|
try {
|
||||||
ContactId id = c.getId();
|
ContactId id = c.getId();
|
||||||
GroupId groupId =
|
GroupId groupId =
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ SelectContactsDialog.Listener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
contacts = contactManager.getContacts();
|
contacts = contactManager.getActiveContacts();
|
||||||
selected = forumSharingManager.getSharedWith(groupId);
|
selected = forumSharingManager.getSharedWith(groupId);
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ public class Contact {
|
|||||||
private final ContactId id;
|
private final ContactId id;
|
||||||
private final Author author;
|
private final Author author;
|
||||||
private final AuthorId localAuthorId;
|
private final AuthorId localAuthorId;
|
||||||
|
private final boolean active;
|
||||||
|
|
||||||
public Contact(ContactId id, Author author, AuthorId localAuthorId) {
|
public Contact(ContactId id, Author author, AuthorId localAuthorId,
|
||||||
|
boolean active) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
this.localAuthorId = localAuthorId;
|
this.localAuthorId = localAuthorId;
|
||||||
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContactId getId() {
|
public ContactId getId() {
|
||||||
@@ -27,6 +30,10 @@ public class Contact {
|
|||||||
return localAuthorId;
|
return localAuthorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return id.hashCode();
|
return id.hashCode();
|
||||||
|
|||||||
@@ -19,17 +19,21 @@ public interface ContactManager {
|
|||||||
* Stores a contact associated with the given local and remote pseudonyms,
|
* Stores a contact associated with the given local and remote pseudonyms,
|
||||||
* and returns an ID for the contact.
|
* and returns an ID for the contact.
|
||||||
*/
|
*/
|
||||||
ContactId addContact(Author remote, AuthorId local) throws DbException;
|
ContactId addContact(Author remote, AuthorId local, boolean active)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/** Returns the contact with the given ID. */
|
/** Returns the contact with the given ID. */
|
||||||
Contact getContact(ContactId c) throws DbException;
|
Contact getContact(ContactId c) throws DbException;
|
||||||
|
|
||||||
/** Returns all contacts. */
|
/** Returns all active contacts. */
|
||||||
Collection<Contact> getContacts() throws DbException;
|
Collection<Contact> getActiveContacts() throws DbException;
|
||||||
|
|
||||||
/** Removes a contact and all associated state. */
|
/** Removes a contact and all associated state. */
|
||||||
void removeContact(ContactId c) throws DbException;
|
void removeContact(ContactId c) throws DbException;
|
||||||
|
|
||||||
|
/** Marks a contact as active or inactive. */
|
||||||
|
void setContactActive(ContactId c, boolean active) throws DbException;
|
||||||
|
|
||||||
interface AddContactHook {
|
interface AddContactHook {
|
||||||
void addingContact(Transaction txn, Contact c) throws DbException;
|
void addingContact(Transaction txn, Contact c) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ public interface DatabaseComponent {
|
|||||||
* Stores a contact associated with the given local and remote pseudonyms,
|
* Stores a contact associated with the given local and remote pseudonyms,
|
||||||
* and returns an ID for the contact.
|
* and returns an ID for the contact.
|
||||||
*/
|
*/
|
||||||
ContactId addContact(Transaction txn, Author remote, AuthorId local)
|
ContactId addContact(Transaction txn, Author remote, AuthorId local,
|
||||||
throws DbException;
|
boolean active) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a group.
|
* Stores a group.
|
||||||
@@ -317,6 +317,12 @@ public interface DatabaseComponent {
|
|||||||
*/
|
*/
|
||||||
void removeTransport(Transaction txn, TransportId t) throws DbException;
|
void removeTransport(Transaction txn, TransportId t) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the given contact as active or inactive.
|
||||||
|
*/
|
||||||
|
void setContactActive(Transaction txn, ContactId c, boolean active)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given message as shared or unshared.
|
* Marks the given message as shared or unshared.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package org.briarproject.api.event;
|
||||||
|
|
||||||
|
import org.briarproject.api.contact.ContactId;
|
||||||
|
|
||||||
|
/** An event that is broadcast when a contact is marked active or inactive. */
|
||||||
|
public class ContactStatusChangedEvent extends Event {
|
||||||
|
|
||||||
|
private final ContactId contactId;
|
||||||
|
private final boolean active;
|
||||||
|
|
||||||
|
public ContactStatusChangedEvent(ContactId contactId, boolean active) {
|
||||||
|
this.contactId = contactId;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactId getContactId() {
|
||||||
|
return contactId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ import org.briarproject.api.identity.AuthorId;
|
|||||||
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
|
import org.briarproject.api.identity.IdentityManager.RemoveIdentityHook;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
@@ -41,12 +43,12 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContactId addContact(Author remote, AuthorId local)
|
public ContactId addContact(Author remote, AuthorId local, boolean active)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
ContactId c;
|
ContactId c;
|
||||||
Transaction txn = db.startTransaction();
|
Transaction txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
c = db.addContact(txn, remote, local);
|
c = db.addContact(txn, remote, local, active);
|
||||||
Contact contact = db.getContact(txn, c);
|
Contact contact = db.getContact(txn, c);
|
||||||
for (AddContactHook hook : addHooks)
|
for (AddContactHook hook : addHooks)
|
||||||
hook.addingContact(txn, contact);
|
hook.addingContact(txn, contact);
|
||||||
@@ -71,7 +73,7 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Contact> getContacts() throws DbException {
|
public Collection<Contact> getActiveContacts() throws DbException {
|
||||||
Collection<Contact> contacts;
|
Collection<Contact> contacts;
|
||||||
Transaction txn = db.startTransaction();
|
Transaction txn = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
@@ -80,7 +82,9 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
return contacts;
|
List<Contact> active = new ArrayList<Contact>(contacts.size());
|
||||||
|
for (Contact c : contacts) if (c.isActive()) active.add(c);
|
||||||
|
return Collections.unmodifiableList(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,6 +98,18 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContactActive(ContactId c, boolean active)
|
||||||
|
throws DbException {
|
||||||
|
Transaction txn = db.startTransaction();
|
||||||
|
try {
|
||||||
|
db.setContactActive(txn, c, active);
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void removeContact(Transaction txn, ContactId c)
|
private void removeContact(Transaction txn, ContactId c)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
Contact contact = db.getContact(txn, c);
|
Contact contact = db.getContact(txn, c);
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ interface Database<T> {
|
|||||||
* Stores a contact associated with the given local and remote pseudonyms,
|
* Stores a contact associated with the given local and remote pseudonyms,
|
||||||
* and returns an ID for the contact.
|
* and returns an ID for the contact.
|
||||||
*/
|
*/
|
||||||
ContactId addContact(T txn, Author remote, AuthorId local)
|
ContactId addContact(T txn, Author remote, AuthorId local, boolean active)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,11 +188,6 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Contact getContact(T txn, ContactId c) throws DbException;
|
Contact getContact(T txn, ContactId c) throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the IDs of all contacts.
|
|
||||||
*/
|
|
||||||
Collection<ContactId> getContactIds(T txn) throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all contacts.
|
* Returns all contacts.
|
||||||
*/
|
*/
|
||||||
@@ -240,6 +235,11 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
Collection<LocalAuthor> getLocalAuthors(T txn) throws DbException;
|
Collection<LocalAuthor> getLocalAuthors(T txn) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the IDs of all messages in the given group.
|
||||||
|
*/
|
||||||
|
Collection<MessageId> getMessageIds(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the metadata for all messages in the given group.
|
* Returns the metadata for all messages in the given group.
|
||||||
*/
|
*/
|
||||||
@@ -424,6 +424,12 @@ interface Database<T> {
|
|||||||
void removeOfferedMessages(T txn, ContactId c,
|
void removeOfferedMessages(T txn, ContactId c,
|
||||||
Collection<MessageId> requested) throws DbException;
|
Collection<MessageId> requested) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the status of the given message with respect to the given
|
||||||
|
* contact.
|
||||||
|
*/
|
||||||
|
void removeStatus(T txn, ContactId c, MessageId m) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a transport (and all associated state) from the database.
|
* Removes a transport (and all associated state) from the database.
|
||||||
*/
|
*/
|
||||||
@@ -440,6 +446,12 @@ interface Database<T> {
|
|||||||
*/
|
*/
|
||||||
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
|
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the given contact as active or inactive.
|
||||||
|
*/
|
||||||
|
void setContactActive(T txn, ContactId c, boolean active)
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given message as shared or unshared.
|
* Marks the given message as shared or unshared.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.briarproject.api.db.NoSuchTransportException;
|
|||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.event.ContactAddedEvent;
|
import org.briarproject.api.event.ContactAddedEvent;
|
||||||
import org.briarproject.api.event.ContactRemovedEvent;
|
import org.briarproject.api.event.ContactRemovedEvent;
|
||||||
|
import org.briarproject.api.event.ContactStatusChangedEvent;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.api.event.GroupAddedEvent;
|
import org.briarproject.api.event.GroupAddedEvent;
|
||||||
@@ -56,7 +57,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -70,12 +70,6 @@ import static org.briarproject.api.sync.ValidationManager.Validity.UNKNOWN;
|
|||||||
import static org.briarproject.api.sync.ValidationManager.Validity.VALID;
|
import static org.briarproject.api.sync.ValidationManager.Validity.VALID;
|
||||||
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation of DatabaseComponent using reentrant read-write locks.
|
|
||||||
* Depending on the JVM's lock implementation, this implementation may allow
|
|
||||||
* writers to starve. LockFairnessTest can be used to test whether this
|
|
||||||
* implementation is safe on a given JVM.
|
|
||||||
*/
|
|
||||||
class DatabaseComponentImpl<T> implements DatabaseComponent {
|
class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -143,13 +137,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ContactId addContact(Transaction transaction, Author remote,
|
public ContactId addContact(Transaction transaction, Author remote,
|
||||||
AuthorId local) throws DbException {
|
AuthorId local, boolean active) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, local))
|
if (!db.containsLocalAuthor(txn, local))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchLocalAuthorException();
|
||||||
if (db.containsContact(txn, remote.getId(), local))
|
if (db.containsContact(txn, remote.getId(), local))
|
||||||
throw new ContactExistsException();
|
throw new ContactExistsException();
|
||||||
ContactId c = db.addContact(txn, remote, local);
|
ContactId c = db.addContact(txn, remote, local, active);
|
||||||
transaction.attach(new ContactAddedEvent(c));
|
transaction.attach(new ContactAddedEvent(c));
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -177,7 +171,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
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())) {
|
||||||
addMessage(txn, m, VALID, shared, null);
|
addMessage(txn, m, VALID, shared);
|
||||||
transaction.attach(new MessageAddedEvent(m, null));
|
transaction.attach(new MessageAddedEvent(m, null));
|
||||||
transaction.attach(new MessageValidatedEvent(m, c, true, true));
|
transaction.attach(new MessageValidatedEvent(m, c, true, true));
|
||||||
if (shared) transaction.attach(new MessageSharedEvent(m));
|
if (shared) transaction.attach(new MessageSharedEvent(m));
|
||||||
@@ -185,26 +179,12 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
db.mergeMessageMetadata(txn, m.getId(), meta);
|
db.mergeMessageMetadata(txn, m.getId(), meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void addMessage(T txn, Message m, Validity validity, boolean shared)
|
||||||
* Stores a message and initialises its status with respect to each contact.
|
throws DbException {
|
||||||
*
|
|
||||||
* @param sender null for a locally generated message.
|
|
||||||
*/
|
|
||||||
private void addMessage(T txn, Message m, Validity validity, boolean shared,
|
|
||||||
ContactId sender) throws DbException {
|
|
||||||
db.addMessage(txn, m, validity, shared);
|
db.addMessage(txn, m, validity, shared);
|
||||||
GroupId g = m.getGroupId();
|
for (ContactId c : db.getVisibility(txn, m.getGroupId())) {
|
||||||
Collection<ContactId> visibility = db.getVisibility(txn, g);
|
boolean offered = db.removeOfferedMessage(txn, c, m.getId());
|
||||||
visibility = new HashSet<ContactId>(visibility);
|
db.addStatus(txn, c, m.getId(), offered, offered);
|
||||||
for (ContactId c : db.getContactIds(txn)) {
|
|
||||||
if (visibility.contains(c)) {
|
|
||||||
boolean offered = db.removeOfferedMessage(txn, c, m.getId());
|
|
||||||
boolean seen = offered || c.equals(sender);
|
|
||||||
db.addStatus(txn, c, m.getId(), offered, seen);
|
|
||||||
} else {
|
|
||||||
if (c.equals(sender)) throw new IllegalStateException();
|
|
||||||
db.addStatus(txn, c, m.getId(), false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,7 +496,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
throw new NoSuchContactException();
|
throw new NoSuchContactException();
|
||||||
if (db.containsVisibleGroup(txn, c, m.getGroupId())) {
|
if (db.containsVisibleGroup(txn, c, m.getGroupId())) {
|
||||||
if (!db.containsMessage(txn, m.getId())) {
|
if (!db.containsMessage(txn, m.getId())) {
|
||||||
addMessage(txn, m, UNKNOWN, false, c);
|
addMessage(txn, m, UNKNOWN, false);
|
||||||
transaction.attach(new MessageAddedEvent(m, c));
|
transaction.attach(new MessageAddedEvent(m, c));
|
||||||
}
|
}
|
||||||
db.raiseAckFlag(txn, c, m.getId());
|
db.raiseAckFlag(txn, c, m.getId());
|
||||||
@@ -529,8 +509,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsContact(txn, c))
|
if (!db.containsContact(txn, c))
|
||||||
throw new NoSuchContactException();
|
throw new NoSuchContactException();
|
||||||
int count = db.countOfferedMessages(txn, c);
|
|
||||||
boolean ack = false, request = false;
|
boolean ack = false, request = false;
|
||||||
|
int count = db.countOfferedMessages(txn, c);
|
||||||
for (MessageId m : o.getMessageIds()) {
|
for (MessageId m : o.getMessageIds()) {
|
||||||
if (db.containsVisibleMessage(txn, c, m)) {
|
if (db.containsVisibleMessage(txn, c, m)) {
|
||||||
db.raiseSeenFlag(txn, c, m);
|
db.raiseSeenFlag(txn, c, m);
|
||||||
@@ -601,6 +581,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
transaction.attach(new TransportRemovedEvent(t));
|
transaction.attach(new TransportRemovedEvent(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContactActive(Transaction transaction, ContactId c,
|
||||||
|
boolean active) throws DbException {
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
if (!db.containsContact(txn, c))
|
||||||
|
throw new NoSuchContactException();
|
||||||
|
db.setContactActive(txn, c, active);
|
||||||
|
transaction.attach(new ContactStatusChangedEvent(c, active));
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessageShared(Transaction transaction, Message m,
|
public void setMessageShared(Transaction transaction, Message m,
|
||||||
boolean shared) throws DbException {
|
boolean shared) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
@@ -638,8 +627,17 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
if (!db.containsGroup(txn, g))
|
if (!db.containsGroup(txn, g))
|
||||||
throw new NoSuchGroupException();
|
throw new NoSuchGroupException();
|
||||||
boolean wasVisible = db.containsVisibleGroup(txn, c, g);
|
boolean wasVisible = db.containsVisibleGroup(txn, c, g);
|
||||||
if (visible && !wasVisible) db.addVisibility(txn, c, g);
|
if (visible && !wasVisible) {
|
||||||
else if (!visible && wasVisible) db.removeVisibility(txn, c, g);
|
db.addVisibility(txn, c, g);
|
||||||
|
for (MessageId m : db.getMessageIds(txn, g)) {
|
||||||
|
boolean seen = db.removeOfferedMessage(txn, c, m);
|
||||||
|
db.addStatus(txn, c, m, seen, seen);
|
||||||
|
}
|
||||||
|
} else if (!visible && wasVisible) {
|
||||||
|
db.removeVisibility(txn, c, g);
|
||||||
|
for (MessageId m : db.getMessageIds(txn, g))
|
||||||
|
db.removeStatus(txn, c, m);
|
||||||
|
}
|
||||||
if (visible != wasVisible) {
|
if (visible != wasVisible) {
|
||||||
List<ContactId> affected = Collections.singletonList(c);
|
List<ContactId> affected = Collections.singletonList(c);
|
||||||
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
transaction.attach(new GroupVisibilityUpdatedEvent(affected));
|
||||||
|
|||||||
@@ -63,15 +63,15 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
|
|||||||
*/
|
*/
|
||||||
abstract class JdbcDatabase implements Database<Connection> {
|
abstract class JdbcDatabase implements Database<Connection> {
|
||||||
|
|
||||||
private static final int SCHEMA_VERSION = 21;
|
private static final int SCHEMA_VERSION = 22;
|
||||||
private static final int MIN_SCHEMA_VERSION = 21;
|
private static final int MIN_SCHEMA_VERSION = 22;
|
||||||
|
|
||||||
private static final String CREATE_SETTINGS =
|
private static final String CREATE_SETTINGS =
|
||||||
"CREATE TABLE settings"
|
"CREATE TABLE settings"
|
||||||
+ " (key VARCHAR NOT NULL,"
|
+ " (namespace VARCHAR NOT NULL,"
|
||||||
|
+ " key VARCHAR NOT NULL,"
|
||||||
+ " value VARCHAR NOT NULL,"
|
+ " value VARCHAR NOT NULL,"
|
||||||
+ " namespace VARCHAR NOT NULL,"
|
+ " PRIMARY KEY (namespace, key))";
|
||||||
+ " PRIMARY KEY (key, namespace))";
|
|
||||||
|
|
||||||
private static final String CREATE_LOCAL_AUTHORS =
|
private static final String CREATE_LOCAL_AUTHORS =
|
||||||
"CREATE TABLE localAuthors"
|
"CREATE TABLE localAuthors"
|
||||||
@@ -89,6 +89,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " name VARCHAR NOT NULL,"
|
+ " name VARCHAR NOT NULL,"
|
||||||
+ " publicKey BINARY NOT NULL,"
|
+ " publicKey BINARY NOT NULL,"
|
||||||
+ " localAuthorId HASH NOT NULL,"
|
+ " localAuthorId HASH NOT NULL,"
|
||||||
|
+ " active BOOLEAN NOT NULL,"
|
||||||
+ " PRIMARY KEY (contactId),"
|
+ " PRIMARY KEY (contactId),"
|
||||||
+ " FOREIGN KEY (localAuthorId)"
|
+ " FOREIGN KEY (localAuthorId)"
|
||||||
+ " REFERENCES localAuthors (authorId)"
|
+ " REFERENCES localAuthors (authorId)"
|
||||||
@@ -441,20 +442,21 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
return new DeviceId(StringUtils.fromHexString(s.get(DEVICE_ID_KEY)));
|
return new DeviceId(StringUtils.fromHexString(s.get(DEVICE_ID_KEY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContactId addContact(Connection txn, Author remote, AuthorId local)
|
public ContactId addContact(Connection txn, Author remote, AuthorId local,
|
||||||
throws DbException {
|
boolean active) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
// Create a contact row
|
// Create a contact row
|
||||||
String sql = "INSERT INTO contacts"
|
String sql = "INSERT INTO contacts"
|
||||||
+ " (authorId, name, publicKey, localAuthorId)"
|
+ " (authorId, name, publicKey, localAuthorId, active)"
|
||||||
+ " VALUES (?, ?, ?, ?)";
|
+ " VALUES (?, ?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, remote.getId().getBytes());
|
ps.setBytes(1, remote.getId().getBytes());
|
||||||
ps.setString(2, remote.getName());
|
ps.setString(2, remote.getName());
|
||||||
ps.setBytes(3, remote.getPublicKey());
|
ps.setBytes(3, remote.getPublicKey());
|
||||||
ps.setBytes(4, local.getBytes());
|
ps.setBytes(4, local.getBytes());
|
||||||
|
ps.setBoolean(5, active);
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -468,31 +470,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rs.next()) throw new DbStateException();
|
if (rs.next()) throw new DbStateException();
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
// Create a status row for each message
|
|
||||||
sql = "SELECT messageID FROM messages";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
Collection<byte[]> ids = new ArrayList<byte[]>();
|
|
||||||
while (rs.next()) ids.add(rs.getBytes(1));
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
if (!ids.isEmpty()) {
|
|
||||||
sql = "INSERT INTO statuses (messageId, contactId, ack,"
|
|
||||||
+ " seen, requested, expiry, txCount)"
|
|
||||||
+ " VALUES (?, ?, FALSE, FALSE, FALSE, 0, 0)";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(2, c.getInt());
|
|
||||||
for (byte[] id : ids) {
|
|
||||||
ps.setBytes(1, id);
|
|
||||||
ps.addBatch();
|
|
||||||
}
|
|
||||||
int[] batchAffected = ps.executeBatch();
|
|
||||||
if (batchAffected.length != ids.size())
|
|
||||||
throw new DbStateException();
|
|
||||||
for (int rows : batchAffected)
|
|
||||||
if (rows != 1) throw new DbStateException();
|
|
||||||
ps.close();
|
|
||||||
}
|
|
||||||
return c;
|
return c;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs);
|
||||||
@@ -951,7 +928,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT authorId, name, publicKey, localAuthorId"
|
String sql = "SELECT authorId, name, publicKey,"
|
||||||
|
+ " localAuthorId, active"
|
||||||
+ " FROM contacts"
|
+ " FROM contacts"
|
||||||
+ " WHERE contactId = ?";
|
+ " WHERE contactId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
@@ -962,30 +940,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
String name = rs.getString(2);
|
String name = rs.getString(2);
|
||||||
byte[] publicKey = rs.getBytes(3);
|
byte[] publicKey = rs.getBytes(3);
|
||||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
|
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
|
||||||
|
boolean active = rs.getBoolean(5);
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
Author author = new Author(authorId, name, publicKey);
|
Author author = new Author(authorId, name, publicKey);
|
||||||
return new Contact(c, author, localAuthorId);
|
return new Contact(c, author, localAuthorId, active);
|
||||||
} catch (SQLException e) {
|
|
||||||
tryToClose(rs);
|
|
||||||
tryToClose(ps);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<ContactId> getContactIds(Connection txn)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT contactId FROM contacts";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
List<ContactId> ids = new ArrayList<ContactId>();
|
|
||||||
while (rs.next()) ids.add(new ContactId(rs.getInt(1)));
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return Collections.unmodifiableList(ids);
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs);
|
tryToClose(rs);
|
||||||
tryToClose(ps);
|
tryToClose(ps);
|
||||||
@@ -999,7 +958,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT contactId, authorId, name, publicKey,"
|
String sql = "SELECT contactId, authorId, name, publicKey,"
|
||||||
+ " localAuthorId"
|
+ " localAuthorId, active"
|
||||||
+ " FROM contacts";
|
+ " FROM contacts";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
@@ -1011,7 +970,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
byte[] publicKey = rs.getBytes(4);
|
byte[] publicKey = rs.getBytes(4);
|
||||||
Author author = new Author(authorId, name, publicKey);
|
Author author = new Author(authorId, name, publicKey);
|
||||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||||
contacts.add(new Contact(contactId, author, localAuthorId));
|
boolean active = rs.getBoolean(6);
|
||||||
|
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||||
|
active));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -1151,6 +1112,27 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<MessageId> getMessageIds(Connection txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT messageId FROM messages WHERE groupId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, g.getBytes());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
List<MessageId> ids = new ArrayList<MessageId>();
|
||||||
|
while (rs.next()) ids.add(new MessageId(rs.getBytes(1)));
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
return Collections.unmodifiableList(ids);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs);
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Map<MessageId, Metadata> getMessageMetadata(Connection txn,
|
public Map<MessageId, Metadata> getMessageMetadata(Connection txn,
|
||||||
GroupId g) throws DbException {
|
GroupId g) throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -1309,15 +1291,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT m.messageId FROM messages AS m"
|
String sql = "SELECT m.messageId FROM messages AS m"
|
||||||
+ " JOIN groupVisibilities AS gv"
|
|
||||||
+ " ON m.groupId = gv.groupId"
|
|
||||||
+ " JOIN statuses AS s"
|
+ " JOIN statuses AS s"
|
||||||
+ " ON m.messageId = s.messageId"
|
+ " ON m.messageId = s.messageId"
|
||||||
+ " AND gv.contactId = s.contactId"
|
+ " WHERE contactId = ?"
|
||||||
+ " WHERE gv.contactId = ?"
|
|
||||||
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
||||||
+ " AND seen = FALSE AND requested = FALSE"
|
+ " AND seen = FALSE AND requested = FALSE"
|
||||||
+ " AND s.expiry < ?"
|
+ " AND expiry < ?"
|
||||||
+ " ORDER BY timestamp DESC LIMIT ?";
|
+ " ORDER BY timestamp DESC LIMIT ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setInt(1, c.getInt());
|
ps.setInt(1, c.getInt());
|
||||||
@@ -1368,15 +1347,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT length, m.messageId FROM messages AS m"
|
String sql = "SELECT length, m.messageId FROM messages AS m"
|
||||||
+ " JOIN groupVisibilities AS gv"
|
|
||||||
+ " ON m.groupId = gv.groupId"
|
|
||||||
+ " JOIN statuses AS s"
|
+ " JOIN statuses AS s"
|
||||||
+ " ON m.messageId = s.messageId"
|
+ " ON m.messageId = s.messageId"
|
||||||
+ " AND gv.contactId = s.contactId"
|
+ " WHERE contactId = ?"
|
||||||
+ " WHERE gv.contactId = ?"
|
|
||||||
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
||||||
+ " AND seen = FALSE"
|
+ " AND seen = FALSE"
|
||||||
+ " AND s.expiry < ?"
|
+ " AND expiry < ?"
|
||||||
+ " ORDER BY timestamp DESC";
|
+ " ORDER BY timestamp DESC";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setInt(1, c.getInt());
|
ps.setInt(1, c.getInt());
|
||||||
@@ -1454,15 +1430,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT length, m.messageId FROM messages AS m"
|
String sql = "SELECT length, m.messageId FROM messages AS m"
|
||||||
+ " JOIN groupVisibilities AS gv"
|
|
||||||
+ " ON m.groupId = gv.groupId"
|
|
||||||
+ " JOIN statuses AS s"
|
+ " JOIN statuses AS s"
|
||||||
+ " ON m.messageId = s.messageId"
|
+ " ON m.messageId = s.messageId"
|
||||||
+ " AND gv.contactId = s.contactId"
|
+ " WHERE contactId = ?"
|
||||||
+ " WHERE gv.contactId = ?"
|
|
||||||
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
+ " AND valid = ? AND shared = TRUE AND raw IS NOT NULL"
|
||||||
+ " AND seen = FALSE AND requested = TRUE"
|
+ " AND seen = FALSE AND requested = TRUE"
|
||||||
+ " AND s.expiry < ?"
|
+ " AND expiry < ?"
|
||||||
+ " ORDER BY timestamp DESC";
|
+ " ORDER BY timestamp DESC";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setInt(1, c.getInt());
|
ps.setInt(1, c.getInt());
|
||||||
@@ -1777,12 +1750,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
try {
|
try {
|
||||||
// Update any settings that already exist
|
// Update any settings that already exist
|
||||||
String sql = "UPDATE settings SET value = ?"
|
String sql = "UPDATE settings SET value = ?"
|
||||||
+ " WHERE key = ? AND namespace = ?";
|
+ " WHERE namespace = ? AND key = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
for (Entry<String, String> e : s.entrySet()) {
|
for (Entry<String, String> e : s.entrySet()) {
|
||||||
ps.setString(1, e.getValue());
|
ps.setString(1, e.getValue());
|
||||||
ps.setString(2, e.getKey());
|
ps.setString(2, namespace);
|
||||||
ps.setString(3, namespace);
|
ps.setString(3, e.getKey());
|
||||||
ps.addBatch();
|
ps.addBatch();
|
||||||
}
|
}
|
||||||
int[] batchAffected = ps.executeBatch();
|
int[] batchAffected = ps.executeBatch();
|
||||||
@@ -1792,15 +1765,15 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
if (rows > 1) throw new DbStateException();
|
if (rows > 1) throw new DbStateException();
|
||||||
}
|
}
|
||||||
// Insert any settings that don't already exist
|
// Insert any settings that don't already exist
|
||||||
sql = "INSERT INTO settings (key, value, namespace)"
|
sql = "INSERT INTO settings (namespace, key, value)"
|
||||||
+ " VALUES (?, ?, ?)";
|
+ " VALUES (?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
int updateIndex = 0, inserted = 0;
|
int updateIndex = 0, inserted = 0;
|
||||||
for (Entry<String, String> e : s.entrySet()) {
|
for (Entry<String, String> e : s.entrySet()) {
|
||||||
if (batchAffected[updateIndex] == 0) {
|
if (batchAffected[updateIndex] == 0) {
|
||||||
ps.setString(1, e.getKey());
|
ps.setString(1, namespace);
|
||||||
ps.setString(2, e.getValue());
|
ps.setString(2, e.getKey());
|
||||||
ps.setString(3, namespace);
|
ps.setString(3, e.getValue());
|
||||||
ps.addBatch();
|
ps.addBatch();
|
||||||
inserted++;
|
inserted++;
|
||||||
}
|
}
|
||||||
@@ -1976,6 +1949,24 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeStatus(Connection txn, ContactId c, MessageId m)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "DELETE FROM statuses"
|
||||||
|
+ " WHERE contactId = ? AND messageId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setInt(1, c.getInt());
|
||||||
|
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 void removeTransport(Connection txn, TransportId t)
|
public void removeTransport(Connection txn, TransportId t)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2028,6 +2019,23 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setContactActive(Connection txn, ContactId c, boolean active)
|
||||||
|
throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE contacts SET active = ? WHERE contactId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBoolean(1, active);
|
||||||
|
ps.setInt(2, c.getInt());
|
||||||
|
int affected = ps.executeUpdate();
|
||||||
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
|
ps.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(ps);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessageShared(Connection txn, MessageId m, boolean shared)
|
public void setMessageShared(Connection txn, MessageId m, boolean shared)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
@@ -2037,7 +2045,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.setBoolean(1, shared);
|
ps.setBoolean(1, shared);
|
||||||
ps.setBytes(2, m.getBytes());
|
ps.setBytes(2, m.getBytes());
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps);
|
||||||
@@ -2054,7 +2062,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
ps.setInt(1, valid ? VALID.getValue() : INVALID.getValue());
|
ps.setInt(1, valid ? VALID.getValue() : INVALID.getValue());
|
||||||
ps.setBytes(2, m.getBytes());
|
ps.setBytes(2, m.getBytes());
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected < 0) throw new DbStateException();
|
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(ps);
|
tryToClose(ps);
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ abstract class Connector extends Thread {
|
|||||||
long timestamp, boolean alice) throws DbException {
|
long timestamp, boolean alice) throws DbException {
|
||||||
// Add the contact to the database
|
// Add the contact to the database
|
||||||
contactId = contactManager.addContact(remoteAuthor,
|
contactId = contactManager.addContact(remoteAuthor,
|
||||||
localAuthor.getId());
|
localAuthor.getId(), true);
|
||||||
// Derive transport keys
|
// Derive transport keys
|
||||||
keyManager.addContact(contactId, master, timestamp, alice);
|
keyManager.addContact(contactId, master, timestamp, alice);
|
||||||
return contactId;
|
return contactId;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
transportId = new TransportId("id");
|
transportId = new TransportId("id");
|
||||||
maxLatency = Integer.MAX_VALUE;
|
maxLatency = Integer.MAX_VALUE;
|
||||||
contactId = new ContactId(234);
|
contactId = new ContactId(234);
|
||||||
contact = new Contact(contactId, author, localAuthorId);
|
contact = new Contact(contactId, author, localAuthorId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabaseComponent createDatabaseComponent(Database<Object> database,
|
private DatabaseComponent createDatabaseComponent(Database<Object> database,
|
||||||
@@ -143,7 +143,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addContact(txn, author, localAuthorId);
|
oneOf(database).addContact(txn, author, localAuthorId, true);
|
||||||
will(returnValue(contactId));
|
will(returnValue(contactId));
|
||||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||||
// getContacts()
|
// getContacts()
|
||||||
@@ -193,7 +193,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
try {
|
try {
|
||||||
db.addLocalAuthor(transaction, localAuthor);
|
db.addLocalAuthor(transaction, localAuthor);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(transaction, author, localAuthorId));
|
db.addContact(transaction, author, localAuthorId, true));
|
||||||
assertEquals(Collections.singletonList(contact),
|
assertEquals(Collections.singletonList(contact),
|
||||||
db.getContacts(transaction));
|
db.getContacts(transaction));
|
||||||
db.addGroup(transaction, group); // First time - listeners called
|
db.addGroup(transaction, group); // First time - listeners called
|
||||||
@@ -261,8 +261,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
oneOf(database).mergeMessageMetadata(txn, messageId, metadata);
|
||||||
oneOf(database).getVisibility(txn, groupId);
|
oneOf(database).getVisibility(txn, groupId);
|
||||||
will(returnValue(Collections.singletonList(contactId)));
|
will(returnValue(Collections.singletonList(contactId)));
|
||||||
oneOf(database).getContactIds(txn);
|
|
||||||
will(returnValue(Collections.singletonList(contactId)));
|
|
||||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addStatus(txn, contactId, messageId, false, false);
|
oneOf(database).addStatus(txn, contactId, messageId, false, false);
|
||||||
@@ -296,11 +294,11 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
final EventBus eventBus = context.mock(EventBus.class);
|
final EventBus eventBus = context.mock(EventBus.class);
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Check whether the contact is in the DB (which it's not)
|
// Check whether the contact is in the DB (which it's not)
|
||||||
exactly(17).of(database).startTransaction();
|
exactly(18).of(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
exactly(17).of(database).containsContact(txn, contactId);
|
exactly(18).of(database).containsContact(txn, contactId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
exactly(17).of(database).abortTransaction(txn);
|
exactly(18).of(database).abortTransaction(txn);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||||
shutdown);
|
shutdown);
|
||||||
@@ -458,6 +456,16 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
db.endTransaction(transaction);
|
db.endTransaction(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transaction = db.startTransaction();
|
||||||
|
try {
|
||||||
|
db.setContactActive(transaction, contactId, true);
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchContactException expected) {
|
||||||
|
// Expected
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
transaction = db.startTransaction();
|
transaction = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
db.setReorderingWindow(transaction, contactId, transportId, 0, 0,
|
db.setReorderingWindow(transaction, contactId, transportId, 0, 0,
|
||||||
@@ -503,7 +511,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
|
|
||||||
Transaction transaction = db.startTransaction();
|
Transaction transaction = db.startTransaction();
|
||||||
try {
|
try {
|
||||||
db.addContact(transaction, author, localAuthorId);
|
db.addContact(transaction, author, localAuthorId, true);
|
||||||
fail();
|
fail();
|
||||||
} catch (NoSuchLocalAuthorException expected) {
|
} catch (NoSuchLocalAuthorException expected) {
|
||||||
// Expected
|
// Expected
|
||||||
@@ -757,7 +765,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addContact(txn, author, localAuthorId);
|
oneOf(database).addContact(txn, author, localAuthorId, true);
|
||||||
will(returnValue(contactId));
|
will(returnValue(contactId));
|
||||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||||
// endTransaction()
|
// endTransaction()
|
||||||
@@ -778,7 +786,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
try {
|
try {
|
||||||
db.addLocalAuthor(transaction, localAuthor);
|
db.addLocalAuthor(transaction, localAuthor);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(transaction, author, localAuthorId));
|
db.addContact(transaction, author, localAuthorId, true));
|
||||||
transaction.setComplete();
|
transaction.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(transaction);
|
db.endTransaction(transaction);
|
||||||
@@ -1074,11 +1082,9 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
oneOf(database).addMessage(txn, message, UNKNOWN, false);
|
oneOf(database).addMessage(txn, message, UNKNOWN, false);
|
||||||
oneOf(database).getVisibility(txn, groupId);
|
oneOf(database).getVisibility(txn, groupId);
|
||||||
will(returnValue(Collections.singletonList(contactId)));
|
will(returnValue(Collections.singletonList(contactId)));
|
||||||
oneOf(database).getContactIds(txn);
|
|
||||||
will(returnValue(Collections.singletonList(contactId)));
|
|
||||||
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addStatus(txn, contactId, messageId, false, true);
|
oneOf(database).addStatus(txn, contactId, messageId, false, false);
|
||||||
oneOf(database).raiseAckFlag(txn, contactId, messageId);
|
oneOf(database).raiseAckFlag(txn, contactId, messageId);
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
// The message was received and added
|
// The message was received and added
|
||||||
@@ -1270,6 +1276,11 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
|||||||
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
oneOf(database).containsVisibleGroup(txn, contactId, groupId);
|
||||||
will(returnValue(false)); // Not yet visible
|
will(returnValue(false)); // Not yet visible
|
||||||
oneOf(database).addVisibility(txn, contactId, groupId);
|
oneOf(database).addVisibility(txn, contactId, groupId);
|
||||||
|
oneOf(database).getMessageIds(txn, groupId);
|
||||||
|
will(returnValue(Collections.singletonList(messageId)));
|
||||||
|
oneOf(database).removeOfferedMessage(txn, contactId, messageId);
|
||||||
|
will(returnValue(false));
|
||||||
|
oneOf(database).addStatus(txn, contactId, messageId, false, false);
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
oneOf(eventBus).broadcast(with(any(
|
oneOf(eventBus).broadcast(with(any(
|
||||||
GroupVisibilityUpdatedEvent.class)));
|
GroupVisibilityUpdatedEvent.class)));
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
assertFalse(db.containsContact(txn, contactId));
|
assertFalse(db.containsContact(txn, contactId));
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
assertTrue(db.containsContact(txn, contactId));
|
assertTrue(db.containsContact(txn, contactId));
|
||||||
assertFalse(db.containsGroup(txn, groupId));
|
assertFalse(db.containsGroup(txn, groupId));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -170,7 +171,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, VALID, true);
|
db.addMessage(txn, message, VALID, true);
|
||||||
@@ -207,7 +209,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and an unvalidated message
|
// Add a contact, a group and an unvalidated message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, UNKNOWN, true);
|
db.addMessage(txn, message, UNKNOWN, true);
|
||||||
@@ -245,7 +248,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and an unshared message
|
// Add a contact, a group and an unshared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, VALID, false);
|
db.addMessage(txn, message, VALID, false);
|
||||||
@@ -283,7 +287,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, VALID, true);
|
db.addMessage(txn, message, VALID, true);
|
||||||
@@ -302,44 +307,6 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendableMessagesMustBeVisible() throws Exception {
|
|
||||||
Database<Connection> db = open(false);
|
|
||||||
Connection txn = db.startTransaction();
|
|
||||||
|
|
||||||
// Add a contact, a group and a message
|
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
|
||||||
db.addGroup(txn, group);
|
|
||||||
db.addMessage(txn, message, VALID, true);
|
|
||||||
db.addStatus(txn, contactId, messageId, false, false);
|
|
||||||
|
|
||||||
// The group is not visible to the contact, so the message
|
|
||||||
// should not be sendable
|
|
||||||
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
|
|
||||||
ONE_MEGABYTE);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
|
|
||||||
// Making the group visible should make the message sendable
|
|
||||||
db.addVisibility(txn, contactId, groupId);
|
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
|
||||||
assertEquals(Collections.singletonList(messageId), ids);
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
|
||||||
assertEquals(Collections.singletonList(messageId), ids);
|
|
||||||
|
|
||||||
// Making the group invisible should make the message unsendable
|
|
||||||
db.removeVisibility(txn, contactId, groupId);
|
|
||||||
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
ids = db.getMessagesToOffer(txn, contactId, 100);
|
|
||||||
assertTrue(ids.isEmpty());
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMessagesToAck() throws Exception {
|
public void testMessagesToAck() throws Exception {
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
@@ -347,7 +314,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact and a group
|
// Add a contact and a group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
|
|
||||||
@@ -383,7 +351,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, VALID, true);
|
db.addMessage(txn, message, VALID, true);
|
||||||
@@ -546,7 +515,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact and a group
|
// Add a contact and a group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
|
|
||||||
@@ -565,7 +535,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact
|
// Add a contact
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
|
|
||||||
// The group is not in the database
|
// The group is not in the database
|
||||||
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
|
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
|
||||||
@@ -582,7 +553,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addMessage(txn, message, VALID, true);
|
db.addMessage(txn, message, VALID, true);
|
||||||
db.addStatus(txn, contactId, messageId, false, false);
|
db.addStatus(txn, contactId, messageId, false, false);
|
||||||
@@ -601,7 +573,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact and a group
|
// Add a contact and a group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
|
|
||||||
// The group should not be visible to the contact
|
// The group should not be visible to the contact
|
||||||
@@ -636,7 +609,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact and the groups
|
// Add a contact and the groups
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
for (Group g : groups) db.addGroup(txn, g);
|
for (Group g : groups) db.addGroup(txn, g);
|
||||||
|
|
||||||
// Make the groups visible to the contact
|
// Make the groups visible to the contact
|
||||||
@@ -668,7 +642,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add the contact, the transport and the transport keys
|
// Add the contact, the transport and the transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
db.addTransportKeys(txn, contactId, keys);
|
db.addTransportKeys(txn, contactId, keys);
|
||||||
|
|
||||||
@@ -729,7 +704,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add the contact, transport and transport keys
|
// Add the contact, transport and transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
||||||
|
|
||||||
@@ -764,7 +740,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add the contact, transport and transport keys
|
// Add the contact, transport and transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
||||||
|
|
||||||
@@ -800,7 +777,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(Collections.emptyList(), contacts);
|
assertEquals(Collections.emptyList(), contacts);
|
||||||
|
|
||||||
// Add a contact associated with the local author
|
// Add a contact associated with the local author
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
contacts = db.getContacts(txn, localAuthorId);
|
contacts = db.getContacts(txn, localAuthorId);
|
||||||
assertEquals(Collections.singletonList(contactId), contacts);
|
assertEquals(Collections.singletonList(contactId), contacts);
|
||||||
|
|
||||||
@@ -821,7 +799,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact - initially there should be no offered messages
|
// Add a contact - initially there should be no offered messages
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
||||||
|
|
||||||
// Add some offered messages and count them
|
// Add some offered messages and count them
|
||||||
@@ -959,7 +938,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact
|
// Add a contact
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
|
|
||||||
// Add a group and make it visible to the contact
|
// Add a group and make it visible to the contact
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -1035,7 +1015,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact and a group
|
// Add a contact and a group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
|
|
||||||
// The group should not be visible to the contact
|
// The group should not be visible to the contact
|
||||||
@@ -1068,8 +1049,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
db.addLocalAuthor(txn, localAuthor1);
|
db.addLocalAuthor(txn, localAuthor1);
|
||||||
|
|
||||||
// Add the same contact for each local pseudonym
|
// Add the same contact for each local pseudonym
|
||||||
ContactId contactId = db.addContact(txn, author, localAuthorId);
|
ContactId contactId = db.addContact(txn, author, localAuthorId, true);
|
||||||
ContactId contactId1 = db.addContact(txn, author, localAuthorId1);
|
ContactId contactId1 = db.addContact(txn, author, localAuthorId1, true);
|
||||||
|
|
||||||
// The contacts should be distinct
|
// The contacts should be distinct
|
||||||
assertNotEquals(contactId, contactId1);
|
assertNotEquals(contactId, contactId1);
|
||||||
@@ -1088,7 +1069,8 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||||
|
true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
db.addVisibility(txn, contactId, groupId);
|
db.addVisibility(txn, contactId, groupId);
|
||||||
db.addMessage(txn, message, VALID, true);
|
db.addMessage(txn, message, VALID, true);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class PluginManagerImplTest extends BriarTestCase {
|
|||||||
Mockery context = new Mockery() {{
|
Mockery context = new Mockery() {{
|
||||||
setThreadingPolicy(new Synchroniser());
|
setThreadingPolicy(new Synchroniser());
|
||||||
}};
|
}};
|
||||||
final Executor ioExecutor = Executors.newCachedThreadPool();
|
final Executor ioExecutor = Executors.newSingleThreadExecutor();
|
||||||
final EventBus eventBus = context.mock(EventBus.class);
|
final EventBus eventBus = context.mock(EventBus.class);
|
||||||
final SimplexPluginConfig simplexPluginConfig =
|
final SimplexPluginConfig simplexPluginConfig =
|
||||||
context.mock(SimplexPluginConfig.class);
|
context.mock(SimplexPluginConfig.class);
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
// Add Bob as a contact
|
// Add Bob as a contact
|
||||||
Author bobAuthor = new Author(bobId, "Bob",
|
Author bobAuthor = new Author(bobId, "Bob",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(bobAuthor, aliceId);
|
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
||||||
|
true);
|
||||||
// Derive and store the transport keys
|
// Derive and store the transport keys
|
||||||
keyManager.addContact(contactId, master, timestamp, true);
|
keyManager.addContact(contactId, master, timestamp, true);
|
||||||
|
|
||||||
@@ -204,7 +205,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
// Add Alice as a contact
|
// Add Alice as a contact
|
||||||
Author aliceAuthor = new Author(aliceId, "Alice",
|
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(aliceAuthor, bobId);
|
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
||||||
|
true);
|
||||||
// Derive and store the transport keys
|
// Derive and store the transport keys
|
||||||
keyManager.addContact(contactId, master, timestamp, false);
|
keyManager.addContact(contactId, master, timestamp, false);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user