diff --git a/pom.xml b/pom.xml
index 1ad6ab003..ea8f3fed5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -109,6 +109,11 @@
1.17.1
+
+ org.antlr
+ stringtemplate
+ 3.2.1
+
diff --git a/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java b/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java
index ab1dbbe0d..2c481dfa9 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java
@@ -257,11 +257,9 @@ public class MessageController extends HttpServlet {
outgoingMessage.setTimestamp(System.currentTimeMillis());
- int index = 0;
-
for (String destination : destinationNumbers) {
if (!destination.equals(incoming.getDestination()))
- outgoingMessage.setDestinations(index++, destination);
+ outgoingMessage.addDestinations(destination);
}
LocalOrRemoteDevice device = null;
diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java b/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
index eb40cada0..d686dd9ce 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
@@ -39,13 +39,13 @@ public class Account implements Serializable {
public Account(String number, boolean supportsSms, Device onlyDevice) {
this(number, supportsSms);
- this.devices.put(onlyDevice.getDeviceId(), onlyDevice);
+ addDevice(onlyDevice);
}
public Account(String number, boolean supportsSms, List devices) {
this(number, supportsSms);
for (Device device : devices)
- this.devices.put(device.getDeviceId(), device);
+ addDevice(device);
}
public void setNumber(String number) {
@@ -86,4 +86,8 @@ public class Account implements Serializable {
}
return true;
}
+
+ public void addDevice(Device device) {
+ devices.put(device.getDeviceId(), device);
+ }
}
diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/Accounts.java b/src/main/java/org/whispersystems/textsecuregcm/storage/Accounts.java
index 7aecbe040..a512132e0 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/storage/Accounts.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/storage/Accounts.java
@@ -28,7 +28,9 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
import org.skife.jdbi.v2.sqlobject.Transaction;
import org.skife.jdbi.v2.sqlobject.customizers.Mapper;
+import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;
import org.skife.jdbi.v2.tweak.ResultSetMapper;
+import org.skife.jdbi.v2.unstable.BindIn;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
@@ -41,7 +43,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+@UseStringTemplate3StatementLocator
public abstract class Accounts {
public static final String ID = "id";
@@ -99,6 +103,10 @@ public abstract class Accounts {
@SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " = :number")
public abstract List getAllByNumber(@Bind("number") String number);
+ @Mapper(DeviceMapper.class)
+ @SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " IN ( )")
+ public abstract List getAllByNumbers(@BindIn("numbers") List numbers);
+
@Transaction(TransactionIsolationLevel.SERIALIZABLE)
public long insertClearingNumber(Device device) {
removeAccountsByNumber(device.getNumber());
diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java b/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
index 3a154981d..409535330 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
@@ -120,20 +120,34 @@ public class AccountsManager {
return Optional.of(new Account(number, devices.get(0).getSupportsSms(), devices));
}
- private List getAllAccounts(Set numbers) {
- //TODO: ONE QUERY
+ private List getAllAccounts(List numbers) {
+ List devices = accounts.getAllByNumbers(numbers);
List accounts = new LinkedList<>();
- for (String number : numbers) {
- Optional account = getAccount(number);
- if (account.isPresent())
- accounts.add(account.get());
+ for (Device device : devices) {
+ Account deviceAccount = null;
+ for (Account account : accounts) {
+ if (account.getNumber().equals(device.getNumber())) {
+ deviceAccount = account;
+ break;
+ }
+ }
+
+ if (deviceAccount == null) {
+ deviceAccount = new Account(device.getNumber(), false, device);
+ accounts.add(deviceAccount);
+ } else {
+ deviceAccount.addDevice(device);
+ }
+
+ if (device.getDeviceId() == 1)
+ deviceAccount.setSupportsSms(device.getSupportsSms());
}
return accounts;
}
public List getAccountsForDevices(Map> destinations) throws MissingDevicesException {
Set numbersMissingDevices = new HashSet<>(destinations.keySet());
- List localAccounts = getAllAccounts(destinations.keySet());
+ List localAccounts = getAllAccounts(new LinkedList<>(destinations.keySet()));
for (Account account : localAccounts){
if (account.hasAllDeviceIds(destinations.get(account.getNumber())))