diff options
author | Edwin Kempin <ekempin@google.com> | 2023-08-16 08:13:43 +0000 |
---|---|---|
committer | Edwin Kempin <ekempin@google.com> | 2023-08-16 08:14:47 +0000 |
commit | 6d861b5eaab02374236bf856e1465039b7def819 (patch) | |
tree | 97f72b814fc2c0e363c48cfad5c5f99bebbfb251 | |
parent | e9edc9fceff535b406e511ac413e90caf4c1b888 (diff) |
ListProjectImpl: Delegate to QueryProjects if prefix is used
QueryProjects supports matching by prefix now (see change Ibfb3b354f),
hence enable delegation to QueryProjects if this option is used.
The delegation only happens when 'gerrit.listProjectsFromIndex' is set
to 'true'.
Searching projects by prefix is only supported from project index
version V8 that added PREFIX_NAME_SPEC. Hence we can only delegate to
QueryProjects if that field is present in the currently used index
schema.
Release-Notes: skip
Change-Id: I140d095a63956c5b04ad911ead12fb6189a480e9
Signed-off-by: Edwin Kempin <ekempin@google.com>
-rw-r--r-- | java/com/google/gerrit/server/restapi/project/ListProjectsImpl.java | 30 | ||||
-rw-r--r-- | javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java | 13 |
2 files changed, 38 insertions, 5 deletions
diff --git a/java/com/google/gerrit/server/restapi/project/ListProjectsImpl.java b/java/com/google/gerrit/server/restapi/project/ListProjectsImpl.java index 055648d2f7..09f6d71478 100644 --- a/java/com/google/gerrit/server/restapi/project/ListProjectsImpl.java +++ b/java/com/google/gerrit/server/restapi/project/ListProjectsImpl.java @@ -41,6 +41,8 @@ import com.google.gerrit.extensions.restapi.MethodNotAllowedException; import com.google.gerrit.extensions.restapi.Response; import com.google.gerrit.extensions.restapi.TopLevelResource; import com.google.gerrit.extensions.restapi.Url; +import com.google.gerrit.index.project.ProjectField; +import com.google.gerrit.index.project.ProjectIndexCollection; import com.google.gerrit.json.OutputFormat; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.WebLinks; @@ -184,6 +186,7 @@ public class ListProjectsImpl extends AbstractListProjects { private AccountGroup.UUID groupUuid; private final Provider<QueryProjects> queryProjectsProvider; private final boolean listProjectsFromIndex; + private final ProjectIndexCollection projectIndexes; @Inject protected ListProjectsImpl( @@ -196,7 +199,8 @@ public class ListProjectsImpl extends AbstractListProjects { ProjectNode.Factory projectNodeFactory, WebLinks webLinks, Provider<QueryProjects> queryProjectsProvider, - @GerritServerConfig Config config) { + @GerritServerConfig Config config, + ProjectIndexCollection projectIndexes) { this.currentUser = currentUser; this.projectCache = projectCache; this.groupResolver = groupResolver; @@ -207,6 +211,7 @@ public class ListProjectsImpl extends AbstractListProjects { this.webLinks = webLinks; this.queryProjectsProvider = queryProjectsProvider; this.listProjectsFromIndex = config.getBoolean("gerrit", "listProjectsFromIndex", false); + this.projectIndexes = projectIndexes; } public List<String> getShowBranch() { @@ -251,11 +256,15 @@ public class ListProjectsImpl extends AbstractListProjects { return display(null); } - private Optional<String> expressAsProjectsQuery() { + private Optional<String> expressAsProjectsQuery() throws BadRequestException { return listProjectsFromIndex && !all && state != HIDDEN - && isNullOrEmpty(matchPrefix) + && (isNullOrEmpty(matchPrefix) + || projectIndexes + .getSearchIndex() + .getSchema() + .hasField(ProjectField.PREFIX_NAME_SPEC)) && isNullOrEmpty(matchRegex) && type == FilterType.ALL && showBranch.isEmpty() @@ -264,12 +273,25 @@ public class ListProjectsImpl extends AbstractListProjects { : Optional.empty(); } - private String toQuery() { + private String toQuery() throws BadRequestException { + // QueryProjects supports specifying matchPrefix and matchSubstring at the same time, but to + // keep the behavior consistent regardless of whether 'gerrit.listProjectsFromIndex' is true or + // false, disallow specifying both at the same time here. This way + // 'gerrit.listProjectsFromIndex' can be troggled without breaking any caller. + if (matchPrefix != null) { + checkMatchOptions(matchSubstring == null); + } else if (matchSubstring != null) { + checkMatchOptions(matchPrefix == null); + } + List<String> queries = new ArrayList<>(); if (state != null) { queries.add(String.format("(state:%s)", state.name())); } + if (!isNullOrEmpty(matchPrefix)) { + queries.add(String.format("prefix:%s", matchPrefix)); + } if (!isNullOrEmpty(matchSubstring)) { queries.add(String.format("substring:%s", matchSubstring)); } diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java index 5a7d7b3271..1b3ff0d5b4 100644 --- a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java +++ b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java @@ -199,7 +199,18 @@ public class ListProjectsIT extends AbstractDaemonTest { } @Test - public void listProjectsWithPrefix() throws Exception { + @GerritConfig(name = "gerrit.listProjectsFromIndex", value = "true") + public void listProjectsWithPrefix_indexEnabled() throws Exception { + testListProjectsWithPrefix(); + } + + @Test + @GerritConfig(name = "gerrit.listProjectsFromIndex", value = "false") + public void listProjectsWithPrefix_indexDisabled() throws Exception { + testListProjectsWithPrefix(); + } + + private void testListProjectsWithPrefix() throws Exception { Project.NameKey someProject = projectOperations.newProject().name("listtest-p1").create(); Project.NameKey someOtherProject = projectOperations.newProject().name("listtest-p2").create(); projectOperations.newProject().name("other-prefix-project").create(); |