Merge "Delete SQL index support"

This commit is contained in:
Shawn Pearce 2013-11-29 20:48:25 +00:00 committed by Gerrit Code Review
commit da07edd370
34 changed files with 238 additions and 1217 deletions

View File

@ -1852,17 +1852,12 @@ A link:http://lucene.apache.org/[Lucene] index is used.
* `SOLR` * `SOLR`
+ +
A link:http://lucene.apache.org/solr/[Solr] index is used. A link:http://lucene.apache.org/solr/[Solr] index is used.
+
* `SQL`
+
No secondary index. Not all query operators are supported. Other
query operators are routed through the standard SQL query engine.
+ +
By default, `SQL`. By default, `LUCENE`.
+ +
After enabling the secondary index, the index must be built using After changing the secondary index type, the index must be rebuilt
the link:pgm-reindex.html[reindex program] before restarting the using the link:pgm-reindex.html[reindex program] before restarting the
Gerrit server. Gerrit server.
[[ldap]]Section ldap [[ldap]]Section ldap

View File

@ -1,26 +0,0 @@
// Copyright (C) 2013 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.acceptance;
import org.eclipse.jgit.lib.Config;
public class AbstractDaemonTestWithSecondaryIndex extends AbstractDaemonTest {
@Override
protected GerritServer startServer(Config cfg, boolean memory)
throws Exception {
return GerritServer.start(cfg, memory, true);
}
}

View File

@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList;
import com.google.gerrit.lucene.LuceneIndexModule; import com.google.gerrit.lucene.LuceneIndexModule;
import com.google.gerrit.pgm.Daemon; import com.google.gerrit.pgm.Daemon;
import com.google.gerrit.pgm.Init; import com.google.gerrit.pgm.Init;
import com.google.gerrit.pgm.Reindex;
import com.google.gerrit.server.config.FactoryModule; import com.google.gerrit.server.config.FactoryModule;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.index.ChangeSchemas; import com.google.gerrit.server.index.ChangeSchemas;
@ -51,12 +50,6 @@ public class GerritServer {
/** Returns fully started Gerrit server */ /** Returns fully started Gerrit server */
static GerritServer start(Config base, boolean memory) throws Exception { static GerritServer start(Config base, boolean memory) throws Exception {
return start(base, memory, false);
}
/** Returns fully started Gerrit server */
static GerritServer start(Config base, boolean memory, boolean index)
throws Exception {
final CyclicBarrier serverStarted = new CyclicBarrier(2); final CyclicBarrier serverStarted = new CyclicBarrier(2);
final Daemon daemon = new Daemon(new Runnable() { final Daemon daemon = new Daemon(new Runnable() {
public void run() { public void run() {
@ -78,25 +71,16 @@ public class GerritServer {
mergeTestConfig(cfg); mergeTestConfig(cfg);
cfg.setBoolean("httpd", null, "requestLog", false); cfg.setBoolean("httpd", null, "requestLog", false);
cfg.setBoolean("sshd", null, "requestLog", false); cfg.setBoolean("sshd", null, "requestLog", false);
if (index) { cfg.setBoolean("index", "lucene", "testInmemory", true);
cfg.setString("index", null, "type", "lucene"); daemon.setLuceneModule(new LuceneIndexModule(
cfg.setBoolean("index", "lucene", "testInmemory", true); ChangeSchemas.getLatest().getVersion(),
daemon.setLuceneModule(new LuceneIndexModule( Runtime.getRuntime().availableProcessors(), null));
ChangeSchemas.getLatest().getVersion(),
Runtime.getRuntime().availableProcessors(), null));
}
daemon.setDatabaseForTesting(ImmutableList.<Module>of( daemon.setDatabaseForTesting(ImmutableList.<Module>of(
new InMemoryTestingDatabaseModule(cfg))); new InMemoryTestingDatabaseModule(cfg)));
daemon.start(); daemon.start();
} else { } else {
Config cfg = base != null ? base : new Config(); Config cfg = base != null ? base : new Config();
if (index) {
cfg.setString("index", null, "type", "lucene");
}
site = initSite(cfg); site = initSite(cfg);
if (index) {
reindex(site);
}
daemonService = Executors.newSingleThreadExecutor(); daemonService = Executors.newSingleThreadExecutor();
daemonService.submit(new Callable<Void>() { daemonService.submit(new Callable<Void>() {
public Void call() throws Exception { public Void call() throws Exception {
@ -137,15 +121,6 @@ public class GerritServer {
return tmp; return tmp;
} }
/** Runs the reindex command. Works only if the site is not currently running. */
private static void reindex(File site) throws Exception {
Reindex reindex = new Reindex();
int rc = reindex.main(new String[] {"-d", site.getPath()});
if (rc != 0) {
throw new RuntimeException("Reindex failed");
}
}
private static void mergeTestConfig(Config cfg) private static void mergeTestConfig(Config cfg)
throws IOException { throws IOException {
InetSocketAddress http = newPort(); InetSocketAddress http = newPort();

View File

@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTestWithSecondaryIndex; import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.AccountCreator; import com.google.gerrit.acceptance.AccountCreator;
import com.google.gerrit.acceptance.RestResponse; import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession; import com.google.gerrit.acceptance.RestSession;
@ -49,7 +49,7 @@ import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.util.Set; import java.util.Set;
public class ConflictsOperatorIT extends AbstractDaemonTestWithSecondaryIndex { public class ConflictsOperatorIT extends AbstractDaemonTest {
@Inject @Inject
private AccountCreator accounts; private AccountCreator accounts;

View File

@ -52,7 +52,6 @@ public class GerritConfig implements Cloneable {
protected int suggestFrom; protected int suggestFrom;
protected int changeUpdateDelay; protected int changeUpdateDelay;
protected AccountGeneralPreferences.ChangeScreen changeScreen; protected AccountGeneralPreferences.ChangeScreen changeScreen;
protected boolean index;
protected int largeChangeSize; protected int largeChangeSize;
public String getLoginUrl() { public String getLoginUrl() {
@ -274,14 +273,6 @@ public class GerritConfig implements Cloneable {
this.changeScreen = ui; this.changeScreen = ui;
} }
public boolean hasIndex() {
return index;
}
public void setIndex(boolean index) {
this.index = index;
}
public int getLargeChangeSize() { public int getLargeChangeSize() {
return largeChangeSize; return largeChangeSize;
} }

View File

@ -198,7 +198,7 @@ class RelatedChanges extends TabPanel {
} }
}); });
if (Gerrit.getConfig().hasIndex() && info.mergeable()) { if (info.mergeable()) {
StringBuilder conflictsQuery = new StringBuilder(); StringBuilder conflictsQuery = new StringBuilder();
conflictsQuery.append("status:open"); conflictsQuery.append("status:open");
conflictsQuery.append(" is:mergeable"); conflictsQuery.append(" is:mergeable");

View File

@ -26,7 +26,6 @@ import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.DownloadConfig; import com.google.gerrit.server.config.DownloadConfig;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.contact.ContactStore; import com.google.gerrit.server.contact.ContactStore;
import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.mail.EmailSender; import com.google.gerrit.server.mail.EmailSender;
import com.google.gerrit.server.ssh.SshInfo; import com.google.gerrit.server.ssh.SshInfo;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -50,7 +49,6 @@ class GerritConfigProvider implements Provider<GerritConfig> {
private final GitWebConfig gitWebConfig; private final GitWebConfig gitWebConfig;
private final AllProjectsName wildProject; private final AllProjectsName wildProject;
private final SshInfo sshInfo; private final SshInfo sshInfo;
private final IndexCollection indexCollection;
private EmailSender emailSender; private EmailSender emailSender;
private final ContactStore contactStore; private final ContactStore contactStore;
@ -61,7 +59,6 @@ class GerritConfigProvider implements Provider<GerritConfig> {
GerritConfigProvider(final Realm r, @GerritServerConfig final Config gsc, GerritConfigProvider(final Realm r, @GerritServerConfig final Config gsc,
final AuthConfig ac, final GitWebConfig gwc, final AllProjectsName wp, final AuthConfig ac, final GitWebConfig gwc, final AllProjectsName wp,
final SshInfo si, final ContactStore cs, final SshInfo si, final ContactStore cs,
final IndexCollection ic,
final ServletContext sc, final DownloadConfig dc, final ServletContext sc, final DownloadConfig dc,
final @AnonymousCowardName String acn) { final @AnonymousCowardName String acn) {
realm = r; realm = r;
@ -70,7 +67,6 @@ class GerritConfigProvider implements Provider<GerritConfig> {
downloadConfig = dc; downloadConfig = dc;
gitWebConfig = gwc; gitWebConfig = gwc;
sshInfo = si; sshInfo = si;
indexCollection = ic;
wildProject = wp; wildProject = wp;
contactStore = cs; contactStore = cs;
servletContext = sc; servletContext = sc;
@ -130,7 +126,6 @@ class GerritConfigProvider implements Provider<GerritConfig> {
config.setChangeScreen(cfg.getEnum( config.setChangeScreen(cfg.getEnum(
"gerrit", null, "changeScreen", "gerrit", null, "changeScreen",
AccountGeneralPreferences.ChangeScreen.CHANGE_SCREEN2)); AccountGeneralPreferences.ChangeScreen.CHANGE_SCREEN2));
config.setIndex(indexCollection.getSearchIndex() != null);
config.setLargeChangeSize(cfg.getInt("change", "largeChange", 500)); config.setLargeChangeSize(cfg.getInt("change", "largeChange", 500));
config.setReportBugUrl(cfg.getString("gerrit", null, "reportBugUrl")); config.setReportBugUrl(cfg.getString("gerrit", null, "reportBugUrl"));

View File

@ -148,9 +148,7 @@ class AccountServiceImpl extends BaseServiceImplementation implements
if (filter != null) { if (filter != null) {
try { try {
ChangeQueryBuilder builder = queryBuilder.create(currentUser.get()); queryBuilder.create(currentUser.get()).parse(filter);
builder.setAllowFileRegex(true);
builder.parse(filter);
} catch (QueryParseException badFilter) { } catch (QueryParseException badFilter) {
throw new InvalidQueryException(badFilter.getMessage(), filter); throw new InvalidQueryException(badFilter.getMessage(), filter);
} }

View File

@ -54,6 +54,7 @@ java_library2(
':init-api', ':init-api',
'//gerrit-common:server', '//gerrit-common:server',
'//gerrit-extension-api:api', '//gerrit-extension-api:api',
'//gerrit-lucene:lucene',
'//gerrit-reviewdb:server', '//gerrit-reviewdb:server',
'//gerrit-server:server', '//gerrit-server:server',
'//gerrit-util-cli:cli', '//gerrit-util-cli:cli',

View File

@ -55,7 +55,7 @@ import com.google.gerrit.server.contact.HttpContactStoreConnection;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule; import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
import com.google.gerrit.server.git.WorkQueue; import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.IndexModule; import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.NoIndexModule; import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
import com.google.gerrit.server.mail.SmtpEmailSender; import com.google.gerrit.server.mail.SmtpEmailSender;
import com.google.gerrit.server.patch.IntraLineWorkerPool; import com.google.gerrit.server.patch.IntraLineWorkerPool;
@ -310,18 +310,7 @@ public class Daemon extends SiteProgram {
modules.add(new SmtpEmailSender.Module()); modules.add(new SmtpEmailSender.Module());
modules.add(new SignedTokenEmailTokenVerifier.Module()); modules.add(new SignedTokenEmailTokenVerifier.Module());
modules.add(new PluginRestApiModule()); modules.add(new PluginRestApiModule());
AbstractModule changeIndexModule; modules.add(createIndexModule());
switch (IndexModule.getIndexType(cfgInjector)) {
case LUCENE:
changeIndexModule = luceneModule != null ? luceneModule : new LuceneIndexModule();
break;
case SOLR:
changeIndexModule = new SolrIndexModule();
break;
default:
changeIndexModule = new NoIndexModule();
}
modules.add(changeIndexModule);
if (Objects.firstNonNull(httpd, true)) { if (Objects.firstNonNull(httpd, true)) {
modules.add(new CanonicalWebUrlModule() { modules.add(new CanonicalWebUrlModule() {
@Override @Override
@ -354,6 +343,18 @@ public class Daemon extends SiteProgram {
return cfgInjector.createChildInjector(modules); return cfgInjector.createChildInjector(modules);
} }
private AbstractModule createIndexModule() {
IndexType indexType = IndexModule.getIndexType(cfgInjector);
switch (indexType) {
case LUCENE:
return luceneModule != null ? luceneModule : new LuceneIndexModule();
case SOLR:
return new SolrIndexModule();
default:
throw new IllegalStateException("unsupported index.type = " + indexType);
}
}
private void initSshd() { private void initSshd() {
sshInjector = createSshInjector(); sshInjector = createSshInjector();
sysInjector.getInstance(PluginGuiceEnvironment.class) sysInjector.getInstance(PluginGuiceEnvironment.class)

View File

@ -35,8 +35,6 @@ import com.google.gerrit.server.index.ChangeIndex;
import com.google.gerrit.server.index.ChangeSchemas; import com.google.gerrit.server.index.ChangeSchemas;
import com.google.gerrit.server.index.IndexCollection; import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.index.IndexModule; import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.index.NoIndexModule;
import com.google.gerrit.server.patch.PatchListCacheImpl; import com.google.gerrit.server.patch.PatchListCacheImpl;
import com.google.gerrit.server.schema.DataSourceProvider; import com.google.gerrit.server.schema.DataSourceProvider;
import com.google.gerrit.server.schema.DataSourceType; import com.google.gerrit.server.schema.DataSourceType;
@ -91,9 +89,6 @@ public class Reindex extends SiteProgram {
public int run() throws Exception { public int run() throws Exception {
mustHaveValidSite(); mustHaveValidSite();
dbInjector = createDbInjector(MULTI_USER); dbInjector = createDbInjector(MULTI_USER);
if (IndexModule.getIndexType(dbInjector) == IndexType.SQL) {
throw die("index.type must be configured (or not SQL)");
}
limitThreads(); limitThreads();
if (version == null) { if (version == null) {
version = ChangeSchemas.getLatest().getVersion(); version = ChangeSchemas.getLatest().getVersion();
@ -144,7 +139,7 @@ public class Reindex extends SiteProgram {
changeIndexModule = new SolrIndexModule(false, threads, outputBase); changeIndexModule = new SolrIndexModule(false, threads, outputBase);
break; break;
default: default:
changeIndexModule = new NoIndexModule(); throw new IllegalStateException("unsupported index.type");
} }
modules.add(changeIndexModule); modules.add(changeIndexModule);
modules.add(new ReviewDbModule()); modules.add(new ReviewDbModule());

View File

@ -0,0 +1,178 @@
// Copyright (C) 2013 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.pgm.init;
import com.google.common.collect.Sets;
import com.google.gerrit.lucene.LuceneChangeIndex;
import com.google.gerrit.lucene.LuceneIndexModule;
import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.config.TrackingFooter;
import com.google.gerrit.server.config.TrackingFooters;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.ChangeIndex;
import com.google.gerrit.server.index.ChangeSchemas;
import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.patch.IntraLineDiff;
import com.google.gerrit.server.patch.IntraLineDiffKey;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListKey;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
import java.io.IOException;
import java.util.Collections;
import java.util.SortedSet;
/** Initialize the {@code index} configuration section. */
@Singleton
class InitIndex implements InitStep {
private final ConsoleUI ui;
private final Section index;
private final SitePaths site;
private final InitFlags initFlags;
@Inject
InitIndex(ConsoleUI ui,
Section.Factory sections,
SitePaths site,
InitFlags initFlags) {
this.ui = ui;
this.index = sections.get("index", null);
this.site = site;
this.initFlags = initFlags;
}
public void run() throws IOException {
ui.header("Index");
IndexType type = index.select("Type", "type", IndexType.LUCENE);
if (site.isNew && type == IndexType.LUCENE) {
createLuceneIndex();
} else {
ui.message("The index must be built before starting Gerrit:\n"
+ " java -jar gerrit.war reindex -d site_path\n");
initFlags.autoStart = false;
}
}
private void createLuceneIndex() throws IOException {
Injector injector = Guice.createInjector(
new LuceneIndexModule(ChangeSchemas.getLatest().getVersion(), 0, null),
new MockIndexSupportModule());
ChangeIndex index = injector.getInstance(LuceneChangeIndex.class);
index.markReady(true);
index.close();
}
private class MockIndexSupportModule extends AbstractModule {
@Override
protected void configure() {
bind(SitePaths.class).toInstance(site);
}
@Provides @GerritServerConfig Config getConfig() {
return new Config();
}
@Provides TrackingFooters newTrackingFooters() {
return new TrackingFooters(Collections.<TrackingFooter> emptyList());
}
@Provides ReviewDb getReviewDb() {
throw new ProvisionException("database not initialized");
}
@Provides SchemaFactory<ReviewDb> getSchemaFactory() {
return new SchemaFactory<ReviewDb>() {
@Override
public ReviewDb open() throws OrmException {
return getReviewDb();
}
};
}
@Provides GitRepositoryManager getGitRepositoryManager() {
return new GitRepositoryManager() {
@Override
public Repository openRepository(Project.NameKey name)
throws RepositoryNotFoundException{
throw new RepositoryNotFoundException(name.get());
}
@Override
public Repository createRepository(Project.NameKey name)
throws RepositoryNotFoundException {
throw new RepositoryNotFoundException(name.get());
}
@Override
public SortedSet<Project.NameKey> list() {
return Sets.newTreeSet();
}
@Override
public String getProjectDescription(Project.NameKey name) {
return null;
}
@Override
public void setProjectDescription(NameKey name, String description) {
}
};
}
@Provides PatchListCache newPatchListCache() {
return new PatchListCache() {
@Override
public PatchList get(PatchListKey key)
throws PatchListNotAvailableException {
throw new PatchListNotAvailableException("new site, no changes");
}
@Override
public PatchList get(Change change, PatchSet patchSet)
throws PatchListNotAvailableException {
throw new PatchListNotAvailableException("new site, no changes");
}
@Override
public IntraLineDiff getIntraLineDiff(IntraLineDiffKey key) {
return null;
}
};
}
}
}

View File

@ -46,6 +46,7 @@ public class InitModule extends FactoryModule {
if (standalone) { if (standalone) {
step().to(InitDatabase.class); step().to(InitDatabase.class);
} }
step().to(InitIndex.class);
step().to(InitAuth.class); step().to(InitAuth.class);
step().to(InitSendEmail.class); step().to(InitSendEmail.class);
if (standalone) { if (standalone) {

View File

@ -14,7 +14,6 @@
package com.google.gerrit.reviewdb.server; package com.google.gerrit.reviewdb.server;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
@ -42,14 +41,6 @@ public interface ChangeAccess extends Access<Change, Change.Id> {
@Query("WHERE dest.projectName = ?") @Query("WHERE dest.projectName = ?")
ResultSet<Change> byProject(Project.NameKey p) throws OrmException; ResultSet<Change> byProject(Project.NameKey p) throws OrmException;
@Deprecated
@Query("WHERE owner = ? AND open = true ORDER BY createdOn, changeId")
ResultSet<Change> byOwnerOpen(Account.Id id) throws OrmException;
@Deprecated
@Query("WHERE owner = ? AND open = false ORDER BY lastUpdatedOn")
ResultSet<Change> byOwnerClosedAll(Account.Id id) throws OrmException;
@Query("WHERE dest = ? AND status = '" + Change.STATUS_SUBMITTED @Query("WHERE dest = ? AND status = '" + Change.STATUS_SUBMITTED
+ "' ORDER BY lastUpdatedOn") + "' ORDER BY lastUpdatedOn")
ResultSet<Change> submitted(Branch.NameKey dest) throws OrmException; ResultSet<Change> submitted(Branch.NameKey dest) throws OrmException;
@ -57,65 +48,17 @@ public interface ChangeAccess extends Access<Change, Change.Id> {
@Query("WHERE status = '" + Change.STATUS_SUBMITTED + "'") @Query("WHERE status = '" + Change.STATUS_SUBMITTED + "'")
ResultSet<Change> allSubmitted() throws OrmException; ResultSet<Change> allSubmitted() throws OrmException;
@Deprecated
@Query("WHERE open = true AND sortKey > ? ORDER BY sortKey LIMIT ?")
ResultSet<Change> allOpenPrev(String sortKey, int limit) throws OrmException;
@Deprecated
@Query("WHERE open = true AND sortKey < ? ORDER BY sortKey DESC LIMIT ?")
ResultSet<Change> allOpenNext(String sortKey, int limit) throws OrmException;
@Query("WHERE open = true AND dest.projectName = ?") @Query("WHERE open = true AND dest.projectName = ?")
ResultSet<Change> byProjectOpenAll(Project.NameKey p) throws OrmException; ResultSet<Change> byProjectOpenAll(Project.NameKey p) throws OrmException;
@Query("WHERE open = true AND dest = ?") @Query("WHERE open = true AND dest = ?")
ResultSet<Change> byBranchOpenAll(Branch.NameKey p) throws OrmException; ResultSet<Change> byBranchOpenAll(Branch.NameKey p) throws OrmException;
@Deprecated
@Query("WHERE open = true AND dest.projectName = ? AND sortKey > ?"
+ " ORDER BY sortKey LIMIT ?")
ResultSet<Change> byProjectOpenPrev(Project.NameKey p, String sortKey,
int limit) throws OrmException;
@Query("WHERE open = true AND dest.projectName = ? AND sortKey < ?" @Query("WHERE open = true AND dest.projectName = ? AND sortKey < ?"
+ " ORDER BY sortKey DESC LIMIT ?") + " ORDER BY sortKey DESC LIMIT ?")
ResultSet<Change> byProjectOpenNext(Project.NameKey p, String sortKey, ResultSet<Change> byProjectOpenNext(Project.NameKey p, String sortKey,
int limit) throws OrmException; int limit) throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND dest.projectName = ? AND sortKey > ?"
+ " ORDER BY sortKey LIMIT ?")
ResultSet<Change> byProjectClosedPrev(char status, Project.NameKey p,
String sortKey, int limit) throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND dest.projectName = ? AND sortKey < ?"
+ " ORDER BY sortKey DESC LIMIT ?")
ResultSet<Change> byProjectClosedNext(char status, Project.NameKey p,
String sortKey, int limit) throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND sortKey > ? ORDER BY sortKey LIMIT ?")
ResultSet<Change> allClosedPrev(char status, String sortKey, int limit)
throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND sortKey < ? ORDER BY sortKey DESC LIMIT ?")
ResultSet<Change> allClosedNext(char status, String sortKey, int limit)
throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND dest = ? AND sortKey > ?"
+ " ORDER BY sortKey LIMIT ?")
ResultSet<Change> byBranchClosedPrev(char status, Branch.NameKey p,
String sortKey, int limit) throws OrmException;
@Deprecated
@Query("WHERE open = false AND status = ? AND dest = ? AND sortKey < ?"
+ " ORDER BY sortKey DESC LIMIT ?")
ResultSet<Change> byBranchClosedNext(char status, Branch.NameKey p,
String sortKey, int limit) throws OrmException;
@Query @Query
ResultSet<Change> all() throws OrmException; ResultSet<Change> all() throws OrmException;
} }

View File

@ -38,14 +38,4 @@ public interface PatchSetApprovalAccess extends
@Query("WHERE key.patchSetId = ? AND key.accountId = ?") @Query("WHERE key.patchSetId = ? AND key.accountId = ?")
ResultSet<PatchSetApproval> byPatchSetUser(PatchSet.Id patchSet, ResultSet<PatchSetApproval> byPatchSetUser(PatchSet.Id patchSet,
Account.Id account) throws OrmException; Account.Id account) throws OrmException;
@Deprecated
@Query("WHERE changeOpen = true AND key.accountId = ?")
ResultSet<PatchSetApproval> openByUser(Account.Id account)
throws OrmException;
@Deprecated
@Query("WHERE changeOpen = false AND key.accountId = ? ORDER BY changeSortKey")
ResultSet<PatchSetApproval> closedByUserAll(Account.Id account)
throws OrmException;
} }

View File

@ -28,9 +28,4 @@ public interface TrackingIdAccess extends Access<TrackingId, TrackingId.Key> {
@Query("WHERE key.changeId = ?") @Query("WHERE key.changeId = ?")
ResultSet<TrackingId> byChange(Change.Id change) throws OrmException; ResultSet<TrackingId> byChange(Change.Id change) throws OrmException;
@Deprecated
@Query("WHERE key.trackingKey = ?")
ResultSet<TrackingId> byTrackingId(TrackingId.Id trackingId)
throws OrmException;
} }

View File

@ -69,23 +69,11 @@ ON account_project_watches (project_name);
-- ********************************************************************* -- *********************************************************************
-- ChangeAccess -- ChangeAccess
-- covers: byOwnerOpen
CREATE INDEX changes_byOwnerOpen
ON changes (open, owner_account_id, created_on, change_id);
-- covers: byOwnerClosed
CREATE INDEX changes_byOwnerClosed
ON changes (open, owner_account_id, last_updated_on);
-- covers: submitted, allSubmitted -- covers: submitted, allSubmitted
CREATE INDEX changes_submitted CREATE INDEX changes_submitted
ON changes (status, dest_project_name, dest_branch_name, last_updated_on); ON changes (status, dest_project_name, dest_branch_name, last_updated_on);
-- covers: allOpenPrev, allOpenNext -- covers: byProjectOpenAll
CREATE INDEX changes_allOpen
ON changes (open, sort_key);
-- covers: byProjectOpenPrev, byProjectOpenNext
CREATE INDEX changes_byProjectOpen CREATE INDEX changes_byProjectOpen
ON changes (open, dest_project_name, sort_key); ON changes (open, dest_project_name, sort_key);
@ -93,30 +81,10 @@ ON changes (open, dest_project_name, sort_key);
CREATE INDEX changes_byProject CREATE INDEX changes_byProject
ON changes (dest_project_name); ON changes (dest_project_name);
-- covers: allClosedPrev, allClosedNext
CREATE INDEX changes_allClosed
ON changes (open, status, sort_key);
-- covers: byBranchClosedPrev, byBranchClosedNext
CREATE INDEX changes_byBranchClosed
ON changes (status, dest_project_name, dest_branch_name, sort_key);
CREATE INDEX changes_key CREATE INDEX changes_key
ON changes (change_key); ON changes (change_key);
-- *********************************************************************
-- PatchSetApprovalAccess
-- @PrimaryKey covers: byPatchSet, byPatchSetUser
-- covers: openByUser
CREATE INDEX patch_set_approvals_openByUser
ON patch_set_approvals (change_open, account_id);
-- covers: closedByUser
CREATE INDEX patch_set_approvals_closedByU
ON patch_set_approvals (change_open, account_id, change_sort_key);
-- ********************************************************************* -- *********************************************************************
-- ChangeMessageAccess -- ChangeMessageAccess
-- @PrimaryKey covers: byChange -- @PrimaryKey covers: byChange

View File

@ -117,63 +117,24 @@ ON account_project_watches (project_name);
-- ********************************************************************* -- *********************************************************************
-- ChangeAccess -- ChangeAccess
-- covers: byOwnerOpen
CREATE INDEX changes_byOwnerOpen
ON changes (owner_account_id, created_on, change_id)
WHERE open = 'Y';
-- covers: byOwnerClosed
CREATE INDEX changes_byOwnerClosed
ON changes (owner_account_id, last_updated_on)
WHERE open = 'N';
-- covers: submitted, allSubmitted -- covers: submitted, allSubmitted
CREATE INDEX changes_submitted CREATE INDEX changes_submitted
ON changes (dest_project_name, dest_branch_name, last_updated_on) ON changes (dest_project_name, dest_branch_name, last_updated_on)
WHERE status = 's'; WHERE status = 's';
-- covers: allOpenPrev, allOpenNext -- covers: byProjectOpenAll
CREATE INDEX changes_allOpen
ON changes (sort_key)
WHERE open = 'Y';
-- covers: byProjectOpenPrev, byProjectOpenNext
CREATE INDEX changes_byProjectOpen CREATE INDEX changes_byProjectOpen
ON changes (dest_project_name, sort_key) ON changes (dest_project_name, sort_key)
WHERE open = 'Y'; WHERE open = 'Y';
-- covers: allClosedPrev, allClosedNext
CREATE INDEX changes_allClosed
ON changes (status, sort_key)
WHERE open = 'N';
-- covers: byProject -- covers: byProject
CREATE INDEX changes_byProject CREATE INDEX changes_byProject
ON changes (dest_project_name); ON changes (dest_project_name);
-- covers: byBranchClosedPrev, byBranchClosedNext
CREATE INDEX changes_byBranchClosed
ON changes (status, dest_project_name, dest_branch_name, sort_key)
WHERE open = 'N';
CREATE INDEX changes_key CREATE INDEX changes_key
ON changes (change_key); ON changes (change_key);
-- *********************************************************************
-- PatchSetApprovalAccess
-- @PrimaryKey covers: byPatchSet, byPatchSetUser
-- covers: openByUser
CREATE INDEX patch_set_approvals_openByUser
ON patch_set_approvals (account_id)
WHERE change_open = 'Y';
-- covers: closedByUser
CREATE INDEX patch_set_approvals_closedByU
ON patch_set_approvals (account_id, change_sort_key)
WHERE change_open = 'N';
-- ********************************************************************* -- *********************************************************************
-- ChangeMessageAccess -- ChangeMessageAccess
-- @PrimaryKey covers: byChange -- @PrimaryKey covers: byChange

View File

@ -32,49 +32,6 @@ import java.io.IOException;
* appropriate. * appropriate.
*/ */
public interface ChangeIndex { public interface ChangeIndex {
/** Instance indicating secondary index is disabled. */
public static final ChangeIndex DISABLED = new ChangeIndex() {
@Override
public Schema<ChangeData> getSchema() {
return null;
}
@Override
public void insert(ChangeData cd) throws IOException {
// Do nothing.
}
@Override
public void replace(ChangeData cd) throws IOException {
// Do nothing.
}
@Override
public void delete(ChangeData cd) throws IOException {
// Do nothing.
}
@Override
public void deleteAll() throws IOException {
// Do nothing.
}
@Override
public ChangeDataSource getSource(Predicate<ChangeData> p, int limit) {
throw new UnsupportedOperationException();
}
@Override
public void close() {
// Do nothing.
}
@Override
public void markReady(boolean ready) {
throw new UnsupportedOperationException();
}
};
/** @return the schema version used by this index. */ /** @return the schema version used by this index. */
public Schema<ChangeData> getSchema(); public Schema<ChangeData> getSchema();

View File

@ -15,7 +15,6 @@
package com.google.gerrit.server.index; package com.google.gerrit.server.index;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.util.concurrent.Callables;
import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.ListeningExecutorService;
@ -38,24 +37,6 @@ public abstract class ChangeIndexer {
ChangeIndexer create(IndexCollection indexes); ChangeIndexer create(IndexCollection indexes);
} }
/** Instance indicating secondary index is disabled. */
public static final ChangeIndexer DISABLED = new ChangeIndexer(null) {
@Override
public CheckedFuture<?, IOException> indexAsync(ChangeData cd) {
return Futures.immediateCheckedFuture(null);
}
@Override
protected Callable<?> indexTask(ChangeData cd) {
return Callables.returning(null);
}
@Override
protected Callable<?> deleteTask(ChangeData cd) {
return Callables.returning(null);
}
};
private static final Function<Exception, IOException> MAPPER = private static final Function<Exception, IOException> MAPPER =
new Function<Exception, IOException>() { new Function<Exception, IOException>() {
@Override @Override

View File

@ -16,7 +16,6 @@ package com.google.gerrit.server.index;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -39,11 +38,7 @@ public class IndexCollection implements LifecycleListener {
this.searchIndex = new AtomicReference<ChangeIndex>(); this.searchIndex = new AtomicReference<ChangeIndex>();
} }
/** /** @return the current search index version. */
* @return the current search index version, or null if the secondary index is
* disabled.
*/
@Nullable
public ChangeIndex getSearchIndex() { public ChangeIndex getSearchIndex() {
return searchIndex.get(); return searchIndex.get();
} }

View File

@ -19,6 +19,7 @@ import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.lifecycle.LifecycleModule; import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.WorkQueue; import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.query.change.BasicChangeRewrites;
import com.google.gerrit.server.query.change.ChangeQueryRewriter; import com.google.gerrit.server.query.change.ChangeQueryRewriter;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -37,14 +38,14 @@ import org.eclipse.jgit.lib.Config;
*/ */
public class IndexModule extends LifecycleModule { public class IndexModule extends LifecycleModule {
public enum IndexType { public enum IndexType {
SQL, LUCENE, SOLR LUCENE, SOLR
} }
/** Type of secondary index. */ /** Type of secondary index. */
public static IndexType getIndexType(Injector injector) { public static IndexType getIndexType(Injector injector) {
Config cfg = injector.getInstance( Config cfg = injector.getInstance(
Key.get(Config.class, GerritServerConfig.class)); Key.get(Config.class, GerritServerConfig.class));
return cfg.getEnum("index", null, "type", IndexType.SQL); return cfg.getEnum("index", null, "type", IndexType.LUCENE);
} }
private final int threads; private final int threads;
@ -63,7 +64,7 @@ public class IndexModule extends LifecycleModule {
@Override @Override
protected void configure() { protected void configure() {
bind(ChangeQueryRewriter.class).to(IndexRewriteImpl.class); bind(ChangeQueryRewriter.class).to(IndexRewriteImpl.class);
bind(IndexRewriteImpl.BasicRewritesImpl.class); bind(BasicChangeRewrites.class);
bind(IndexCollection.class); bind(IndexCollection.class);
listener().to(IndexCollection.class); listener().to(IndexCollection.class);
install(new FactoryModuleBuilder() install(new FactoryModuleBuilder()

View File

@ -25,7 +25,6 @@ import com.google.gerrit.server.query.NotPredicate;
import com.google.gerrit.server.query.OrPredicate; import com.google.gerrit.server.query.OrPredicate;
import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException; import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.QueryRewriter;
import com.google.gerrit.server.query.change.AndSource; import com.google.gerrit.server.query.change.AndSource;
import com.google.gerrit.server.query.change.BasicChangeRewrites; import com.google.gerrit.server.query.change.BasicChangeRewrites;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
@ -33,7 +32,6 @@ import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.ChangeQueryRewriter; import com.google.gerrit.server.query.change.ChangeQueryRewriter;
import com.google.gerrit.server.query.change.ChangeStatusPredicate; import com.google.gerrit.server.query.change.ChangeStatusPredicate;
import com.google.gerrit.server.query.change.OrSource; import com.google.gerrit.server.query.change.OrSource;
import com.google.gerrit.server.query.change.SqlRewriterImpl;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
@ -125,27 +123,21 @@ public class IndexRewriteImpl implements ChangeQueryRewriter {
private final IndexCollection indexes; private final IndexCollection indexes;
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
private final BasicRewritesImpl basicRewrites; private final BasicChangeRewrites basicRewrites;
private final SqlRewriterImpl sqlRewriter;
@Inject @Inject
IndexRewriteImpl(IndexCollection indexes, IndexRewriteImpl(IndexCollection indexes,
Provider<ReviewDb> db, Provider<ReviewDb> db,
BasicRewritesImpl basicRewrites, BasicChangeRewrites basicRewrites) {
SqlRewriterImpl sqlRewriter) {
this.indexes = indexes; this.indexes = indexes;
this.db = db; this.db = db;
this.basicRewrites = basicRewrites; this.basicRewrites = basicRewrites;
this.sqlRewriter = sqlRewriter;
} }
@Override @Override
public Predicate<ChangeData> rewrite(Predicate<ChangeData> in) public Predicate<ChangeData> rewrite(Predicate<ChangeData> in)
throws QueryParseException { throws QueryParseException {
ChangeIndex index = indexes.getSearchIndex(); ChangeIndex index = indexes.getSearchIndex();
if (index == null) {
return sqlRewriter.rewrite(in);
}
in = basicRewrites.rewrite(in); in = basicRewrites.rewrite(in);
int limit = ChangeQueryBuilder.hasLimit(in) int limit = ChangeQueryBuilder.hasLimit(in)
? ChangeQueryBuilder.getLimit(in) ? ChangeQueryBuilder.getLimit(in)
@ -271,14 +263,4 @@ public class IndexRewriteImpl implements ChangeQueryRewriter {
|| p instanceof OrPredicate || p instanceof OrPredicate
|| p instanceof NotPredicate); || p instanceof NotPredicate);
} }
static class BasicRewritesImpl extends BasicChangeRewrites {
private static final QueryRewriter.Definition<ChangeData, BasicRewritesImpl> mydef =
new QueryRewriter.Definition<ChangeData, BasicRewritesImpl>(
BasicRewritesImpl.class, SqlRewriterImpl.BUILDER);
@Inject
BasicRewritesImpl(Provider<ReviewDb> db, IndexCollection indexes) {
super(mydef, db, indexes);
}
}
} }

View File

@ -1,32 +0,0 @@
// Copyright (C) 2013 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.index;
import com.google.gerrit.server.query.change.ChangeQueryRewriter;
import com.google.gerrit.server.query.change.SqlRewriterImpl;
import com.google.inject.AbstractModule;
public class NoIndexModule extends AbstractModule {
// TODO(dborowitz): This module should go away when the index becomes
// obligatory, as should the interfaces that exist only to support the
// non-index case.
@Override
protected void configure() {
bind(ChangeIndex.class).toInstance(ChangeIndex.DISABLED);
bind(ChangeIndexer.class).toInstance(ChangeIndexer.DISABLED);
bind(ChangeQueryRewriter.class).to(SqlRewriterImpl.class);
}
}

View File

@ -202,7 +202,6 @@ public class ProjectWatch {
} }
if (filter != null) { if (filter != null) {
qb.setAllowFileRegex(true);
Predicate<ChangeData> filterPredicate = qb.parse(filter); Predicate<ChangeData> filterPredicate = qb.parse(filter);
if (p == null) { if (p == null) {
p = filterPredicate; p = filterPredicate;

View File

@ -24,18 +24,23 @@ import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.query.IntPredicate; import com.google.gerrit.server.query.IntPredicate;
import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryRewriter; import com.google.gerrit.server.query.QueryRewriter;
import com.google.inject.Inject;
import com.google.inject.OutOfScopeException; import com.google.inject.OutOfScopeException;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.name.Named; import com.google.inject.name.Named;
public abstract class BasicChangeRewrites extends QueryRewriter<ChangeData> { public class BasicChangeRewrites extends QueryRewriter<ChangeData> {
protected static final ChangeQueryBuilder BUILDER = new ChangeQueryBuilder( private static final ChangeQueryBuilder BUILDER = new ChangeQueryBuilder(
new ChangeQueryBuilder.Arguments( // new ChangeQueryBuilder.Arguments( //
new InvalidProvider<ReviewDb>(), // new InvalidProvider<ReviewDb>(), //
new InvalidProvider<ChangeQueryRewriter>(), // new InvalidProvider<ChangeQueryRewriter>(), //
null, null, null, null, null, null, null, // null, null, null, null, null, null, null, //
null, null, null, null, null, null, null), null); null, null, null, null, null, null, null), null);
private static final QueryRewriter.Definition<ChangeData, BasicChangeRewrites> mydef =
new QueryRewriter.Definition<ChangeData, BasicChangeRewrites>(
BasicChangeRewrites.class, BUILDER);
static Schema<ChangeData> schema(@Nullable IndexCollection indexes) { static Schema<ChangeData> schema(@Nullable IndexCollection indexes) {
ChangeIndex index = indexes != null ? indexes.getSearchIndex() : null; ChangeIndex index = indexes != null ? indexes.getSearchIndex() : null;
return index != null ? index.getSchema() : null; return index != null ? index.getSchema() : null;
@ -44,10 +49,9 @@ public abstract class BasicChangeRewrites extends QueryRewriter<ChangeData> {
protected final Provider<ReviewDb> dbProvider; protected final Provider<ReviewDb> dbProvider;
private final IndexCollection indexes; private final IndexCollection indexes;
protected BasicChangeRewrites( @Inject
Definition<ChangeData, ? extends QueryRewriter<ChangeData>> def, public BasicChangeRewrites(Provider<ReviewDb> dbProvider, IndexCollection indexes) {
Provider<ReviewDb> dbProvider, IndexCollection indexes) { super(mydef);
super(def);
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.indexes = indexes; this.indexes = indexes;
} }

View File

@ -201,7 +201,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
private final Arguments args; private final Arguments args;
private final CurrentUser currentUser; private final CurrentUser currentUser;
private boolean allowFileRegex;
@Inject @Inject
public ChangeQueryBuilder(Arguments args, @Assisted CurrentUser currentUser) { public ChangeQueryBuilder(Arguments args, @Assisted CurrentUser currentUser) {
@ -219,10 +218,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
this.currentUser = currentUser; this.currentUser = currentUser;
} }
public void setAllowFileRegex(boolean on) {
allowFileRegex = on;
}
@Operator @Operator
public Predicate<ChangeData> age(String value) { public Predicate<ChangeData> age(String value) {
return new AgePredicate(args.dbProvider, value); return new AgePredicate(args.dbProvider, value);
@ -243,7 +238,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
@Operator @Operator
public Predicate<ChangeData> comment(String value) throws QueryParseException { public Predicate<ChangeData> comment(String value) throws QueryParseException {
ChangeIndex index = requireIndex(FIELD_COMMENT, value); ChangeIndex index = args.indexes.getSearchIndex();
return new CommentPredicate(args.dbProvider, index, value); return new CommentPredicate(args.dbProvider, index, value);
} }
@ -307,7 +302,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
} }
if ("mergeable".equalsIgnoreCase(value)) { if ("mergeable".equalsIgnoreCase(value)) {
requireIndex(FIELD_IS, "mergeable");
return new IsMergeablePredicate(args.dbProvider); return new IsMergeablePredicate(args.dbProvider);
} }
@ -329,7 +323,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
@Operator @Operator
public Predicate<ChangeData> conflicts(String value) throws OrmException, public Predicate<ChangeData> conflicts(String value) throws OrmException,
QueryParseException { QueryParseException {
requireIndex(FIELD_CONFLICTS, value);
return new ConflictsPredicate(args.dbProvider, args.patchListCache, return new ConflictsPredicate(args.dbProvider, args.patchListCache,
args.submitStrategyFactory, args.changeControlGenericFactory, args.submitStrategyFactory, args.changeControlGenericFactory,
args.userFactory, args.repoManager, args.projectCache, args.userFactory, args.repoManager, args.projectCache,
@ -389,12 +382,8 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
@Operator @Operator
public Predicate<ChangeData> file(String file) throws QueryParseException { public Predicate<ChangeData> file(String file) throws QueryParseException {
if (file.startsWith("^")) { if (file.startsWith("^")) {
if (!allowFileRegex) {
requireIndex(FIELD_FILE, file);
}
return new RegexFilePredicate(args.dbProvider, args.patchListCache, file); return new RegexFilePredicate(args.dbProvider, args.patchListCache, file);
} else { } else {
requireIndex(FIELD_FILE, file);
return new EqualsFilePredicate(args.dbProvider, args.patchListCache, file); return new EqualsFilePredicate(args.dbProvider, args.patchListCache, file);
} }
} }
@ -456,10 +445,6 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
@Operator @Operator
public Predicate<ChangeData> message(String text) throws QueryParseException { public Predicate<ChangeData> message(String text) throws QueryParseException {
ChangeIndex index = args.indexes.getSearchIndex(); ChangeIndex index = args.indexes.getSearchIndex();
if (index == null) {
return new LegacyMessagePredicate(args.dbProvider, args.repoManager, text);
}
return new MessagePredicate(args.dbProvider, index, text); return new MessagePredicate(args.dbProvider, index, text);
} }
@ -753,13 +738,4 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
} }
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
private ChangeIndex requireIndex(String field, String value)
throws QueryParseException {
ChangeIndex idx = args.indexes.getSearchIndex();
if (idx == null) {
throw error("secondary index must be enabled for " + field + ":" + value);
}
return idx;
}
} }

View File

@ -1,69 +0,0 @@
// Copyright (C) 2013 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.server.ReviewDb;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Provider;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* Predicate to match changes that contains specified text in commit messages
* body.
*/
public class LegacyMessagePredicate extends RevWalkPredicate {
private static final Logger log = LoggerFactory
.getLogger(LegacyMessagePredicate.class);
private final RevFilter rFilter;
public LegacyMessagePredicate(Provider<ReviewDb> db,
GitRepositoryManager repoManager, String text) {
super(db, repoManager, ChangeQueryBuilder.FIELD_MESSAGE, text);
this.rFilter = MessageRevFilter.create(text);
}
@Override
public boolean match(Repository repo, RevWalk rw, Arguments args) {
try {
return rFilter.include(rw, rw.parseCommit(args.objectId));
} catch (MissingObjectException e) {
log.error(args.projectName.get() + "\" commit does not exist.", e);
} catch (IncorrectObjectTypeException e) {
log.error(args.projectName.get() + "\" revision is not a commit.", e);
} catch (IOException e) {
log.error(
"Could not search for commit message in \"" + args.projectName.get()
+ "\" repository.", e);
}
return false;
}
@Override
public int getCost() {
return 1;
}
}

View File

@ -1,658 +0,0 @@
// Copyright (C) 2009 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.common.annotations.VisibleForTesting;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ChangeAccess;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.query.IntPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryRewriter;
import com.google.gerrit.server.query.RewritePredicate;
import com.google.gerrit.server.query.change.ChangeQueryBuilder.LimitPredicate;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import java.util.Collection;
public class SqlRewriterImpl extends BasicChangeRewrites
implements ChangeQueryRewriter {
private static final QueryRewriter.Definition<ChangeData, SqlRewriterImpl> mydef =
new QueryRewriter.Definition<ChangeData, SqlRewriterImpl>(
SqlRewriterImpl.class, BUILDER);
@Inject
@VisibleForTesting
public SqlRewriterImpl(Provider<ReviewDb> dbProvider) {
super(mydef, dbProvider, null);
}
@Override
public Predicate<ChangeData> and(Collection<? extends Predicate<ChangeData>> l) {
return hasSource(l) ? new AndSource(dbProvider, l) : super.and(l);
}
@Override
public Predicate<ChangeData> or(Collection<? extends Predicate<ChangeData>> l) {
return hasSource(l) ? new OrSource(l) : super.or(l);
}
@Rewrite("status:open P=(project:*) B=(ref:*)")
public Predicate<ChangeData> r05_byBranchOpen(
@Named("P") final ProjectPredicate p,
@Named("B") final RefPredicate b) {
return new ChangeSource(500) {
@Override
ResultSet<Change> scan(ChangeAccess a)
throws OrmException {
return a.byBranchOpenAll(
new Branch.NameKey(p.getValueKey(), b.getValue()));
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen()
&& p.match(cd)
&& b.match(cd);
}
};
}
@Rewrite("status:merged P=(project:*) B=(ref:*) S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r05_byBranchMergedPrev(
@Named("P") final ProjectPredicate p,
@Named("B") final RefPredicate b,
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byBranchClosedPrev(Change.Status.MERGED.getCode(), //
new Branch.NameKey(p.getValueKey(), b.getValue()), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& p.match(cd) //
&& b.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:merged P=(project:*) B=(ref:*) S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r05_byBranchMergedNext(
@Named("P") final ProjectPredicate p,
@Named("B") final RefPredicate b,
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byBranchClosedNext(Change.Status.MERGED.getCode(), //
new Branch.NameKey(p.getValueKey(), b.getValue()), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& p.match(cd) //
&& b.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:open P=(project:*) S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectOpenPrev(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(500, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectOpenPrev(p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen() //
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:open P=(project:*) S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectOpenNext(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(500, s.getValue(), l.intValue()) {
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectOpenNext(p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen() //
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:merged P=(project:*) S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectMergedPrev(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectClosedPrev(Change.Status.MERGED.getCode(), //
p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:merged P=(project:*) S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectMergedNext(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectClosedNext(Change.Status.MERGED.getCode(), //
p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:abandoned P=(project:*) S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectAbandonedPrev(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectClosedPrev(Change.Status.ABANDONED.getCode(), //
p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.ABANDONED
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:abandoned P=(project:*) S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r10_byProjectAbandonedNext(
@Named("P") final ProjectPredicate p,
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(40000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.byProjectClosedNext(Change.Status.ABANDONED.getCode(), //
p.getValueKey(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.ABANDONED
&& p.match(cd) //
&& s.match(cd);
}
};
}
@Rewrite("status:open S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r20_byOpenPrev(
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(2000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allOpenPrev(key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen() && s.match(cd);
}
};
}
@Rewrite("status:open S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r20_byOpenNext(
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(2000, s.getValue(), l.intValue()) {
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allOpenNext(key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen() && s.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:merged S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r20_byMergedPrev(
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(50000, s.getValue(), l.intValue()) {
{
init("r20_byMergedPrev", s, l);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allClosedPrev(Change.Status.MERGED.getCode(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& s.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:merged S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r20_byMergedNext(
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(50000, s.getValue(), l.intValue()) {
{
init("r20_byMergedNext", s, l);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allClosedNext(Change.Status.MERGED.getCode(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.MERGED
&& s.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:abandoned S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r20_byAbandonedPrev(
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(50000, s.getValue(), l.intValue()) {
{
init("r20_byAbandonedPrev", s, l);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allClosedPrev(Change.Status.ABANDONED.getCode(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.ABANDONED
&& s.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:abandoned S=(sortkey_before:*) L=(limit:*)")
public Predicate<ChangeData> r20_byAbandonedNext(
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return new PaginatedSource(50000, s.getValue(), l.intValue()) {
{
init("r20_byAbandonedNext", s, l);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException {
return a.allClosedNext(Change.Status.ABANDONED.getCode(), key, limit);
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.ABANDONED
&& s.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:closed S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r20_byClosedPrev(
@Named("S") final SortKeyPredicate.After s,
@Named("L") final IntPredicate<ChangeData> l) {
return or(r20_byMergedPrev(s, l), r20_byAbandonedPrev(s, l));
}
@SuppressWarnings("unchecked")
@Rewrite("status:closed S=(sortkey_after:*) L=(limit:*)")
public Predicate<ChangeData> r20_byClosedNext(
@Named("S") final SortKeyPredicate.Before s,
@Named("L") final IntPredicate<ChangeData> l) {
return or(r20_byMergedNext(s, l), r20_byAbandonedNext(s, l));
}
@SuppressWarnings("unchecked")
@Rewrite("status:open O=(owner:*)")
public Predicate<ChangeData> r25_byOwnerOpen(
@Named("O") final OwnerPredicate o) {
return new ChangeSource(50) {
{
init("r25_byOwnerOpen", o);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a) throws OrmException {
return a.byOwnerOpen(o.getAccountId());
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isOpen() && o.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:closed O=(owner:*)")
public Predicate<ChangeData> r25_byOwnerClosed(
@Named("O") final OwnerPredicate o) {
return new ChangeSource(5000) {
{
init("r25_byOwnerClosed", o);
}
@SuppressWarnings("deprecation")
@Override
ResultSet<Change> scan(ChangeAccess a) throws OrmException {
return a.byOwnerClosedAll(o.getAccountId());
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus().isClosed() && o.match(cd);
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("O=(owner:*)")
public Predicate<ChangeData> r26_byOwner(@Named("O") OwnerPredicate o) {
return or(r25_byOwnerOpen(o), r25_byOwnerClosed(o));
}
@SuppressWarnings("unchecked")
@Rewrite("status:open R=(reviewer:*)")
public Predicate<ChangeData> r30_byReviewerOpen(
@Named("R") final ReviewerPredicate r) {
return new Source() {
{
init("r30_byReviewerOpen", r);
}
@SuppressWarnings("deprecation")
@Override
public ResultSet<ChangeData> read() throws OrmException {
return ChangeDataResultSet.patchSetApproval(dbProvider.get()
.patchSetApprovals().openByUser(r.getAccountId()));
}
@Override
public boolean match(ChangeData cd) throws OrmException {
Change change = cd.change(dbProvider);
return change != null && change.getStatus().isOpen() && r.match(cd);
}
@Override
public int getCardinality() {
return 50;
}
@Override
public int getCost() {
return ChangeCosts.cost(ChangeCosts.APPROVALS_SCAN, getCardinality());
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("status:closed R=(reviewer:*)")
public Predicate<ChangeData> r30_byReviewerClosed(
@Named("R") final ReviewerPredicate r) {
return new Source() {
{
init("r30_byReviewerClosed", r);
}
@SuppressWarnings("deprecation")
@Override
public ResultSet<ChangeData> read() throws OrmException {
return ChangeDataResultSet.patchSetApproval(dbProvider.get()
.patchSetApprovals().closedByUserAll(r.getAccountId()));
}
@Override
public boolean match(ChangeData cd) throws OrmException {
Change change = cd.change(dbProvider);
return change != null && change.getStatus().isClosed() && r.match(cd);
}
@Override
public int getCardinality() {
return 5000;
}
@Override
public int getCost() {
return ChangeCosts.cost(ChangeCosts.APPROVALS_SCAN, getCardinality());
}
};
}
@SuppressWarnings("unchecked")
@Rewrite("R=(reviewer:*)")
public Predicate<ChangeData> r31_byReviewer(
@Named("R") final ReviewerPredicate r) {
return or(r30_byReviewerOpen(r), r30_byReviewerClosed(r));
}
@Rewrite("status:closed")
public Predicate<ChangeData> r99_allClosed() {
return r20_byClosedNext(
new SortKeyPredicate.Before(null, dbProvider, "z"),
new LimitPredicate(Integer.MAX_VALUE));
}
@Rewrite("status:submitted")
public Predicate<ChangeData> r99_allSubmitted() {
return new ChangeSource(50) {
@Override
ResultSet<Change> scan(ChangeAccess a) throws OrmException {
return a.allSubmitted();
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return cd.change(dbProvider).getStatus() == Change.Status.SUBMITTED;
}
};
}
@Rewrite("P=(project:*)")
public Predicate<ChangeData> r99_byProject(
@Named("P") final ProjectPredicate p) {
return new ChangeSource(1000000) {
@Override
ResultSet<Change> scan(ChangeAccess a) throws OrmException {
return a.byProject(p.getValueKey());
}
@Override
public boolean match(ChangeData cd) throws OrmException {
return p.match(cd);
}
};
}
private static boolean hasSource(Collection<? extends Predicate<ChangeData>> l) {
for (Predicate<ChangeData> p : l) {
if (p instanceof ChangeDataSource) {
return true;
}
}
return false;
}
private abstract static class Source extends RewritePredicate<ChangeData>
implements ChangeDataSource {
@Override
public boolean hasChange() {
return false;
}
}
private abstract class ChangeSource extends Source {
private final int cardinality;
ChangeSource(int card) {
this.cardinality = card;
}
abstract ResultSet<Change> scan(ChangeAccess a) throws OrmException;
@Override
public ResultSet<ChangeData> read() throws OrmException {
return ChangeDataResultSet.change(scan(dbProvider.get().changes()));
}
@Override
public boolean hasChange() {
return true;
}
@Override
public int getCardinality() {
return cardinality;
}
@Override
public int getCost() {
return ChangeCosts.cost(ChangeCosts.CHANGES_SCAN, getCardinality());
}
}
private abstract class PaginatedSource extends ChangeSource implements
Paginated {
private final String startKey;
private final int limit;
PaginatedSource(int card, String start, int lim) {
super(card);
this.startKey = start;
this.limit = lim;
}
@Override
public int limit() {
return limit;
}
@Override
ResultSet<Change> scan(ChangeAccess a) throws OrmException {
return scan(a, startKey, limit);
}
@Override
public ResultSet<ChangeData> restart(ChangeData last) throws OrmException {
return ChangeDataResultSet.change(scan(dbProvider.get().changes(), //
last.change(dbProvider).getSortKey(), //
limit));
}
abstract ResultSet<Change> scan(ChangeAccess a, String key, int limit)
throws OrmException;
}
}

View File

@ -14,21 +14,14 @@
package com.google.gerrit.server.query.change; package com.google.gerrit.server.query.change;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.TrackingId; import com.google.gerrit.reviewdb.client.TrackingId;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.index.ChangeField; import com.google.gerrit.server.index.ChangeField;
import com.google.gerrit.server.index.IndexPredicate; import com.google.gerrit.server.index.IndexPredicate;
import com.google.gwtorm.server.ListResultSet;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Provider; import com.google.inject.Provider;
import java.util.ArrayList; class TrackingIdPredicate extends IndexPredicate<ChangeData> {
import java.util.HashSet;
class TrackingIdPredicate extends IndexPredicate<ChangeData> implements
ChangeDataSource {
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
TrackingIdPredicate(Provider<ReviewDb> db, String trackingId) { TrackingIdPredicate(Provider<ReviewDb> db, String trackingId) {
@ -46,34 +39,10 @@ class TrackingIdPredicate extends IndexPredicate<ChangeData> implements
return false; return false;
} }
@SuppressWarnings("deprecation")
@Override
public ResultSet<ChangeData> read() throws OrmException {
HashSet<Change.Id> ids = new HashSet<Change.Id>();
for (TrackingId sc : db.get().trackingIds() //
.byTrackingId(new TrackingId.Id(getValue()))) {
ids.add(sc.getChangeId());
}
ArrayList<ChangeData> r = new ArrayList<ChangeData>(ids.size());
for (Change.Id id : ids) {
r.add(new ChangeData(id));
}
return new ListResultSet<ChangeData>(r);
}
@Override
public boolean hasChange() {
return false;
}
@Override
public int getCardinality() {
return ChangeCosts.CARD_TRACKING_IDS;
}
@Override @Override
public int getCost() { public int getCost() {
return ChangeCosts.cost(ChangeCosts.TR_SCAN, getCardinality()); return ChangeCosts.cost(
ChangeCosts.TR_SCAN,
ChangeCosts.CARD_TRACKING_IDS);
} }
} }

View File

@ -28,12 +28,12 @@ import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.query.AndPredicate; import com.google.gerrit.server.query.AndPredicate;
import com.google.gerrit.server.query.Predicate; import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException; import com.google.gerrit.server.query.QueryParseException;
import com.google.gerrit.server.query.RewritePredicate;
import com.google.gerrit.server.query.change.AndSource; import com.google.gerrit.server.query.change.AndSource;
import com.google.gerrit.server.query.change.BasicChangeRewrites;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder; import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.OrSource; import com.google.gerrit.server.query.change.OrSource;
import com.google.gerrit.server.query.change.SqlRewriterImpl;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -56,8 +56,7 @@ public class IndexRewriteTest {
rewrite = new IndexRewriteImpl( rewrite = new IndexRewriteImpl(
indexes, indexes,
null, null,
new IndexRewriteImpl.BasicRewritesImpl(null, indexes), new BasicChangeRewrites(null, indexes));
new SqlRewriterImpl(null));
} }
@Test @Test
@ -202,19 +201,6 @@ public class IndexRewriteTest {
out.getChildren()); out.getChildren());
} }
@Test
public void testNoChangeIndexUsesSqlRewrites() throws Exception {
Predicate<ChangeData> in = parse("status:open project:p ref:b");
Predicate<ChangeData> out;
out = rewrite(in);
assertTrue(out instanceof AndPredicate || out instanceof IndexedChangeQuery);
indexes.setSearchIndex(null);
out = rewrite(in);
assertTrue(out instanceof RewritePredicate);
}
private Predicate<ChangeData> parse(String query) throws QueryParseException { private Predicate<ChangeData> parse(String query) throws QueryParseException {
return queryBuilder.parse(query); return queryBuilder.parse(query);
} }

View File

@ -1,29 +0,0 @@
// Copyright (C) 2013 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.testutil.InMemoryModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.eclipse.jgit.lib.Config;
public class SqlQueryChangesTest extends AbstractQueryChangesTest {
protected Injector createInjector() {
Config cfg = InMemoryModule.newDefaultConfig();
cfg.setString("index", null, "type", "sql");
return Guice.createInjector(new InMemoryModule(cfg));
}
}

View File

@ -43,7 +43,6 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.PerThreadRequestScope; import com.google.gerrit.server.git.PerThreadRequestScope;
import com.google.gerrit.server.index.ChangeSchemas; import com.google.gerrit.server.index.ChangeSchemas;
import com.google.gerrit.server.index.IndexModule.IndexType; import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.index.NoIndexModule;
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
import com.google.gerrit.server.mail.SmtpEmailSender; import com.google.gerrit.server.mail.SmtpEmailSender;
import com.google.gerrit.server.schema.Current; import com.google.gerrit.server.schema.Current;
@ -83,6 +82,9 @@ public class InMemoryModule extends FactoryModule {
cfg.setString("user", null, "email", "gerrit@localhost"); cfg.setString("user", null, "email", "gerrit@localhost");
cfg.setBoolean("sendemail", null, "enable", false); cfg.setBoolean("sendemail", null, "enable", false);
cfg.setString("cache", null, "directory", null); cfg.setString("cache", null, "directory", null);
cfg.setString("index", null, "type", "lucene");
cfg.setBoolean("index", "lucene", "testInmemory", true);
cfg.setInt("index", "lucene", "testVersion", 4);
return cfg; return cfg;
} }
@ -155,7 +157,7 @@ public class InMemoryModule extends FactoryModule {
IndexType indexType = null; IndexType indexType = null;
try { try {
indexType = cfg.getEnum("index", null, "type", IndexType.SQL); indexType = cfg.getEnum("index", null, "type", IndexType.LUCENE);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// Custom index type, caller must provide their own module. // Custom index type, caller must provide their own module.
} }
@ -164,9 +166,6 @@ public class InMemoryModule extends FactoryModule {
case LUCENE: case LUCENE:
install(luceneIndexModule()); install(luceneIndexModule());
break; break;
case SQL:
install(new NoIndexModule());
break;
default: default:
throw new ProvisionException( throw new ProvisionException(
"index type unsupported in tests: " + indexType); "index type unsupported in tests: " + indexType);

View File

@ -40,7 +40,6 @@ import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.git.ReceiveCommitsExecutorModule; import com.google.gerrit.server.git.ReceiveCommitsExecutorModule;
import com.google.gerrit.server.git.WorkQueue; import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.IndexModule; import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.NoIndexModule;
import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier; import com.google.gerrit.server.mail.SignedTokenEmailTokenVerifier;
import com.google.gerrit.server.mail.SmtpEmailSender; import com.google.gerrit.server.mail.SmtpEmailSender;
import com.google.gerrit.server.patch.IntraLineWorkerPool; import com.google.gerrit.server.patch.IntraLineWorkerPool;
@ -268,7 +267,7 @@ public class WebAppInitializer extends GuiceServletContextListener
changeIndexModule = new SolrIndexModule(); changeIndexModule = new SolrIndexModule();
break; break;
default: default:
changeIndexModule = new NoIndexModule(); throw new IllegalStateException("unsupported index.type");
} }
modules.add(changeIndexModule); modules.add(changeIndexModule);
modules.add(new CanonicalWebUrlModule() { modules.add(new CanonicalWebUrlModule() {