/changes/: Permit multiple queries at once
Allow the client to specify more than one q parameter. When there
is more than one query defined the result is an array of arrays,
one per query in the same order the queries were given in.
This query now approximates how to show a user's dashboard:
$ curl -n --digest 'http://127.0.0.1:8080/a/changes/?q=is:open+owner:self&q=is:open+reviewer:self+-owner:self&q=is:closed+owner:self+limit:5&format=JSON'
)]}'
[
[
{
"project": "tools/repo",
"branch": "master",
"id": "I37f758e238c2dbc891a0d876547cb7acc29fc7f7",
}
],
[],
[]
]
Change-Id: I1914a9971c519a5539ce0fbe56c6d5776d7bd72f
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
index 87377cd..ecfec96 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ListChanges.java
@@ -43,6 +43,7 @@
import java.io.IOException;
import java.io.Writer;
import java.sql.Timestamp;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -59,8 +60,8 @@
@Option(name = "--format", metaVar = "FMT", usage = "Output display format")
private OutputFormat format = OutputFormat.TEXT;
- @Option(name = "--query", aliases = {"-q"}, metaVar = "QUERY", usage = "Query string")
- private String query = "status:open";
+ @Option(name = "--query", aliases = {"-q"}, metaVar = "QUERY", multiValued = true, usage = "Query string")
+ private List<String> queries;
@Option(name = "--limit", aliases = {"-n"}, metaVar = "CNT", usage = "Maximum number of results to return")
void setLimit(int limit) {
@@ -115,46 +116,65 @@
if (imp.isDisabled()) {
throw new QueryParseException("query disabled");
}
-
- List<ChangeData> changes = imp.queryChanges(query);
- boolean moreChanges = imp.getLimit() > 0 && changes.size() > imp.getLimit();
- if (moreChanges) {
- if (reverse) {
- changes = changes.subList(1, changes.size());
- } else {
- changes = changes.subList(0, imp.getLimit());
- }
+ if (queries == null || queries.isEmpty()) {
+ queries = Collections.singletonList("status:open");
+ } else if (queries.size() > 10) {
+ // Hard-code a default maximum number of queries to prevent
+ // users from submitting too much to the server in a single call.
+ throw new QueryParseException("limit of 10 queries");
}
- List<ChangeInfo> info = Lists.newArrayListWithCapacity(changes.size());
- for (ChangeData cd : changes) {
- info.add(toChangeInfo(cd));
- }
- if (moreChanges && !info.isEmpty()) {
- if (reverse) {
- info.get(0)._moreChanges = true;
- } else {
- info.get(info.size() - 1)._moreChanges = true;
+ List<List<ChangeInfo>> res = Lists.newArrayListWithCapacity(queries.size());
+ for (String query : queries) {
+ List<ChangeData> changes = imp.queryChanges(query);
+ boolean moreChanges = imp.getLimit() > 0 && changes.size() > imp.getLimit();
+ if (moreChanges) {
+ if (reverse) {
+ changes = changes.subList(1, changes.size());
+ } else {
+ changes = changes.subList(0, imp.getLimit());
+ }
}
+
+ List<ChangeInfo> info = Lists.newArrayListWithCapacity(changes.size());
+ for (ChangeData cd : changes) {
+ info.add(toChangeInfo(cd));
+ }
+ if (moreChanges && !info.isEmpty()) {
+ if (reverse) {
+ info.get(0)._moreChanges = true;
+ } else {
+ info.get(info.size() - 1)._moreChanges = true;
+ }
+ }
+ res.add(info);
}
if (format.isJson()) {
format.newGson().toJson(
- info,
+ res.size() == 1 ? res.get(0) : res,
new TypeToken<List<ChangeInfo>>() {}.getType(),
out);
out.write('\n');
} else {
- for (ChangeInfo c : info) {
- String id = new Change.Key(c.id).abbreviate();
- String subject = c.subject;
- if (subject.length() + id.length() > 80) {
- subject = subject.substring(0, 80 - id.length());
+ boolean firstQuery = true;
+ for (List<ChangeInfo> info : res) {
+ if (firstQuery) {
+ firstQuery = false;
+ } else {
+ out.write('\n');
}
- out.write(id);
- out.write(' ');
- out.write(subject.replace('\n', ' '));
- out.write('\n');
+ for (ChangeInfo c : info) {
+ String id = new Change.Key(c.id).abbreviate();
+ String subject = c.subject;
+ if (subject.length() + id.length() > 80) {
+ subject = subject.substring(0, 80 - id.length());
+ }
+ out.write(id);
+ out.write(' ');
+ out.write(subject.replace('\n', ' '));
+ out.write('\n');
+ }
}
}
}