Add a --no-limit option to the ssh and rest query commands
This option will return all possible results and overrides the default limit and any limit specified using "limit" query operator. This is useful for applications that need the entire result set with a single query. Getting data with a single query improves the accuracy since there is less chance of the data being modified between calls. Change-Id: Idc4dd5799195110c580c7e6d88c0a6e8c6734d6c
This commit is contained in:
committed by
Sabari Ajay Kumar
parent
36786eaf54
commit
b186cd759f
@@ -17,6 +17,7 @@ _ssh_ -p <port> <host> _gerrit query_
|
|||||||
[--submit-records]
|
[--submit-records]
|
||||||
[--all-reviewers]
|
[--all-reviewers]
|
||||||
[--start <n> | -S <n>]
|
[--start <n> | -S <n>]
|
||||||
|
[--no-limit]
|
||||||
[--]
|
[--]
|
||||||
<query>
|
<query>
|
||||||
[limit:<n>]
|
[limit:<n>]
|
||||||
@@ -101,6 +102,9 @@ command line parser in the server).
|
|||||||
-S::
|
-S::
|
||||||
Number of changes to skip.
|
Number of changes to skip.
|
||||||
|
|
||||||
|
--no-limit::
|
||||||
|
Return all results, overriding the default limit.
|
||||||
|
|
||||||
limit:<n>::
|
limit:<n>::
|
||||||
Maximum number of results to return. This is actually a
|
Maximum number of results to return. This is actually a
|
||||||
query operator, and not a command line option. If more
|
query operator, and not a command line option. If more
|
||||||
|
|||||||
@@ -350,6 +350,11 @@ be recomputed often, which is slow for projects with big trees.
|
|||||||
as link:#tracking-id-info[TrackingIdInfo].
|
as link:#tracking-id-info[TrackingIdInfo].
|
||||||
--
|
--
|
||||||
|
|
||||||
|
[[no-limit]]
|
||||||
|
--
|
||||||
|
* `NO-LIMIT`: Return all results
|
||||||
|
--
|
||||||
|
|
||||||
.Request
|
.Request
|
||||||
----
|
----
|
||||||
GET /changes/?q=97&o=CURRENT_REVISION&o=CURRENT_COMMIT&o=CURRENT_FILES&o=DOWNLOAD_COMMANDS HTTP/1.0
|
GET /changes/?q=97&o=CURRENT_REVISION&o=CURRENT_COMMIT&o=CURRENT_FILES&o=DOWNLOAD_COMMANDS HTTP/1.0
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.google.gerrit.common.data.LabelFunction;
|
|||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.LabelValue;
|
import com.google.gerrit.common.data.LabelValue;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
|
import com.google.gerrit.common.data.PermissionRange;
|
||||||
import com.google.gerrit.common.data.PermissionRule;
|
import com.google.gerrit.common.data.PermissionRule;
|
||||||
import com.google.gerrit.common.data.PermissionRule.Action;
|
import com.google.gerrit.common.data.PermissionRule.Action;
|
||||||
import com.google.gerrit.extensions.api.GerritApi;
|
import com.google.gerrit.extensions.api.GerritApi;
|
||||||
@@ -954,6 +955,17 @@ public abstract class AbstractDaemonTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void allowGlobalCapabilities(
|
||||||
|
AccountGroup.UUID id, int min, int max, String... capabilityNames) throws Exception {
|
||||||
|
try (ProjectConfigUpdate u = updateProject(allProjects)) {
|
||||||
|
for (String capabilityName : capabilityNames) {
|
||||||
|
Util.allow(
|
||||||
|
u.getConfig(), capabilityName, id, new PermissionRange(capabilityName, min, max));
|
||||||
|
}
|
||||||
|
u.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void allowGlobalCapabilities(AccountGroup.UUID id, String... capabilityNames)
|
protected void allowGlobalCapabilities(AccountGroup.UUID id, String... capabilityNames)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
allowGlobalCapabilities(id, Arrays.asList(capabilityNames));
|
allowGlobalCapabilities(id, Arrays.asList(capabilityNames));
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ public interface Changes {
|
|||||||
private String query;
|
private String query;
|
||||||
private int limit;
|
private int limit;
|
||||||
private int start;
|
private int start;
|
||||||
|
private boolean isNoLimit;
|
||||||
private EnumSet<ListChangesOption> options = EnumSet.noneOf(ListChangesOption.class);
|
private EnumSet<ListChangesOption> options = EnumSet.noneOf(ListChangesOption.class);
|
||||||
|
|
||||||
public abstract List<ChangeInfo> get() throws RestApiException;
|
public abstract List<ChangeInfo> get() throws RestApiException;
|
||||||
@@ -89,6 +90,11 @@ public interface Changes {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryRequest withNoLimit() {
|
||||||
|
this.isNoLimit = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public QueryRequest withStart(int start) {
|
public QueryRequest withStart(int start) {
|
||||||
this.start = start;
|
this.start = start;
|
||||||
return this;
|
return this;
|
||||||
@@ -117,6 +123,10 @@ public interface Changes {
|
|||||||
return limit;
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getNoLimit() {
|
||||||
|
return isNoLimit;
|
||||||
|
}
|
||||||
|
|
||||||
public int getStart() {
|
public int getStart() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
@@ -137,7 +147,11 @@ public interface Changes {
|
|||||||
if (!options.isEmpty()) {
|
if (!options.isEmpty()) {
|
||||||
sb.append("options=").append(options);
|
sb.append("options=").append(options);
|
||||||
}
|
}
|
||||||
return sb.append('}').toString();
|
sb.append('}');
|
||||||
|
if (isNoLimit == true) {
|
||||||
|
sb.append(" --no-limit");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ public abstract class QueryProcessor<T> {
|
|||||||
|
|
||||||
private boolean enforceVisibility = true;
|
private boolean enforceVisibility = true;
|
||||||
private int userProvidedLimit;
|
private int userProvidedLimit;
|
||||||
|
private boolean isNoLimit;
|
||||||
private Set<String> requestedFields;
|
private Set<String> requestedFields;
|
||||||
|
|
||||||
protected QueryProcessor(
|
protected QueryProcessor(
|
||||||
@@ -157,6 +158,11 @@ public abstract class QueryProcessor<T> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QueryProcessor<T> setNoLimit(boolean isNoLimit) {
|
||||||
|
this.isNoLimit = isNoLimit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public QueryProcessor<T> setRequestedFields(Set<String> fields) {
|
public QueryProcessor<T> setRequestedFields(Set<String> fields) {
|
||||||
requestedFields = fields;
|
requestedFields = fields;
|
||||||
return this;
|
return this;
|
||||||
@@ -354,6 +360,9 @@ public abstract class QueryProcessor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getEffectiveLimit(Predicate<T> p) {
|
private int getEffectiveLimit(Predicate<T> p) {
|
||||||
|
if (isNoLimit == true) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
List<Integer> possibleLimits = new ArrayList<>(4);
|
List<Integer> possibleLimits = new ArrayList<>(4);
|
||||||
possibleLimits.add(getBackendSupportedLimit());
|
possibleLimits.add(getBackendSupportedLimit());
|
||||||
possibleLimits.add(getPermittedLimit());
|
possibleLimits.add(getPermittedLimit());
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ class ChangesImpl implements Changes {
|
|||||||
}
|
}
|
||||||
qc.setLimit(q.getLimit());
|
qc.setLimit(q.getLimit());
|
||||||
qc.setStart(q.getStart());
|
qc.setStart(q.getStart());
|
||||||
|
qc.setNoLimit(q.getNoLimit());
|
||||||
for (ListChangesOption option : q.getOptions()) {
|
for (ListChangesOption option : q.getOptions()) {
|
||||||
qc.addOption(option);
|
qc.addOption(option);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,16 +124,28 @@ public class Util {
|
|||||||
|
|
||||||
public static PermissionRule allow(
|
public static PermissionRule allow(
|
||||||
ProjectConfig project, String capabilityName, AccountGroup.UUID group) {
|
ProjectConfig project, String capabilityName, AccountGroup.UUID group) {
|
||||||
|
return allow(project, capabilityName, group, (PermissionRange) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PermissionRule allow(
|
||||||
|
ProjectConfig project,
|
||||||
|
String capabilityName,
|
||||||
|
AccountGroup.UUID group,
|
||||||
|
PermissionRange customRange) {
|
||||||
PermissionRule rule = newRule(project, group);
|
PermissionRule rule = newRule(project, group);
|
||||||
project
|
project
|
||||||
.getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
|
.getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
|
||||||
.getPermission(capabilityName, true)
|
.getPermission(capabilityName, true)
|
||||||
.add(rule);
|
.add(rule);
|
||||||
if (GlobalCapability.hasRange(capabilityName)) {
|
if (GlobalCapability.hasRange(capabilityName)) {
|
||||||
PermissionRange.WithDefaults range = GlobalCapability.getRange(capabilityName);
|
if (customRange == null) {
|
||||||
if (range != null) {
|
PermissionRange.WithDefaults range = GlobalCapability.getRange(capabilityName);
|
||||||
rule.setRange(range.getDefaultMin(), range.getDefaultMax());
|
if (range != null) {
|
||||||
|
rule.setRange(range.getDefaultMin(), range.getDefaultMax());
|
||||||
|
}
|
||||||
|
return rule;
|
||||||
}
|
}
|
||||||
|
rule.setRange(customRange.getMin(), customRange.getMax());
|
||||||
}
|
}
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ public class OutputStreamQuery {
|
|||||||
queryProcessor.setUserProvidedLimit(n);
|
queryProcessor.setUserProvidedLimit(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNoLimit(boolean on) {
|
||||||
|
queryProcessor.setNoLimit(on);
|
||||||
|
}
|
||||||
|
|
||||||
public void setStart(int n) {
|
public void setStart(int n) {
|
||||||
queryProcessor.setStart(n);
|
queryProcessor.setStart(n);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ public class QueryChanges implements RestReadView<TopLevelResource>, DynamicOpti
|
|||||||
imp.setStart(start);
|
imp.setStart(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Option(name = "--no-limit", usage = "Return all results, overriding the default limit")
|
||||||
|
public void setNoLimit(boolean on) {
|
||||||
|
imp.setNoLimit(on);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDynamicBean(String plugin, DynamicOptions.DynamicBean dynamicBean) {
|
public void setDynamicBean(String plugin, DynamicOptions.DynamicBean dynamicBean) {
|
||||||
imp.setDynamicBean(plugin, dynamicBean);
|
imp.setDynamicBean(plugin, dynamicBean);
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ public class Query extends SshCommand implements DynamicOptions.BeanReceiver {
|
|||||||
processor.setStart(start);
|
processor.setStart(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Option(name = "--no-limit", usage = "Return all results, overriding the default limit")
|
||||||
|
void setNoLimit(boolean on) {
|
||||||
|
processor.setNoLimit(on);
|
||||||
|
}
|
||||||
|
|
||||||
@Argument(
|
@Argument(
|
||||||
index = 0,
|
index = 0,
|
||||||
required = true,
|
required = true,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
|
|||||||
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
|
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
|
||||||
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
|
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
|
||||||
import com.google.gerrit.common.FooterConstants;
|
import com.google.gerrit.common.FooterConstants;
|
||||||
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.common.data.LabelFunction;
|
import com.google.gerrit.common.data.LabelFunction;
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
@@ -2553,6 +2554,19 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
assertThat(Iterables.getOnlyElement(results).changeId).isEqualTo(r2.getChangeId());
|
assertThat(Iterables.getOnlyElement(results).changeId).isEqualTo(r2.getChangeId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryChangesNoLimit() throws Exception {
|
||||||
|
allowGlobalCapabilities(
|
||||||
|
SystemGroupBackend.REGISTERED_USERS, 0, 2, GlobalCapability.QUERY_LIMIT);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
createChange();
|
||||||
|
}
|
||||||
|
List<ChangeInfo> resultsWithDefaultLimit = gApi.changes().query().get();
|
||||||
|
List<ChangeInfo> resultsWithNoLimit = gApi.changes().query().withNoLimit().get();
|
||||||
|
assertThat(resultsWithDefaultLimit).hasSize(2);
|
||||||
|
assertThat(resultsWithNoLimit.size()).isAtLeast(3);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void queryChangesStart() throws Exception {
|
public void queryChangesStart() throws Exception {
|
||||||
PushOneCommit.Result r1 = createChange();
|
PushOneCommit.Result r1 = createChange();
|
||||||
|
|||||||
Reference in New Issue
Block a user