One query to get set of accounts and long-existing logic error.

This commit is contained in:
Matt Corallo 2014-01-11 17:02:08 -10:00
parent eedaa8b3f4
commit 6f9226dcf9
5 changed files with 41 additions and 12 deletions

View File

@ -109,6 +109,11 @@
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>stringtemplate</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
<build>

View File

@ -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;

View File

@ -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<Device> 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);
}
}

View File

@ -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<Device> getAllByNumber(@Bind("number") String number);
@Mapper(DeviceMapper.class)
@SqlQuery("SELECT * FROM accounts WHERE " + NUMBER + " IN ( <numbers> )")
public abstract List<Device> getAllByNumbers(@BindIn("numbers") List<String> numbers);
@Transaction(TransactionIsolationLevel.SERIALIZABLE)
public long insertClearingNumber(Device device) {
removeAccountsByNumber(device.getNumber());

View File

@ -120,20 +120,34 @@ public class AccountsManager {
return Optional.of(new Account(number, devices.get(0).getSupportsSms(), devices));
}
private List<Account> getAllAccounts(Set<String> numbers) {
//TODO: ONE QUERY
private List<Account> getAllAccounts(List<String> numbers) {
List<Device> devices = accounts.getAllByNumbers(numbers);
List<Account> accounts = new LinkedList<>();
for (String number : numbers) {
Optional<Account> 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<Account> getAccountsForDevices(Map<String, Set<Long>> destinations) throws MissingDevicesException {
Set<String> numbersMissingDevices = new HashSet<>(destinations.keySet());
List<Account> localAccounts = getAllAccounts(destinations.keySet());
List<Account> localAccounts = getAllAccounts(new LinkedList<>(destinations.keySet()));
for (Account account : localAccounts){
if (account.hasAllDeviceIds(destinations.get(account.getNumber())))