Add a "projects" field for searching projects by prefix
Index alongside the "project" field, which is an exact match field, since we do not assume index implementations can search exact match and prefix on the same field. We do not want to modify the existing "project" to return prefixes. Upgrade Lucene to 4.7.0, as this was released since the last schema change. Change-Id: I7c3379c087fc54af3e5790cb875a5e676e674338
This commit is contained in:
parent
2212801e98
commit
4aed07b7ce
@ -127,6 +127,11 @@ matches project names by regular expression. The
|
||||
link:http://www.brics.dk/automaton/[dk.brics.automaton
|
||||
library] is used for evaluation of such patterns.
|
||||
|
||||
[[projects]]
|
||||
projects:'PREFIX'::
|
||||
+
|
||||
Changes occurring in projects starting with 'PREFIX'.
|
||||
|
||||
[[parentproject]]
|
||||
parentproject:'PROJECT'::
|
||||
+
|
||||
|
@ -81,6 +81,7 @@ public class SearchSuggestOracle extends HighlightSuggestOracle {
|
||||
suggestions.add("comment:");
|
||||
suggestions.add("conflicts:");
|
||||
suggestions.add("project:");
|
||||
suggestions.add("projects:");
|
||||
suggestions.add("parentproject:");
|
||||
suggestions.add("branch:");
|
||||
suggestions.add("topic:");
|
||||
|
@ -125,14 +125,18 @@ public class LuceneChangeIndex implements ChangeIndex {
|
||||
Version lucene43 = Version.LUCENE_43;
|
||||
@SuppressWarnings("deprecation")
|
||||
Version lucene44 = Version.LUCENE_44;
|
||||
@SuppressWarnings("deprecation")
|
||||
Version lucene46 = Version.LUCENE_46;
|
||||
for (Map.Entry<Integer, Schema<ChangeData>> e
|
||||
: ChangeSchemas.ALL.entrySet()) {
|
||||
if (e.getKey() <= 3) {
|
||||
versions.put(e.getValue(), lucene43);
|
||||
} else if (e.getKey() <= 5) {
|
||||
versions.put(e.getValue(), lucene44);
|
||||
} else if (e.getKey() <= 8) {
|
||||
versions.put(e.getValue(), lucene46);
|
||||
} else {
|
||||
versions.put(e.getValue(), Version.LUCENE_46);
|
||||
versions.put(e.getValue(), Version.LUCENE_47);
|
||||
}
|
||||
}
|
||||
LUCENE_VERSIONS = versions.build();
|
||||
|
@ -46,6 +46,7 @@ public class QueryDocumentationExecutor {
|
||||
private static final Logger log =
|
||||
LoggerFactory.getLogger(QueryDocumentationExecutor.class);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Version LUCENE_VERSION = Version.LUCENE_46;
|
||||
|
||||
private IndexSearcher searcher;
|
||||
|
@ -93,6 +93,17 @@ public class ChangeField {
|
||||
}
|
||||
};
|
||||
|
||||
/** Project containing the change, as a prefix field. */
|
||||
public static final FieldDef<ChangeData, String> PROJECTS =
|
||||
new FieldDef.Single<ChangeData, String>(
|
||||
ChangeQueryBuilder.FIELD_PROJECTS, FieldType.PREFIX, false) {
|
||||
@Override
|
||||
public String get(ChangeData input, FillArgs args)
|
||||
throws OrmException {
|
||||
return input.change().getProject().get();
|
||||
}
|
||||
};
|
||||
|
||||
/** Reference (aka branch) the change will submit onto. */
|
||||
public static final FieldDef<ChangeData, String> REF =
|
||||
new FieldDef.Single<ChangeData, String>(
|
||||
|
@ -169,6 +169,29 @@ public class ChangeSchemas {
|
||||
ChangeField.APPROVAL,
|
||||
ChangeField.MERGEABLE);
|
||||
|
||||
static final Schema<ChangeData> V9 = release(
|
||||
ChangeField.LEGACY_ID,
|
||||
ChangeField.ID,
|
||||
ChangeField.STATUS,
|
||||
ChangeField.PROJECT,
|
||||
ChangeField.PROJECTS,
|
||||
ChangeField.REF,
|
||||
ChangeField.TOPIC,
|
||||
ChangeField.UPDATED,
|
||||
ChangeField.FILE_PART,
|
||||
ChangeField.PATH,
|
||||
ChangeField.OWNER,
|
||||
ChangeField.REVIEWER,
|
||||
ChangeField.COMMIT,
|
||||
ChangeField.TR,
|
||||
ChangeField.LABEL,
|
||||
ChangeField.REVIEWED,
|
||||
ChangeField.COMMIT_MESSAGE,
|
||||
ChangeField.COMMENT,
|
||||
ChangeField.CHANGE,
|
||||
ChangeField.APPROVAL,
|
||||
ChangeField.MERGEABLE);
|
||||
|
||||
|
||||
private static Schema<ChangeData> release(Collection<FieldDef<ChangeData, ?>> fields) {
|
||||
return new Schema<ChangeData>(true, fields);
|
||||
|
@ -82,6 +82,10 @@ public class Schema<T> {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public final boolean hasField(FieldDef<T, ?> field) {
|
||||
return fields.get(field.getName()) == field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build all fields in the schema from an input object.
|
||||
* <p>
|
||||
|
@ -36,6 +36,7 @@ import com.google.gerrit.server.config.GerritServerConfig;
|
||||
import com.google.gerrit.server.config.TrackingFooters;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.git.strategy.SubmitStrategyFactory;
|
||||
import com.google.gerrit.server.index.ChangeField;
|
||||
import com.google.gerrit.server.index.ChangeIndex;
|
||||
import com.google.gerrit.server.index.IndexCollection;
|
||||
import com.google.gerrit.server.index.Schema;
|
||||
@ -106,6 +107,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
public static final String FIELD_PARENTPROJECT = "parentproject";
|
||||
public static final String FIELD_PATH = "path";
|
||||
public static final String FIELD_PROJECT = "project";
|
||||
public static final String FIELD_PROJECTS = "projects";
|
||||
public static final String FIELD_REF = "ref";
|
||||
public static final String FIELD_REVIEWER = "reviewer";
|
||||
public static final String FIELD_REVIEWERIN = "reviewerin";
|
||||
@ -371,6 +373,14 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
|
||||
return new ProjectPredicate(name);
|
||||
}
|
||||
|
||||
@Operator
|
||||
public Predicate<ChangeData> projects(String name) throws QueryParseException {
|
||||
if (!schema(args.indexes).hasField(ChangeField.PROJECTS)) {
|
||||
throw new QueryParseException("Unsupported operator: " + FIELD_PROJECTS);
|
||||
}
|
||||
return new ProjectPrefixPredicate(name);
|
||||
}
|
||||
|
||||
@Operator
|
||||
public Predicate<ChangeData> parentproject(String name) {
|
||||
return new ParentProjectPredicate(args.db, args.projectCache,
|
||||
|
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2014 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.query.change;
|
||||
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.index.ChangeField;
|
||||
import com.google.gerrit.server.index.IndexPredicate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
class ProjectPrefixPredicate extends IndexPredicate<ChangeData> {
|
||||
ProjectPrefixPredicate(String prefix) {
|
||||
super(ChangeField.PROJECTS, prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean match(ChangeData object) throws OrmException {
|
||||
Change c = object.change();
|
||||
return c != null && c.getDest().getParentKey().get().startsWith(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCost() {
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -304,10 +304,29 @@ public abstract class AbstractQueryChangesTest {
|
||||
Change change2 = newChange(repo2, null, null, null, null).insert();
|
||||
|
||||
assertTrue(query("project:foo").isEmpty());
|
||||
assertTrue(query("project:repo").isEmpty());
|
||||
assertResultEquals(change1, queryOne("project:repo1"));
|
||||
assertResultEquals(change2, queryOne("project:repo2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byProjectPrefix() throws Exception {
|
||||
TestRepository<InMemoryRepository> repo1 = createProject("repo1");
|
||||
TestRepository<InMemoryRepository> repo2 = createProject("repo2");
|
||||
Change change1 = newChange(repo1, null, null, null, null).insert();
|
||||
Change change2 = newChange(repo2, null, null, null, null).insert();
|
||||
|
||||
assertTrue(query("projects:foo").isEmpty());
|
||||
assertResultEquals(change1, queryOne("projects:repo1"));
|
||||
assertResultEquals(change2, queryOne("projects:repo2"));
|
||||
|
||||
List<ChangeInfo> results;
|
||||
results = query("projects:repo");
|
||||
assertEquals(results.toString(), 2, results.size());
|
||||
assertResultEquals(change2, results.get(0));
|
||||
assertResultEquals(change1, results.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byBranchAndRef() throws Exception {
|
||||
TestRepository<InMemoryRepository> repo = createProject("repo");
|
||||
|
@ -32,6 +32,7 @@ import com.google.inject.Injector;
|
||||
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
|
||||
import org.eclipse.jgit.junit.TestRepository;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
@ -43,6 +44,13 @@ public class LuceneQueryChangesV7Test extends AbstractQueryChangesTest {
|
||||
return Guice.createInjector(new InMemoryModule(cfg));
|
||||
}
|
||||
|
||||
// Tests for features not supported in V7.
|
||||
@Ignore
|
||||
@Override
|
||||
@Test
|
||||
public void byProjectPrefix() {}
|
||||
// End tests for features not supported in V7.
|
||||
|
||||
@Test
|
||||
public void pagination() throws Exception {
|
||||
TestRepository<InMemoryRepository> repo = createProject("repo");
|
||||
|
@ -51,6 +51,7 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class DocIndexer {
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Version LUCENE_VERSION = Version.LUCENE_46;
|
||||
private static final Pattern SECTION_HEADER = Pattern.compile("^=+ (.*)");
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
include_defs('//lib/maven.defs')
|
||||
|
||||
VERSION = '4.6.0'
|
||||
VERSION = '4.7.0'
|
||||
|
||||
maven_jar(
|
||||
name = 'core',
|
||||
id = 'org.apache.lucene:lucene-core:' + VERSION,
|
||||
bin_sha1 = 'f1d974facaea30a3a0c1752a24097af5a7d40e60',
|
||||
src_sha1 = '19d4eb5def4bc2517a00b50f7a875b7ce33988a7',
|
||||
sha1 = '12d2b92d15158ac0d7b2864f537403acb4d7f69e',
|
||||
license = 'Apache2.0',
|
||||
exclude = [
|
||||
'META-INF/LICENSE.txt',
|
||||
@ -17,8 +16,7 @@ maven_jar(
|
||||
maven_jar(
|
||||
name = 'analyzers-common',
|
||||
id = 'org.apache.lucene:lucene-analyzers-common:' + VERSION,
|
||||
bin_sha1 = '25dda6706bcb7a741f25f57cdbec6c2f36adc557',
|
||||
src_sha1 = '04866d0e36e3ef708d099014752ad4fef61d4243',
|
||||
sha1 = '399fa6b0d750c8e5c9e4ae73e6407c8b3ed4e8c1',
|
||||
license = 'Apache2.0',
|
||||
exclude = [
|
||||
'META-INF/LICENSE.txt',
|
||||
@ -29,7 +27,6 @@ maven_jar(
|
||||
maven_jar(
|
||||
name = 'query-parser',
|
||||
id = 'org.apache.lucene:lucene-queryparser:' + VERSION,
|
||||
bin_sha1 = 'ef35f1eb55e50725777162e376e7b5222f45f7fa',
|
||||
src_sha1 = 'e99e3b298e83461c03ef6eb66ab9798a4b712dc6',
|
||||
sha1 = 'f78a804de1582c511224d214c2d9c82ce48379e7',
|
||||
license = 'Apache2.0',
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user