Set '_more_accounts' on last account of query result

If the number of accounts matching the query exceeds the limit the
last account has a '_more_accounts: true' JSON field set.

Change-Id: Icc8c34c37c72f7df00bb06c67602bea36a4ae09f
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2016-06-30 15:29:05 +02:00
parent 6115eae5d0
commit 7bb93e4601
4 changed files with 45 additions and 31 deletions

View File

@@ -23,7 +23,7 @@ returned.
.Request
----
GET /accounts/?q=name:John+email:example.com HTTP/1.0
GET /accounts/?q=name:John+email:example.com&n=2 HTTP/1.0
----
.Response
@@ -44,11 +44,16 @@ returned.
"_account_id": 1001439,
"name": "John Smith",
"email": "john.smith@example.com",
"username": "jsmith"
"username": "jsmith",
"_more_accounts": true
}
]
----
If the number of accounts matching the query exceeds either the
internal limit or a supplied `n` query parameter, the last account
object has a `_more_accounts: true` JSON field set.
The `S` or `start` query parameter can be supplied to skip a number
of accounts from the list.
@@ -1938,20 +1943,23 @@ registered.
The `AccountInfo` entity contains information about an account.
[options="header",cols="1,^1,5"]
|===========================
|Field Name ||Description
|`_account_id` ||The numeric ID of the account.
|`name` |optional|The full name of the user. +
|=============================
|Field Name ||Description
|`_account_id` ||The numeric ID of the account.
|`name` |optional|The full name of the user. +
Only set if link:rest-api-changes.html#detailed-accounts[detailed
account information] is requested.
|`email` |optional|
|`email` |optional|
The email address the user prefers to be contacted through. +
Only set if link:rest-api-changes.html#detailed-accounts[detailed
account information] is requested.
|`username` |optional|The username of the user. +
|`username` |optional|The username of the user. +
Only set if link:rest-api-changes.html#detailed-accounts[detailed
account information] is requested.
|===========================
|`_more_accounts`|optional, not set if `false`|
Whether the query would deliver more results if not limited. +
Only set on the last account that is returned.
|=============================
[[account-input]]
=== AccountInput

View File

@@ -22,6 +22,7 @@ public class AccountInfo {
public String email;
public String username;
public List<AvatarInfo> avatars;
public Boolean _moreAccounts;
public AccountInfo(Integer id) {
this._accountId = id;

View File

@@ -15,7 +15,7 @@
package com.google.gerrit.server.account;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
@@ -39,7 +39,6 @@ import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
import org.kohsuke.args4j.Option;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -139,23 +138,20 @@ public class QueryAccounts implements RestReadView<TopLevelResource> {
}
AccountIndex searchIndex = indexes.getSearchIndex();
Collection<AccountInfo> matches;
if (searchIndex != null) {
matches = queryFromIndex();
} else {
if (!suggest) {
throw new MethodNotAllowedException();
}
if (start != null) {
throw new MethodNotAllowedException("option start not allowed");
}
matches = queryFromDb();
return queryFromIndex();
}
return AccountInfoComparator.ORDER_NULLS_LAST.sortedCopy(matches);
if (!suggest) {
throw new MethodNotAllowedException();
}
if (start != null) {
throw new MethodNotAllowedException("option start not allowed");
}
return queryFromDb();
}
public Collection<AccountInfo> queryFromIndex()
public List<AccountInfo> queryFromIndex()
throws BadRequestException, MethodNotAllowedException, OrmException {
if (queryProcessor.isDisabled()) {
throw new MethodNotAllowedException("query disabled");
@@ -179,18 +175,24 @@ public class QueryAccounts implements RestReadView<TopLevelResource> {
Account.Id id = accountState.getAccount().getId();
matches.put(id, accountLoader.get(id));
}
accountLoader.fill();
List<AccountInfo> sorted =
AccountInfoComparator.ORDER_NULLS_LAST.sortedCopy(matches.values());
if (!sorted.isEmpty() && result.more()) {
sorted.get(sorted.size() - 1)._moreAccounts = true;
}
return sorted;
} catch (QueryParseException e) {
if (suggest) {
return ImmutableSet.of();
return ImmutableList.of();
}
throw new BadRequestException(e.getMessage());
}
accountLoader.fill();
return matches.values();
}
public Collection<AccountInfo> queryFromDb() throws OrmException {
public List<AccountInfo> queryFromDb() throws OrmException {
String a = query;
String b = a + MAX_SUFFIX;
@@ -223,7 +225,7 @@ public class QueryAccounts implements RestReadView<TopLevelResource> {
}
}
return matches.values();
return AccountInfoComparator.ORDER_NULLS_LAST.sortedCopy(matches.values());
}
private boolean addSuggestion(Map<Account.Id, AccountInfo> map, Account a) {

View File

@@ -252,8 +252,11 @@ public abstract class AbstractQueryAccountsTest extends GerritServerTests {
AccountInfo user2 = newAccountWithEmail("user2", "user2@" + domain);
AccountInfo user3 = newAccountWithEmail("user3", "user3@" + domain);
assertQuery(domain, user1, user2, user3);
assertQuery(newQuery(domain).withLimit(2), user1, user2);
List<AccountInfo> result = assertQuery(domain, user1, user2, user3);
assertThat(result.get(result.size() - 1)._moreAccounts).isNull();
result = assertQuery(newQuery(domain).withLimit(2), user1, user2);
assertThat(result.get(result.size() - 1)._moreAccounts).isTrue();
}
@Test