Merge branch 'stable-2.13' into stable-2.14

* stable-2.13:
  Support Jdbc implementation of AccountPatchReviewStore

Change-Id: I27577b1df515d994d0f28a36d33b75110916d945
This commit is contained in:
David Pursehouse
2017-04-26 10:21:46 +02:00
12 changed files with 679 additions and 249 deletions

View File

@@ -15,13 +15,8 @@
package com.google.gerrit.server.schema;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.AccountPatchReviewStore;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
@@ -29,31 +24,11 @@ import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.Optional;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class H2AccountPatchReviewStore implements AccountPatchReviewStore, LifecycleListener {
private static final Logger log = LoggerFactory.getLogger(H2AccountPatchReviewStore.class);
public static class Module extends LifecycleModule {
@Override
protected void configure() {
DynamicItem.bind(binder(), AccountPatchReviewStore.class).to(H2AccountPatchReviewStore.class);
listener().to(H2AccountPatchReviewStore.class);
}
}
public class H2AccountPatchReviewStore extends JdbcAccountPatchReviewStore {
@VisibleForTesting
public static class InMemoryModule extends LifecycleModule {
@@ -65,15 +40,9 @@ public class H2AccountPatchReviewStore implements AccountPatchReviewStore, Lifec
}
}
private final DataSource ds;
@Inject
H2AccountPatchReviewStore(@GerritServerConfig Config cfg, SitePaths sitePaths) {
this.ds = createDataSource(H2.appendUrlOptions(cfg, getUrl(sitePaths)));
}
public static String getUrl(SitePaths sitePaths) {
return H2.createUrl(sitePaths.db_dir.resolve("account_patch_reviews"));
super(cfg, sitePaths);
}
/**
@@ -85,196 +54,11 @@ public class H2AccountPatchReviewStore implements AccountPatchReviewStore, Lifec
// DB_CLOSE_DELAY=-1: By default the content of an in-memory H2 database is
// lost at the moment the last connection is closed. This option keeps the
// content as long as the vm lives.
this.ds = createDataSource("jdbc:h2:mem:account_patch_reviews;DB_CLOSE_DELAY=-1");
}
private static DataSource createDataSource(String url) {
BasicDataSource datasource = new BasicDataSource();
datasource.setDriverClassName("org.h2.Driver");
datasource.setUrl(url);
datasource.setMaxActive(50);
datasource.setMinIdle(4);
datasource.setMaxIdle(16);
long evictIdleTimeMs = 1000 * 60;
datasource.setMinEvictableIdleTimeMillis(evictIdleTimeMs);
datasource.setTimeBetweenEvictionRunsMillis(evictIdleTimeMs / 2);
return datasource;
super(createDataSource("jdbc:h2:mem:account_patch_reviews;DB_CLOSE_DELAY=-1"));
}
@Override
public void start() {
try {
createTableIfNotExists();
} catch (OrmException e) {
log.error("Failed to create table to store account patch reviews", e);
}
}
public static void createTableIfNotExists(String url) throws OrmException {
try (Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement()) {
doCreateTable(stmt);
} catch (SQLException e) {
throw convertError("create", e);
}
}
private void createTableIfNotExists() throws OrmException {
try (Connection con = ds.getConnection();
Statement stmt = con.createStatement()) {
doCreateTable(stmt);
} catch (SQLException e) {
throw convertError("create", e);
}
}
private static void doCreateTable(Statement stmt) throws SQLException {
stmt.executeUpdate(
"CREATE TABLE IF NOT EXISTS account_patch_reviews ("
+ "account_id INTEGER DEFAULT 0 NOT NULL, "
+ "change_id INTEGER DEFAULT 0 NOT NULL, "
+ "patch_set_id INTEGER DEFAULT 0 NOT NULL, "
+ "file_name VARCHAR(4096) DEFAULT '' NOT NULL, "
+ "CONSTRAINT primary_key_account_patch_reviews "
+ "PRIMARY KEY (account_id, change_id, patch_set_id, file_name)"
+ ")");
}
public static void dropTableIfExists(String url) throws OrmException {
try (Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement()) {
stmt.executeUpdate("DROP TABLE IF EXISTS account_patch_reviews");
} catch (SQLException e) {
throw convertError("create", e);
}
}
@Override
public void stop() {}
@Override
public boolean markReviewed(PatchSet.Id psId, Account.Id accountId, String path)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
+ "(account_id, change_id, patch_set_id, file_name) VALUES "
+ "(?, ?, ?, ?)")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.executeUpdate();
return true;
} catch (SQLException e) {
OrmException ormException = convertError("insert", e);
if (ormException instanceof OrmDuplicateKeyException) {
return false;
}
throw ormException;
}
}
@Override
public void markReviewed(PatchSet.Id psId, Account.Id accountId, Collection<String> paths)
throws OrmException {
if (paths == null || paths.isEmpty()) {
return;
}
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
+ "(account_id, change_id, patch_set_id, file_name) VALUES "
+ "(?, ?, ?, ?)")) {
for (String path : paths) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.addBatch();
}
stmt.executeBatch();
} catch (SQLException e) {
OrmException ormException = convertError("insert", e);
if (ormException instanceof OrmDuplicateKeyException) {
return;
}
throw ormException;
}
}
@Override
public void clearReviewed(PatchSet.Id psId, Account.Id accountId, String path)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
+ "WHERE account_id = ? AND change_id = ? AND "
+ "patch_set_id = ? AND file_name = ?")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.executeUpdate();
} catch (SQLException e) {
throw convertError("delete", e);
}
}
@Override
public void clearReviewed(PatchSet.Id psId) throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
+ "WHERE change_id = ? AND patch_set_id = ?")) {
stmt.setInt(1, psId.getParentKey().get());
stmt.setInt(2, psId.get());
stmt.executeUpdate();
} catch (SQLException e) {
throw convertError("delete", e);
}
}
@Override
public Optional<PatchSetWithReviewedFiles> findReviewed(PatchSet.Id psId, Account.Id accountId)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"SELECT patch_set_id, file_name FROM account_patch_reviews APR1 "
+ "WHERE account_id = ? AND change_id = ? AND patch_set_id = "
+ "(SELECT MAX(patch_set_id) FROM account_patch_reviews APR2 WHERE "
+ "APR1.account_id = APR2.account_id "
+ "AND APR1.change_id = APR2.change_id "
+ "AND patch_set_id <= ?)")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
PatchSet.Id id = new PatchSet.Id(psId.getParentKey(), rs.getInt("PATCH_SET_ID"));
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
do {
builder.add(rs.getString("FILE_NAME"));
} while (rs.next());
return Optional.of(
AccountPatchReviewStore.PatchSetWithReviewedFiles.create(id, builder.build()));
}
return Optional.empty();
}
} catch (SQLException e) {
throw convertError("select", e);
}
}
public static OrmException convertError(String op, SQLException err) {
public OrmException convertError(String op, SQLException err) {
switch (getSQLStateInt(err)) {
case 23001: // UNIQUE CONSTRAINT VIOLATION
case 23505: // DUPLICATE_KEY_1
@@ -287,23 +71,4 @@ public class H2AccountPatchReviewStore implements AccountPatchReviewStore, Lifec
return new OrmException(op + " failure on account_patch_reviews", err);
}
}
private static String getSQLState(SQLException err) {
String ec;
SQLException next = err;
do {
ec = next.getSQLState();
next = next.getNextException();
} while (ec == null && next != null);
return ec;
}
private static int getSQLStateInt(SQLException err) {
String s = getSQLState(err);
if (s != null) {
Integer i = Ints.tryParse(s);
return i != null ? i : -1;
}
return 0;
}
}

View File

@@ -0,0 +1,320 @@
// Copyright (C) 2016 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.schema;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.AccountPatchReviewStore;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.Optional;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class JdbcAccountPatchReviewStore
implements AccountPatchReviewStore, LifecycleListener {
private static final Logger log = LoggerFactory.getLogger(JdbcAccountPatchReviewStore.class);
public static class Module extends LifecycleModule {
private final Config cfg;
public Module(Config cfg) {
this.cfg = cfg;
}
@Override
protected void configure() {
String url = cfg.getString("accountPatchReviewDb", null, "url");
if (url == null || url.contains("h2")) {
DynamicItem.bind(binder(), AccountPatchReviewStore.class)
.to(H2AccountPatchReviewStore.class);
listener().to(H2AccountPatchReviewStore.class);
} else if (url.contains("postgresql")) {
DynamicItem.bind(binder(), AccountPatchReviewStore.class)
.to(PostgresqlAccountPatchReviewStore.class);
listener().to(PostgresqlAccountPatchReviewStore.class);
} else if (url.contains("mysql")) {
DynamicItem.bind(binder(), AccountPatchReviewStore.class)
.to(MysqlAccountPatchReviewStore.class);
listener().to(MysqlAccountPatchReviewStore.class);
} else {
throw new IllegalArgumentException(
"unsupported driver type for account patch reviews db: " + url);
}
}
}
private final DataSource ds;
public static JdbcAccountPatchReviewStore createAccountPatchReviewStore(
Config cfg, SitePaths sitePaths) {
String url = cfg.getString("accountPatchReviewDb", null, "url");
if (url == null || url.contains("h2")) {
return new H2AccountPatchReviewStore(cfg, sitePaths);
} else if (url.contains("postgresql")) {
return new PostgresqlAccountPatchReviewStore(cfg, sitePaths);
} else if (url.contains("mysql")) {
return new MysqlAccountPatchReviewStore(cfg, sitePaths);
} else {
throw new IllegalArgumentException(
"unsupported driver type for account patch reviews db: " + url);
}
}
protected JdbcAccountPatchReviewStore(Config cfg, SitePaths sitePaths) {
this.ds = createDataSource(getUrl(cfg, sitePaths));
}
protected JdbcAccountPatchReviewStore(DataSource ds) {
this.ds = ds;
}
private static String getUrl(@GerritServerConfig Config cfg, SitePaths sitePaths) {
String url = cfg.getString("accountPatchReviewDb", null, "url");
if (url == null) {
return H2.createUrl(sitePaths.db_dir.resolve("account_patch_reviews"));
}
return url;
}
protected static DataSource createDataSource(String url) {
BasicDataSource datasource = new BasicDataSource();
if (url.contains("postgresql")) {
datasource.setDriverClassName("org.postgresql.Driver");
} else if (url.contains("h2")) {
datasource.setDriverClassName("org.h2.Driver");
} else if (url.contains("mysql")) {
datasource.setDriverClassName("com.mysql.jdbc.Driver");
}
datasource.setUrl(url);
datasource.setMaxActive(50);
datasource.setMinIdle(4);
datasource.setMaxIdle(16);
long evictIdleTimeMs = 1000 * 60;
datasource.setMinEvictableIdleTimeMillis(evictIdleTimeMs);
datasource.setTimeBetweenEvictionRunsMillis(evictIdleTimeMs / 2);
return datasource;
}
@Override
public void start() {
try {
createTableIfNotExists();
} catch (OrmException e) {
log.error("Failed to create table to store account patch reviews", e);
}
}
public Connection getConnection() throws SQLException {
return ds.getConnection();
}
public void createTableIfNotExists() throws OrmException {
try (Connection con = ds.getConnection();
Statement stmt = con.createStatement()) {
doCreateTable(stmt);
} catch (SQLException e) {
throw convertError("create", e);
}
}
private static void doCreateTable(Statement stmt) throws SQLException {
stmt.executeUpdate(
"CREATE TABLE IF NOT EXISTS account_patch_reviews ("
+ "account_id INTEGER DEFAULT 0 NOT NULL, "
+ "change_id INTEGER DEFAULT 0 NOT NULL, "
+ "patch_set_id INTEGER DEFAULT 0 NOT NULL, "
+ "file_name VARCHAR(4096) DEFAULT '' NOT NULL, "
+ "CONSTRAINT primary_key_account_patch_reviews "
+ "PRIMARY KEY (account_id, change_id, patch_set_id, file_name)"
+ ")");
}
public void dropTableIfExists() throws OrmException {
try (Connection con = ds.getConnection();
Statement stmt = con.createStatement()) {
stmt.executeUpdate("DROP TABLE IF EXISTS account_patch_reviews");
} catch (SQLException e) {
throw convertError("create", e);
}
}
@Override
public void stop() {}
@Override
public boolean markReviewed(PatchSet.Id psId, Account.Id accountId, String path)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
+ "(account_id, change_id, patch_set_id, file_name) VALUES "
+ "(?, ?, ?, ?)")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.executeUpdate();
return true;
} catch (SQLException e) {
OrmException ormException = convertError("insert", e);
if (ormException instanceof OrmDuplicateKeyException) {
return false;
}
throw ormException;
}
}
@Override
public void markReviewed(PatchSet.Id psId, Account.Id accountId, Collection<String> paths)
throws OrmException {
if (paths == null || paths.isEmpty()) {
return;
}
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
+ "(account_id, change_id, patch_set_id, file_name) VALUES "
+ "(?, ?, ?, ?)")) {
for (String path : paths) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.addBatch();
}
stmt.executeBatch();
} catch (SQLException e) {
OrmException ormException = convertError("insert", e);
if (ormException instanceof OrmDuplicateKeyException) {
return;
}
throw ormException;
}
}
@Override
public void clearReviewed(PatchSet.Id psId, Account.Id accountId, String path)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
+ "WHERE account_id = ? AND change_id = ? AND "
+ "patch_set_id = ? AND file_name = ?")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
stmt.setString(4, path);
stmt.executeUpdate();
} catch (SQLException e) {
throw convertError("delete", e);
}
}
@Override
public void clearReviewed(PatchSet.Id psId) throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"DELETE FROM account_patch_reviews "
+ "WHERE change_id = ? AND patch_set_id = ?")) {
stmt.setInt(1, psId.getParentKey().get());
stmt.setInt(2, psId.get());
stmt.executeUpdate();
} catch (SQLException e) {
throw convertError("delete", e);
}
}
@Override
public Optional<PatchSetWithReviewedFiles> findReviewed(PatchSet.Id psId, Account.Id accountId)
throws OrmException {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"SELECT patch_set_id, file_name FROM account_patch_reviews APR1 "
+ "WHERE account_id = ? AND change_id = ? AND patch_set_id = "
+ "(SELECT MAX(patch_set_id) FROM account_patch_reviews APR2 WHERE "
+ "APR1.account_id = APR2.account_id "
+ "AND APR1.change_id = APR2.change_id "
+ "AND patch_set_id <= ?)")) {
stmt.setInt(1, accountId.get());
stmt.setInt(2, psId.getParentKey().get());
stmt.setInt(3, psId.get());
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
PatchSet.Id id = new PatchSet.Id(psId.getParentKey(), rs.getInt("patch_set_id"));
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
do {
builder.add(rs.getString("file_name"));
} while (rs.next());
return Optional.of(
AccountPatchReviewStore.PatchSetWithReviewedFiles.create(id, builder.build()));
}
return Optional.empty();
}
} catch (SQLException e) {
throw convertError("select", e);
}
}
public OrmException convertError(String op, SQLException err) {
if (err.getCause() == null && err.getNextException() != null) {
err.initCause(err.getNextException());
}
return new OrmException(op + " failure on account_patch_reviews", err);
}
private static String getSQLState(SQLException err) {
String ec;
SQLException next = err;
do {
ec = next.getSQLState();
next = next.getNextException();
} while (ec == null && next != null);
return ec;
}
protected static int getSQLStateInt(SQLException err) {
String s = getSQLState(err);
if (s != null) {
Integer i = Ints.tryParse(s);
return i != null ? i : -1;
}
return 0;
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2017 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.schema;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.sql.SQLException;
import org.eclipse.jgit.lib.Config;
@Singleton
public class MysqlAccountPatchReviewStore extends JdbcAccountPatchReviewStore {
@Inject
MysqlAccountPatchReviewStore(@GerritServerConfig Config cfg, SitePaths sitePaths) {
super(cfg, sitePaths);
}
@Override
public OrmException convertError(String op, SQLException err) {
switch (getSQLStateInt(err)) {
case 1022: // ER_DUP_KEY
case 1062: // ER_DUP_ENTRY
case 1169: // ER_DUP_UNIQUE;
return new OrmDuplicateKeyException("ACCOUNT_PATCH_REVIEWS", err);
default:
if (err.getCause() == null && err.getNextException() != null) {
err.initCause(err.getNextException());
}
return new OrmException(op + " failure on ACCOUNT_PATCH_REVIEWS", err);
}
}
}

View File

@@ -0,0 +1,51 @@
// Copyright (C) 2017 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.schema;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.sql.SQLException;
import org.eclipse.jgit.lib.Config;
@Singleton
public class PostgresqlAccountPatchReviewStore extends JdbcAccountPatchReviewStore {
@Inject
PostgresqlAccountPatchReviewStore(@GerritServerConfig Config cfg, SitePaths sitePaths) {
super(cfg, sitePaths);
}
@Override
public OrmException convertError(String op, SQLException err) {
switch (getSQLStateInt(err)) {
case 23505: // DUPLICATE_KEY_1
return new OrmDuplicateKeyException("ACCOUNT_PATCH_REVIEWS", err);
case 23514: // CHECK CONSTRAINT VIOLATION
case 23503: // FOREIGN KEY CONSTRAINT VIOLATION
case 23502: // NOT NULL CONSTRAINT VIOLATION
case 23001: // RESTRICT VIOLATION
default:
if (err.getCause() == null && err.getNextException() != null) {
err.initCause(err.getNextException());
}
return new OrmException(op + " failure on ACCOUNT_PATCH_REVIEWS", err);
}
}
}

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.group.SystemGroupBackend;
@@ -39,6 +40,7 @@ import java.io.IOException;
import java.sql.SQLException;
import java.util.Collections;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.PersonIdent;
/** Creates or updates the current database schema. */
@@ -72,6 +74,7 @@ public class SchemaUpdater {
new Key<?>[] {
Key.get(PersonIdent.class, GerritPersonIdent.class),
Key.get(String.class, AnonymousCowardName.class),
Key.get(Config.class, GerritServerConfig.class),
}) {
rebind(parent, k);
}

View File

@@ -15,34 +15,38 @@
package com.google.gerrit.server.schema;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.eclipse.jgit.lib.Config;
public class Schema_127 extends SchemaVersion {
private static final int MAX_BATCH_SIZE = 1000;
private final SitePaths sitePaths;
private final Config cfg;
@Inject
Schema_127(Provider<Schema_126> prior, SitePaths sitePaths) {
Schema_127(Provider<Schema_126> prior, SitePaths sitePaths, @GerritServerConfig Config cfg) {
super(prior);
this.sitePaths = sitePaths;
this.cfg = cfg;
}
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
String url = H2AccountPatchReviewStore.getUrl(sitePaths);
H2AccountPatchReviewStore.dropTableIfExists(url);
H2AccountPatchReviewStore.createTableIfNotExists(url);
try (Connection con = DriverManager.getConnection(url);
JdbcAccountPatchReviewStore jdbcAccountPatchReviewStore =
JdbcAccountPatchReviewStore.createAccountPatchReviewStore(cfg, sitePaths);
jdbcAccountPatchReviewStore.dropTableIfExists();
jdbcAccountPatchReviewStore.createTableIfNotExists();
try (Connection con = jdbcAccountPatchReviewStore.getConnection();
PreparedStatement stmt =
con.prepareStatement(
"INSERT INTO account_patch_reviews "
@@ -69,7 +73,7 @@ public class Schema_127 extends SchemaVersion {
stmt.executeBatch();
}
} catch (SQLException e) {
throw H2AccountPatchReviewStore.convertError("insert", e);
throw jdbcAccountPatchReviewStore.convertError("insert", e);
}
}
}