Remove Project.Id and use only Project.NameKey

We remove the secondary unique column Project.Id and change the
schema to rely upon only the Project.NameKey property.  This is
necessary to support databases which cannot do multiple unique
attributes on the same entity.

Change-Id: I1a9184d69e4779f8e9f755a151ce55c9b9efc4d6
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2009-12-31 07:21:40 -08:00
parent 8c01fe20e5
commit 8df7cf7689
12 changed files with 100 additions and 92 deletions

View File

@@ -14,10 +14,11 @@
package com.google.gerrit.client.admin;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.Dispatcher;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.AccountScreen;
import com.google.gerrit.client.ui.Hyperlink;
import com.google.gerrit.client.ui.NavigationTable;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.PageLinks;
@@ -26,7 +27,6 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.History;
import com.google.gerrit.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
@@ -96,7 +96,7 @@ public class ProjectListScreen extends AccountScreen {
@Override
protected Object getRowItemKey(final Project item) {
return item.getId();
return item.getNameKey();
}
@Override

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.reviewdb;
import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.IntKey;
import com.google.gwtorm.client.StringKey;
/** Projects match a source code repository managed by Gerrit */
@@ -53,31 +52,6 @@ public final class Project {
}
}
/** Synthetic key to link to within the database */
public static class Id extends IntKey<com.google.gwtorm.client.Key<?>> {
private static final long serialVersionUID = 1L;
@Column(id = 1)
protected int id;
protected Id() {
}
public Id(final int id) {
this.id = id;
}
@Override
public int get() {
return id;
}
@Override
protected void set(int newValue) {
id = newValue;
}
}
public static enum SubmitType {
FAST_FORWARD_ONLY('F'),
@@ -110,35 +84,27 @@ public final class Project {
@Column(id = 1)
protected NameKey name;
@Column(id = 2)
protected Id projectId;
@Column(id = 3, length = Integer.MAX_VALUE, notNull = false)
@Column(id = 2, length = Integer.MAX_VALUE, notNull = false)
protected String description;
@Column(id = 4)
@Column(id = 3)
protected boolean useContributorAgreements;
@Column(id = 5)
@Column(id = 4)
protected boolean useSignedOffBy;
@Column(id = 6)
@Column(id = 5)
protected char submitType;
protected Project() {
}
public Project(final Project.NameKey newName, final Project.Id newId) {
public Project(final Project.NameKey newName) {
name = newName;
projectId = newId;
useContributorAgreements = true;
setSubmitType(SubmitType.MERGE_IF_NECESSARY);
}
public Project.Id getId() {
return projectId;
}
public Project.NameKey getNameKey() {
return name;
}

View File

@@ -19,15 +19,11 @@ import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.PrimaryKey;
import com.google.gwtorm.client.Query;
import com.google.gwtorm.client.ResultSet;
import com.google.gwtorm.client.SecondaryKey;
public interface ProjectAccess extends Access<Project, Project.NameKey> {
@PrimaryKey("name")
Project get(Project.NameKey name) throws OrmException;
@SecondaryKey("projectId")
Project get(Project.Id id) throws OrmException;
@Query("ORDER BY name")
ResultSet<Project> all() throws OrmException;

View File

@@ -117,10 +117,6 @@ public interface ReviewDb extends Schema {
@Sequence
int nextAccountGroupId() throws OrmException;
/** Next unique id for a {@link Project}. */
@Sequence
int nextProjectId() throws OrmException;
/** Next unique id for a {@link Change}. */
@Sequence
int nextChangeId() throws OrmException;

View File

@@ -74,6 +74,10 @@ public final class SystemConfig {
@Column(id = 6)
public AccountGroup.Id registeredGroupId;
/** Identity of the project */
@Column(id = 7)
public Project.NameKey wildProjectName;
protected SystemConfig() {
}
}

View File

@@ -1,45 +1,33 @@
// 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.config;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
public class WildProjectNameProvider implements Provider<Project.NameKey> {
/** Project.Id meaning "any and all projects on this server". */
public static final Project.Id WILD_PROJECT_ID = new Project.Id(0);
private final SchemaFactory<ReviewDb> schema;
private final Project.NameKey name;
@Inject
WildProjectNameProvider(final SchemaFactory<ReviewDb> schema,
/*
* Unused, but we need to force it to load before we do, otherwise we risk
* reading an empty database without the wild project being in the database.
* Asking for it should ensures Guice loads it first.
*/
final SystemConfig config) {
this.schema = schema;
WildProjectNameProvider(final SystemConfig config) {
name = config.wildProjectName;
}
public Project.NameKey get() {
try {
final ReviewDb db = schema.open();
try {
final Project p = db.projects().get(WILD_PROJECT_ID);
if (p == null) {
throw new ProvisionException("No project " + WILD_PROJECT_ID);
}
return p.getNameKey();
} finally {
db.close();
}
} catch (OrmException e) {
throw new ProvisionException("Cannot load " + WILD_PROJECT_ID, e);
}
return name;
}
}

View File

@@ -94,8 +94,7 @@ public class GitProjectImporter {
}
final Project.NameKey nameKey = new Project.NameKey(name);
final Project.Id idKey = new Project.Id(db.nextProjectId());
final Project p = new Project(nameKey, idKey);
final Project p = new Project(nameKey);
p.setDescription(repositoryManager.getProjectDescription(name));
p.setSubmitType(SubmitType.MERGE_IF_NECESSARY);

View File

@@ -24,7 +24,6 @@ import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.config.WildProjectNameProvider;
import com.google.gerrit.server.workflow.NoOpFunction;
import com.google.gerrit.server.workflow.SubmitFunction;
import com.google.gwtjsonrpc.server.SignedToken;
@@ -139,6 +138,7 @@ public class SchemaCreator {
s.adminGroupId = admin.getId();
s.anonymousGroupId = anonymous.getId();
s.registeredGroupId = registered.getId();
s.wildProjectName = DEFAULT_WILD_NAME;
try {
s.sitePath = site_path.getCanonicalPath();
} catch (IOException e) {
@@ -151,7 +151,7 @@ public class SchemaCreator {
private void initWildCardProject(final ReviewDb c) throws OrmException {
final Project p;
p = new Project(DEFAULT_WILD_NAME, WildProjectNameProvider.WILD_PROJECT_ID);
p = new Project(DEFAULT_WILD_NAME);
p.setDescription("Rights inherited by all other projects");
p.setUseContributorAgreements(false);
c.projects().insert(Collections.singleton(p));

View File

@@ -32,7 +32,7 @@ import java.util.List;
/** A version of the database schema. */
public abstract class SchemaVersion {
/** The current schema version. */
private static final Class<? extends SchemaVersion> C = Schema_20.class;
private static final Class<? extends SchemaVersion> C = Schema_21.class;
public static class Module extends AbstractModule {
@Override

View File

@@ -0,0 +1,59 @@
// 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.schema;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collections;
class Schema_21 extends SchemaVersion {
@Inject
Schema_21(Provider<Schema_20> prior) {
super(prior);
}
@Override
protected void migrateData(ReviewDb db) throws OrmException, SQLException {
SystemConfig sc = db.systemConfig().get(new SystemConfig.Key());
Statement s = ((JdbcSchema) db).getConnection().createStatement();
try {
ResultSet r;
r = s.executeQuery("SELECT name FROM projects WHERE project_id = 0");
try {
if (!r.next()) {
throw new OrmException("Cannot read old wild project");
}
sc.wildProjectName = new Project.NameKey(r.getString(1));
} finally {
r.close();
}
} finally {
s.close();
}
db.systemConfig().update(Collections.singleton(sc));
}
}

View File

@@ -21,7 +21,6 @@ import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.ProjectRight;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gerrit.server.config.WildProjectNameProvider;
import com.google.gerrit.server.workflow.NoOpFunction;
import com.google.gerrit.server.workflow.SubmitFunction;
import com.google.gerrit.testutil.TestDatabase;
@@ -155,12 +154,13 @@ public class SchemaCreatorTest extends TestCase {
public void testCreateSchema_WildCardProject() throws OrmException {
final ReviewDb c = db.create().open();
try {
final SystemConfig cfg;
final Project all;
all = c.projects().get(WildProjectNameProvider.WILD_PROJECT_ID);
cfg = c.systemConfig().get(new SystemConfig.Key());
all = c.projects().get(cfg.wildProjectName);
assertNotNull(all);
assertEquals("-- All Projects --", all.getName());
assertEquals(new Project.Id(0), all.getId());
assertFalse(all.isUseContributorAgreements());
assertFalse(all.isUseSignedOffBy());
} finally {
@@ -341,10 +341,12 @@ public class SchemaCreatorTest extends TestCase {
final ApprovalCategory.Id category, int min, int max) throws OrmException {
final ReviewDb c = db.open();
try {
final SystemConfig cfg;
final Project all;
final ProjectRight right;
all = c.projects().get(WildProjectNameProvider.WILD_PROJECT_ID);
cfg = c.systemConfig().get(new SystemConfig.Key());
all = c.projects().get(cfg.wildProjectName);
right = c.projectRights().get( //
new ProjectRight.Key(all.getNameKey(), category, group));

View File

@@ -113,9 +113,7 @@ final class AdminCreateProject extends BaseCommand {
private void createProject(Transaction txn) throws OrmException {
final Project.NameKey newProjectNameKey = new Project.NameKey(projectName);
final Project newProject =
new Project(newProjectNameKey, new Project.Id(db.nextProjectId()));
final Project newProject = new Project(newProjectNameKey);
newProject.setDescription(projectDescription);
newProject.setSubmitType(submitType);