summaryrefslogtreecommitdiffstats
path: root/extensions/TrackingFlags/bin/bulk_flag_clear.pl
blob: 470269f132f7c38931a7cb965534cf9c15ad6ac0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/perl
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

use strict;
use warnings;
use 5.10.1;

use lib qw(. lib local/lib/perl5);

BEGIN {
  use Bugzilla;
  Bugzilla->extensions;
}

use Bugzilla::Constants;
use Bugzilla::Extension::TrackingFlags::Flag;
use Bugzilla::Extension::TrackingFlags::Flag::Bug;
use Bugzilla::User;

use Getopt::Long;

Bugzilla->usage_mode(USAGE_MODE_CMDLINE);

my $config = {};
GetOptions($config, "trace=i", "update_db", "flag=s", "modified_before=s",
  "modified_after=s", "value=s")
  or exit;
unless ($config->{flag}
  && ($config->{modified_before} || $config->{modified_after} || $config->{value})
  )
{
  die <<EOF;
$0
  clears tracking flags matching the specified criteria.
  the last-modified will be updated, however bugmail will not be generated.

SYNTAX
  $0 --flag <flag> (conditions) [--update_db]

CONDITIONS
  --modified_before <datetime>      bug last-modified before <datetime>
  --modified_after <datetime>       bug last-modified after <datetime>
  --value <flag value>              flag = <flag value>

OPTIONS
  --update_db : by default only the impacted bugs will be listed.  pass this
                switch to update the database.
EOF
}

# build sql

my (@where, @values);

my $flag
  = Bugzilla::Extension::TrackingFlags::Flag->check({name => $config->{flag}});
push @where,  'tracking_flags_bugs.tracking_flag_id = ?';
push @values, $flag->flag_id;

if ($config->{modified_before}) {
  push @where,  'bugs.delta_ts < ?';
  push @values, $config->{modified_before};
}

if ($config->{modified_after}) {
  push @where,  'bugs.delta_ts > ?';
  push @values, $config->{modified_after};
}

if ($config->{value}) {
  push @where,  'tracking_flags_bugs.value = ?';
  push @values, $config->{value};
}

my $sql = "
    SELECT tracking_flags_bugs.bug_id
      FROM tracking_flags_bugs
           INNER JOIN bugs ON bugs.bug_id = tracking_flags_bugs.bug_id
     WHERE (" . join(") AND (", @where) . ")
     ORDER BY tracking_flags_bugs.bug_id
";

# execute query

my $dbh = Bugzilla->dbh;
$dbh->{TraceLevel} = $config->{trace} if $config->{trace};

my $bug_ids = $dbh->selectcol_arrayref($sql, undef, @values);

if (!@$bug_ids) {
  die "no matching bugs found\n";
}

if (!$config->{update_db}) {
  print "bugs found: ", scalar(@$bug_ids), "\n\n", join(',', @$bug_ids), "\n\n";
  print "--update_db not provided, no changes made to the database\n";
  exit;
}

# update bugs

my $nobody = Bugzilla::User->check({name => Bugzilla->params->{'nobody_user'}});

# put our nobody user into all groups to avoid permissions issues
$nobody->{groups} = [Bugzilla::Group->get_all];
Bugzilla->set_user($nobody);

foreach my $bug_id (@$bug_ids) {
  print "updating bug $bug_id\n";
  $dbh->bz_start_transaction;

  # update the bug
  # this will deal with history for us but not send bugmail
  my $bug = Bugzilla::Bug->check({id => $bug_id});
  $bug->set_all({$flag->name => '---'});
  $bug->update;

  # update lastdiffed to skip bugmail for this change
  $dbh->do("UPDATE bugs SET lastdiffed = delta_ts WHERE bug_id = ?",
    undef, $bug->id);
  $dbh->bz_commit_transaction;
}