summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rwxr-xr-xcontrib/convert-workflow.pl49
1 files changed, 46 insertions, 3 deletions
diff --git a/contrib/convert-workflow.pl b/contrib/convert-workflow.pl
index 60029f67a..3dce21f12 100755
--- a/contrib/convert-workflow.pl
+++ b/contrib/convert-workflow.pl
@@ -20,7 +20,6 @@
# Max Kanat-Alexander <mkanat@bugzilla.org>
use strict;
-use warnings;
use lib qw(. lib);
use Bugzilla;
@@ -82,6 +81,8 @@ $dbh->bz_start_transaction();
foreach my $pair (@translation) {
my ($from, $to) = @$pair;
print "Converting $from to $to...\n";
+ # There is no FK on bugs.bug_status pointing to bug_status.value,
+ # so it's fine to update the bugs table first.
$dbh->do('UPDATE bugs SET bug_status = ? WHERE bug_status = ?',
undef, $to, $from);
@@ -103,11 +104,53 @@ foreach my $pair (@translation) {
# If the new status already exists, just delete the old one, but retain
# the workflow items from it.
- if (my $existing = new Bugzilla::Status({ name => $to })) {
+ my $new_status = new Bugzilla::Status({ name => $to });
+ my $old_status = new Bugzilla::Status({ name => $from });
+
+ if ($new_status && $old_status) {
+ my $to_id = $new_status->id;
+ my $from_id = $old_status->id;
+ # The subselect collects existing transitions from the target bug status.
+ # The main select collects existing transitions from the renamed bug status.
+ # The diff tells us which transitions are missing from the target bug status.
+ my $missing_transitions =
+ $dbh->selectcol_arrayref('SELECT sw1.new_status
+ FROM status_workflow sw1
+ WHERE sw1.old_status = ?
+ AND sw1.new_status NOT IN (SELECT sw2.new_status
+ FROM status_workflow sw2
+ WHERE sw2.old_status = ?)',
+ undef, ($from_id, $to_id));
+
+ $dbh->do('UPDATE status_workflow SET old_status = ? WHERE old_status = ? AND '
+ . $dbh->sql_in('new_status', $missing_transitions),
+ undef, ($to_id, $from_id)) if @$missing_transitions;
+
+ # The subselect collects existing transitions to the target bug status.
+ # The main select collects existing transitions to the renamed bug status.
+ # The diff tells us which transitions are missing to the target bug status.
+ # We have to explicitly exclude NULL from the subselect, because NOT IN
+ # doesn't know what to do with it (neither true nor false) and no data is returned.
+ $missing_transitions =
+ $dbh->selectcol_arrayref('SELECT sw1.old_status
+ FROM status_workflow sw1
+ WHERE sw1.new_status = ?
+ AND sw1.old_status NOT IN (SELECT sw2.old_status
+ FROM status_workflow sw2
+ WHERE sw2.new_status = ?
+ AND sw2.old_status IS NOT NULL)',
+ undef, ($from_id, $to_id));
+
+ $dbh->do('UPDATE status_workflow SET new_status = ? WHERE new_status = ? AND '
+ . $dbh->sql_in('old_status', $missing_transitions),
+ undef, ($to_id, $from_id)) if @$missing_transitions;
+
+ # Delete rows where old_status = new_status, and then the old status itself.
+ $dbh->do('DELETE FROM status_workflow WHERE old_status = new_status');
$dbh->do('DELETE FROM bug_status WHERE value = ?', undef, $from);
}
# Otherwise, rename the old status to the new one.
- else {
+ elsif ($old_status) {
$dbh->do('UPDATE bug_status SET value = ? WHERE value = ?',
undef, $to, $from);
}