Add STATE field to ProjectIndex
This commit adds the ProjectState to the project index and makes it queryable. V2 was added in this series, so adding a field does not require creating V3. Our post processors filter out hidden projects, so it doesn't make much sense for users to query for them. As a future optimisation we can make the default query exclude hidden projects by adding 'not state:hidden' so that we have to do less post-filtering. Change-Id: I98434e4b4ea232e257cca4b551fcaba21b3db656
This commit is contained in:
parent
814d296805
commit
36de336dc1
@ -24,6 +24,11 @@ description:'DESCRIPTION'::
|
||||
Matches projects whose description contains 'DESCRIPTION', using a
|
||||
full-text search.
|
||||
|
||||
[[state]]
|
||||
state:'STATE'::
|
||||
+
|
||||
Matches project's state. Can be either 'active' or 'read-only'.
|
||||
|
||||
== Magical Operators
|
||||
|
||||
[[is-visible]]
|
||||
|
@ -45,6 +45,9 @@ public class ProjectField {
|
||||
public static final FieldDef<ProjectData, Iterable<String>> NAME_PART =
|
||||
prefix("name_part").buildRepeatable(p -> SchemaUtil.getNameParts(p.getProject().getName()));
|
||||
|
||||
public static final FieldDef<ProjectData, String> STATE =
|
||||
exact("state").stored().build(p -> p.getProject().getState().name());
|
||||
|
||||
public static final FieldDef<ProjectData, Iterable<String>> ANCESTOR_NAME =
|
||||
exact("ancestor_name").buildRepeatable(p -> p.getParentNames());
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class ProjectSchemaDefinitions extends SchemaDefinitions<ProjectData> {
|
||||
ProjectField.NAME_PART,
|
||||
ProjectField.ANCESTOR_NAME);
|
||||
|
||||
static final Schema<ProjectData> V2 = schema(V1, ProjectField.REF_STATE);
|
||||
static final Schema<ProjectData> V2 = schema(V1, ProjectField.STATE, ProjectField.REF_STATE);
|
||||
|
||||
public static final ProjectSchemaDefinitions INSTANCE = new ProjectSchemaDefinitions();
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.query.project;
|
||||
|
||||
import com.google.gerrit.extensions.client.ProjectState;
|
||||
import com.google.gerrit.index.project.ProjectData;
|
||||
import com.google.gerrit.index.project.ProjectField;
|
||||
import com.google.gerrit.index.project.ProjectPredicate;
|
||||
@ -34,5 +35,9 @@ public class ProjectPredicates {
|
||||
return new ProjectPredicate(ProjectField.DESCRIPTION, description);
|
||||
}
|
||||
|
||||
public static Predicate<ProjectData> state(ProjectState state) {
|
||||
return new ProjectPredicate(ProjectField.STATE, state.name());
|
||||
}
|
||||
|
||||
private ProjectPredicates() {}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package com.google.gerrit.server.query.project;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.gerrit.extensions.client.ProjectState;
|
||||
import com.google.gerrit.index.project.ProjectData;
|
||||
import com.google.gerrit.index.query.LimitPredicate;
|
||||
import com.google.gerrit.index.query.Predicate;
|
||||
@ -60,6 +61,23 @@ public class ProjectQueryBuilder extends QueryBuilder<ProjectData> {
|
||||
return ProjectPredicates.description(description);
|
||||
}
|
||||
|
||||
@Operator
|
||||
public Predicate<ProjectData> state(String state) throws QueryParseException {
|
||||
if (Strings.isNullOrEmpty(state)) {
|
||||
throw error("state operator requires a value");
|
||||
}
|
||||
ProjectState parsedState;
|
||||
try {
|
||||
parsedState = ProjectState.valueOf(state.replace('-', '_').toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw error("state operator must be either 'active' or 'read-only'");
|
||||
}
|
||||
if (parsedState == ProjectState.HIDDEN) {
|
||||
throw error("state operator must be either 'active' or 'read-only'");
|
||||
}
|
||||
return ProjectPredicates.state(parsedState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<ProjectData> defaultField(String query) throws QueryParseException {
|
||||
// Adapt the capacity of this list when adding more default predicates.
|
||||
|
@ -15,15 +15,21 @@
|
||||
package com.google.gerrit.server.query.project;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.TruthJUnit.assume;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.gerrit.extensions.api.GerritApi;
|
||||
import com.google.gerrit.extensions.api.projects.ConfigInput;
|
||||
import com.google.gerrit.extensions.api.projects.ProjectInput;
|
||||
import com.google.gerrit.extensions.api.projects.Projects.QueryRequest;
|
||||
import com.google.gerrit.extensions.client.ProjectState;
|
||||
import com.google.gerrit.extensions.common.AccountInfo;
|
||||
import com.google.gerrit.extensions.common.ProjectInfo;
|
||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.index.Schema;
|
||||
import com.google.gerrit.index.project.ProjectData;
|
||||
import com.google.gerrit.index.project.ProjectIndexCollection;
|
||||
import com.google.gerrit.lifecycle.LifecycleManager;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
@ -38,7 +44,6 @@ import com.google.gerrit.server.account.Accounts;
|
||||
import com.google.gerrit.server.account.AccountsUpdate;
|
||||
import com.google.gerrit.server.account.AuthRequest;
|
||||
import com.google.gerrit.server.config.AllProjectsName;
|
||||
import com.google.gerrit.server.query.account.InternalAccountQuery;
|
||||
import com.google.gerrit.server.schema.SchemaCreator;
|
||||
import com.google.gerrit.server.util.ManualRequestContext;
|
||||
import com.google.gerrit.server.util.OneOffRequestContext;
|
||||
@ -83,7 +88,7 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
|
||||
|
||||
@Inject protected OneOffRequestContext oneOffRequestContext;
|
||||
|
||||
@Inject protected InternalAccountQuery internalAccountQuery;
|
||||
@Inject protected ProjectIndexCollection indexes;
|
||||
|
||||
@Inject protected AllProjectsName allProjects;
|
||||
|
||||
@ -210,6 +215,30 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
|
||||
assertQuery("description:\"\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byState() throws Exception {
|
||||
assume().that(getSchemaVersion() >= 2).isTrue();
|
||||
|
||||
ProjectInfo project1 = createProjectWithState(name("project1"), ProjectState.ACTIVE);
|
||||
ProjectInfo project2 = createProjectWithState(name("project2"), ProjectState.READ_ONLY);
|
||||
assertQuery("state:active", project1);
|
||||
assertQuery("state:read-only", project2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byState_emptyQuery() throws Exception {
|
||||
exception.expect(BadRequestException.class);
|
||||
exception.expectMessage("state operator requires a value");
|
||||
assertQuery("state:\"\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byState_badQuery() throws Exception {
|
||||
exception.expect(BadRequestException.class);
|
||||
exception.expectMessage("state operator must be either 'active' or 'read-only'");
|
||||
assertQuery("state:bla");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byDefaultField() throws Exception {
|
||||
ProjectInfo project1 = createProject(name("foo-project"));
|
||||
@ -291,6 +320,14 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
|
||||
return gApi.projects().create(in).get();
|
||||
}
|
||||
|
||||
protected ProjectInfo createProjectWithState(String name, ProjectState state) throws Exception {
|
||||
ProjectInfo info = createProject(name);
|
||||
ConfigInput config = new ConfigInput();
|
||||
config.state = state;
|
||||
gApi.projects().name(info.name).config(config);
|
||||
return info;
|
||||
}
|
||||
|
||||
protected ProjectInfo getProject(Project.NameKey nameKey) throws Exception {
|
||||
return gApi.projects().name(nameKey.get()).get();
|
||||
}
|
||||
@ -354,6 +391,14 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
protected int getSchemaVersion() {
|
||||
return getSchema().getVersion();
|
||||
}
|
||||
|
||||
protected Schema<ProjectData> getSchema() {
|
||||
return indexes.getSearchIndex().getSchema();
|
||||
}
|
||||
|
||||
protected static Iterable<String> names(ProjectInfo... projects) {
|
||||
return names(Arrays.asList(projects));
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ java_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//java/com/google/gerrit/extensions:api",
|
||||
"//java/com/google/gerrit/index",
|
||||
"//java/com/google/gerrit/index/project",
|
||||
"//java/com/google/gerrit/lifecycle",
|
||||
"//java/com/google/gerrit/reviewdb:server",
|
||||
"//java/com/google/gerrit/server",
|
||||
|
Loading…
x
Reference in New Issue
Block a user