Only allow one private group (the inbox) to be shared with each contact.

This commit is contained in:
akwizgran
2013-12-19 22:12:49 +00:00
parent 0dc869228b
commit caec26e9cd
8 changed files with 68 additions and 61 deletions

View File

@@ -152,11 +152,11 @@ interface Database<T> {
throws DbException;
/**
* Makes the given group visible to the given contact.
* Makes a public group visible to the given contact.
* <p>
* Locking: subscription write.
*/
void addVisibility(T txn, ContactId c, GroupId g) throws DbException;
void addVisibility(T txn, ContactId c, Group g) throws DbException;
/**
* Returns true if the database contains the given contact.
@@ -616,11 +616,11 @@ interface Database<T> {
void removeTransport(T txn, TransportId t) throws DbException;
/**
* Makes the given group invisible to the given contact.
* Makes a public group invisible to the given contact.
* <p>
* Locking: subscription write.
*/
void removeVisibility(T txn, ContactId c, GroupId g) throws DbException;
void removeVisibility(T txn, ContactId c, Group g) throws DbException;
/**
* Sets the connection reordering window for the given endpoint in the
@@ -732,11 +732,11 @@ interface Database<T> {
long version) throws DbException;
/**
* Makes the given group visible or invisible to future contacts by default.
* Makes a public group visible or invisible to future contacts by default.
* <p>
* Locking: subscription write.
*/
void setVisibleToAll(T txn, GroupId g, boolean all) throws DbException;
void setVisibleToAll(T txn, Group g, boolean all) throws DbException;
/**
* Updates the expiry times of the given messages with respect to the given

View File

@@ -1871,8 +1871,9 @@ DatabaseCleaner.Callback {
}
}
public void setVisibility(GroupId g, Collection<ContactId> visible)
public void setVisibility(Group g, Collection<ContactId> visible)
throws DbException {
if(g.isPrivate()) throw new IllegalArgumentException();
Collection<ContactId> affected = new ArrayList<ContactId>();
contactLock.readLock().lock();
try {
@@ -1880,11 +1881,12 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
if(!db.containsGroup(txn, g))
if(!db.containsGroup(txn, g.getId()))
throw new NoSuchSubscriptionException();
// Use HashSets for O(1) lookups, O(n) overall running time
HashSet<ContactId> now = new HashSet<ContactId>(visible);
Collection<ContactId> before = db.getVisibility(txn, g);
Collection<ContactId> before =
db.getVisibility(txn, g.getId());
before = new HashSet<ContactId>(before);
// Set the group's visibility for each current contact
for(ContactId c : db.getContactIds(txn)) {
@@ -1915,7 +1917,8 @@ DatabaseCleaner.Callback {
callListeners(new LocalSubscriptionsUpdatedEvent(affected));
}
public void setVisibleToAll(GroupId g, boolean all) throws DbException {
public void setVisibleToAll(Group g, boolean all) throws DbException {
if(g.isPrivate()) throw new IllegalArgumentException();
Collection<ContactId> affected = new ArrayList<ContactId>();
contactLock.readLock().lock();
try {
@@ -1923,13 +1926,14 @@ DatabaseCleaner.Callback {
try {
T txn = db.startTransaction();
try {
if(!db.containsGroup(txn, g))
if(!db.containsGroup(txn, g.getId()))
throw new NoSuchSubscriptionException();
// Make the group visible or invisible to future contacts
db.setVisibleToAll(txn, g, all);
if(all) {
// Make the group visible to all current contacts
Collection<ContactId> before = db.getVisibility(txn, g);
Collection<ContactId> before =
db.getVisibility(txn, g.getId());
before = new HashSet<ContactId>(before);
for(ContactId c : db.getContactIds(txn)) {
if(!before.contains(c)) {

View File

@@ -900,8 +900,9 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void addVisibility(Connection txn, ContactId c, GroupId g)
public void addVisibility(Connection txn, ContactId c, Group g)
throws DbException {
if(g.isPrivate()) throw new IllegalArgumentException();
PreparedStatement ps = null;
try {
String sql = "INSERT INTO groupVisibilities"
@@ -909,7 +910,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " VALUES (?, ?, FALSE)";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setBytes(2, g.getBytes());
ps.setBytes(2, g.getId().getBytes());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -2633,15 +2634,16 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void removeVisibility(Connection txn, ContactId c, GroupId g)
public void removeVisibility(Connection txn, ContactId c, Group g)
throws DbException {
if(g.isPrivate()) throw new IllegalArgumentException();
PreparedStatement ps = null;
try {
String sql = "DELETE FROM groupVisibilities"
+ " WHERE contactId = ? AND groupId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt());
ps.setBytes(2, g.getBytes());
ps.setBytes(2, g.getId().getBytes());
int affected = ps.executeUpdate();
if(affected != 1) throw new DbStateException();
ps.close();
@@ -3074,14 +3076,15 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public void setVisibleToAll(Connection txn, GroupId g, boolean all)
public void setVisibleToAll(Connection txn, Group g, boolean all)
throws DbException {
if(g.isPrivate()) throw new IllegalArgumentException();
PreparedStatement ps = null;
try {
String sql = "UPDATE groups SET visibleToAll = ? WHERE groupId = ?";
ps = txn.prepareStatement(sql);
ps.setBoolean(1, all);
ps.setBytes(2, g.getBytes());
ps.setBytes(2, g.getId().getBytes());
int affected = ps.executeUpdate();
if(affected > 1) throw new DbStateException();
ps.close();