summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Attachment.pm15
-rw-r--r--Bugzilla/Auth/Verify.pm8
-rw-r--r--Bugzilla/Auth/Verify/DB.pm1
-rw-r--r--Bugzilla/Bug.pm2
-rw-r--r--Bugzilla/Classification.pm14
-rw-r--r--Bugzilla/Comment/TagWeights.pm3
-rw-r--r--Bugzilla/Field.pm2
-rw-r--r--Bugzilla/Flag.pm2
-rw-r--r--Bugzilla/FlagType.pm12
-rw-r--r--Bugzilla/Install/Requirements.pm6
-rw-r--r--Bugzilla/Memcached.pm34
-rw-r--r--Bugzilla/Milestone.pm1
-rw-r--r--Bugzilla/Object.pm20
-rw-r--r--Bugzilla/Search/Recent.pm3
-rw-r--r--Bugzilla/Search/Saved.pm1
-rw-r--r--Bugzilla/User.pm1
-rwxr-xr-xbuglist.cgi1
-rwxr-xr-xcontrib/merge-users.pl5
-rwxr-xr-xcontrib/reorg-tools/bmo-plan.txt82
-rwxr-xr-xcontrib/reorg-tools/convert_date_time_date.pl4
-rwxr-xr-xcontrib/reorg-tools/fix_all_open_status_queries.pl4
-rwxr-xr-xcontrib/reorg-tools/fixgroupqueries.pl4
-rwxr-xr-xcontrib/reorg-tools/fixqueries.pl4
-rwxr-xr-xcontrib/reorg-tools/migrate_crash_signatures.pl8
-rwxr-xr-xcontrib/reorg-tools/migrate_orange_bugs.pl4
-rwxr-xr-xcontrib/reorg-tools/move_flag_types.pl4
-rwxr-xr-xcontrib/reorg-tools/movebugs.pl4
-rwxr-xr-xcontrib/reorg-tools/movecomponent.pl11
-rwxr-xr-xcontrib/reorg-tools/reset_default_user.pl2
-rwxr-xr-xeditclassifications.cgi11
-rwxr-xr-xeditusers.cgi5
-rw-r--r--extensions/ContributorEngagement/Extension.pm2
-rw-r--r--extensions/EditComments/Extension.pm1
-rw-r--r--extensions/FlagDefaultRequestee/Extension.pm1
-rw-r--r--extensions/Push/lib/BacklogMessage.pm1
-rw-r--r--extensions/Push/lib/Backoff.pm1
-rw-r--r--extensions/Push/lib/LogEntry.pm1
-rw-r--r--extensions/Push/lib/Message.pm1
-rw-r--r--extensions/Review/Extension.pm1
-rw-r--r--extensions/Review/lib/Util.pm1
-rw-r--r--extensions/TagNewUsers/Extension.pm2
-rw-r--r--extensions/UserProfile/Extension.pm2
-rwxr-xr-xextensions/UserProfile/bin/update.pl1
-rw-r--r--extensions/UserProfile/lib/Util.pm4
-rwxr-xr-xquery.cgi9
-rwxr-xr-xsanitycheck.cgi26
-rwxr-xr-xuserprefs.cgi5
47 files changed, 226 insertions, 111 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm
index bb0f83aba..2b2159346 100644
--- a/Bugzilla/Attachment.pm
+++ b/Bugzilla/Attachment.pm
@@ -921,6 +921,9 @@ sub update {
$dbh->do('UPDATE bugs SET delta_ts = ? WHERE bug_id = ?',
undef, ($timestamp, $self->bug_id));
$self->{modification_time} = $timestamp;
+ # because we updated the attachments table after SUPER::update(), we
+ # need to ensure the cache is flushed.
+ Bugzilla->memcached->clear({ table => 'attachments', id => $self->id });
}
return $changes;
@@ -945,11 +948,21 @@ sub remove_from_db {
my $dbh = Bugzilla->dbh;
$dbh->bz_start_transaction();
- $dbh->do('DELETE FROM flags WHERE attach_id = ?', undef, $self->id);
+ my $flag_ids = $dbh->selectcol_arrayref(
+ 'SELECT id FROM flags WHERE attach_id = ?', undef, $self->id);
+ $dbh->do('DELETE FROM flags WHERE ' . $dbh->sql_in('id', $flag_ids))
+ if @$flag_ids;
$dbh->do('DELETE FROM attach_data WHERE id = ?', undef, $self->id);
$dbh->do('UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ?
WHERE attach_id = ?', undef, ('text/plain', 0, 1, $self->id));
$dbh->bz_commit_transaction();
+
+ # As we don't call SUPER->remove_from_db we need to manually clear
+ # memcached here.
+ Bugzilla->memcached->clear({ table => 'attachments', id => $self->id });
+ foreach my $flag_id (@$flag_ids) {
+ Bugzilla->memcached->clear({ table => 'flags', id => $flag_id });
+ }
}
###############################
diff --git a/Bugzilla/Auth/Verify.pm b/Bugzilla/Auth/Verify.pm
index a8cd0af2c..3578631f1 100644
--- a/Bugzilla/Auth/Verify.pm
+++ b/Bugzilla/Auth/Verify.pm
@@ -97,6 +97,7 @@ sub create_or_update_user {
if ($extern_id && $username_user_id && !$extern_user_id) {
$dbh->do('UPDATE profiles SET extern_id = ? WHERE userid = ?',
undef, $extern_id, $username_user_id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $username_user_id });
}
# Finally, at this point, one of these will give us a valid user id.
@@ -109,23 +110,26 @@ sub create_or_update_user {
'Bugzilla::Auth::Verify::create_or_update_user'})
unless $user_id;
- my $user = new Bugzilla::User($user_id);
+ my $user = new Bugzilla::User({ id => $user_id, cache => 1 });
# Now that we have a valid User, we need to see if any data has to be
# updated.
+ my $user_updated = 0;
if ($username && lc($user->login) ne lc($username)) {
validate_email_syntax($username)
|| return { failure => AUTH_ERROR, error => 'auth_invalid_email',
details => {addr => $username} };
$user->set_login($username);
+ $user_updated = 1;
}
if ($real_name && $user->name ne $real_name) {
# $real_name is more than likely tainted, but we only use it
# in a placeholder and we never use it after this.
trick_taint($real_name);
$user->set_name($real_name);
+ $user_updated = 1;
}
- $user->update();
+ $user->update() if $user_updated;
return { user => $user };
}
diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm
index 2fcfd4017..783e7490a 100644
--- a/Bugzilla/Auth/Verify/DB.pm
+++ b/Bugzilla/Auth/Verify/DB.pm
@@ -103,6 +103,7 @@ sub change_password {
my $cryptpassword = bz_crypt($password);
$dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?",
undef, $cryptpassword, $user->id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $user->id });
}
1;
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index b6861b509..a99dfaf85 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -76,6 +76,8 @@ use constant LIST_ORDER => ID_FIELD;
# Bugs have their own auditing table, bugs_activity.
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
+# This will be enabled later
+use constant USE_MEMCACHED => 0;
# This is a sub because it needs to call other subroutines.
sub DB_COLUMNS {
diff --git a/Bugzilla/Classification.pm b/Bugzilla/Classification.pm
index 88ec4eb3b..5d75a6dc6 100644
--- a/Bugzilla/Classification.pm
+++ b/Bugzilla/Classification.pm
@@ -56,6 +56,7 @@ use constant VALIDATORS => {
###############################
#### Constructors #####
###############################
+
sub remove_from_db {
my $self = shift;
my $dbh = Bugzilla->dbh;
@@ -63,9 +64,18 @@ sub remove_from_db {
ThrowUserError("classification_not_deletable") if ($self->id == 1);
$dbh->bz_start_transaction();
+
# Reclassify products to the default classification, if needed.
- $dbh->do("UPDATE products SET classification_id = 1
- WHERE classification_id = ?", undef, $self->id);
+ my $product_ids = $dbh->selectcol_arrayref(
+ 'SELECT id FROM products WHERE classification_id = ?', undef, $self->id);
+
+ if (@$product_ids) {
+ $dbh->do('UPDATE products SET classification_id = 1 WHERE '
+ . $dbh->sql_in('id', $product_ids));
+ foreach my $id (@$product_ids) {
+ Bugzilla->memcached->clear({ table => 'products', id => $id });
+ }
+ }
$self->SUPER::remove_from_db();
diff --git a/Bugzilla/Comment/TagWeights.pm b/Bugzilla/Comment/TagWeights.pm
index 5835efbc4..f1a220a47 100644
--- a/Bugzilla/Comment/TagWeights.pm
+++ b/Bugzilla/Comment/TagWeights.pm
@@ -35,6 +35,9 @@ use constant NAME_FIELD => 'tag';
use constant LIST_ORDER => 'weight DESC';
use constant VALIDATORS => { };
+# There's no gain to caching these objects
+use constant USE_MEMCACHED => 0;
+
sub tag { return $_[0]->{'tag'} }
sub weight { return $_[0]->{'weight'} }
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm
index 5cd246b8e..97d03dc42 100644
--- a/Bugzilla/Field.pm
+++ b/Bugzilla/Field.pm
@@ -1078,6 +1078,8 @@ sub create {
# Restore the original obsolete state of the custom field.
$dbh->do('UPDATE fielddefs SET obsolete = 0 WHERE id = ?', undef, $field->id)
unless $is_obsolete;
+
+ Bugzilla->memcached->clear({ table => 'fielddefs', id => $field->id });
}
};
diff --git a/Bugzilla/Flag.pm b/Bugzilla/Flag.pm
index 089ac6c9f..6ef7be81e 100644
--- a/Bugzilla/Flag.pm
+++ b/Bugzilla/Flag.pm
@@ -480,6 +480,7 @@ sub update {
$dbh->do('UPDATE flags SET modification_date = ? WHERE id = ?',
undef, ($timestamp, $self->id));
$self->{'modification_date'} = format_time($timestamp, '%Y.%m.%d %T');
+ Bugzilla->memcached->clear({ table => 'flags', id => $self->id });
}
return $changes;
}
@@ -626,6 +627,7 @@ sub force_retarget {
if ($is_retargetted) {
$dbh->do('UPDATE flags SET type_id = ? WHERE id = ?',
undef, ($flag->type_id, $flag->id));
+ Bugzilla->memcached->clear({ table => 'flags', id => $flag->id });
}
else {
# Track deleted attachment flags.
diff --git a/Bugzilla/FlagType.pm b/Bugzilla/FlagType.pm
index 910e2d425..3325c8c5c 100644
--- a/Bugzilla/FlagType.pm
+++ b/Bugzilla/FlagType.pm
@@ -200,8 +200,16 @@ sub update {
# Silently remove requestees from flags which are no longer
# specifically requestable.
if (!$self->is_requesteeble) {
- $dbh->do('UPDATE flags SET requestee_id = NULL WHERE type_id = ?',
- undef, $self->id);
+ my $ids = $dbh->selectcol_arrayref(
+ 'SELECT id FROM flags WHERE type_id = ? AND requestee_id IS NOT NULL',
+ undef, $self->id);
+
+ if (@$ids) {
+ $dbh->do('UPDATE flags SET requestee_id = NULL WHERE ' . $dbh->sql_in('id', $ids));
+ foreach my $id (@$ids) {
+ Bugzilla->memcached->clear({ table => 'flags', id => $id });
+ }
+ }
}
Bugzilla::Hook::process('flagtype_end_of_update',
diff --git a/Bugzilla/Install/Requirements.pm b/Bugzilla/Install/Requirements.pm
index cea5a4a34..384df221e 100644
--- a/Bugzilla/Install/Requirements.pm
+++ b/Bugzilla/Install/Requirements.pm
@@ -375,6 +375,12 @@ sub OPTIONAL_MODULES {
# memcached
{
+ package => 'URI-Escape',
+ module => 'URI::Escape',
+ version => 0,
+ feature => ['memcached'],
+ },
+ {
package => 'Cache-Memcached',
module => 'Cache::Memcached',
version => '0',
diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm
index b1b10311b..4bfca2b65 100644
--- a/Bugzilla/Memcached.pm
+++ b/Bugzilla/Memcached.pm
@@ -14,6 +14,12 @@ use warnings;
use Bugzilla::Error;
use Bugzilla::Util qw(trick_taint);
use Scalar::Util qw(blessed);
+use URI::Escape;
+use Encode;
+use Sys::Syslog qw(:DEFAULT);
+
+# memcached keys have a maximum length of 250 bytes
+use constant MAX_KEY_LENGTH => 250;
sub _new {
my $invocant = shift;
@@ -26,10 +32,11 @@ sub _new {
&& Bugzilla->params->{memcached_servers})
{
require Cache::Memcached;
+ $self->{namespace} = Bugzilla->params->{memcached_namespace} || '';
$self->{memcached} =
Cache::Memcached->new({
servers => [ split(/[, ]+/, Bugzilla->params->{memcached_servers}) ],
- namespace => Bugzilla->params->{memcached_namespace} || '',
+ namespace => $self->{namespace},
});
}
return bless($self, $class);
@@ -129,6 +136,11 @@ sub clear_all {
if (!$memcached->incr("prefix", 1)) {
$memcached->add("prefix", time());
}
+
+ # BMO - log that we've wiped the cache
+ openlog('apache', 'cons,pid', 'local4');
+ syslog('notice', encode_utf8('[memcached] cache cleared'));
+ closelog();
}
# in order to clear all our keys, we add a prefix to all our keys. when we
@@ -155,6 +167,14 @@ sub _prefix {
return $request_cache->{memcached_prefix};
}
+sub _encode_key {
+ my ($self, $key) = @_;
+ $key = $self->_prefix . ':' . uri_escape_utf8($key);
+ return length($self->{namespace} . $key) > MAX_KEY_LENGTH
+ ? undef
+ : $key;
+}
+
sub _set {
my ($self, $key, $value) = @_;
if (blessed($value)) {
@@ -162,13 +182,17 @@ sub _set {
ThrowCodeError('param_invalid', { function => "Bugzilla::Memcached::set",
param => "value" });
}
- return $self->{memcached}->set($self->_prefix . ':' . $key, $value);
+ $key = $self->_encode_key($key)
+ or return;
+ return $self->{memcached}->set($key, $value);
}
sub _get {
my ($self, $key) = @_;
- my $value = $self->{memcached}->get($self->_prefix . ':' . $key);
+ $key = $self->_encode_key($key)
+ or return;
+ my $value = $self->{memcached}->get($key);
return unless defined $value;
# detaint returned values
@@ -187,7 +211,9 @@ sub _get {
sub _delete {
my ($self, $key) = @_;
- return $self->{memcached}->delete($self->_prefix . ':' . $key);
+ $key = $self->_encode_key($key)
+ or return;
+ return $self->{memcached}->delete($key);
}
1;
diff --git a/Bugzilla/Milestone.pm b/Bugzilla/Milestone.pm
index 92bc2192a..a5f3ed383 100644
--- a/Bugzilla/Milestone.pm
+++ b/Bugzilla/Milestone.pm
@@ -121,6 +121,7 @@ sub update {
$dbh->do('UPDATE products SET defaultmilestone = ?
WHERE id = ? AND defaultmilestone = ?',
undef, ($self->name, $self->product_id, $changes->{value}->[0]));
+ Bugzilla->memcached->clear({ table => 'produles', id => $self->product_id });
}
return $changes;
}
diff --git a/Bugzilla/Object.pm b/Bugzilla/Object.pm
index 43d2c07ac..936465b3f 100644
--- a/Bugzilla/Object.pm
+++ b/Bugzilla/Object.pm
@@ -48,9 +48,8 @@ use constant AUDIT_UPDATES => 1;
use constant AUDIT_REMOVES => 1;
# When USE_MEMCACHED is true, the class is suitable for serialisation to
-# Memcached. This will be flipped to true by default once the majority of
-# Bugzilla Object have been tested with Memcached.
-use constant USE_MEMCACHED => 0;
+# Memcached. See documentation in Bugzilla::Memcached for more information.
+use constant USE_MEMCACHED => 1;
# This allows the JSON-RPC interface to return Bugzilla::Object instances
# as though they were hashes. In the future, this may be modified to return
@@ -188,7 +187,20 @@ sub new_from_list {
# their own implementation of match which is not compatible
# with this one. However, match() still needs to have the right $invocant
# in order to do $class->DB_TABLE and so on.
- return match($invocant, { $id_field => \@detainted_ids });
+ my $list = match($invocant, { $id_field => \@detainted_ids });
+
+ # BMO: Populate the object cache with bug objects, which helps
+ # inline-history when viewing bugs with dependencies.
+ if ($class eq 'Bugzilla::Bug') {
+ foreach my $object (@$list) {
+ $class->_object_cache_set(
+ { id => $object->id, cache => 1 },
+ $object
+ );
+ }
+ }
+
+ return $list;
}
sub new_from_hash {
diff --git a/Bugzilla/Search/Recent.pm b/Bugzilla/Search/Recent.pm
index 125850e85..b9f6428d7 100644
--- a/Bugzilla/Search/Recent.pm
+++ b/Bugzilla/Search/Recent.pm
@@ -53,6 +53,9 @@ use constant VALIDATORS => {
use constant UPDATE_COLUMNS => qw(bug_list list_order);
+# There's no gain to caching these objects
+use constant USE_MEMCACHED => 0;
+
###################
# DB Manipulation #
###################
diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm
index 99194112a..536cf39a4 100644
--- a/Bugzilla/Search/Saved.pm
+++ b/Bugzilla/Search/Saved.pm
@@ -199,6 +199,7 @@ sub rename_field_value {
}
$dbh->do("UPDATE $table SET query = ? WHERE $id_field = ?",
undef, $query, $id);
+ Bugzilla->memcached->clear({ table => $table, id => $id });
}
$dbh->bz_commit_transaction();
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index 1c6e68078..0429a25e3 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -305,6 +305,7 @@ sub update_last_seen_date {
# pending changes
$dbh->do("UPDATE profiles SET last_seen_date = ? WHERE userid = ?",
undef, $date, $self->id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $self->id });
}
}
diff --git a/buglist.cgi b/buglist.cgi
index f9cda72ec..57b906949 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -435,6 +435,7 @@ if ($cmdtype eq "dorem") {
$dbh->do('DELETE FROM namedquery_group_map
WHERE namedquery_id = ?',
undef, $query_id);
+ Bugzilla->memcached->clear({ table => 'namedqueries', id => $query_id });
}
# Now reset the cached queries
diff --git a/contrib/merge-users.pl b/contrib/merge-users.pl
index 99fe3fef0..de2fe9ec5 100755
--- a/contrib/merge-users.pl
+++ b/contrib/merge-users.pl
@@ -244,4 +244,9 @@ Bugzilla::Hook::process('merge_users_after', { old_id => $old_id, new_id => $new
# Commit the transaction
$dbh->bz_commit_transaction();
+# It's complex to determine which items now need to be flushed from memcached.
+# As user merge is expected to be a rare event, we just flush the entire cache
+# when users are merged.
+Bugzilla->memcached->clear_all();
+
print "Done.\n";
diff --git a/contrib/reorg-tools/bmo-plan.txt b/contrib/reorg-tools/bmo-plan.txt
deleted file mode 100755
index 838ff0ab9..000000000
--- a/contrib/reorg-tools/bmo-plan.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-==BMO Reorg Plan==
-
-Do the following things, mostly in order (but see "Timing" at the end):
-
-1) Create new classifications using GUI:
- Graveyard (Description: "Old, retired products", sort key: <last>)
-
-2) Rename classifications using GUI:
- Client Support to Other
-
-3) Move products between classification using GUI:
- Grendel from Client Software to Graveyard
- CCK from Unclassified to Graveyard
- Derivatives from Unclassified to Graveyard
- MozillaClassic from Unclassified to Graveyard
- UI: "reclassify" link from the top-level classification list
-
-4) Create new products using GUI:
- Core Graveyard in Graveyard
- (desc: "Old, retired Core components", closed for entry, no charts)
- MailNews Core in Components
- (desc: "Mail and news components common to Thunderbird and SeaMonkey",
- open for bug entry, create charts)
-
-5) Rename products using GUI, and fix queries using fixqueries.pl:
-mysql> update series_categories set name="SeaMonkey (2)" where id=32;
- Mozilla Application Suite to SeaMonkey
- Sumo to support.mozilla.com
-
-5.5) Rename versions and milestones in Toolkit to match Firefox before step 6
-
-6) Sync milestones, versions and groups between products using
-syncmsandversions.pl:
- Core -> Core Graveyard (new)
- Core -> MailNews Core (new)
- Firefox -> Toolkit
- Core -> SeaMonkey
- mozilla.org -> Websites (only 1)
-
-6.5) Sync flag inclusions using syncflags.pl:
- Core -> Core Graveyard (new)
- Core -> MailNews Core (new)
- Core -> SeaMonkey
- mozilla.org -> Websites (only 1)
-
-6.7) Allow Firefox flags temporarily in Toolkit:
- 250 | blocking-firefox3 | blocking1.9 - 387
- 419 | blocking-firefox3.1 | blocking1.9.1 - 416
- 63 | blocking0.8 | blocking1.6 - 69
- 76 | blocking0.9 | blocking1.7 - 83
- 36 | review | review - 4
- 356 | wanted-firefox3 | wanted1.9 - 357
- 418 | wanted-firefox3.1 | wanted1.9.1 - 417
-
-7) Move components using movecomponent.pl.
- Any instruction beginning "moved from".
- Can't fix the queries for this - oh well
- <Very long list>
-
-8) Rename components using GUI, and fix queries using fixqueries.pl.
- Any instruction beginning "renamed from" or "MailNews: prefix removed".
- <Long list>
-
-9) Create new components using GUI.
- Any instruction beginning "new".
- <Long list>
-
-10) Move open bugs using GUI:
- XP Miscellany to Core/General
-
-11) Merge components by moving bugs using GUI:
- Any instruction beginning "merge in".
- Merge all bugs, including closed. Delete empty component when done.
- <long list of merges>
-
-12) Close Core Graveyard (and Grendel if necessary) to new bugs
-
-13) Rename Toolkit versions and milestones back (from 5.5)
-
-14) Execute flag mapping SQL using Reed's mapping to update bugs in Toolkit
-
-15) Disable above-listed flags in point 6.7 in Toolkit again
diff --git a/contrib/reorg-tools/convert_date_time_date.pl b/contrib/reorg-tools/convert_date_time_date.pl
index aa3b58ca1..a2e9bfffc 100755
--- a/contrib/reorg-tools/convert_date_time_date.pl
+++ b/contrib/reorg-tools/convert_date_time_date.pl
@@ -55,4 +55,8 @@ Bugzilla->dbh->bz_alter_column('bugs', $column, { TYPE => 'DATE' });
Bugzilla->dbh->do("UPDATE fielddefs SET type = ? WHERE name = ?",
undef, FIELD_TYPE_DATE, $column);
+# It's complex to determine which items now need to be flushed from memcached.
+# As this is expected to be a rare event, we just flush the entire cache.
+Bugzilla->memcached->clear_all();
+
print "\ndone.\n";
diff --git a/contrib/reorg-tools/fix_all_open_status_queries.pl b/contrib/reorg-tools/fix_all_open_status_queries.pl
index b51ac21c2..7c8d8be68 100755
--- a/contrib/reorg-tools/fix_all_open_status_queries.pl
+++ b/contrib/reorg-tools/fix_all_open_status_queries.pl
@@ -137,4 +137,8 @@ print "Adding new status '$new_status'.\n\n";
do_namedqueries($new_status);
do_series($new_status);
+# It's complex to determine which items now need to be flushed from memcached.
+# As this is expected to be a rare event, we just flush the entire cache.
+Bugzilla->memcached->clear_all();
+
exit(0);
diff --git a/contrib/reorg-tools/fixgroupqueries.pl b/contrib/reorg-tools/fixgroupqueries.pl
index 1c75edb97..0bd64cd40 100755
--- a/contrib/reorg-tools/fixgroupqueries.pl
+++ b/contrib/reorg-tools/fixgroupqueries.pl
@@ -116,4 +116,8 @@ print "Changing all instances of '$old' to '$new'.\n\n";
#do_namedqueries($old, $new);
do_series($old, $new);
+# It's complex to determine which items now need to be flushed from memcached.
+# As this is expected to be a rare event, we just flush the entire cache.
+Bugzilla->memcached->clear_all();
+
exit(0);
diff --git a/contrib/reorg-tools/fixqueries.pl b/contrib/reorg-tools/fixqueries.pl
index 4b862fd72..221213058 100755
--- a/contrib/reorg-tools/fixqueries.pl
+++ b/contrib/reorg-tools/fixqueries.pl
@@ -128,5 +128,9 @@ do_namedqueries($field, $old, $new);
do_series($field, $old, $new);
do_series_categories($old, $new);
+# It's complex to determine which items now need to be flushed from memcached.
+# As this is expected to be a rare event, we just flush the entire cache.
+Bugzilla->memcached->clear_all();
+
exit(0);
diff --git a/contrib/reorg-tools/migrate_crash_signatures.pl b/contrib/reorg-tools/migrate_crash_signatures.pl
index b12446280..4323c1d01 100755
--- a/contrib/reorg-tools/migrate_crash_signatures.pl
+++ b/contrib/reorg-tools/migrate_crash_signatures.pl
@@ -123,4 +123,10 @@ foreach my $bug (@$bugs) {
print "done.\n";
}
-$dbh->bz_commit_transaction() if $UPDATE_DB;
+if ($UPDATE_DB) {
+ $dbh->bz_commit_transaction();
+
+ # It's complex to determine which items now need to be flushed from memcached.
+ # As this is expected to be a rare event, we just flush the entire cache.
+ Bugzilla->memcached->clear_all();
+}
diff --git a/contrib/reorg-tools/migrate_orange_bugs.pl b/contrib/reorg-tools/migrate_orange_bugs.pl
index ae68b227c..4902464a3 100755
--- a/contrib/reorg-tools/migrate_orange_bugs.pl
+++ b/contrib/reorg-tools/migrate_orange_bugs.pl
@@ -145,6 +145,10 @@ foreach my $bug (@$bugs) {
$dbh->bz_commit_transaction() if $doit;
if ($doit) {
+ # It's complex to determine which items now need to be flushed from memcached.
+ # As this is expected to be a rare event, we just flush the entire cache.
+ Bugzilla->memcached->clear_all();
+
print colored(['green'], "DATABASE WAS UPDATED\n");
}
else {
diff --git a/contrib/reorg-tools/move_flag_types.pl b/contrib/reorg-tools/move_flag_types.pl
index a75b7f497..7b7fe2081 100755
--- a/contrib/reorg-tools/move_flag_types.pl
+++ b/contrib/reorg-tools/move_flag_types.pl
@@ -162,6 +162,10 @@ if (@$flags) {
$flag_update_sth->execute($params{'newid'}, $flag_id);
}
}
+
+ # It's complex to determine which items now need to be flushed from memcached.
+ # As this is expected to be a rare event, we just flush the entire cache.
+ Bugzilla->memcached->clear_all();
}
else {
print "No flags to move\n";
diff --git a/contrib/reorg-tools/movebugs.pl b/contrib/reorg-tools/movebugs.pl
index adc02a1e0..b9acc2443 100755
--- a/contrib/reorg-tools/movebugs.pl
+++ b/contrib/reorg-tools/movebugs.pl
@@ -173,3 +173,7 @@ Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => $ra_ids } );
$dbh->bz_commit_transaction();
+foreach my $bug_id (@$ra_ids) {
+ Bugzilla->memcached->clear({ table => 'bugs', id => $bug_id });
+}
+
diff --git a/contrib/reorg-tools/movecomponent.pl b/contrib/reorg-tools/movecomponent.pl
index 702dbc6f0..162942627 100755
--- a/contrib/reorg-tools/movecomponent.pl
+++ b/contrib/reorg-tools/movecomponent.pl
@@ -193,4 +193,13 @@ $dbh->do("INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed,
($userid, $fieldid, $oldproduct, $newproduct, $compid));
Bugzilla::Hook::process('reorg_move_bugs', { bug_ids => $ra_ids } ) if $doit;
-$dbh->bz_commit_transaction() if $doit;
+
+if ($doit) {
+ $dbh->bz_commit_transaction();
+
+ # It's complex to determine which items now need to be flushed from memcached.
+ # As this is expected to be a rare event, we just flush the entire cache.
+ Bugzilla->memcached->clear_all();
+}
+
+
diff --git a/contrib/reorg-tools/reset_default_user.pl b/contrib/reorg-tools/reset_default_user.pl
index 42a7998de..173d03849 100755
--- a/contrib/reorg-tools/reset_default_user.pl
+++ b/contrib/reorg-tools/reset_default_user.pl
@@ -136,6 +136,8 @@ foreach my $bug (@$bugs) {
$dbh->do("UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?",
undef, $timestamp, $timestamp, $bug_id);
+ Bugzilla->memcached->clear({ table => 'bugs', id => $bug_id });
+
print "done.\n";
}
}
diff --git a/editclassifications.cgi b/editclassifications.cgi
index db9dd7f0a..817c53af7 100755
--- a/editclassifications.cgi
+++ b/editclassifications.cgi
@@ -198,9 +198,10 @@ if ($action eq 'update') {
if ($action eq 'reclassify') {
my $classification = Bugzilla::Classification->check($class_name);
-
+
my $sth = $dbh->prepare("UPDATE products SET classification_id = ?
WHERE name = ?");
+ my @names;
if (defined $cgi->param('add_products')) {
check_token_data($token, 'reclassify_classifications');
@@ -208,6 +209,7 @@ if ($action eq 'reclassify') {
foreach my $prod ($cgi->param("prodlist")) {
trick_taint($prod);
$sth->execute($classification->id, $prod);
+ push @names, $prod;
}
}
delete_token($token);
@@ -216,7 +218,8 @@ if ($action eq 'reclassify') {
if (defined $cgi->param('myprodlist')) {
foreach my $prod ($cgi->param("myprodlist")) {
trick_taint($prod);
- $sth->execute(1,$prod);
+ $sth->execute(1, $prod);
+ push @names, $prod;
}
}
delete_token($token);
@@ -226,6 +229,10 @@ if ($action eq 'reclassify') {
$vars->{'classification'} = $classification;
$vars->{'token'} = issue_session_token('reclassify_classifications');
+ foreach my $name (@names) {
+ Bugzilla->memcached->clear({ table => 'products', name => $name });
+ }
+
LoadTemplate($action);
}
diff --git a/editusers.cgi b/editusers.cgi
index a6a93c41e..b92ace507 100755
--- a/editusers.cgi
+++ b/editusers.cgi
@@ -646,6 +646,11 @@ if ($action eq 'search') {
$dbh->bz_commit_transaction();
delete_token($token);
+ # It's complex to determine which items now need to be flushed from
+ # memcached. As user deletion is expected to be a rare event, we just
+ # flush the entire cache when a user is deleted.
+ Bugzilla->memcached->clear_all();
+
$vars->{'message'} = 'account_deleted';
$vars->{'otheruser'}{'login'} = $otherUser->login;
$vars->{'restrictablegroups'} = $user->bless_groups();
diff --git a/extensions/ContributorEngagement/Extension.pm b/extensions/ContributorEngagement/Extension.pm
index 0e86eb4ca..aa8804034 100644
--- a/extensions/ContributorEngagement/Extension.pm
+++ b/extensions/ContributorEngagement/Extension.pm
@@ -39,6 +39,7 @@ sub install_update_db {
_populate_first_reviewed_ids();
}
}
+
sub _populate_first_reviewed_ids {
my $dbh = Bugzilla->dbh;
@@ -96,6 +97,7 @@ sub flag_end_of_update {
Bugzilla->dbh->do("UPDATE profiles SET first_patch_reviewed_id = ? WHERE userid = ?",
undef, $attachment->id, $attachment->attacher->id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $$attachment->attacher->id });
last;
}
}
diff --git a/extensions/EditComments/Extension.pm b/extensions/EditComments/Extension.pm
index 7396c6f28..a3769544f 100644
--- a/extensions/EditComments/Extension.pm
+++ b/extensions/EditComments/Extension.pm
@@ -226,6 +226,7 @@ sub bug_end_of_update {
$dbh->do("UPDATE longdescs SET thetext = ?, edit_count = edit_count + 1
WHERE comment_id = ?",
undef, $new_comment, $comment_id);
+ Bugzilla->memcached->clear({ table => 'longdescs', id => $comment_id });
# Log old comment to the longdescs activity table
$timestamp ||= $dbh->selectrow_array("SELECT NOW()");
diff --git a/extensions/FlagDefaultRequestee/Extension.pm b/extensions/FlagDefaultRequestee/Extension.pm
index 9c15f741a..0ab599cd3 100644
--- a/extensions/FlagDefaultRequestee/Extension.pm
+++ b/extensions/FlagDefaultRequestee/Extension.pm
@@ -121,6 +121,7 @@ sub _set_default_requestee {
$dbh->do("UPDATE flagtypes SET default_requestee = ? WHERE id = ?",
undef, $requestee_id, $type->id);
+ Bugzilla->memcached->clear({ table => 'flagtypes', id => $type->id });
}
##################
diff --git a/extensions/Push/lib/BacklogMessage.pm b/extensions/Push/lib/BacklogMessage.pm
index 8f5263038..cd40ebefb 100644
--- a/extensions/Push/lib/BacklogMessage.pm
+++ b/extensions/Push/lib/BacklogMessage.pm
@@ -15,6 +15,7 @@ use base 'Bugzilla::Object';
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
use constant AUDIT_REMOVES => 0;
+use constant USE_MEMCACHED => 0;
use Bugzilla;
use Bugzilla::Error;
diff --git a/extensions/Push/lib/Backoff.pm b/extensions/Push/lib/Backoff.pm
index 05ee0a775..55552e5e1 100644
--- a/extensions/Push/lib/Backoff.pm
+++ b/extensions/Push/lib/Backoff.pm
@@ -15,6 +15,7 @@ use base 'Bugzilla::Object';
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
use constant AUDIT_REMOVES => 0;
+use constant USE_MEMCACHED => 0;
use Bugzilla;
use Bugzilla::Util;
diff --git a/extensions/Push/lib/LogEntry.pm b/extensions/Push/lib/LogEntry.pm
index 303c19da4..848df0480 100644
--- a/extensions/Push/lib/LogEntry.pm
+++ b/extensions/Push/lib/LogEntry.pm
@@ -15,6 +15,7 @@ use base 'Bugzilla::Object';
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
use constant AUDIT_REMOVES => 0;
+use constant USE_MEMCACHED => 0;
use Bugzilla;
use Bugzilla::Error;
diff --git a/extensions/Push/lib/Message.pm b/extensions/Push/lib/Message.pm
index ebe32d0ea..6d2ed2531 100644
--- a/extensions/Push/lib/Message.pm
+++ b/extensions/Push/lib/Message.pm
@@ -15,6 +15,7 @@ use base 'Bugzilla::Object';
use constant AUDIT_CREATES => 0;
use constant AUDIT_UPDATES => 0;
use constant AUDIT_REMOVES => 0;
+use constant USE_MEMCACHED => 0;
use Bugzilla;
use Bugzilla::Error;
diff --git a/extensions/Review/Extension.pm b/extensions/Review/Extension.pm
index c92d17d8b..b495c9ecd 100644
--- a/extensions/Review/Extension.pm
+++ b/extensions/Review/Extension.pm
@@ -273,6 +273,7 @@ sub _adjust_request_count {
undef,
$requestee_id
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $requestee_id });
}
sub _new_reviewers_from_input {
diff --git a/extensions/Review/lib/Util.pm b/extensions/Review/lib/Util.pm
index 7304f9ba6..83589e2d0 100644
--- a/extensions/Review/lib/Util.pm
+++ b/extensions/Review/lib/Util.pm
@@ -58,6 +58,7 @@ sub _update_profile {
$data->{needinfo} || 0,
$data->{id}
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $data->{id} });
}
1;
diff --git a/extensions/TagNewUsers/Extension.pm b/extensions/TagNewUsers/Extension.pm
index 599504225..7f12445fb 100644
--- a/extensions/TagNewUsers/Extension.pm
+++ b/extensions/TagNewUsers/Extension.pm
@@ -168,6 +168,7 @@ sub _update_comment_count {
'UPDATE profiles SET comment_count=? WHERE userid=?',
undef, $count, $id
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $id });
$self->{comment_count} = $count;
}
@@ -179,6 +180,7 @@ sub _first_patch_bug_id {
'UPDATE profiles SET first_patch_bug_id=? WHERE userid=?',
undef, $bug_id, $self->id
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $self->id });
$self->{first_patch_bug_id} = $bug_id;
}
diff --git a/extensions/UserProfile/Extension.pm b/extensions/UserProfile/Extension.pm
index 673c0c2a1..efd83591d 100644
--- a/extensions/UserProfile/Extension.pm
+++ b/extensions/UserProfile/Extension.pm
@@ -45,6 +45,7 @@ sub _user_set_last_activity_ts {
"UPDATE profiles SET last_activity_ts = ? WHERE userid = ?",
undef,
$value, $self->id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $self->id });
}
sub _user_clear_last_statistics_ts {
@@ -56,6 +57,7 @@ sub _user_clear_last_statistics_ts {
"UPDATE profiles SET last_statistics_ts = NULL WHERE userid = ?",
undef,
$self->id);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $self->id });
}
#
diff --git a/extensions/UserProfile/bin/update.pl b/extensions/UserProfile/bin/update.pl
index 457585f8d..2a4997aee 100755
--- a/extensions/UserProfile/bin/update.pl
+++ b/extensions/UserProfile/bin/update.pl
@@ -50,6 +50,7 @@ if (@$user_ids) {
last_user_activity($user_id),
$user_id
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $user_id });
}
$dbh->do(
"DELETE FROM profiles_statistics_recalc WHERE " . $dbh->sql_in('user_id', $user_ids)
diff --git a/extensions/UserProfile/lib/Util.pm b/extensions/UserProfile/lib/Util.pm
index b5550bdc1..71d0e6501 100644
--- a/extensions/UserProfile/lib/Util.pm
+++ b/extensions/UserProfile/lib/Util.pm
@@ -171,6 +171,9 @@ EOF
$dbh->do(
"UPDATE profiles SET last_statistics_ts=NULL WHERE " . $dbh->sql_in('userid', $user_ids)
);
+ foreach my $id (@$user_ids) {
+ Bugzilla->memcached->clear({ table => 'profiles', id => $id });
+ }
return scalar(@$user_ids);
}
@@ -209,6 +212,7 @@ sub _set_last_statistics_ts {
undef,
$timestamp, $user_id,
);
+ Bugzilla->memcached->clear({ table => 'profiles', id => $user_id });
}
sub _update_statistics {
diff --git a/query.cgi b/query.cgi
index 26c26049d..a05d4034b 100755
--- a/query.cgi
+++ b/query.cgi
@@ -32,6 +32,7 @@ use Bugzilla;
use Bugzilla::Bug;
use Bugzilla::Constants;
use Bugzilla::Search;
+use Bugzilla::Search::Saved;
use Bugzilla::User;
use Bugzilla::Util;
use Bugzilla::Error;
@@ -54,9 +55,11 @@ if ($cgi->param('nukedefaultquery')) {
if ($userid) {
my $token = $cgi->param('token');
check_hash_token($token, ['nukedefaultquery']);
- $dbh->do("DELETE FROM namedqueries" .
- " WHERE userid = ? AND name = ?",
- undef, ($userid, DEFAULT_QUERY_NAME));
+ my $named_queries = Bugzilla::Search::Saved->match(
+ { userid => $userid, name => DEFAULT_QUERY_NAME });
+ if (@$named_queries) {
+ $named_queries->[0]->remove_from_db();
+ }
}
$buffer = "";
}
diff --git a/sanitycheck.cgi b/sanitycheck.cgi
index 36751d821..f718312f4 100755
--- a/sanitycheck.cgi
+++ b/sanitycheck.cgi
@@ -91,6 +91,7 @@ else {
}
}
my $vars = {};
+my $clear_memcached = 0;
print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_CMDLINE;
@@ -167,6 +168,7 @@ if ($cgi->param('createmissinggroupcontrolmapentries')) {
}
Status('group_control_map_entries_repaired', {counter => $counter});
+ $clear_memcached = 1 if $counter;
}
###########################################################################
@@ -193,6 +195,7 @@ if ($cgi->param('repair_creation_date')) {
$sth_UpdateDate->execute($date, $bugid);
}
Status('bug_creation_date_fixed', {bug_count => scalar(@$bug_ids)});
+ $clear_memcached = 1 if @$bug_ids;
}
###########################################################################
@@ -209,6 +212,7 @@ if ($cgi->param('repair_everconfirmed')) {
$dbh->do("UPDATE bugs SET everconfirmed = 1 WHERE bug_status IN ($confirmed_open_states)");
Status('everconfirmed_end');
+ $clear_memcached = 1;
}
###########################################################################
@@ -224,11 +228,12 @@ if ($cgi->param('repair_bugs_fulltext')) {
ON bugs_fulltext.bug_id = bugs.bug_id
WHERE bugs_fulltext.bug_id IS NULL');
- foreach my $bugid (@$bug_ids) {
- Bugzilla::Bug->new($bugid)->_sync_fulltext( new_bug => 1 );
- }
+ foreach my $bugid (@$bug_ids) {
+ Bugzilla::Bug->new($bugid)->_sync_fulltext( new_bug => 1 );
+ }
- Status('bugs_fulltext_fixed', {bug_count => scalar(@$bug_ids)});
+ Status('bugs_fulltext_fixed', {bug_count => scalar(@$bug_ids)});
+ $clear_memcached = 1 if @$bug_ids;
}
###########################################################################
@@ -264,7 +269,10 @@ if ($cgi->param('rescanallBugMail')) {
Bugzilla::BugMail::Send($bugid, $vars);
}
- Status('send_bugmail_end') if scalar(@$list);
+ if (@$list) {
+ Status('send_bugmail_end');
+ Bugzilla->memcached->clear_all();
+ }
unless (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
$template->process('global/footer.html.tmpl', $vars)
@@ -298,6 +306,7 @@ if ($cgi->param('remove_invalid_bug_references')) {
if (scalar(@$bug_ids)) {
$dbh->do("DELETE FROM $table WHERE $field IN (" . join(',', @$bug_ids) . ")");
+ $clear_memcached = 1;
}
}
@@ -328,6 +337,7 @@ if ($cgi->param('remove_invalid_attach_references')) {
$dbh->bz_commit_transaction();
Status('attachment_reference_deletion_end');
+ $clear_memcached = 1 if @$attach_ids;
}
###########################################################################
@@ -354,12 +364,17 @@ if ($cgi->param('remove_old_whine_targets')) {
$dbh->do("DELETE FROM whine_schedules
WHERE mailto_type = $type AND mailto IN (" .
join(',', @$old_ids) . ")");
+ $clear_memcached = 1;
}
}
$dbh->bz_commit_transaction();
Status('whines_obsolete_target_deletion_end');
}
+# If any repairs were attempted or made, we need to clear memcached to ensure
+# state is consistent.
+Bugzilla->memcached->clear_all() if $clear_memcached;
+
###########################################################################
# Repair hook
###########################################################################
@@ -735,6 +750,7 @@ if (scalar(@invalid_flags)) {
# Silently delete these flags, with no notification to requesters/setters.
$dbh->do('DELETE FROM flags WHERE id IN (' . join(',', @flag_ids) .')');
Status('flag_deletion_end');
+ Bugzilla->memcached->clear_all();
}
else {
foreach my $flag (@$invalid_flags) {
diff --git a/userprefs.cgi b/userprefs.cgi
index b0969b93d..4ba0fd906 100755
--- a/userprefs.cgi
+++ b/userprefs.cgi
@@ -511,12 +511,13 @@ sub SaveSavedSearches {
}
$user->flush_queries_cache;
-
+
# Update profiles.mybugslink.
my $showmybugslink = defined($cgi->param("showmybugslink")) ? 1 : 0;
$dbh->do("UPDATE profiles SET mybugslink = ? WHERE userid = ?",
- undef, ($showmybugslink, $user->id));
+ undef, ($showmybugslink, $user->id));
$user->{'showmybugslink'} = $showmybugslink;
+ Bugzilla->memcached->clear({ table => 'profiles', id => $user->id });
}