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())))