From 8df7cf76891bca1b65aa48df7b5369c2245b8432 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 31 Dec 2009 07:21:40 -0800 Subject: [PATCH] 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 --- .../client/admin/ProjectListScreen.java | 6 +- .../com/google/gerrit/reviewdb/Project.java | 44 ++------------ .../google/gerrit/reviewdb/ProjectAccess.java | 4 -- .../com/google/gerrit/reviewdb/ReviewDb.java | 4 -- .../google/gerrit/reviewdb/SystemConfig.java | 4 ++ .../config/WildProjectNameProvider.java | 48 ++++++--------- .../gerrit/server/git/GitProjectImporter.java | 3 +- .../gerrit/server/schema/SchemaCreator.java | 4 +- .../gerrit/server/schema/SchemaVersion.java | 2 +- .../gerrit/server/schema/Schema_21.java | 59 +++++++++++++++++++ .../server/schema/SchemaCreatorTest.java | 10 ++-- .../sshd/commands/AdminCreateProject.java | 4 +- 12 files changed, 100 insertions(+), 92 deletions(-) create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_21.java diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java index 40d915720a..04d7038a26 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectListScreen.java @@ -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 diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Project.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Project.java index d640c37543..ad8184c90c 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Project.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/Project.java @@ -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> { - 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; } diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ProjectAccess.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ProjectAccess.java index e406a8fdec..b9adadae02 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ProjectAccess.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ProjectAccess.java @@ -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 { @PrimaryKey("name") Project get(Project.NameKey name) throws OrmException; - @SecondaryKey("projectId") - Project get(Project.Id id) throws OrmException; - @Query("ORDER BY name") ResultSet all() throws OrmException; diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ReviewDb.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ReviewDb.java index 60724f5378..35c30d9365 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ReviewDb.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/ReviewDb.java @@ -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; diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/SystemConfig.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/SystemConfig.java index a94244cbdf..16175e7b51 100644 --- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/SystemConfig.java +++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/SystemConfig.java @@ -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() { } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java index ffb4cdeb65..ee8df40b62 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java @@ -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.Id meaning "any and all projects on this server". */ - public static final Project.Id WILD_PROJECT_ID = new Project.Id(0); - - private final SchemaFactory schema; + private final Project.NameKey name; @Inject - WildProjectNameProvider(final SchemaFactory 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; } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/GitProjectImporter.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/GitProjectImporter.java index e0edeb0cae..42e695ecef 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/GitProjectImporter.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/GitProjectImporter.java @@ -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); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java index e1c7f50da9..9c882dea40 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaCreator.java @@ -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)); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java index 4eff0fb0ac..8d53b4b070 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java @@ -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 C = Schema_20.class; + private static final Class C = Schema_21.class; public static class Module extends AbstractModule { @Override diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_21.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_21.java new file mode 100644 index 0000000000..a6be2ad73d --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_21.java @@ -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 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)); + } +} diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java index cc34a49602..7164e99de8 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java @@ -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)); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminCreateProject.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminCreateProject.java index e284173f9e..0bd092e0ff 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminCreateProject.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminCreateProject.java @@ -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);