Enable watching of all projects

Some users want to get e-mail notifications for all projects hosted
in Gerrit. So far it was only possible to watch all projects
by explicitly adding each project to the watch list. With this
change adding the wild card project to the watch list allows you
to configure e-mail notification for all projects.

Bug: issue 535
Signed-off-by: Edwin Kempin <edwin.kempin@gmail.com>
Change-Id: I15da036fc7aa1c90a72cf0c6935f0df45640c3ec
This commit is contained in:
Edwin Kempin 2010-06-28 11:35:47 +02:00 committed by Shawn O. Pearce
parent 55661b1ca1
commit e7d485ccc4
8 changed files with 94 additions and 48 deletions

View File

@ -28,15 +28,6 @@ public interface AccountProjectWatchAccess extends
@Query("WHERE key.accountId = ?")
ResultSet<AccountProjectWatch> byAccount(Account.Id id) throws OrmException;
@Query("WHERE notifyNewChanges = true AND key.projectName = ?")
ResultSet<AccountProjectWatch> notifyNewChanges(Project.NameKey name)
throws OrmException;
@Query("WHERE notifyAllComments = true AND key.projectName = ?")
ResultSet<AccountProjectWatch> notifyAllComments(Project.NameKey name)
throws OrmException;
@Query("WHERE notifySubmittedChanges = true AND key.projectName = ?")
ResultSet<AccountProjectWatch> notifySubmittedChanges(Project.NameKey name)
throws OrmException;
@Query("WHERE key.projectName = ?")
ResultSet<AccountProjectWatch> byProject(Project.NameKey name) throws OrmException;
}

View File

@ -47,17 +47,9 @@ ON account_group_members (group_id);
-- *********************************************************************
-- AccountProjectWatchAccess
-- @PrimaryKey covers: byAccount
-- covers: notifyNewChanges
CREATE INDEX account_project_watches_ntNew
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_name);
-- covers: notifySubmittedChanges
CREATE INDEX account_project_watches_ntSub
ON account_project_watches (notify_submitted_changes, project_name);
-- covers: byProject
CREATE INDEX account_project_watches_byProject
ON account_project_watches (project_name);
-- *********************************************************************

View File

@ -86,20 +86,9 @@ ON account_group_members (group_id);
-- *********************************************************************
-- AccountProjectWatchAccess
-- @PrimaryKey covers: byAccount
-- covers: notifyNewChanges
CREATE INDEX account_project_watches_ntNew
-- covers: byProject
CREATE INDEX account_project_watches_byProject
ON account_project_watches (project_name)
WHERE notify_new_changes = 'Y';
-- covers: notifyAllComments
CREATE INDEX account_project_watches_ntCmt
ON account_project_watches (project_name)
WHERE notify_all_comments = 'Y';
-- covers: notifySubmittedChanges
CREATE INDEX account_project_watches_ntSub
ON account_project_watches (project_name)
WHERE notify_submitted_changes = 'Y';
-- *********************************************************************

View File

@ -63,12 +63,13 @@ public class CreateChangeSender extends NewChangeSender {
// BCC anyone who has interest in this project's changes
//
for (AccountProjectWatch w : db.accountProjectWatches()
.notifyNewChanges(ps.getProject().getNameKey())) {
if (owners.contains(w.getAccountId())) {
add(RecipientType.TO, w.getAccountId());
} else {
add(RecipientType.BCC, w.getAccountId());
for (final AccountProjectWatch w : getProjectWatches()) {
if (w.isNotifyNewChanges()) {
if (owners.contains(w.getAccountId())) {
add(RecipientType.TO, w.getAccountId());
} else {
add(RecipientType.BCC, w.getAccountId());
}
}
}
}

View File

@ -163,9 +163,10 @@ public class MergedSender extends ReplyToChangeSender {
//
final ProjectState ps = getProjectState();
if (ps != null) {
for (AccountProjectWatch w : db.accountProjectWatches()
.notifySubmittedChanges(ps.getProject().getNameKey())) {
add(RecipientType.BCC, w.getAccountId());
for (final AccountProjectWatch w : getProjectWatches()) {
if (w.isNotifySubmittedChanges()) {
add(RecipientType.BCC, w.getAccountId());
}
}
}
} catch (OrmException err) {

View File

@ -22,12 +22,14 @@ import com.google.gerrit.reviewdb.ChangeMessage;
import com.google.gerrit.reviewdb.PatchSet;
import com.google.gerrit.reviewdb.PatchSetApproval;
import com.google.gerrit.reviewdb.PatchSetInfo;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.StarredChange;
import com.google.gerrit.reviewdb.UserIdentity;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.WildProjectName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
@ -108,6 +110,10 @@ public abstract class OutgoingEmail {
@Nullable
private Provider<String> urlProvider;
@Inject
@WildProjectName
private Project.NameKey wildProject;
private ProjectState projectState;
protected OutgoingEmail(final Change c, final String mc) {
@ -570,9 +576,10 @@ public abstract class OutgoingEmail {
//
final ProjectState ps = getProjectState();
if (ps != null) {
for (final AccountProjectWatch w : db.accountProjectWatches()
.notifyAllComments(ps.getProject().getNameKey())) {
add(RecipientType.BCC, w.getAccountId());
for (final AccountProjectWatch w : getProjectWatches()) {
if (w.isNotifyAllComments()) {
add(RecipientType.BCC, w.getAccountId());
}
}
}
} catch (OrmException err) {
@ -583,6 +590,27 @@ public abstract class OutgoingEmail {
}
}
/** Returns all watches that are relevant for this project */
final protected Set<AccountProjectWatch> getProjectWatches() throws OrmException {
final Set<AccountProjectWatch> projectWatches = new HashSet<AccountProjectWatch>();
final Set<Account.Id> projectWatchers = new HashSet<Account.Id>();
final ProjectState ps = getProjectState();
if (ps != null) {
for (final AccountProjectWatch w : db.accountProjectWatches().byProject(ps.getProject().getNameKey())) {
projectWatches.add(w);
projectWatchers.add(w.getAccountId());
}
}
for (final AccountProjectWatch w : db.accountProjectWatches().byProject(wildProject)) {
if (!projectWatchers.contains(w.getAccountId())) {
// the all projects watch settings are only relevant if the user did not configure
// any specific rules for the concrete project
projectWatches.add(w);
}
}
return Collections.unmodifiableSet(projectWatches);
}
/** Any user who has published comments on this change. */
protected void ccAllApprovals() {
ccApprovals(true);

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_35.class;
private static final Class<? extends SchemaVersion> C = Schema_36.class;
public static class Module extends AbstractModule {
@Override

View File

@ -0,0 +1,44 @@
// Copyright (C) 2010 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.ReviewDb;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.sql.SQLException;
import java.sql.Statement;
public class Schema_36 extends SchemaVersion {
@Inject
Schema_36(Provider<Schema_35> prior) {
super(prior);
}
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws SQLException {
Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
try {
stmt.execute("DROP INDEX account_project_watches_ntNew");
stmt.execute("DROP INDEX account_project_watches_ntCmt");
stmt.execute("DROP INDEX account_project_watches_ntSub");
stmt.execute("CREATE INDEX account_project_watches_byProject"
+ " ON account_project_watches (project_name)");
} finally {
stmt.close();
}
}
}