Add a schema version table to facilitate live upgrades

The current version of the database schema is stored into the
schema_version.version_nbr field.  Future versions of Gerrit2
can update this to a different value and detect at startup if
an upgrade is required.  Upgrades would involve adding columns
to tables, or possibly manipulating data to conform to a new
convention.  The actual code required to perform an upgrade
isn't here yet, but we abort if the schema version isn't
recognized by the server.  This prevents an older Gerrit2 from
using a newer schema (once a newer schema is developed).

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-01-19 10:28:06 -08:00
parent 0d54b48e9a
commit f5a97c4ce6
4 changed files with 105 additions and 6 deletions

View File

@@ -21,6 +21,9 @@ import com.google.gwtorm.client.Sequence;
/** The review service database schema. */
public interface ReviewDb extends Schema {
@Relation
SchemaVersionAccess schemaVersion();
@Relation
SystemConfigAccess systemConfig();

View File

@@ -0,0 +1,59 @@
// Copyright 2009 Google Inc.
//
// 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.client.reviewdb;
import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.StringKey;
/** Current version of the database schema, to facilitate live upgrades. */
public final class SchemaVersion {
public static final class Key extends
StringKey<com.google.gwtorm.client.Key<?>> {
private static final String VALUE = "X";
@Column(length = 1)
protected String one = VALUE;
public Key() {
}
@Override
public String get() {
return VALUE;
}
@Override
protected void set(final String newValue) {
assert get().equals(newValue);
}
}
/** Construct a new, unconfigured instance. */
public static SchemaVersion create() {
final SchemaVersion r = new SchemaVersion();
r.singleton = new SchemaVersion.Key();
return r;
}
@Column
protected Key singleton;
/** Current version number of the schema. */
@Column
public transient int versionNbr;
protected SchemaVersion() {
}
}

View File

@@ -0,0 +1,26 @@
// Copyright 2009 Google Inc.
//
// 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.client.reviewdb;
import com.google.gwtorm.client.Access;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.PrimaryKey;
/** Access interface for {@link SchemaVersion}. */
public interface SchemaVersionAccess extends
Access<SchemaVersion, SchemaVersion.Key> {
@PrimaryKey("singleton")
SchemaVersion get(SchemaVersion.Key key) throws OrmException;
}

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.client.reviewdb.ApprovalCategoryValue;
import com.google.gerrit.client.reviewdb.Project;
import com.google.gerrit.client.reviewdb.ProjectRight;
import com.google.gerrit.client.reviewdb.ReviewDb;
import com.google.gerrit.client.reviewdb.SchemaVersion;
import com.google.gerrit.client.reviewdb.SystemConfig;
import com.google.gerrit.client.rpc.Common;
import com.google.gerrit.client.workflow.NoOpFunction;
@@ -332,19 +333,23 @@ public class GerritServer {
private void loadSystemConfig() throws OrmException {
final ReviewDb c = db.open();
try {
SchemaVersion sVer;
try {
sConfig = c.systemConfig().get(new SystemConfig.Key());
sVer = c.schemaVersion().get(new SchemaVersion.Key());
} catch (OrmException e) {
// Assume the schema doesn't exist, and create it.
// TODO Implement schema upgrades and/or exporting to a script file.
// Assume the schema doesn't exist.
//
sConfig = null;
c.createSchema();
sVer = null;
}
if (sConfig == null) {
if (sVer == null) {
// Assume the schema is empty and populate it.
//
c.createSchema();
sVer = SchemaVersion.create();
sVer.versionNbr = 2;
c.schemaVersion().insert(Collections.singleton(sVer));
initSystemConfig(c);
sConfig = c.systemConfig().get(new SystemConfig.Key());
initWildCardProject(c);
@@ -352,6 +357,12 @@ public class GerritServer {
initVerifiedCategory(c);
initCodeReviewCategory(c);
initSubmitCategory(c);
} else if (sVer.versionNbr == 2) {
sConfig = c.systemConfig().get(new SystemConfig.Key());
} else {
throw new OrmException("Unsupported schema version " + sVer.versionNbr);
}
loadGerritConfig(c);