diff options
author | Shawn O. Pearce <sop@google.com> | 2009-08-04 17:14:16 -0700 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2009-08-04 17:14:16 -0700 |
commit | af70a696b7224298970565478fd4253f96d928e7 (patch) | |
tree | be5996f616e170781eb045486a7d9062bc8822d7 | |
parent | 9706c38b7713c2fbe621d2d27c04724b6f0dddfd (diff) |
Change project to use Project.NameKey as the primary key
Almost. We still keep Project.Id around, but all code does lookups
and foreign keys now by Project.NameKey. The only real value we now
get from Project.Id is the magical meaning of Project.Id(0), which is
the wild card project. We obtain the name of that project from the
database during startup, but otherwise look for the wildcard project
by name rather than by id anytime we need to do conditional logic on
an entity that might or might not be a member of the wildcard project.
This change facilitates a future change we're looking at making, which
is to move the data store for each project into its own Git repository,
where global assignment of an integer identity just won't make sense.
Since Project.NameKey already cannot be changed without a great deal
of pain, adding to the pain by not being able to easily move the
ProjectRight or AccountWatchedProjects makes sense.
Signed-off-by: Shawn O. Pearce <sop@google.com>
31 files changed, 334 insertions, 183 deletions
diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java b/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java index fec6e8e2a1..a79e3bd75e 100644 --- a/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java +++ b/src/main/java/com/google/gerrit/client/admin/ProjectAdminScreen.java @@ -18,6 +18,7 @@ import com.google.gerrit.client.Gerrit; import com.google.gerrit.client.Link; import com.google.gerrit.client.reviewdb.Project; import com.google.gerrit.client.reviewdb.ProjectRight; +import com.google.gerrit.client.rpc.Common; import com.google.gerrit.client.rpc.ScreenLoadCallback; import com.google.gerrit.client.ui.AccountScreen; import com.google.gwt.event.logical.shared.SelectionEvent; @@ -73,7 +74,7 @@ public class ProjectAdminScreen extends AccountScreen { }, Util.C.projectAdminTabGeneral()); tabTokens.add(Link.toProjectAdmin(projectName, INFO_TAB)); - if (!ProjectRight.WILD_PROJECT.equals(projectName)) { + if (!Common.getGerritConfig().getWildProject().equals(projectName)) { tabs.add(new LazyPanel() { @Override protected ProjectBranchesPanel createWidget() { diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java b/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java index 36ccf8c6fe..011db11e5c 100644 --- a/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java +++ b/src/main/java/com/google/gerrit/client/admin/ProjectInfoPanel.java @@ -163,7 +163,8 @@ public class ProjectInfoPanel extends Composite { void display(final ProjectDetail result) { project = result.project; - final boolean isall = ProjectRight.WILD_PROJECT.equals(project.getId()); + final boolean isall = + Common.getGerritConfig().getWildProject().equals(project.getNameKey()); submitTypePanel.setVisible(!isall); agreementsPanel.setVisible(!isall); useContributorAgreements.setVisible(Common.getGerritConfig() diff --git a/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java b/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java index cf425580e2..635ec4734a 100644 --- a/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java +++ b/src/main/java/com/google/gerrit/client/admin/ProjectRightsPanel.java @@ -119,7 +119,7 @@ public class ProjectRightsPanel extends Composite { } for (final ApprovalType at : Common.getGerritConfig().getActionTypes()) { final ApprovalCategory c = at.getCategory(); - if (ProjectRight.WILD_PROJECT.equals(projectName) + if (Common.getGerritConfig().getWildProject().equals(projectName) && ApprovalCategory.OWN.equals(c.getId())) { // Giving out control of the WILD_PROJECT to other groups beyond // Administrators is dangerous. Having control over WILD_PROJECT @@ -370,8 +370,8 @@ public class ProjectRightsPanel extends Composite { final ApprovalType ar = config.getApprovalType(k.getApprovalCategoryId()); final AccountGroup group = groups.get(k.getAccountGroupId()); - if (ProjectRight.WILD_PROJECT.equals(k.getProjectId()) - && !ProjectRight.WILD_PROJECT.equals(projectName)) { + if (Common.getGerritConfig().getWildProject().equals(k.getProjectNameKey()) + && !Common.getGerritConfig().getWildProject().equals(projectName)) { table.setText(row, 1, ""); } else { table.setWidget(row, 1, new CheckBox()); diff --git a/src/main/java/com/google/gerrit/client/data/GerritConfig.java b/src/main/java/com/google/gerrit/client/data/GerritConfig.java index 4920317c6a..72bb1b7bcd 100644 --- a/src/main/java/com/google/gerrit/client/data/GerritConfig.java +++ b/src/main/java/com/google/gerrit/client/data/GerritConfig.java @@ -16,6 +16,7 @@ package com.google.gerrit.client.data; import com.google.gerrit.client.reviewdb.ApprovalCategory; import com.google.gerrit.client.reviewdb.LoginType; +import com.google.gerrit.client.reviewdb.Project; import java.util.ArrayList; import java.util.HashMap; @@ -34,6 +35,7 @@ public class GerritConfig implements Cloneable { protected boolean useRepoDownload; protected String gitDaemonUrl; protected String sshdAddress; + protected Project.NameKey wildProject; private transient Map<ApprovalCategory.Id, ApprovalType> byCategoryId; public GerritConfig() { @@ -163,4 +165,12 @@ public class GerritConfig implements Cloneable { public void setSshdAddress(final String addr) { sshdAddress = addr; } + + public Project.NameKey getWildProject() { + return wildProject; + } + + public void setWildProject(final Project.NameKey wp) { + wildProject = wp; + } } diff --git a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java index 6133c710e5..9a0be5d13e 100644 --- a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java +++ b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatch.java @@ -26,16 +26,16 @@ public final class AccountProjectWatch { protected Account.Id accountId; @Column - protected Project.Id projectId; + protected Project.NameKey projectName; protected Key() { accountId = new Account.Id(); - projectId = new Project.Id(); + projectName = new Project.NameKey(); } - public Key(final Account.Id a, final Project.Id g) { + public Key(final Account.Id a, final Project.NameKey g) { accountId = a; - projectId = g; + projectName = g; } @Override @@ -45,7 +45,7 @@ public final class AccountProjectWatch { @Override public com.google.gwtorm.client.Key<?>[] members() { - return new com.google.gwtorm.client.Key<?>[] {projectId}; + return new com.google.gwtorm.client.Key<?>[] {projectName}; } } @@ -79,8 +79,8 @@ public final class AccountProjectWatch { return key.accountId; } - public Project.Id getProjectId() { - return key.projectId; + public Project.NameKey getProjectNameKey() { + return key.projectName; } public boolean isNotifyNewChanges() { diff --git a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java index 2d8929bc21..2aaeab71ae 100644 --- a/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java +++ b/src/main/java/com/google/gerrit/client/reviewdb/AccountProjectWatchAccess.java @@ -28,15 +28,15 @@ public interface AccountProjectWatchAccess extends @Query("WHERE key.accountId = ?") ResultSet<AccountProjectWatch> byAccount(Account.Id id) throws OrmException; - @Query("WHERE notifyNewChanges = true AND key.projectId = ?") - ResultSet<AccountProjectWatch> notifyNewChanges(Project.Id id) + @Query("WHERE notifyNewChanges = true AND key.projectName = ?") + ResultSet<AccountProjectWatch> notifyNewChanges(Project.NameKey name) throws OrmException; - @Query("WHERE notifyAllComments = true AND key.projectId = ?") - ResultSet<AccountProjectWatch> notifyAllComments(Project.Id id) + @Query("WHERE notifyAllComments = true AND key.projectName = ?") + ResultSet<AccountProjectWatch> notifyAllComments(Project.NameKey name) throws OrmException; - @Query("WHERE notifySubmittedChanges = true AND key.projectId = ?") - ResultSet<AccountProjectWatch> notifySubmittedChanges(Project.Id id) + @Query("WHERE notifySubmittedChanges = true AND key.projectName = ?") + ResultSet<AccountProjectWatch> notifySubmittedChanges(Project.NameKey name) throws OrmException; } diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java b/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java index cf7c6cbdde..c543c88122 100644 --- a/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java +++ b/src/main/java/com/google/gerrit/client/reviewdb/ApprovalCategory.java @@ -69,7 +69,7 @@ public final class ApprovalCategory { id = newValue; } - /** True if the right can inherit from {@link ProjectRight#WILD_PROJECT}. */ + /** True if the right can inherit from {@link ProjectRight#WILD_PROJECT_ID}. */ public boolean canInheritFromWildProject() { if (OWN.equals(this)) { return false; diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java index 4806a5fe51..46b6d60710 100644 --- a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java +++ b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRight.java @@ -19,14 +19,11 @@ import com.google.gwtorm.client.CompoundKey; /** Grant to use an {@link ApprovalCategory} in the scope of a {@link Project}. */ public final class ProjectRight { - /** Project.Id meaning "any and all projects on this server". */ - public static final Project.Id WILD_PROJECT = new Project.Id(0); - - public static class Key extends CompoundKey<Project.Id> { + public static class Key extends CompoundKey<Project.NameKey> { private static final long serialVersionUID = 1L; @Column - protected Project.Id projectId; + protected Project.NameKey projectName; @Column protected ApprovalCategory.Id categoryId; @@ -35,25 +32,25 @@ public final class ProjectRight { protected AccountGroup.Id groupId; protected Key() { - projectId = new Project.Id(); + projectName = new Project.NameKey(); categoryId = new ApprovalCategory.Id(); groupId = new AccountGroup.Id(); } - public Key(final Project.Id p, final ApprovalCategory.Id a, + public Key(final Project.NameKey p, final ApprovalCategory.Id a, final AccountGroup.Id g) { - projectId = p; + projectName = p; categoryId = a; groupId = g; } @Override - public Project.Id getParentKey() { - return projectId; + public Project.NameKey getParentKey() { + return projectName; } - public Project.Id getProjectId() { - return projectId; + public Project.NameKey getProjectNameKey() { + return projectName; } @Override @@ -82,8 +79,8 @@ public final class ProjectRight { return key; } - public Project.Id getProjectId() { - return key.projectId; + public Project.NameKey getProjectNameKey() { + return key.projectName; } public ApprovalCategory.Id getApprovalCategoryId() { diff --git a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java index 3623b7eadf..4f722f9608 100644 --- a/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java +++ b/src/main/java/com/google/gerrit/client/reviewdb/ProjectRightAccess.java @@ -25,8 +25,8 @@ public interface ProjectRightAccess extends @PrimaryKey("key") ProjectRight get(ProjectRight.Key key) throws OrmException; - @Query("WHERE key.projectId = ?") - ResultSet<ProjectRight> byProject(Project.Id id) throws OrmException; + @Query("WHERE key.projectName = ?") + ResultSet<ProjectRight> byProject(Project.NameKey name) throws OrmException; @Query("WHERE key.categoryId = ? AND key.groupId = ?") ResultSet<ProjectRight> byCategoryGroup(ApprovalCategory.Id cat, diff --git a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java index fefd70c8c3..ee314ed4f5 100644 --- a/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java +++ b/src/main/java/com/google/gerrit/git/PushAllProjectsOp.java @@ -16,9 +16,9 @@ package com.google.gerrit.git; import com.google.gerrit.client.reviewdb.Branch; 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.server.config.Nullable; +import com.google.gerrit.server.config.WildProjectName; import com.google.gwtorm.client.OrmException; import com.google.gwtorm.client.SchemaFactory; import com.google.inject.Inject; @@ -40,15 +40,18 @@ public class PushAllProjectsOp extends DefaultQueueOp { private final SchemaFactory<ReviewDb> schema; private final ReplicationQueue replication; + private final Project.NameKey wildProject; private final String urlMatch; @Inject public PushAllProjectsOp(final WorkQueue wq, final SchemaFactory<ReviewDb> sf, final ReplicationQueue rq, + @WildProjectName final Project.NameKey wp, @Assisted @Nullable final String urlMatch) { super(wq); this.schema = sf; this.replication = rq; + this.wildProject = wp; this.urlMatch = urlMatch; } @@ -65,7 +68,7 @@ public class PushAllProjectsOp extends DefaultQueueOp { final ReviewDb db = schema.open(); try { for (final Project project : db.projects().all()) { - if (!ProjectRight.WILD_PROJECT.equals(project.getId())) { + if (!project.getNameKey().equals(wildProject)) { replication.scheduleFullSync(project.getNameKey(), urlMatch); } } diff --git a/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java b/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java index 56aadceac6..c252c77013 100644 --- a/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java +++ b/src/main/java/com/google/gerrit/server/config/GerritConfigProvider.java @@ -18,6 +18,7 @@ import com.google.gerrit.client.data.ApprovalType; import com.google.gerrit.client.data.GerritConfig; import com.google.gerrit.client.data.GitwebLink; import com.google.gerrit.client.reviewdb.ApprovalCategory; +import com.google.gerrit.client.reviewdb.Project; import com.google.gerrit.client.reviewdb.ReviewDb; import com.google.gerrit.client.rpc.Common; import com.google.gerrit.server.ContactStore; @@ -45,6 +46,7 @@ public class GerritConfigProvider implements Provider<GerritConfig> { private final String canonicalWebUrl; private final AuthConfig authConfig; private final SchemaFactory<ReviewDb> schema; + private final Project.NameKey wildProject; private SshInfo sshd; private EmailSender emailSender; @@ -53,11 +55,13 @@ public class GerritConfigProvider implements Provider<GerritConfig> { @Inject GerritConfigProvider(@GerritServerConfig final Config gsc, @CanonicalWebUrl @Nullable final String cwu, final AuthConfig ac, - final SchemaFactory<ReviewDb> sf) { + final SchemaFactory<ReviewDb> sf, + @WildProjectName final Project.NameKey wp) { cfg = gsc; canonicalWebUrl = cwu; authConfig = ac; schema = sf; + wildProject = wp; } @Inject(optional = true) @@ -87,6 +91,7 @@ public class GerritConfigProvider implements Provider<GerritConfig> { config.setAllowRegisterNewEmail(emailSender != null && emailSender.isEnabled()); config.setLoginType(authConfig.getLoginType()); + config.setWildProject(wildProject); final String gitwebUrl = cfg.getString("gitweb", null, "url"); if (gitwebUrl != null) { diff --git a/src/main/java/com/google/gerrit/server/config/GerritServerModule.java b/src/main/java/com/google/gerrit/server/config/GerritServerModule.java index 592cb6b657..240fec9c92 100644 --- a/src/main/java/com/google/gerrit/server/config/GerritServerModule.java +++ b/src/main/java/com/google/gerrit/server/config/GerritServerModule.java @@ -16,6 +16,7 @@ package com.google.gerrit.server.config; import static com.google.inject.Scopes.SINGLETON; +import com.google.gerrit.client.reviewdb.Project; import com.google.gerrit.git.ChangeMergeQueue; import com.google.gerrit.git.MergeOp; import com.google.gerrit.git.MergeQueue; @@ -61,6 +62,8 @@ public class GerritServerModule extends FactoryModule { protected void configure() { bind(File.class).annotatedWith(SitePath.class).toProvider( SitePathProvider.class).in(SINGLETON); + bind(Project.NameKey.class).annotatedWith(WildProjectName.class) + .toProvider(WildProjectNameProvider.class).in(SINGLETON); bind(Config.class).annotatedWith(GerritServerConfig.class).toProvider( GerritServerConfigProvider.class).in(SINGLETON); bind(AuthConfig.class).in(SINGLETON); diff --git a/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java b/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java index 375411f4ac..1fa2984015 100644 --- a/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java +++ b/src/main/java/com/google/gerrit/server/config/SystemConfigProvider.java @@ -40,6 +40,8 @@ import java.util.List; /** Loads the {@link SystemConfig} from the database. */ class SystemConfigProvider implements Provider<SystemConfig> { + private static final Project.NameKey DEFAULT_WILD_NAME = + new Project.NameKey("-- All Projects --"); private final SchemaFactory<ReviewDb> schema; @Inject @@ -183,14 +185,12 @@ class SystemConfigProvider implements Provider<SystemConfig> { } private void initWildCardProject(final ReviewDb c) throws OrmException { - final Project proj; - - proj = - new Project(new Project.NameKey("-- All Projects --"), - ProjectRight.WILD_PROJECT); - proj.setDescription("Rights inherited by all other projects"); - proj.setUseContributorAgreements(false); - c.projects().insert(Collections.singleton(proj)); + final Project p; + + p = new Project(DEFAULT_WILD_NAME, WildProjectNameProvider.WILD_PROJECT_ID); + p.setDescription("Rights inherited by all other projects"); + p.setUseContributorAgreements(false); + c.projects().insert(Collections.singleton(p)); } private void initVerifiedCategory(final ReviewDb c) throws OrmException { @@ -228,8 +228,8 @@ class SystemConfigProvider implements Provider<SystemConfig> { txn.commit(); final ProjectRight approve = - new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat - .getId(), sConfig.registeredGroupId)); + new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(), + sConfig.registeredGroupId)); approve.setMaxValue((short) 1); approve.setMinValue((short) -1); c.projectRights().insert(Collections.singleton(approve)); @@ -267,16 +267,16 @@ class SystemConfigProvider implements Provider<SystemConfig> { txn.commit(); { final ProjectRight read = - new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat - .getId(), sConfig.anonymousGroupId)); + new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(), + sConfig.anonymousGroupId)); read.setMaxValue((short) 1); read.setMinValue((short) 1); c.projectRights().insert(Collections.singleton(read)); } { final ProjectRight read = - new ProjectRight(new ProjectRight.Key(ProjectRight.WILD_PROJECT, cat - .getId(), sConfig.adminGroupId)); + new ProjectRight(new ProjectRight.Key(DEFAULT_WILD_NAME, cat.getId(), + sConfig.adminGroupId)); read.setMaxValue((short) 1); read.setMinValue((short) 1); c.projectRights().insert(Collections.singleton(read)); diff --git a/src/main/java/com/google/gerrit/server/config/WildProjectName.java b/src/main/java/com/google/gerrit/server/config/WildProjectName.java new file mode 100644 index 0000000000..7c7bfa92dc --- /dev/null +++ b/src/main/java/com/google/gerrit/server/config/WildProjectName.java @@ -0,0 +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 static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.google.gerrit.client.reviewdb.Project; +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.Retention; + +/** + * Marker on a {@link Project.NameKey} for the current wildcard project. + * <p> + * This is the name of the project whose rights inherit into every other project + * in the system. + */ +@Retention(RUNTIME) +@BindingAnnotation +public @interface WildProjectName { +} diff --git a/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java b/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java new file mode 100644 index 0000000000..1d67491de7 --- /dev/null +++ b/src/main/java/com/google/gerrit/server/config/WildProjectNameProvider.java @@ -0,0 +1,45 @@ +package com.google.gerrit.server.config; + +import com.google.gerrit.client.reviewdb.Project; +import com.google.gerrit.client.reviewdb.ReviewDb; +import com.google.gerrit.client.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; + +class WildProjectNameProvider implements Provider<Project.NameKey> { + /** Project.Id meaning "any and all projects on this server". */ + static final Project.Id WILD_PROJECT_ID = new Project.Id(0); + + private final SchemaFactory<ReviewDb> schema; + + @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; + } + + 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); + } + } +} diff --git a/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java b/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java index b0fe702ebf..1c0bee7596 100644 --- a/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java +++ b/src/main/java/com/google/gerrit/server/mail/CreateChangeSender.java @@ -19,7 +19,7 @@ import com.google.gerrit.client.reviewdb.AccountGroup; import com.google.gerrit.client.reviewdb.AccountGroupMember; import com.google.gerrit.client.reviewdb.AccountProjectWatch; import com.google.gerrit.client.reviewdb.Change; -import com.google.gerrit.client.reviewdb.Project; +import com.google.gerrit.server.project.ProjectState; import com.google.gwtorm.client.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; @@ -50,8 +50,8 @@ public class CreateChangeSender extends NewChangeSender { try { // BCC anyone else who has interest in this project's changes // - final Project project = getProject(); - if (project != null) { + final ProjectState ps = getProjectState(); + if (ps != null) { // Try to mark interested owners with a TO and not a BCC line. // final Set<Account.Id> owners = new HashSet<Account.Id>(); @@ -64,7 +64,7 @@ public class CreateChangeSender extends NewChangeSender { // BCC anyone who has interest in this project's changes // for (AccountProjectWatch w : db.accountProjectWatches() - .notifyNewChanges(project.getId())) { + .notifyNewChanges(ps.getProject().getNameKey())) { if (owners.contains(w.getAccountId())) { add(RecipientType.TO, w.getAccountId()); } else { diff --git a/src/main/java/com/google/gerrit/server/mail/MergedSender.java b/src/main/java/com/google/gerrit/server/mail/MergedSender.java index 04478f31bc..ddacd4729c 100644 --- a/src/main/java/com/google/gerrit/server/mail/MergedSender.java +++ b/src/main/java/com/google/gerrit/server/mail/MergedSender.java @@ -23,7 +23,7 @@ import com.google.gerrit.client.reviewdb.ApprovalCategoryValue; import com.google.gerrit.client.reviewdb.Branch; import com.google.gerrit.client.reviewdb.Change; import com.google.gerrit.client.reviewdb.ChangeApproval; -import com.google.gerrit.client.reviewdb.Project; +import com.google.gerrit.server.project.ProjectState; import com.google.gwtorm.client.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; @@ -160,10 +160,10 @@ public class MergedSender extends ReplyToChangeSender { try { // BCC anyone else who has interest in this project's changes // - final Project project = getProject(); - if (project != null) { + final ProjectState ps = getProjectState(); + if (ps != null) { for (AccountProjectWatch w : db.accountProjectWatches() - .notifySubmittedChanges(project.getId())) { + .notifySubmittedChanges(ps.getProject().getNameKey())) { add(RecipientType.BCC, w.getAccountId()); } } diff --git a/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java b/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java index b3a844a560..4c6b8d5323 100644 --- a/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java +++ b/src/main/java/com/google/gerrit/server/mail/OutgoingEmail.java @@ -23,12 +23,12 @@ import com.google.gerrit.client.reviewdb.ChangeMessage; import com.google.gerrit.client.reviewdb.Patch; import com.google.gerrit.client.reviewdb.PatchSet; import com.google.gerrit.client.reviewdb.PatchSetInfo; -import com.google.gerrit.client.reviewdb.Project; import com.google.gerrit.client.reviewdb.ReviewDb; import com.google.gerrit.client.reviewdb.StarredChange; import com.google.gerrit.client.reviewdb.UserIdentity; import com.google.gerrit.client.rpc.Common; import com.google.gerrit.server.GerritServer; +import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.Nullable; import com.google.gerrit.server.patch.PatchSetInfoFactory; @@ -90,15 +90,27 @@ public abstract class OutgoingEmail { private PatchSetInfoFactory patchSetInfoFactory; @Inject + private IdentifiedUser.GenericFactory identifiedUserFactory; + + @Inject @CanonicalWebUrl @Nullable private Provider<String> urlProvider; + private ProjectState projectState; protected OutgoingEmail(final Change c, final String mc) { change = c; - projectName = change != null ? change.getDest().getParentKey().get() : null; messageClass = mc; headers = new LinkedHashMap<String, EmailHeader>(); + + if (change != null) { + projectState = projectCache.get(change.getDest().getParentKey()); + projectName = + projectState != null ? projectState.getProject().getName() : null; + } else { + projectState = null; + projectName = null; + } } protected OutgoingEmail(final String mc) { @@ -463,11 +475,8 @@ public abstract class OutgoingEmail { } /** Get the project entity the change is in; null if its been deleted. */ - protected Project getProject() { - final ProjectState r; - - r = projectCache.get(change.getDest().getParentKey()); - return r != null ? r.getProject() : null; + protected ProjectState getProjectState() { + return projectState; } /** Get the groups which own the project. */ @@ -526,10 +535,10 @@ public abstract class OutgoingEmail { try { // BCC anyone else who has interest in this project's changes // - final Project project = getProject(); - if (project != null) { - for (AccountProjectWatch w : db.accountProjectWatches() - .notifyAllComments(project.getId())) { + final ProjectState ps = getProjectState(); + if (ps != null) { + for (final AccountProjectWatch w : db.accountProjectWatches() + .notifyAllComments(ps.getProject().getNameKey())) { add(RecipientType.BCC, w.getAccountId()); } } @@ -569,11 +578,19 @@ public abstract class OutgoingEmail { /** Schedule delivery of this message to the given account. */ protected void add(final RecipientType rt, final Account.Id to) { - if (rcptTo.add(to)) { + if (!rcptTo.contains(to) && isVisibleTo(to)) { + rcptTo.add(to); add(rt, toAddress(to)); } } + private boolean isVisibleTo(final Account.Id to) { + return projectState == null + || change == null + || projectState.controlFor(identifiedUserFactory.create(to)) + .controlFor(change).isVisible(); + } + /** Schedule delivery of this message to the given account. */ protected void add(final RecipientType rt, final Address addr) { if (addr != null && addr.email != null && addr.email.length() > 0) { diff --git a/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java b/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java index ea6515b2db..55c7de3155 100644 --- a/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java +++ b/src/main/java/com/google/gerrit/server/project/NoSuchProjectException.java @@ -25,12 +25,4 @@ public class NoSuchProjectException extends Exception { public NoSuchProjectException(final Project.NameKey key, final Throwable why) { super(key.toString(), why); } - - public NoSuchProjectException(final Project.Id key) { - this(key, null); - } - - public NoSuchProjectException(final Project.Id key, final Throwable why) { - super(key.toString(), why); - } } diff --git a/src/main/java/com/google/gerrit/server/project/ProjectCache.java b/src/main/java/com/google/gerrit/server/project/ProjectCache.java index a92309cbaa..0e517dec2d 100644 --- a/src/main/java/com/google/gerrit/server/project/ProjectCache.java +++ b/src/main/java/com/google/gerrit/server/project/ProjectCache.java @@ -18,6 +18,7 @@ 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.server.AnonymousUser; +import com.google.gerrit.server.config.WildProjectName; import com.google.gwtorm.client.OrmException; import com.google.gwtorm.client.SchemaFactory; import com.google.inject.Inject; @@ -42,38 +43,31 @@ public class ProjectCache { final AnonymousUser anonymousUser; private final SchemaFactory<ReviewDb> schema; + private final Project.NameKey wildProject; private final Cache raw; private final SelfPopulatingCache auto; @Inject ProjectCache(final AnonymousUser au, final SchemaFactory<ReviewDb> sf, - final CacheManager mgr) { + @WildProjectName final Project.NameKey wp, final CacheManager mgr) { anonymousUser = au; schema = sf; + wildProject = wp; raw = mgr.getCache("projects"); auto = new SelfPopulatingCache(raw, new CacheEntryFactory() { @Override public Object createEntry(final Object key) throws Exception { - return lookup(key); + return lookup((Project.NameKey) key); } }); mgr.replaceCacheWithDecoratedCache(raw, auto); } - private ProjectState lookup(final Object key) throws OrmException { + private ProjectState lookup(final Project.NameKey key) throws OrmException { final ReviewDb db = schema.open(); try { - final Project p; - if (key instanceof Project.Id) { - p = db.projects().get((Project.Id) key); - - } else if (key instanceof Project.NameKey) { - p = db.projects().get((Project.NameKey) key); - - } else { - p = null; - } + final Project p = db.projects().get(key); return p != null ? new ProjectState(this, db, p) : null; } finally { db.close(); @@ -82,40 +76,17 @@ public class ProjectCache { /** Get the rights which are applied to all projects in the system. */ public Collection<ProjectRight> getWildcardRights() { - return get(ProjectRight.WILD_PROJECT).getRights(); + return get(wildProject).getRights(); } /** Invalidate the cached information about the given project. */ public void invalidate(final Project p) { if (p != null) { auto.remove(p.getNameKey()); - auto.remove(p.getId()); - } - } - - /** Invalidate the cached information about the given project. */ - public void invalidate(final Project.Id projectId) { - if (projectId != null) { - final Element e = raw.get(projectId); - if (e != null && e.getObjectValue() != null) { - invalidate(((ProjectState) e.getObjectValue()).getProject()); - } else { - auto.remove(projectId); - } } } /** - * Get the cached data for a project by its unique id. - * - * @param projectId id of the project. - * @return the cached data; null if no such project exists. - */ - public ProjectState get(final Project.Id projectId) { - return get0(projectId); - } - - /** * Get the cached data for a project by its unique name. * * @param projectName name of the project. diff --git a/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/src/main/java/com/google/gerrit/server/project/ProjectControl.java index 8bca51e98b..59b2795d03 100644 --- a/src/main/java/com/google/gerrit/server/project/ProjectControl.java +++ b/src/main/java/com/google/gerrit/server/project/ProjectControl.java @@ -46,15 +46,6 @@ public class ProjectControl { return p.controlFor(user.get()); } - public ProjectControl controlFor(final Project.Id projectId) - throws NoSuchProjectException { - final ProjectState p = projectCache.get(projectId); - if (p == null) { - throw new NoSuchProjectException(projectId); - } - return p.controlFor(user.get()); - } - public ProjectControl validateFor(final Project.NameKey nameKey) throws NoSuchProjectException { final ProjectControl c = controlFor(nameKey); @@ -63,15 +54,6 @@ public class ProjectControl { } return c; } - - public ProjectControl validateFor(final Project.Id projectId) - throws NoSuchProjectException { - final ProjectControl c = controlFor(projectId); - if (!c.isVisible()) { - throw new NoSuchProjectException(projectId); - } - return c; - } } private final CurrentUser user; diff --git a/src/main/java/com/google/gerrit/server/project/ProjectState.java b/src/main/java/com/google/gerrit/server/project/ProjectState.java index 04f857dfb4..9e4742b0dd 100644 --- a/src/main/java/com/google/gerrit/server/project/ProjectState.java +++ b/src/main/java/com/google/gerrit/server/project/ProjectState.java @@ -40,7 +40,7 @@ public class ProjectState { project = p; rights = Collections.unmodifiableCollection(db.projectRights().byProject( - project.getId()).toList()); + project.getNameKey()).toList()); final HashSet<AccountGroup.Id> groups = new HashSet<AccountGroup.Id>(); for (final ProjectRight right : rights) { diff --git a/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java b/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java index 2618ee8e69..e2030ee508 100644 --- a/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java +++ b/src/main/java/com/google/gerrit/server/rpc/AccountServiceImpl.java @@ -25,8 +25,9 @@ import com.google.gerrit.client.reviewdb.ReviewDb; import com.google.gerrit.client.rpc.Common; import com.google.gerrit.client.rpc.NoSuchEntityException; import com.google.gerrit.server.BaseServiceImplementation; -import com.google.gerrit.server.project.ProjectCache; -import com.google.gerrit.server.project.ProjectState; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.project.NoSuchProjectException; +import com.google.gerrit.server.project.ProjectControl; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwtjsonrpc.client.VoidResult; import com.google.gwtorm.client.OrmException; @@ -42,13 +43,13 @@ import java.util.Set; class AccountServiceImpl extends BaseServiceImplementation implements AccountService { - private final ProjectCache projectCache; + private final ProjectControl.Factory projectControlFactory; @Inject AccountServiceImpl(final Provider<ReviewDb> sf, - final ProjectCache projectCache) { + final ProjectControl.Factory projectControlFactory) { super(sf); - this.projectCache = projectCache; + this.projectControlFactory = projectControlFactory; } public void myAccount(final AsyncCallback<Account> callback) { @@ -89,12 +90,14 @@ class AccountServiceImpl extends BaseServiceImplementation implements for (final AccountProjectWatch w : db.accountProjectWatches() .byAccount(Common.getAccountId()).toList()) { - final ProjectState project = projectCache.get(w.getProjectId()); - if (project == null) { + final ProjectControl ctl; + try { + ctl = projectControlFactory.validateFor(w.getProjectNameKey()); + } catch (NoSuchProjectException e) { db.accountProjectWatches().delete(Collections.singleton(w)); continue; } - r.add(new AccountProjectWatchInfo(w, project.getProject())); + r.add(new AccountProjectWatchInfo(w, ctl.getProject())); } Collections.sort(r, new Comparator<AccountProjectWatchInfo>() { public int compare(final AccountProjectWatchInfo a, @@ -111,18 +114,16 @@ class AccountServiceImpl extends BaseServiceImplementation implements final AsyncCallback<AccountProjectWatchInfo> callback) { run(callback, new Action<AccountProjectWatchInfo>() { public AccountProjectWatchInfo run(ReviewDb db) throws OrmException, - Failure { - final ProjectState project = - projectCache.get(new Project.NameKey(projectName)); - if (project == null) { - throw new Failure(new NoSuchEntityException()); - } + NoSuchProjectException { + final Project.NameKey nameKey = new Project.NameKey(projectName); + final ProjectControl ctl = projectControlFactory.validateFor(nameKey); final AccountProjectWatch watch = - new AccountProjectWatch(new AccountProjectWatch.Key(Common - .getAccountId(), project.getProject().getId())); + new AccountProjectWatch( + new AccountProjectWatch.Key(((IdentifiedUser) ctl + .getCurrentUser()).getAccountId(), nameKey)); db.accountProjectWatches().insert(Collections.singleton(watch)); - return new AccountProjectWatchInfo(watch, project.getProject()); + return new AccountProjectWatchInfo(watch, ctl.getProject()); } }); } diff --git a/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java b/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java index 475c9941c4..238135399c 100644 --- a/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java +++ b/src/main/java/com/google/gerrit/server/rpc/project/ProjectAdminServiceImpl.java @@ -33,6 +33,7 @@ import com.google.gerrit.git.ReplicationQueue; import com.google.gerrit.server.BaseServiceImplementation; import com.google.gerrit.server.GerritServer; import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.config.WildProjectName; import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectControl; @@ -60,7 +61,6 @@ import org.spearce.jgit.revwalk.RevCommit; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; @@ -72,6 +72,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements private final Logger log = LoggerFactory.getLogger(getClass()); private final GerritServer server; private final ProjectCache projectCache; + private final Project.NameKey wildProject; private final ProjectControl.Factory projectControlFactory; private final ReplicationQueue replication; private final Provider<IdentifiedUser> identifiedUser; @@ -82,12 +83,14 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements ProjectAdminServiceImpl(final Provider<ReviewDb> sf, final GerritServer gs, final ProjectCache pc, final ReplicationQueue rq, final Provider<IdentifiedUser> iu, + @WildProjectName final Project.NameKey wp, final ProjectControl.Factory projectControlFactory, final ProjectDetailFactory.Factory projectDetailFactory) { super(sf); this.server = gs; this.projectCache = pc; this.replication = rq; + this.wildProject = wp; this.identifiedUser = iu; this.projectControlFactory = projectControlFactory; this.projectDetailFactory = projectDetailFactory; @@ -126,7 +129,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements db.projects().update(Collections.singleton(proj)); projectCache.invalidate(proj); - if (!ProjectRight.WILD_PROJECT.equals(update.getId())) { + if (!wildProject.equals(projectName)) { // Update git's description file, in case gitweb is being used // try { @@ -175,7 +178,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements throw new NoSuchProjectException(name); } for (final ProjectRight.Key k : keys) { - if (!control.getProject().getId().equals(k.getProjectId())) { + if (!name.equals(k.getProjectNameKey())) { throw new Failure(new NoSuchEntityException()); } } @@ -212,7 +215,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements throw new Failure(new NoSuchEntityException()); } - if (ProjectRight.WILD_PROJECT.equals(proj.getId()) + if (wildProject.equals(projectName) && ApprovalCategory.OWN.equals(categoryId)) { // Giving out control of the WILD_PROJECT to other groups beyond // Administrators is dangerous. Having control over WILD_PROJECT @@ -244,7 +247,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements } final ProjectRight.Key key = - new ProjectRight.Key(proj.getId(), categoryId, group.getId()); + new ProjectRight.Key(projectName, categoryId, group.getId()); ProjectRight pr = db.projectRights().get(key); if (pr == null) { pr = new ProjectRight(key); @@ -485,22 +488,17 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements return db.projects().all().toList(); } - final HashSet<Project.Id> seen = new HashSet<Project.Id>(); + final HashSet<Project.NameKey> seen = new HashSet<Project.NameKey>(); final List<Project> own = new ArrayList<Project>(); for (final AccountGroup.Id groupId : myGroups()) { for (final ProjectRight r : db.projectRights().byCategoryGroup( ApprovalCategory.OWN, groupId)) { - if (!seen.add(r.getProjectId())) { + final Project.NameKey name = r.getProjectNameKey(); + if (!seen.add(name)) { continue; } - - final Project p = db.projects().get(r.getProjectId()); - if (p == null) { - continue; - } - try { - ProjectControl c = projectControlFactory.controlFor(p.getNameKey()); + ProjectControl c = projectControlFactory.controlFor(name); if (c.isOwner()) { own.add(c.getProject()); } diff --git a/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java b/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java index 7a7849f110..f2f566134b 100644 --- a/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java +++ b/src/main/java/com/google/gerrit/server/rpc/project/ProjectDetailFactory.java @@ -20,6 +20,7 @@ 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.rpc.NoSuchEntityException; +import com.google.gerrit.server.config.WildProjectName; import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.rpc.Handler; @@ -35,11 +36,12 @@ import java.util.Map; class ProjectDetailFactory extends Handler<ProjectDetail> { interface Factory { - ProjectDetailFactory create(Project.NameKey name); + ProjectDetailFactory create(@Assisted("name") Project.NameKey name); } private final ProjectCache projectCache; private final ReviewDb db; + private final Project.NameKey wildProject; private final Project.NameKey projectName; private ProjectDetail detail; @@ -47,9 +49,11 @@ class ProjectDetailFactory extends Handler<ProjectDetail> { @Inject ProjectDetailFactory(final ProjectCache projectCache, final ReviewDb db, - @Assisted final Project.NameKey name) { + @WildProjectName final Project.NameKey wp, + @Assisted("name") final Project.NameKey name) { this.projectCache = projectCache; this.db = db; + this.wildProject = wp; this.projectName = name; } @@ -70,7 +74,7 @@ class ProjectDetailFactory extends Handler<ProjectDetail> { rights.add(p); wantGroup(p.getAccountGroupId()); } - if (!ProjectRight.WILD_PROJECT.equals(e.getProject().getId())) { + if (!wildProject.equals(e.getProject().getNameKey())) { for (final ProjectRight p : projectCache.getWildcardRights()) { rights.add(p); wantGroup(p.getAccountGroupId()); diff --git a/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java b/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java index 0c5d96b0f9..d0ee1ebe19 100644 --- a/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java +++ b/src/main/java/com/google/gerrit/server/ssh/commands/AbstractGitCommand.java @@ -16,7 +16,6 @@ package com.google.gerrit.server.ssh.commands; import com.google.gerrit.client.reviewdb.ApprovalCategory; import com.google.gerrit.client.reviewdb.Project; -import com.google.gerrit.client.reviewdb.ProjectRight; import com.google.gerrit.server.GerritServer; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.project.ProjectCache; @@ -81,10 +80,6 @@ abstract class AbstractGitCommand extends BaseCommand { } proj = cachedProj.getProject(); - if (ProjectRight.WILD_PROJECT.equals(proj.getId())) { - throw new Failure(1, "fatal: '" + reqProjName + "': not a valid project", - new IllegalArgumentException("Cannot access the wildcard project")); - } if (!canPerform(ApprovalCategory.READ, (short) 1)) { throw new Failure(1, "fatal: '" + reqProjName + "': unknown project", new SecurityException("Account lacks Read permission")); diff --git a/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java b/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java index 6cb65f8f5e..3274464811 100644 --- a/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java +++ b/src/main/java/com/google/gerrit/server/ssh/commands/ListProjects.java @@ -15,9 +15,9 @@ package com.google.gerrit.server.ssh.commands; 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.server.IdentifiedUser; +import com.google.gerrit.server.config.WildProjectName; import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectState; import com.google.gerrit.server.ssh.BaseCommand; @@ -36,6 +36,10 @@ final class ListProjects extends BaseCommand { @Inject private ProjectCache projectCache; + @Inject + @WildProjectName + private Project.NameKey wildProject; + @Override public void start() { startThread(new CommandRunnable() { @@ -51,7 +55,7 @@ final class ListProjects extends BaseCommand { final PrintWriter stdout = toPrintWriter(out); try { for (final Project p : db.projects().all()) { - if (ProjectRight.WILD_PROJECT.equals(p.getId())) { + if (p.getNameKey().equals(wildProject)) { // This project "doesn't exist". At least not as a repository. // continue; diff --git a/src/main/webapp/WEB-INF/sql/index_generic.sql b/src/main/webapp/WEB-INF/sql/index_generic.sql index 0e508af115..253a478238 100644 --- a/src/main/webapp/WEB-INF/sql/index_generic.sql +++ b/src/main/webapp/WEB-INF/sql/index_generic.sql @@ -55,15 +55,15 @@ ON account_group_members (group_id); -- @PrimaryKey covers: byAccount -- covers: notifyNewChanges CREATE INDEX account_project_watches_ntNew -ON account_project_watches (notify_new_changes, project_id); +ON account_project_watches (notify_new_changes, project_name); -- covers: notifyAllComments CREATE INDEX account_project_watches_ntCmt -ON account_project_watches (notify_all_comments, project_id); +ON account_project_watches (notify_all_comments, project_name); -- covers: notifySubmittedChanges CREATE INDEX account_project_watches_ntSub -ON account_project_watches (notify_submitted_changes, project_id); +ON account_project_watches (notify_submitted_changes, project_name); -- ********************************************************************* diff --git a/src/main/webapp/WEB-INF/sql/index_postgres.sql b/src/main/webapp/WEB-INF/sql/index_postgres.sql index 52e1695d26..4356c64d61 100644 --- a/src/main/webapp/WEB-INF/sql/index_postgres.sql +++ b/src/main/webapp/WEB-INF/sql/index_postgres.sql @@ -68,17 +68,17 @@ ON account_group_members (group_id); -- @PrimaryKey covers: byAccount -- covers: notifyNewChanges CREATE INDEX account_project_watches_ntNew -ON account_project_watches (project_id) +ON account_project_watches (project_name) WHERE notify_new_changes = 'Y'; -- covers: notifyAllComments CREATE INDEX account_project_watches_ntCmt -ON account_project_watches (project_id) +ON account_project_watches (project_name) WHERE notify_all_comments = 'Y'; -- covers: notifySubmittedChanges CREATE INDEX account_project_watches_ntSub -ON account_project_watches (project_id) +ON account_project_watches (project_name) WHERE notify_submitted_changes = 'Y'; diff --git a/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql new file mode 100644 index 0000000000..9dfa4d3a98 --- /dev/null +++ b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_mysql.sql @@ -0,0 +1,42 @@ +-- Upgrade: schema_version 15 to 16 (MySQL) +-- + +-- account_project_watches +-- +DELETE FROM account_project_watches WHERE project_id NOT IN (SELECT project_id FROM projects); +ALTER TABLE account_project_watches ADD project_name VARCHAR(255); +UPDATE account_project_watches SET project_name = +(SELECT name FROM projects + WHERE account_project_watches.project_id = projects.project_id); +ALTER TABLE account_project_watches MODIFY COLUMN project_name VARCHAR(255) NOT NULL; +ALTER TABLE account_project_watches DROP PRIMARY KEY; +ALTER TABLE account_project_watches ADD PRIMARY KEY (account_id, project_name); +ALTER TABLE account_project_watches DROP COLUMN project_id; + +DROP INDEX account_project_watches_ntcmt ON account_project_watches; +DROP INDEX account_project_watches_ntnew ON account_project_watches; +DROP INDEX account_project_watches_ntsub ON account_project_watches; + +CREATE INDEX account_project_watches_ntNew +ON account_project_watches (notify_new_changes, project_name); + +CREATE INDEX account_project_watches_ntCmt +ON account_project_watches (notify_all_comments, project_name); + +CREATE INDEX account_project_watches_ntSub +ON account_project_watches (notify_submitted_changes, project_name); + + +-- project_rights +-- +DELETE FROM project_rights WHERE project_id NOT IN (SELECT project_id FROM projects); +ALTER TABLE project_rights ADD project_name VARCHAR(255); +UPDATE project_rights SET project_name = +(SELECT name FROM projects + WHERE project_rights.project_id = projects.project_id); +ALTER TABLE project_rights MODIFY COLUMN project_name VARCHAR(255) NOT NULL; +ALTER TABLE project_rights DROP PRIMARY KEY; +ALTER TABLE project_rights ADD PRIMARY KEY (project_name, category_id, group_id); +ALTER TABLE project_rights DROP COLUMN project_id; + +UPDATE schema_version SET version_nbr = 16; diff --git a/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql new file mode 100644 index 0000000000..133e984a4a --- /dev/null +++ b/src/main/webapp/WEB-INF/sql/upgrade015_016_part1_postgres.sql @@ -0,0 +1,47 @@ +-- Upgrade: schema_version 15 to 16 (PostgreSQL) +-- + +-- account_project_watches +-- +DROP INDEX account_project_watches_ntcmt; +DROP INDEX account_project_watches_ntnew; +DROP INDEX account_project_watches_ntsub; + +DELETE FROM account_project_watches WHERE project_id NOT IN (SELECT project_id FROM projects); +ALTER TABLE account_project_watches ADD project_name VARCHAR(255); +UPDATE account_project_watches SET project_name = +(SELECT name FROM projects + WHERE account_project_watches.project_id = projects.project_id); +ALTER TABLE account_project_watches ALTER COLUMN project_name SET NOT NULL; +ALTER TABLE account_project_watches DROP CONSTRAINT account_project_watches_pkey; +ALTER TABLE account_project_watches ADD PRIMARY KEY (account_id, project_name); +ALTER TABLE account_project_watches DROP COLUMN project_id; + +CREATE INDEX account_project_watches_ntNew +ON account_project_watches (project_name) +WHERE notify_new_changes = 'Y'; + +CREATE INDEX account_project_watches_ntCmt +ON account_project_watches (project_name) +WHERE notify_all_comments = 'Y'; + +CREATE INDEX account_project_watches_ntSub +ON account_project_watches (project_name) +WHERE notify_submitted_changes = 'Y'; + + +-- project_rights +-- +DELETE FROM project_rights WHERE project_id NOT IN (SELECT project_id FROM projects); +ALTER TABLE project_rights ADD project_name VARCHAR(255); +UPDATE project_rights SET project_name = +(SELECT name FROM projects + WHERE project_rights.project_id = projects.project_id) + WHERE project_id IS NOT NULL; +ALTER TABLE project_rights ALTER COLUMN project_name SET NOT NULL; +ALTER TABLE project_rights DROP CONSTRAINT project_rights_pkey; +ALTER TABLE project_rights ADD PRIMARY KEY (project_name, category_id, group_id); +ALTER TABLE project_rights DROP COLUMN project_id; + + +UPDATE schema_version SET version_nbr = 16; |