AccountIndex: Add field for exact preferred email

All callers that query accounts be preferred email are interested in
exact matches. With the new field we can do exact queries instead of
doing a prefix query and post filter the results.

Change-Id: I1dcdfb1be7090211eda97ad4709fa49a2a8fecdd
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2017-08-18 09:24:40 +02:00
parent 790250d0c7
commit 8752079965
6 changed files with 42 additions and 1 deletions

View File

@@ -90,6 +90,9 @@ public class AccountField {
return preferredEmail != null ? preferredEmail.toLowerCase() : null;
});
public static final FieldDef<AccountState, String> PREFERRED_EMAIL_EXACT =
exact("preferredemail_exact").build(a -> a.getAccount().getPreferredEmail());
public static final FieldDef<AccountState, Timestamp> REGISTERED =
timestamp("registered").build(a -> a.getAccount().getRegisteredOn());

View File

@@ -36,9 +36,12 @@ public class AccountSchemaDefinitions extends SchemaDefinitions<AccountState> {
@Deprecated static final Schema<AccountState> V5 = schema(V4, AccountField.PREFERRED_EMAIL);
@Deprecated
static final Schema<AccountState> V6 =
schema(V5, AccountField.REF_STATE, AccountField.EXTERNAL_ID_STATE);
static final Schema<AccountState> V7 = schema(V6, AccountField.PREFERRED_EMAIL_EXACT);
public static final String NAME = "accounts";
public static final AccountSchemaDefinitions INSTANCE = new AccountSchemaDefinitions();

View File

@@ -66,6 +66,11 @@ public class AccountPredicates {
email.toLowerCase());
}
public static Predicate<AccountState> preferredEmailExact(String email) {
return new AccountPredicate(
AccountField.PREFERRED_EMAIL_EXACT, AccountQueryBuilder.FIELD_PREFERRED_EMAIL_EXACT, email);
}
public static Predicate<AccountState> equalsName(String name) {
return new AccountPredicate(
AccountField.NAME_PART, AccountQueryBuilder.FIELD_NAME, name.toLowerCase());

View File

@@ -37,6 +37,7 @@ public class AccountQueryBuilder extends QueryBuilder<AccountState> {
public static final String FIELD_LIMIT = "limit";
public static final String FIELD_NAME = "name";
public static final String FIELD_PREFERRED_EMAIL = "preferredemail";
public static final String FIELD_PREFERRED_EMAIL_EXACT = "preferredemail_exact";
public static final String FIELD_USERNAME = "username";
public static final String FIELD_VISIBLETO = "visibleto";

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.index.query.InternalQuery;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.index.account.AccountField;
import com.google.gerrit.server.index.account.AccountIndexCollection;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -122,6 +123,10 @@ public class InternalAccountQuery extends InternalQuery<AccountState> {
* @throws OrmException if query cannot be parsed
*/
public List<AccountState> byPreferredEmail(String email) throws OrmException {
if (schema().hasField(AccountField.PREFERRED_EMAIL_EXACT)) {
return query(AccountPredicates.preferredEmailExact(email));
}
return query(AccountPredicates.preferredEmail(email))
.stream()
.filter(a -> a.getAccount().getPreferredEmail().equals(email))
@@ -138,6 +143,21 @@ public class InternalAccountQuery extends InternalQuery<AccountState> {
*/
public Multimap<String, AccountState> byPreferredEmail(String... emails) throws OrmException {
List<String> emailList = Arrays.asList(emails);
if (schema().hasField(AccountField.PREFERRED_EMAIL_EXACT)) {
List<List<AccountState>> r =
query(
emailList
.stream()
.map(e -> AccountPredicates.preferredEmailExact(e))
.collect(toList()));
Multimap<String, AccountState> accountsByEmail = ArrayListMultimap.create();
for (int i = 0; i < emailList.size(); i++) {
accountsByEmail.putAll(emailList.get(i), r.get(i));
}
return accountsByEmail;
}
List<List<AccountState>> r =
query(emailList.stream().map(e -> AccountPredicates.preferredEmail(e)).collect(toList()));
Multimap<String, AccountState> accountsByEmail = ArrayListMultimap.create();