summaryrefslogtreecommitdiffstats
path: root/contrib/merge-users.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/merge-users.pl')
-rwxr-xr-xcontrib/merge-users.pl31
1 files changed, 31 insertions, 0 deletions
diff --git a/contrib/merge-users.pl b/contrib/merge-users.pl
index ee6ec8628..aeb8156ad 100755
--- a/contrib/merge-users.pl
+++ b/contrib/merge-users.pl
@@ -50,6 +50,7 @@ use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Util;
use Bugzilla::User;
+use Bugzilla::Hook;
use Getopt::Long;
use Pod::Usage;
@@ -156,10 +157,32 @@ foreach my $table (qw(logincookies tokens profiles)) {
# Start the transaction
$dbh->bz_start_transaction();
+# BMO - pre-work hook
+Bugzilla::Hook::process('merge_users_before', { old_id => $old_id, new_id => $new_id });
+
# Delete old records from logincookies and tokens tables.
$dbh->do('DELETE FROM logincookies WHERE userid = ?', undef, $old_id);
$dbh->do('DELETE FROM tokens WHERE userid = ?', undef, $old_id);
+# Special care needs to be done with bug_user_last_visit table as the
+# source user and destination user may have visited the same bug id at one time.
+# In this case we remove the one with the oldest timestamp.
+my $dupe_ids = $dbh->selectcol_arrayref("
+ SELECT earlier.id
+ FROM bug_user_last_visit as earlier
+ INNER JOIN bug_user_last_visit as later
+ ON (earlier.user_id != later.user_id
+ AND earlier.last_visit_ts < later.last_visit_ts
+ AND earlier.bug_id = later.bug_id)
+ WHERE (earlier.user_id = ? OR earlier.user_id = ?)
+ AND (later.user_id = ? OR later.user_id = ?)",
+ undef, $old_id, $new_id, $old_id, $new_id);
+
+if (@$dupe_ids) {
+ $dbh->do("DELETE FROM bug_user_last_visit WHERE " .
+ $dbh->sql_in('id', $dupe_ids));
+}
+
# Migrate records from old user to new user.
foreach my $table (keys %changes) {
foreach my $column_list (@{ $changes{$table} }) {
@@ -234,7 +257,15 @@ $dbh->do('DELETE FROM profiles WHERE userid = ?', undef, $old_id);
my $user = new Bugzilla::User($new_id);
$user->derive_regexp_groups();
+# BMO - post-work hook
+Bugzilla::Hook::process('merge_users_after', { old_id => $old_id, new_id => $new_id });
+
# 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";