aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2019-11-30 23:12:11 -0800
committerRobin H. Johnson <robbat2@gentoo.org>2019-12-01 14:53:51 -0800
commit70780e40e5586c6882e33dd65a3dc3f31031a321 (patch)
tree51fc3608bd44e7b92d07a976ca3112fd5d87d843 /contrib
parentMerge commit '3395d78cc8b0bd660e56f73a2689d495f2a22628' into bugstest (diff)
downloadbugzilla-70780e40e5586c6882e33dd65a3dc3f31031a321.tar.gz
bugzilla-70780e40e5586c6882e33dd65a3dc3f31031a321.tar.bz2
bugzilla-70780e40e5586c6882e33dd65a3dc3f31031a321.zip
Gentoo-local version of 7f3a749d7bd78a3e4aee163f562d7e95b0954b44 w/ Perl-Tidy-20180220
Reformat all code using Perl-Tidy v20180220 and .perltidyrc from matching upstream 7f3a749d7bd78a3e4aee163f562d7e95b0954b44 commit. Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/Bugzilla.pm2
-rwxr-xr-xcontrib/bz_webservice_demo.pl239
-rwxr-xr-xcontrib/bzdbcopy.pl306
-rwxr-xr-xcontrib/console.pl157
-rwxr-xr-xcontrib/convert-workflow.pl178
-rwxr-xr-xcontrib/extension-convert.pl304
-rwxr-xr-xcontrib/merge-users.pl204
-rwxr-xr-xcontrib/mysqld-watcher.pl93
-rwxr-xr-xcontrib/recode.pl315
-rwxr-xr-xcontrib/sendbugmail.pl35
-rwxr-xr-xcontrib/sendunsentbugmail.pl38
-rwxr-xr-xcontrib/syncLDAP.pl377
12 files changed, 1175 insertions, 1073 deletions
diff --git a/contrib/Bugzilla.pm b/contrib/Bugzilla.pm
index 31e0a0f6d..e7452bbb8 100644
--- a/contrib/Bugzilla.pm
+++ b/contrib/Bugzilla.pm
@@ -36,7 +36,7 @@ use warnings;
#######################################################################
use constant BZ_ROOT_DIR => '/usr/share/bugzilla/lib';
-use constant BZ_LIB_DIR => BZ_ROOT_DIR . '/lib';
+use constant BZ_LIB_DIR => BZ_ROOT_DIR . '/lib';
#######################################################################
# DO NOT EDIT THE CODE BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING!! #
diff --git a/contrib/bz_webservice_demo.pl b/contrib/bz_webservice_demo.pl
index 6c8c21dfa..bf6d504ad 100755
--- a/contrib/bz_webservice_demo.pl
+++ b/contrib/bz_webservice_demo.pl
@@ -50,21 +50,22 @@ my $work_time;
my $fetch_extension_info = 0;
my $debug;
-GetOptions('help|h|?' => \$help,
- 'uri=s' => \$Bugzilla_uri,
- 'login:s' => \$Bugzilla_login,
- 'password=s' => \$Bugzilla_password,
- 'restrictlogin!' => \$Bugzilla_restrict,
- 'bug_id:s' => \$bug_id,
- 'product_name:s' => \$product_name,
- 'create:s' => \$create_file_name,
- 'field:s' => \$legal_field_values,
- 'comment:s' => \$add_comment,
- 'private:i' => \$private,
- 'worktime:f' => \$work_time,
- 'extension_info' => \$fetch_extension_info,
- 'debug' => \$debug
- ) or pod2usage({'-verbose' => 0, '-exitval' => 1});
+GetOptions(
+ 'help|h|?' => \$help,
+ 'uri=s' => \$Bugzilla_uri,
+ 'login:s' => \$Bugzilla_login,
+ 'password=s' => \$Bugzilla_password,
+ 'restrictlogin!' => \$Bugzilla_restrict,
+ 'bug_id:s' => \$bug_id,
+ 'product_name:s' => \$product_name,
+ 'create:s' => \$create_file_name,
+ 'field:s' => \$legal_field_values,
+ 'comment:s' => \$add_comment,
+ 'private:i' => \$private,
+ 'worktime:f' => \$work_time,
+ 'extension_info' => \$fetch_extension_info,
+ 'debug' => \$debug
+) or pod2usage({'-verbose' => 0, '-exitval' => 1});
=head1 OPTIONS
@@ -171,7 +172,7 @@ Enable tracing at the debug level of XMLRPC requests and responses if requested.
=cut
if ($debug) {
- $proxy->import(+trace => 'debug');
+ $proxy->import(+trace => 'debug');
}
=head2 Checking Bugzilla's version
@@ -184,7 +185,8 @@ minimum required version your application needs.
$soapresult = $proxy->call('Bugzilla.version');
_die_on_fault($soapresult);
-print 'Connecting to a Bugzilla of version ' . $soapresult->result()->{version} . ".\n";
+print 'Connecting to a Bugzilla of version '
+ . $soapresult->result()->{version} . ".\n";
=head2 Checking Bugzilla's timezone
@@ -217,22 +219,27 @@ parameter).
=cut
if (defined($Bugzilla_login)) {
- if ($Bugzilla_login ne '') {
- # Log in.
- $soapresult = $proxy->call('User.login',
- { login => $Bugzilla_login,
- password => $Bugzilla_password,
- restrict_login => $Bugzilla_restrict } );
- $Bugzilla_token = $soapresult->result->{token};
- _die_on_fault($soapresult);
- print "Login successful.\n";
- }
- else {
- # Log out.
- $soapresult = $proxy->call('User.logout');
- _die_on_fault($soapresult);
- print "Logout successful.\n";
- }
+ if ($Bugzilla_login ne '') {
+
+ # Log in.
+ $soapresult = $proxy->call(
+ 'User.login',
+ {
+ login => $Bugzilla_login,
+ password => $Bugzilla_password,
+ restrict_login => $Bugzilla_restrict
+ }
+ );
+ $Bugzilla_token = $soapresult->result->{token};
+ _die_on_fault($soapresult);
+ print "Login successful.\n";
+ }
+ else {
+ # Log out.
+ $soapresult = $proxy->call('User.logout');
+ _die_on_fault($soapresult);
+ print "Logout successful.\n";
+ }
}
=head2 Getting Extension Information
@@ -242,16 +249,16 @@ Returns all the information any extensions have decided to provide to the webser
=cut
if ($fetch_extension_info) {
- $soapresult = $proxy->call('Bugzilla.extensions', {token => $Bugzilla_token});
- _die_on_fault($soapresult);
- my $extensions = $soapresult->result()->{extensions};
- foreach my $extensionname (keys(%$extensions)) {
- print "Extension '$extensionname' information\n";
- my $extension = $extensions->{$extensionname};
- foreach my $data (keys(%$extension)) {
- print ' ' . $data . ' => ' . $extension->{$data} . "\n";
- }
+ $soapresult = $proxy->call('Bugzilla.extensions', {token => $Bugzilla_token});
+ _die_on_fault($soapresult);
+ my $extensions = $soapresult->result()->{extensions};
+ foreach my $extensionname (keys(%$extensions)) {
+ print "Extension '$extensionname' information\n";
+ my $extension = $extensions->{$extensionname};
+ foreach my $data (keys(%$extension)) {
+ print ' ' . $data . ' => ' . $extension->{$data} . "\n";
}
+ }
}
=head2 Retrieving Bug Information
@@ -262,21 +269,22 @@ The call will return a C<Bugzilla::Bug> object.
=cut
if ($bug_id) {
- $soapresult = $proxy->call('Bug.get', { ids => [$bug_id], token => $Bugzilla_token});
- _die_on_fault($soapresult);
- $result = $soapresult->result;
- my $bug = $result->{bugs}->[0];
- foreach my $field (keys(%$bug)) {
- my $value = $bug->{$field};
- if (ref($value) eq 'HASH') {
- foreach (keys %$value) {
- print "$_: " . $value->{$_} . "\n";
- }
- }
- else {
- print "$field: $value\n";
- }
+ $soapresult
+ = $proxy->call('Bug.get', {ids => [$bug_id], token => $Bugzilla_token});
+ _die_on_fault($soapresult);
+ $result = $soapresult->result;
+ my $bug = $result->{bugs}->[0];
+ foreach my $field (keys(%$bug)) {
+ my $value = $bug->{$field};
+ if (ref($value) eq 'HASH') {
+ foreach (keys %$value) {
+ print "$_: " . $value->{$_} . "\n";
+ }
}
+ else {
+ print "$field: $value\n";
+ }
+ }
}
=head2 Retrieving Product Information
@@ -287,27 +295,28 @@ The call will return a C<Bugzilla::Product> object.
=cut
if ($product_name) {
- $soapresult = $proxy->call('Product.get', {'names' => [$product_name], token => $Bugzilla_token});
- _die_on_fault($soapresult);
- $result = $soapresult->result()->{'products'}->[0];
-
- # Iterate all entries, the values may be scalars or array refs with hash refs.
- foreach my $key (sort(keys %$result)) {
- my $value = $result->{$key};
-
- if (ref($value)) {
- my $counter = 0;
- foreach my $hash (@$value) {
- while (my ($innerKey, $innerValue) = each %$hash) {
- print "$key.$counter.$innerKey: $innerValue\n";
- }
- ++$counter;
+ $soapresult = $proxy->call('Product.get',
+ {'names' => [$product_name], token => $Bugzilla_token});
+ _die_on_fault($soapresult);
+ $result = $soapresult->result()->{'products'}->[0];
+
+ # Iterate all entries, the values may be scalars or array refs with hash refs.
+ foreach my $key (sort(keys %$result)) {
+ my $value = $result->{$key};
+
+ if (ref($value)) {
+ my $counter = 0;
+ foreach my $hash (@$value) {
+ while (my ($innerKey, $innerValue) = each %$hash) {
+ print "$key.$counter.$innerKey: $innerValue\n";
}
- }
- else {
- print "$key: $value\n"
+ ++$counter;
}
}
+ else {
+ print "$key: $value\n";
+ }
+ }
}
=head2 Creating A Bug
@@ -320,20 +329,20 @@ The call will return a hash with a bug id for the newly created bug.
=cut
if ($create_file_name) {
- my $bug_fields = do "$create_file_name";
- $bug_fields->{Bugzilla_token} = $Bugzilla_token;
- $soapresult = $proxy->call('Bug.create', \%$bug_fields);
- _die_on_fault($soapresult);
- $result = $soapresult->result;
-
- if (ref($result) eq 'HASH') {
- foreach (keys(%$result)) {
- print "$_: $$result{$_}\n";
- }
- }
- else {
- print "$result\n";
+ my $bug_fields = do "$create_file_name";
+ $bug_fields->{Bugzilla_token} = $Bugzilla_token;
+ $soapresult = $proxy->call('Bug.create', \%$bug_fields);
+ _die_on_fault($soapresult);
+ $result = $soapresult->result;
+
+ if (ref($result) eq 'HASH') {
+ foreach (keys(%$result)) {
+ print "$_: $$result{$_}\n";
}
+ }
+ else {
+ print "$result\n";
+ }
}
@@ -346,11 +355,12 @@ list of legal values for this field.
=cut
if ($legal_field_values) {
- $soapresult = $proxy->call('Bug.legal_values', {field => $legal_field_values, token => $Bugzilla_token} );
- _die_on_fault($soapresult);
- $result = $soapresult->result;
+ $soapresult = $proxy->call('Bug.legal_values',
+ {field => $legal_field_values, token => $Bugzilla_token});
+ _die_on_fault($soapresult);
+ $result = $soapresult->result;
- print join("\n", @{$result->{values}}) . "\n";
+ print join("\n", @{$result->{values}}) . "\n";
}
=head2 Adding a comment to a bug
@@ -362,15 +372,23 @@ or not.
=cut
if ($add_comment) {
- if ($bug_id) {
- $soapresult = $proxy->call('Bug.add_comment', {id => $bug_id,
- comment => $add_comment, private => $private, work_time => $work_time, token => $Bugzilla_token});
- _die_on_fault($soapresult);
- print "Comment added.\n";
- }
- else {
- print "A --bug_id must be supplied to add a comment.";
- }
+ if ($bug_id) {
+ $soapresult = $proxy->call(
+ 'Bug.add_comment',
+ {
+ id => $bug_id,
+ comment => $add_comment,
+ private => $private,
+ work_time => $work_time,
+ token => $Bugzilla_token
+ }
+ );
+ _die_on_fault($soapresult);
+ print "Comment added.\n";
+ }
+ else {
+ print "A --bug_id must be supplied to add a comment.";
+ }
}
=head1 NOTES
@@ -407,18 +425,19 @@ help to you.
=cut
sub _die_on_fault {
- my $soapresult = shift;
-
- if ($soapresult->fault) {
- my ($package, $filename, $line) = caller;
- die $soapresult->faultcode . ' ' . $soapresult->faultstring .
- " in SOAP call near $filename line $line.\n";
- }
+ my $soapresult = shift;
+
+ if ($soapresult->fault) {
+ my ($package, $filename, $line) = caller;
+ die $soapresult->faultcode . ' '
+ . $soapresult->faultstring
+ . " in SOAP call near $filename line $line.\n";
+ }
}
sub _syntaxhelp {
- my $msg = shift;
+ my $msg = shift;
- print "Error: $msg\n";
- pod2usage({'-verbose' => 0, '-exitval' => 1});
+ print "Error: $msg\n";
+ pod2usage({'-verbose' => 0, '-exitval' => 1});
}
diff --git a/contrib/bzdbcopy.pl b/contrib/bzdbcopy.pl
index fcdbefd56..5556a167e 100755
--- a/contrib/bzdbcopy.pl
+++ b/contrib/bzdbcopy.pl
@@ -22,51 +22,56 @@ use Bugzilla::Util;
#####################################################################
# Settings for the 'Source' DB that you are copying from.
-use constant SOURCE_DB_TYPE => 'Mysql';
-use constant SOURCE_DB_NAME => 'bugs';
-use constant SOURCE_DB_USER => 'bugs';
+use constant SOURCE_DB_TYPE => 'Mysql';
+use constant SOURCE_DB_NAME => 'bugs';
+use constant SOURCE_DB_USER => 'bugs';
use constant SOURCE_DB_PASSWORD => '';
-use constant SOURCE_DB_HOST => 'localhost';
+use constant SOURCE_DB_HOST => 'localhost';
# Settings for the 'Target' DB that you are copying to.
-use constant TARGET_DB_TYPE => 'Pg';
-use constant TARGET_DB_NAME => 'bugs';
-use constant TARGET_DB_USER => 'bugs';
+use constant TARGET_DB_TYPE => 'Pg';
+use constant TARGET_DB_NAME => 'bugs';
+use constant TARGET_DB_USER => 'bugs';
use constant TARGET_DB_PASSWORD => '';
-use constant TARGET_DB_HOST => 'localhost';
+use constant TARGET_DB_HOST => 'localhost';
#####################################################################
# MAIN SCRIPT
#####################################################################
-print "Connecting to the '" . SOURCE_DB_NAME . "' source database on "
- . SOURCE_DB_TYPE . "...\n";
+print "Connecting to the '"
+ . SOURCE_DB_NAME
+ . "' source database on "
+ . SOURCE_DB_TYPE . "...\n";
my $source_db = Bugzilla::DB::_connect({
- db_driver => SOURCE_DB_TYPE,
- db_host => SOURCE_DB_HOST,
- db_name => SOURCE_DB_NAME,
- db_user => SOURCE_DB_USER,
- db_pass => SOURCE_DB_PASSWORD,
+ db_driver => SOURCE_DB_TYPE,
+ db_host => SOURCE_DB_HOST,
+ db_name => SOURCE_DB_NAME,
+ db_user => SOURCE_DB_USER,
+ db_pass => SOURCE_DB_PASSWORD,
});
+
# Don't read entire tables into memory.
if (SOURCE_DB_TYPE eq 'Mysql') {
- $source_db->{'mysql_use_result'} = 1;
+ $source_db->{'mysql_use_result'} = 1;
- # MySQL cannot have two queries running at the same time. Ensure the schema
- # is loaded from the database so bz_column_info will not execute a query
- $source_db->_bz_real_schema;
+ # MySQL cannot have two queries running at the same time. Ensure the schema
+ # is loaded from the database so bz_column_info will not execute a query
+ $source_db->_bz_real_schema;
}
-print "Connecting to the '" . TARGET_DB_NAME . "' target database on "
- . TARGET_DB_TYPE . "...\n";
+print "Connecting to the '"
+ . TARGET_DB_NAME
+ . "' target database on "
+ . TARGET_DB_TYPE . "...\n";
my $target_db = Bugzilla::DB::_connect({
- db_driver => TARGET_DB_TYPE,
- db_host => TARGET_DB_HOST,
- db_name => TARGET_DB_NAME,
- db_user => TARGET_DB_USER,
- db_pass => TARGET_DB_PASSWORD,
+ db_driver => TARGET_DB_TYPE,
+ db_host => TARGET_DB_HOST,
+ db_name => TARGET_DB_NAME,
+ db_user => TARGET_DB_USER,
+ db_pass => TARGET_DB_PASSWORD,
});
-my $ident_char = $target_db->get_info( 29 ); # SQL_IDENTIFIER_QUOTE_CHAR
+my $ident_char = $target_db->get_info(29); # SQL_IDENTIFIER_QUOTE_CHAR
# We use the table list from the target DB, because if somebody
# has customized their source DB, we still want the script to work,
@@ -79,136 +84,145 @@ my @table_list = grep { $_ ne 'bz_schema' } $target_db->bz_table_list_real();
# Instead of figuring out some fancy algorithm to insert data in the right
# order and not break FK integrity, we just drop them all.
$target_db->bz_drop_foreign_keys();
+
# We start a transaction on the target DB, which helps when we're doing
# so many inserts.
$target_db->bz_start_transaction();
foreach my $table (@table_list) {
- my @serial_cols;
- print "Reading data from the source '$table' table on "
- . SOURCE_DB_TYPE . "...\n";
- my @table_columns = $target_db->bz_table_columns_real($table);
- # The column names could be quoted using the quote identifier char
- # Remove these chars as different databases use different quote chars
- @table_columns = map { s/^\Q$ident_char\E?(.*?)\Q$ident_char\E?$/$1/; $_ }
- @table_columns;
-
- my ($total) = $source_db->selectrow_array("SELECT COUNT(*) FROM $table");
- my $select_query = "SELECT " . join(',', @table_columns) . " FROM $table";
- my $select_sth = $source_db->prepare($select_query);
- $select_sth->execute();
-
- my $insert_query = "INSERT INTO $table ( " . join(',', @table_columns)
- . " ) VALUES (";
- $insert_query .= '?,' foreach (@table_columns);
- # Remove the last comma.
- chop($insert_query);
- $insert_query .= ")";
- my $insert_sth = $target_db->prepare($insert_query);
-
- print "Clearing out the target '$table' table on "
- . TARGET_DB_TYPE . "...\n";
- $target_db->do("DELETE FROM $table");
-
- # Oracle doesn't like us manually inserting into tables that have
- # auto-increment PKs set, because of the way we made auto-increment
- # fields work.
- if ($target_db->isa('Bugzilla::DB::Oracle')) {
- foreach my $column (@table_columns) {
- my $col_info = $source_db->bz_column_info($table, $column);
- if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) {
- print "Dropping the sequence + trigger on $table.$column...\n";
- $target_db->do("DROP TRIGGER ${table}_${column}_TR");
- $target_db->do("DROP SEQUENCE ${table}_${column}_SEQ");
- }
- }
+ my @serial_cols;
+ print "Reading data from the source '$table' table on "
+ . SOURCE_DB_TYPE . "...\n";
+ my @table_columns = $target_db->bz_table_columns_real($table);
+
+ # The column names could be quoted using the quote identifier char
+ # Remove these chars as different databases use different quote chars
+ @table_columns
+ = map { s/^\Q$ident_char\E?(.*?)\Q$ident_char\E?$/$1/; $_ } @table_columns;
+
+ my ($total) = $source_db->selectrow_array("SELECT COUNT(*) FROM $table");
+ my $select_query = "SELECT " . join(',', @table_columns) . " FROM $table";
+ my $select_sth = $source_db->prepare($select_query);
+ $select_sth->execute();
+
+ my $insert_query
+ = "INSERT INTO $table ( " . join(',', @table_columns) . " ) VALUES (";
+ $insert_query .= '?,' foreach (@table_columns);
+
+ # Remove the last comma.
+ chop($insert_query);
+ $insert_query .= ")";
+ my $insert_sth = $target_db->prepare($insert_query);
+
+ print "Clearing out the target '$table' table on " . TARGET_DB_TYPE . "...\n";
+ $target_db->do("DELETE FROM $table");
+
+ # Oracle doesn't like us manually inserting into tables that have
+ # auto-increment PKs set, because of the way we made auto-increment
+ # fields work.
+ if ($target_db->isa('Bugzilla::DB::Oracle')) {
+ foreach my $column (@table_columns) {
+ my $col_info = $source_db->bz_column_info($table, $column);
+ if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) {
+ print "Dropping the sequence + trigger on $table.$column...\n";
+ $target_db->do("DROP TRIGGER ${table}_${column}_TR");
+ $target_db->do("DROP SEQUENCE ${table}_${column}_SEQ");
+ }
}
-
- print "Writing data to the target '$table' table on "
- . TARGET_DB_TYPE . "...\n";
- my $count = 0;
- while (my $row = $select_sth->fetchrow_arrayref) {
- # Each column needs to be bound separately, because
- # many columns need to be dealt with specially.
- my $colnum = 0;
- foreach my $column (@table_columns) {
- # bind_param args start at 1, but arrays start at 0.
- my $param_num = $colnum + 1;
- my $already_bound;
-
- # Certain types of columns need special handling.
- my $col_info = $source_db->bz_column_info($table, $column);
- if ($col_info && $col_info->{TYPE} eq 'LONGBLOB') {
- $insert_sth->bind_param($param_num,
- $row->[$colnum], $target_db->BLOB_TYPE);
- $already_bound = 1;
- }
- elsif ($col_info && $col_info->{TYPE} =~ /decimal/) {
- # In MySQL, decimal cols can be too long.
- my $col_type = $col_info->{TYPE};
- $col_type =~ /decimal\((\d+),(\d+)\)/;
- my ($precision, $decimals) = ($1, $2);
- # If it's longer than precision + decimal point
- if ( length($row->[$colnum]) > ($precision + 1) ) {
- # Truncate it to the highest allowed value.
- my $orig_value = $row->[$colnum];
- $row->[$colnum] = '';
- my $non_decimal = $precision - $decimals;
- $row->[$colnum] .= '9' while ($non_decimal--);
- $row->[$colnum] .= '.';
- $row->[$colnum] .= '9' while ($decimals--);
- print "Truncated value $orig_value to " . $row->[$colnum]
- . " for $table.$column.\n";
- }
- }
- elsif ($col_info && $col_info->{TYPE} =~ /DATETIME/i) {
- my $date = $row->[$colnum];
- # MySQL can have strange invalid values for Datetimes.
- $row->[$colnum] = '1901-01-01 00:00:00'
- if $date && $date eq '0000-00-00 00:00:00';
- }
-
- $insert_sth->bind_param($param_num, $row->[$colnum])
- unless $already_bound;
- $colnum++;
- }
+ }
- $insert_sth->execute();
- $count++;
- indicate_progress({ current => $count, total => $total, every => 100 });
- }
+ print "Writing data to the target '$table' table on "
+ . TARGET_DB_TYPE . "...\n";
+ my $count = 0;
+ while (my $row = $select_sth->fetchrow_arrayref) {
- # For some DBs, we have to do clever things with auto-increment fields.
+ # Each column needs to be bound separately, because
+ # many columns need to be dealt with specially.
+ my $colnum = 0;
foreach my $column (@table_columns) {
- next if $target_db->isa('Bugzilla::DB::Mysql');
- my $col_info = $source_db->bz_column_info($table, $column);
- if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) {
- my ($max_val) = $target_db->selectrow_array(
- "SELECT MAX($column) FROM $table");
- # Set the sequence to the current max value + 1.
- $max_val = 0 if !defined $max_val;
- $max_val++;
- print "\nSetting the next value for $table.$column to $max_val.";
- if ($target_db->isa('Bugzilla::DB::Pg')) {
- # PostgreSQL doesn't like it when you insert values into
- # a serial field; it doesn't increment the counter
- # automatically.
- $target_db->bz_set_next_serial_value($table, $column);
- }
- elsif ($target_db->isa('Bugzilla::DB::Oracle')) {
- # Oracle increments the counter on every insert, and *always*
- # sets the field, even if you gave it a value. So if there
- # were already rows in the target DB (like the default rows
- # created by checksetup), you'll get crazy values in your
- # id columns. So we just dropped the sequences above and
- # we re-create them here, starting with the right number.
- my @sql = $target_db->_bz_real_schema->_get_create_seq_ddl(
- $table, $column, $max_val);
- $target_db->do($_) foreach @sql;
- }
+
+ # bind_param args start at 1, but arrays start at 0.
+ my $param_num = $colnum + 1;
+ my $already_bound;
+
+ # Certain types of columns need special handling.
+ my $col_info = $source_db->bz_column_info($table, $column);
+ if ($col_info && $col_info->{TYPE} eq 'LONGBLOB') {
+ $insert_sth->bind_param($param_num, $row->[$colnum], $target_db->BLOB_TYPE);
+ $already_bound = 1;
+ }
+ elsif ($col_info && $col_info->{TYPE} =~ /decimal/) {
+
+ # In MySQL, decimal cols can be too long.
+ my $col_type = $col_info->{TYPE};
+ $col_type =~ /decimal\((\d+),(\d+)\)/;
+ my ($precision, $decimals) = ($1, $2);
+
+ # If it's longer than precision + decimal point
+ if (length($row->[$colnum]) > ($precision + 1)) {
+
+ # Truncate it to the highest allowed value.
+ my $orig_value = $row->[$colnum];
+ $row->[$colnum] = '';
+ my $non_decimal = $precision - $decimals;
+ $row->[$colnum] .= '9' while ($non_decimal--);
+ $row->[$colnum] .= '.';
+ $row->[$colnum] .= '9' while ($decimals--);
+ print "Truncated value $orig_value to "
+ . $row->[$colnum]
+ . " for $table.$column.\n";
}
+ }
+ elsif ($col_info && $col_info->{TYPE} =~ /DATETIME/i) {
+ my $date = $row->[$colnum];
+
+ # MySQL can have strange invalid values for Datetimes.
+ $row->[$colnum] = '1901-01-01 00:00:00'
+ if $date && $date eq '0000-00-00 00:00:00';
+ }
+
+ $insert_sth->bind_param($param_num, $row->[$colnum]) unless $already_bound;
+ $colnum++;
+ }
+
+ $insert_sth->execute();
+ $count++;
+ indicate_progress({current => $count, total => $total, every => 100});
+ }
+
+ # For some DBs, we have to do clever things with auto-increment fields.
+ foreach my $column (@table_columns) {
+ next if $target_db->isa('Bugzilla::DB::Mysql');
+ my $col_info = $source_db->bz_column_info($table, $column);
+ if ($col_info && $col_info->{TYPE} =~ /SERIAL/i) {
+ my ($max_val) = $target_db->selectrow_array("SELECT MAX($column) FROM $table");
+
+ # Set the sequence to the current max value + 1.
+ $max_val = 0 if !defined $max_val;
+ $max_val++;
+ print "\nSetting the next value for $table.$column to $max_val.";
+ if ($target_db->isa('Bugzilla::DB::Pg')) {
+
+ # PostgreSQL doesn't like it when you insert values into
+ # a serial field; it doesn't increment the counter
+ # automatically.
+ $target_db->bz_set_next_serial_value($table, $column);
+ }
+ elsif ($target_db->isa('Bugzilla::DB::Oracle')) {
+
+ # Oracle increments the counter on every insert, and *always*
+ # sets the field, even if you gave it a value. So if there
+ # were already rows in the target DB (like the default rows
+ # created by checksetup), you'll get crazy values in your
+ # id columns. So we just dropped the sequences above and
+ # we re-create them here, starting with the right number.
+ my @sql
+ = $target_db->_bz_real_schema->_get_create_seq_ddl($table, $column, $max_val);
+ $target_db->do($_) foreach @sql;
+ }
}
+ }
- print "\n\n";
+ print "\n\n";
}
print "Committing changes to the target database...\n";
diff --git a/contrib/console.pl b/contrib/console.pl
index fe2342cd9..a3e042236 100755
--- a/contrib/console.pl
+++ b/contrib/console.pl
@@ -20,115 +20,120 @@ use Bugzilla::Bug;
use Term::ReadLine;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
-$Data::Dumper::Terse = 1;
-$Data::Dumper::Indent = 1;
-$Data::Dumper::Useqq = 1;
+$Data::Dumper::Terse = 1;
+$Data::Dumper::Indent = 1;
+$Data::Dumper::Useqq = 1;
$Data::Dumper::Maxdepth = 1;
-$Data::Dumper::Deparse = 0;
+$Data::Dumper::Deparse = 0;
my $sysname = get_text('term', {term => 'Bugzilla'});
my $term = new Term::ReadLine "$sysname Console";
read_history($term);
END { write_history($term) }
-while ( defined (my $input = $term->readline("$sysname> ")) ) {
- my @res = eval($input);
- if ($@) {
- warn $@;
- }
- else {
- print Dumper(@res);
- }
+while (defined(my $input = $term->readline("$sysname> "))) {
+ my @res = eval($input);
+ if ($@) {
+ warn $@;
+ }
+ else {
+ print Dumper(@res);
+ }
}
print STDERR "\n";
exit 0;
# d: full dump (normal behavior is limited to depth of 1)
sub d {
- local $Data::Dumper::Maxdepth = 0;
- local $Data::Dumper::Deparse = 1;
- print Dumper(@_);
- return ();
+ local $Data::Dumper::Maxdepth = 0;
+ local $Data::Dumper::Deparse = 1;
+ print Dumper(@_);
+ return ();
}
# p: print as a single string (normal behavior puts list items on separate lines)
sub p {
- no warnings; # suppress possible undefined var message
- print(@_, "\n");
- return ();
+ no warnings; # suppress possible undefined var message
+ print(@_, "\n");
+ return ();
}
sub filter {
- my $name = shift;
- my $filter = Bugzilla->template->{SERVICE}->{CONTEXT}->{CONFIG}->{FILTERS}->{$name};
- if (scalar @_) {
- return $filter->(@_);
- }
- else {
- return $filter;
- }
+ my $name = shift;
+ my $filter
+ = Bugzilla->template->{SERVICE}->{CONTEXT}->{CONFIG}->{FILTERS}->{$name};
+ if (scalar @_) {
+ return $filter->(@_);
+ }
+ else {
+ return $filter;
+ }
}
-sub b { get_object('Bugzilla::Bug', @_) }
-sub u { get_object('Bugzilla::User', @_) }
+sub b { get_object('Bugzilla::Bug', @_) }
+sub u { get_object('Bugzilla::User', @_) }
sub f { get_object('Bugzilla::Field', @_) }
sub get_object {
- my $class = shift;
- $_ = shift;
- my @results = ();
-
- if (ref $_ eq 'HASH' && keys %$_) {
- @results = @{$class->match($_)};
- }
- elsif (m/^\d+$/) {
- @results = ($class->new($_));
- }
- elsif (m/\w/i && grep {$_ eq 'name'} ($class->_get_db_columns)) {
- @results = @{$class->match({name => $_})};
- }
- else {
- @results = ();
- }
-
- if (wantarray) {
- return @results;
- }
- else {
- return shift @results;
- }
+ my $class = shift;
+ $_ = shift;
+ my @results = ();
+
+ if (ref $_ eq 'HASH' && keys %$_) {
+ @results = @{$class->match($_)};
+ }
+ elsif (m/^\d+$/) {
+ @results = ($class->new($_));
+ }
+ elsif (m/\w/i && grep { $_ eq 'name' } ($class->_get_db_columns)) {
+ @results = @{$class->match({name => $_})};
+ }
+ else {
+ @results = ();
+ }
+
+ if (wantarray) {
+ return @results;
+ }
+ else {
+ return shift @results;
+ }
}
sub read_history {
- my ($term) = @_;
-
- if (open HIST, "<$ENV{HOME}/.bugzilla_console_history") {
- foreach (<HIST>) {
- chomp;
- $term->addhistory($_);
- }
- close HIST;
+ my ($term) = @_;
+
+ if (open HIST, "<$ENV{HOME}/.bugzilla_console_history") {
+ foreach (<HIST>) {
+ chomp;
+ $term->addhistory($_);
}
+ close HIST;
+ }
}
sub write_history {
- my ($term) = @_;
-
- if ($term->can('GetHistory') && open HIST, ">$ENV{HOME}/.bugzilla_console_history") {
- my %seen_hist = ();
- my @hist = ();
- foreach my $line (reverse $term->GetHistory()) {
- next unless $line =~ m/\S/;
- next if $seen_hist{$line};
- $seen_hist{$line} = 1;
- push @hist, $line;
- last if (scalar @hist > 500);
- }
- foreach (reverse @hist) {
- print HIST $_, "\n";
- }
- close HIST;
+ my ($term) = @_;
+
+ if (
+ $term->can('GetHistory') && open HIST,
+ ">$ENV{HOME}/.bugzilla_console_history"
+ )
+ {
+ my %seen_hist = ();
+ my @hist = ();
+ foreach my $line (reverse $term->GetHistory()) {
+ next unless $line =~ m/\S/;
+ next if $seen_hist{$line};
+ $seen_hist{$line} = 1;
+ push @hist, $line;
+ last if (scalar @hist > 500);
+ }
+ foreach (reverse @hist) {
+ print HIST $_, "\n";
}
+ close HIST;
+ }
}
__END__
diff --git a/contrib/convert-workflow.pl b/contrib/convert-workflow.pl
index d9bffb7bb..f25bb0ea7 100755
--- a/contrib/convert-workflow.pl
+++ b/contrib/convert-workflow.pl
@@ -18,14 +18,14 @@ use Bugzilla::Search::Saved;
use Bugzilla::Status;
use Getopt::Long;
-my $confirmed = new Bugzilla::Status({ name => 'CONFIRMED' });
-my $in_progress = new Bugzilla::Status({ name => 'IN_PROGRESS' });
+my $confirmed = new Bugzilla::Status({name => 'CONFIRMED'});
+my $in_progress = new Bugzilla::Status({name => 'IN_PROGRESS'});
if ($confirmed and $in_progress) {
- print "You are already using the new workflow.\n";
- exit 1;
+ print "You are already using the new workflow.\n";
+ exit 1;
}
-my $enable_unconfirmed = 0;
+my $enable_unconfirmed = 0;
my $result = GetOptions("enable-unconfirmed" => \$enable_unconfirmed);
print <<END;
@@ -44,9 +44,10 @@ Emails will not be sent for the change.
END
if ($enable_unconfirmed) {
- print "UNCONFIRMED will be enabled in all products.\n";
-} else {
- print <<END;
+ print "UNCONFIRMED will be enabled in all products.\n";
+}
+else {
+ print <<END;
If you also want to enable the UNCONFIRMED status in every product,
restart this script with the --enable-unconfirmed option.
END
@@ -55,103 +56,116 @@ print "\nTo continue, press any key, or press Ctrl-C to stop this program...";
getc;
my $dbh = Bugzilla->dbh;
+
# This is an array instead of a hash so that we can be sure that
# the translation happens in the right order. In particular, we
# want NEW to be renamed to CONFIRMED, instead of having REOPENED
# be the one that gets renamed.
my @translation = (
- [NEW => 'CONFIRMED'],
- [ASSIGNED => 'IN_PROGRESS'],
- [REOPENED => 'CONFIRMED'],
- [CLOSED => 'VERIFIED'],
+ [NEW => 'CONFIRMED'],
+ [ASSIGNED => 'IN_PROGRESS'],
+ [REOPENED => 'CONFIRMED'],
+ [CLOSED => 'VERIFIED'],
);
my $status_field = Bugzilla::Field->check('bug_status');
$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);
-
- if (Bugzilla->params->{'duplicate_or_move_bug_status'} eq $from) {
- SetParam('duplicate_or_move_bug_status', $to);
- write_params();
- }
-
- foreach my $what (qw(added removed)) {
- $dbh->do("UPDATE bugs_activity SET $what = ?
- WHERE fieldid = ? AND $what = ?",
- undef, $to, $status_field->id, $from);
- }
-
- # Delete any transitions where it now appears that
- # a bug moved from a status to itself.
- $dbh->do('DELETE FROM bugs_activity WHERE fieldid = ? AND added = removed',
- undef, $status_field->id);
-
- # If the new status already exists, just delete the old one, but retain
- # the workflow items from it.
- 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
+ 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);
+
+ if (Bugzilla->params->{'duplicate_or_move_bug_status'} eq $from) {
+ SetParam('duplicate_or_move_bug_status', $to);
+ write_params();
+ }
+
+ foreach my $what (qw(added removed)) {
+ $dbh->do(
+ "UPDATE bugs_activity SET $what = ?
+ WHERE fieldid = ? AND $what = ?", undef, $to, $status_field->id,
+ $from
+ );
+ }
+
+ # Delete any transitions where it now appears that
+ # a bug moved from a status to itself.
+ $dbh->do('DELETE FROM bugs_activity WHERE fieldid = ? AND added = removed',
+ undef, $status_field->id);
+
+ # If the new status already exists, just delete the old one, but retain
+ # the workflow items from it.
+ 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
+ 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.
- elsif ($old_status) {
- $dbh->do('UPDATE bug_status SET value = ? WHERE value = ?',
- undef, $to, $from);
- }
-
- Bugzilla::Search::Saved->rename_field_value('bug_status', $from, $to);
- Bugzilla::Series->Bugzilla::Search::Saved::rename_field_value('bug_status',
- $from, $to);
+ 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.
+ elsif ($old_status) {
+ $dbh->do('UPDATE bug_status SET value = ? WHERE value = ?', undef, $to, $from);
+ }
+
+ Bugzilla::Search::Saved->rename_field_value('bug_status', $from, $to);
+ Bugzilla::Series->Bugzilla::Search::Saved::rename_field_value('bug_status',
+ $from, $to);
}
if ($enable_unconfirmed) {
- print "Enabling UNCONFIRMED in all products...\n";
- $dbh->do('UPDATE products SET allows_unconfirmed = 1');
+ print "Enabling UNCONFIRMED in all products...\n";
+ $dbh->do('UPDATE products SET allows_unconfirmed = 1');
}
$dbh->bz_commit_transaction();
Bugzilla->memcached->clear_all();
diff --git a/contrib/extension-convert.pl b/contrib/extension-convert.pl
index 91a77b839..d0fc791b2 100755
--- a/contrib/extension-convert.pl
+++ b/contrib/extension-convert.pl
@@ -21,8 +21,7 @@ use File::Copy qw(move);
use File::Find;
use File::Path qw(mkpath rmtree);
-my $from = $ARGV[0]
- or die <<END;
+my $from = $ARGV[0] or die <<END;
You must specify the name of the extension you are converting from,
as the first argument.
END
@@ -32,33 +31,33 @@ my $extdir = bz_locations()->{'extensionsdir'};
my $from_dir = "$extdir/$from";
if (!-d $from_dir) {
- die "$from_dir does not exist.\n";
+ die "$from_dir does not exist.\n";
}
my $to_dir = "$extdir/$extension_name";
if (-d $to_dir) {
- die "$to_dir already exists, not converting.\n";
+ die "$to_dir already exists, not converting.\n";
}
if (ON_WINDOWS) {
- # There's no easy way to recursively copy a directory on Windows.
- print "WARNING: This will modify the contents of $from_dir.\n",
- "Press Ctrl-C to stop or any other key to continue...\n";
- getc;
- move($from_dir, $to_dir)
- || die "rename of $from_dir to $to_dir failed: $!";
+
+ # There's no easy way to recursively copy a directory on Windows.
+ print "WARNING: This will modify the contents of $from_dir.\n",
+ "Press Ctrl-C to stop or any other key to continue...\n";
+ getc;
+ move($from_dir, $to_dir) || die "rename of $from_dir to $to_dir failed: $!";
}
else {
- print "Copying $from_dir to $to_dir...\n";
- system("cp", "-r", $from_dir, $to_dir);
+ print "Copying $from_dir to $to_dir...\n";
+ system("cp", "-r", $from_dir, $to_dir);
}
-# Make sure we don't accidentally modify the $from_dir anywhere else
+# Make sure we don't accidentally modify the $from_dir anywhere else
# in this script.
undef $from_dir;
if (!-d $to_dir) {
- die "$to_dir was not created.\n";
+ die "$to_dir was not created.\n";
}
my $version = get_version($to_dir);
@@ -96,7 +95,7 @@ END
open(my $config_fh, '>', "$to_dir/Config.pm") || die "$to_dir/Config.pm: $!";
print $config_fh $config_pm;
close($config_fh);
-open(my $extension_fh, '>', "$to_dir/Extension.pm")
+open(my $extension_fh, '>', "$to_dir/Extension.pm")
|| die "$to_dir/Extension.pm: $!";
print $extension_fh $extension_pm;
close($extension_fh);
@@ -109,176 +108,179 @@ unlink("$to_dir/info.pl");
###############
sub rename_module_packages {
- my ($dir, $name) = @_;
- my $lib_dir = "$dir/lib";
-
- # We don't want things like Bugzilla::Extension::Testopia::Testopia.
- if (-d "$lib_dir/$name") {
- print "Moving contents of $lib_dir/$name into $lib_dir...\n";
- foreach my $file (glob("$lib_dir/$name/*")) {
- my $dirname = dirname($file);
- my $basename = basename($file);
- rename($file, "$dirname/../$basename") || warn "$file: $!\n";
- }
+ my ($dir, $name) = @_;
+ my $lib_dir = "$dir/lib";
+
+ # We don't want things like Bugzilla::Extension::Testopia::Testopia.
+ if (-d "$lib_dir/$name") {
+ print "Moving contents of $lib_dir/$name into $lib_dir...\n";
+ foreach my $file (glob("$lib_dir/$name/*")) {
+ my $dirname = dirname($file);
+ my $basename = basename($file);
+ rename($file, "$dirname/../$basename") || warn "$file: $!\n";
}
+ }
- my @modules;
- find({ wanted => sub { $_ =~ /\.pm$/i and push(@modules, $_) },
- no_chdir => 1 }, $lib_dir);
- my %module_rename;
- foreach my $file (@modules) {
- open(my $fh, '<', $file) || die "$file: $!";
- my $content = do { local $/ = undef; <$fh> };
- close($fh);
- if ($content =~ /^package (\S+);/m) {
- my $package = $1;
- my $new_name = $file;
- $new_name =~ s/^$lib_dir\///;
- $new_name =~ s/\.pm$//;
- $new_name = join('::', File::Spec->splitdir($new_name));
- $new_name = "Bugzilla::Extension::${name}::$new_name";
- print "Renaming $package to $new_name...\n";
- $content =~ s/^package \Q$package\E;/package \Q$new_name\E;/;
- open(my $write_fh, '>', $file) || die "$file: $!";
- print $write_fh $content;
- close($write_fh);
- $module_rename{$package} = $new_name;
- }
+ my @modules;
+ find({wanted => sub { $_ =~ /\.pm$/i and push(@modules, $_) }, no_chdir => 1},
+ $lib_dir);
+ my %module_rename;
+ foreach my $file (@modules) {
+ open(my $fh, '<', $file) || die "$file: $!";
+ my $content = do { local $/ = undef; <$fh> };
+ close($fh);
+ if ($content =~ /^package (\S+);/m) {
+ my $package = $1;
+ my $new_name = $file;
+ $new_name =~ s/^$lib_dir\///;
+ $new_name =~ s/\.pm$//;
+ $new_name = join('::', File::Spec->splitdir($new_name));
+ $new_name = "Bugzilla::Extension::${name}::$new_name";
+ print "Renaming $package to $new_name...\n";
+ $content =~ s/^package \Q$package\E;/package \Q$new_name\E;/;
+ open(my $write_fh, '>', $file) || die "$file: $!";
+ print $write_fh $content;
+ close($write_fh);
+ $module_rename{$package} = $new_name;
}
+ }
- print "Renaming module names inside of library and code files...\n";
- my @code_files = glob("$dir/code/*.pl");
- rename_modules_internally(\%module_rename, [@modules, @code_files]);
+ print "Renaming module names inside of library and code files...\n";
+ my @code_files = glob("$dir/code/*.pl");
+ rename_modules_internally(\%module_rename, [@modules, @code_files]);
}
sub rename_modules_internally {
- my ($rename, $files) = @_;
-
- # We can't use \b because :: matches \b.
- my $break = qr/^|[^\w:]|$/;
- foreach my $file (@$files) {
- open(my $fh, '<', $file) || die "$file: $!";
- my $content = do { local $/ = undef; <$fh> };
- close($fh);
- foreach my $old_name (keys %$rename) {
- my $new_name = $rename->{$old_name};
- $content =~ s/($break)\Q$old_name\E($break)/$1$new_name$2/gms;
- }
- open(my $write_fh, '>', $file) || die "$file: $!";
- print $write_fh $content;
- close($write_fh);
+ my ($rename, $files) = @_;
+
+ # We can't use \b because :: matches \b.
+ my $break = qr/^|[^\w:]|$/;
+ foreach my $file (@$files) {
+ open(my $fh, '<', $file) || die "$file: $!";
+ my $content = do { local $/ = undef; <$fh> };
+ close($fh);
+ foreach my $old_name (keys %$rename) {
+ my $new_name = $rename->{$old_name};
+ $content =~ s/($break)\Q$old_name\E($break)/$1$new_name$2/gms;
}
+ open(my $write_fh, '>', $file) || die "$file: $!";
+ print $write_fh $content;
+ close($write_fh);
+ }
}
sub get_version {
- my ($dir) = @_;
- print "Getting version info from info.pl...\n";
- my $info;
- {
- local @INC = ("$dir/lib", @INC);
- $info = do "$dir/info.pl"; die $@ if $@;
- }
- return $info->{version};
+ my ($dir) = @_;
+ print "Getting version info from info.pl...\n";
+ my $info;
+ {
+ local @INC = ("$dir/lib", @INC);
+ $info = do "$dir/info.pl";
+ die $@ if $@;
+ }
+ return $info->{version};
}
sub get_install_requirements {
- my ($dir) = @_;
- my $file = "$dir/code/install-requirements.pl";
- return '' if !-f $file;
-
- print "Moving install-requirements.pl code into Config.pm...\n";
- my ($modules, $code) = process_code_file($file);
- $modules = join('', @$modules);
- $code = join('', @$code);
- if ($modules) {
- return "$modules\n\n$code";
- }
- return $code;
+ my ($dir) = @_;
+ my $file = "$dir/code/install-requirements.pl";
+ return '' if !-f $file;
+
+ print "Moving install-requirements.pl code into Config.pm...\n";
+ my ($modules, $code) = process_code_file($file);
+ $modules = join('', @$modules);
+ $code = join('', @$code);
+ if ($modules) {
+ return "$modules\n\n$code";
+ }
+ return $code;
}
sub process_code_file {
- my ($file) = @_;
- open(my $fh, '<', $file) || die "$file: $!";
- my $stuff_started;
- my (@modules, @code);
- foreach my $line (<$fh>) {
- $stuff_started = 1 if $line !~ /^#/;
- next if !$stuff_started;
- next if $line =~ /^use (warnings|strict|lib|Bugzilla)[^\w:]/;
- if ($line =~ /^(?:use|require)\b/) {
- push(@modules, $line);
- }
- else {
- push(@code, $line);
- }
+ my ($file) = @_;
+ open(my $fh, '<', $file) || die "$file: $!";
+ my $stuff_started;
+ my (@modules, @code);
+ foreach my $line (<$fh>) {
+ $stuff_started = 1 if $line !~ /^#/;
+ next if !$stuff_started;
+ next if $line =~ /^use (warnings|strict|lib|Bugzilla)[^\w:]/;
+ if ($line =~ /^(?:use|require)\b/) {
+ push(@modules, $line);
+ }
+ else {
+ push(@code, $line);
}
- close $fh;
- return (\@modules, \@code);
+ }
+ close $fh;
+ return (\@modules, \@code);
}
sub code_files_to_subroutines {
- my ($dir) = @_;
-
- my @dir_files = glob("$dir/code/*.pl");
- my (@all_modules, @subroutines);
- foreach my $file (@dir_files) {
- next if $file =~ /install-requirements/;
- print "Moving $file code into Extension.pm...\n";
- my ($modules, $code) = process_code_file($file);
- my @code_lines = map { " $_" } @$code;
- my $code_string = join('', @code_lines);
- $code_string =~ s/Bugzilla->hook_args/\$args/g;
- $code_string =~ s/my\s+\$args\s+=\s+\$args;//gs;
- chomp($code_string);
- push(@all_modules, @$modules);
- my $name = basename($file);
- $name =~ s/-/_/;
- $name =~ s/\.pl$//;
-
- my $subroutine = <<END;
+ my ($dir) = @_;
+
+ my @dir_files = glob("$dir/code/*.pl");
+ my (@all_modules, @subroutines);
+ foreach my $file (@dir_files) {
+ next if $file =~ /install-requirements/;
+ print "Moving $file code into Extension.pm...\n";
+ my ($modules, $code) = process_code_file($file);
+ my @code_lines = map {" $_"} @$code;
+ my $code_string = join('', @code_lines);
+ $code_string =~ s/Bugzilla->hook_args/\$args/g;
+ $code_string =~ s/my\s+\$args\s+=\s+\$args;//gs;
+ chomp($code_string);
+ push(@all_modules, @$modules);
+ my $name = basename($file);
+ $name =~ s/-/_/;
+ $name =~ s/\.pl$//;
+
+ my $subroutine = <<END;
sub $name {
my (\$self, \$args) = \@_;
$code_string
}
END
- push(@subroutines, $subroutine);
- }
+ push(@subroutines, $subroutine);
+ }
- my %seen_modules = map { trim($_) => 1 } @all_modules;
- my $module_string = join("\n", sort keys %seen_modules);
- my $subroutine_string = join("\n", @subroutines);
- return ($module_string, $subroutine_string);
+ my %seen_modules = map { trim($_) => 1 } @all_modules;
+ my $module_string = join("\n", sort keys %seen_modules);
+ my $subroutine_string = join("\n", @subroutines);
+ return ($module_string, $subroutine_string);
}
sub move_template_hooks {
- my ($dir) = @_;
- foreach my $lang (glob("$dir/template/*")) {
- next if !_file_matters($lang);
- my $hook_container = "$lang/default/hook";
- mkpath($hook_container) || warn "$hook_container: $!";
- # Hooks can be in all sorts of weird places, including
- # template/default/hook.
- foreach my $file (glob("$lang/*")) {
- next if !_file_matters($file, 1);
- my $dirname = basename($file);
- print "Moving $file to $hook_container/$dirname...\n";
- rename($file, "$hook_container/$dirname") || die "move failed: $!";
- }
+ my ($dir) = @_;
+ foreach my $lang (glob("$dir/template/*")) {
+ next if !_file_matters($lang);
+ my $hook_container = "$lang/default/hook";
+ mkpath($hook_container) || warn "$hook_container: $!";
+
+ # Hooks can be in all sorts of weird places, including
+ # template/default/hook.
+ foreach my $file (glob("$lang/*")) {
+ next if !_file_matters($file, 1);
+ my $dirname = basename($file);
+ print "Moving $file to $hook_container/$dirname...\n";
+ rename($file, "$hook_container/$dirname") || die "move failed: $!";
}
+ }
}
sub _file_matters {
- my ($path, $tmpl) = @_;
- my @ignore = qw(default custom CVS);
- my $file = basename($path);
- return 0 if grep(lc($_) eq lc($file), @ignore);
- # Hidden files
- return 0 if $file =~ /^\./;
- if ($tmpl) {
- return 1 if $file =~ /\.tmpl$/;
- }
- return 0 if !-d $path;
- return 1;
+ my ($path, $tmpl) = @_;
+ my @ignore = qw(default custom CVS);
+ my $file = basename($path);
+ return 0 if grep(lc($_) eq lc($file), @ignore);
+
+ # Hidden files
+ return 0 if $file =~ /^\./;
+ if ($tmpl) {
+ return 1 if $file =~ /\.tmpl$/;
+ }
+ return 0 if !-d $path;
+ return 1;
}
__END__
diff --git a/contrib/merge-users.pl b/contrib/merge-users.pl
index 86b209ab2..dbc9b10fe 100755
--- a/contrib/merge-users.pl
+++ b/contrib/merge-users.pl
@@ -44,7 +44,7 @@ use Pod::Usage;
my $dbh = Bugzilla->dbh;
# Display the help if called with --help or -?.
-my $help = 0;
+my $help = 0;
my $result = GetOptions("help|?" => \$help);
pod2usage(0) if $help;
@@ -53,49 +53,54 @@ pod2usage(0) if $help;
my $old = $ARGV[0] || die "You must specify an old user account.\n";
my $old_id;
if ($old =~ /^id:(\d+)$/) {
- # As the old user account may be a deleted one, we don't
- # check whether this user ID is valid or not.
- # If it never existed, no damage will be done.
- $old_id = $1;
+
+ # As the old user account may be a deleted one, we don't
+ # check whether this user ID is valid or not.
+ # If it never existed, no damage will be done.
+ $old_id = $1;
}
else {
- trick_taint($old);
- $old_id = $dbh->selectrow_array('SELECT userid FROM profiles
- WHERE login_name = ?',
- undef, $old);
+ trick_taint($old);
+ $old_id = $dbh->selectrow_array(
+ 'SELECT userid FROM profiles
+ WHERE login_name = ?', undef, $old
+ );
}
if ($old_id) {
- print "OK, old user account $old found; user ID: $old_id.\n";
+ print "OK, old user account $old found; user ID: $old_id.\n";
}
else {
- die "The old user account $old does not exist.\n";
+ die "The old user account $old does not exist.\n";
}
my $new = $ARGV[1] || die "You must specify a new user account.\n";
my $new_id;
if ($new =~ /^id:(\d+)$/) {
- $new_id = $1;
- # Make sure this user ID exists.
- $new_id = $dbh->selectrow_array('SELECT userid FROM profiles
- WHERE userid = ?',
- undef, $new_id);
+ $new_id = $1;
+
+ # Make sure this user ID exists.
+ $new_id = $dbh->selectrow_array(
+ 'SELECT userid FROM profiles
+ WHERE userid = ?', undef, $new_id
+ );
}
else {
- trick_taint($new);
- $new_id = $dbh->selectrow_array('SELECT userid FROM profiles
- WHERE login_name = ?',
- undef, $new);
+ trick_taint($new);
+ $new_id = $dbh->selectrow_array(
+ 'SELECT userid FROM profiles
+ WHERE login_name = ?', undef, $new
+ );
}
if ($new_id) {
- print "OK, new user account $new found; user ID: $new_id.\n";
+ print "OK, new user account $new found; user ID: $new_id.\n";
}
else {
- die "The new user account $new does not exist.\n";
+ die "The new user account $new does not exist.\n";
}
# Make sure the old and new accounts are different.
if ($old_id == $new_id) {
- die "\nBoth accounts are identical. There is nothing to migrate.\n";
+ die "\nBoth accounts are identical. There is nothing to migrate.\n";
}
@@ -112,32 +117,34 @@ if ($old_id == $new_id) {
# We set the tables that require custom stuff (multiple columns to check)
# here, but the simple stuff is all handled below by bz_get_related_fks.
my %changes = (
- cc => ['who bug_id'],
- # Tables affecting global behavior / other users.
- component_cc => ['user_id component_id'],
- watch => ['watcher watched', 'watched watcher'],
- # Tables affecting the user directly.
- namedqueries => ['userid name'],
- namedqueries_link_in_footer => ['user_id namedquery_id'],
- user_group_map => ['user_id group_id isbless grant_type'],
- email_setting => ['user_id relationship event'],
- profile_setting => ['user_id setting_name'],
-
- # Only do it if mailto_type = 0, i.e is pointing to a user account!
- # This requires to be done separately due to this condition.
- whine_schedules => [], # ['mailto'],
+ cc => ['who bug_id'],
+
+ # Tables affecting global behavior / other users.
+ component_cc => ['user_id component_id'],
+ watch => ['watcher watched', 'watched watcher'],
+
+ # Tables affecting the user directly.
+ namedqueries => ['userid name'],
+ namedqueries_link_in_footer => ['user_id namedquery_id'],
+ user_group_map => ['user_id group_id isbless grant_type'],
+ email_setting => ['user_id relationship event'],
+ profile_setting => ['user_id setting_name'],
+
+ # Only do it if mailto_type = 0, i.e is pointing to a user account!
+ # This requires to be done separately due to this condition.
+ whine_schedules => [], # ['mailto'],
);
my $userid_fks = $dbh->bz_get_related_fks('profiles', 'userid');
foreach my $item (@$userid_fks) {
- my ($table, $column) = @$item;
- $changes{$table} ||= [];
- push(@{ $changes{$table} }, $column);
+ my ($table, $column) = @$item;
+ $changes{$table} ||= [];
+ push(@{$changes{$table}}, $column);
}
# Delete all old records for these tables; no migration.
foreach my $table (qw(logincookies tokens profiles)) {
- $changes{$table} = [];
+ $changes{$table} = [];
}
# Start the transaction
@@ -145,7 +152,7 @@ $dbh->bz_start_transaction();
# 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);
+$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.
@@ -158,78 +165,87 @@ my $dupe_ids = $dbh->selectcol_arrayref("
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);
+ 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));
+ $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} }) {
- # Get all columns to consider. There is always at least
- # one column given: the one to update.
- my @columns = split(/[\s]+/, $column_list);
- my $cols_to_check = join(' AND ', map {"$_ = ?"} @columns);
- # The first column of the list is the one to update.
- my $col_to_update = shift @columns;
-
- # Will be used to migrate the old user account to the new one.
- my $sth_update = $dbh->prepare("UPDATE $table
+ foreach my $column_list (@{$changes{$table}}) {
+
+ # Get all columns to consider. There is always at least
+ # one column given: the one to update.
+ my @columns = split(/[\s]+/, $column_list);
+ my $cols_to_check = join(' AND ', map {"$_ = ?"} @columns);
+
+ # The first column of the list is the one to update.
+ my $col_to_update = shift @columns;
+
+ # Will be used to migrate the old user account to the new one.
+ my $sth_update = $dbh->prepare(
+ "UPDATE $table
SET $col_to_update = ?
- WHERE $cols_to_check");
+ WHERE $cols_to_check"
+ );
- # Do we have additional columns to take care of?
- if (scalar(@columns)) {
- my $cols_to_query = join(', ', @columns);
+ # Do we have additional columns to take care of?
+ if (scalar(@columns)) {
+ my $cols_to_query = join(', ', @columns);
- # Get existing entries for the old user account.
- my $old_entries =
- $dbh->selectall_arrayref("SELECT $cols_to_query
+ # Get existing entries for the old user account.
+ my $old_entries = $dbh->selectall_arrayref(
+ "SELECT $cols_to_query
FROM $table
- WHERE $col_to_update = ?",
- undef, $old_id);
+ WHERE $col_to_update = ?", undef, $old_id
+ );
- # Will be used to check whether the same entry exists
- # for the new user account.
- my $sth_select = $dbh->prepare("SELECT COUNT(*)
+ # Will be used to check whether the same entry exists
+ # for the new user account.
+ my $sth_select = $dbh->prepare(
+ "SELECT COUNT(*)
FROM $table
- WHERE $cols_to_check");
-
- # Will be used to delete duplicated entries.
- my $sth_delete = $dbh->prepare("DELETE FROM $table
- WHERE $cols_to_check");
-
- foreach my $entry (@$old_entries) {
- my $exists = $dbh->selectrow_array($sth_select, undef,
- ($new_id, @$entry));
-
- if ($exists) {
- $sth_delete->execute($old_id, @$entry);
- }
- else {
- $sth_update->execute($new_id, $old_id, @$entry);
- }
- }
+ WHERE $cols_to_check"
+ );
+
+ # Will be used to delete duplicated entries.
+ my $sth_delete = $dbh->prepare(
+ "DELETE FROM $table
+ WHERE $cols_to_check"
+ );
+
+ foreach my $entry (@$old_entries) {
+ my $exists = $dbh->selectrow_array($sth_select, undef, ($new_id, @$entry));
+
+ if ($exists) {
+ $sth_delete->execute($old_id, @$entry);
}
- # No check required. Update the column directly.
else {
- $sth_update->execute($new_id, $old_id);
+ $sth_update->execute($new_id, $old_id, @$entry);
}
- print "OK, records in the '$col_to_update' column of the '$table' table\n" .
- "have been migrated to the new user account.\n";
+ }
}
+
+ # No check required. Update the column directly.
+ else {
+ $sth_update->execute($new_id, $old_id);
+ }
+ print "OK, records in the '$col_to_update' column of the '$table' table\n"
+ . "have been migrated to the new user account.\n";
+ }
}
# Only update 'whine_schedules' if mailto_type = 0.
# (i.e. is pointing to a user ID).
-$dbh->do('UPDATE whine_schedules SET mailto = ?
- WHERE mailto = ? AND mailto_type = ?',
- undef, ($new_id, $old_id, 0));
-print "OK, records in the 'mailto' column of the 'whine_schedules' table\n" .
- "have been migrated to the new user account.\n";
+$dbh->do(
+ 'UPDATE whine_schedules SET mailto = ?
+ WHERE mailto = ? AND mailto_type = ?', undef, ($new_id, $old_id, 0)
+);
+print "OK, records in the 'mailto' column of the 'whine_schedules' table\n"
+ . "have been migrated to the new user account.\n";
# Delete the old record from the profiles table.
$dbh->do('DELETE FROM profiles WHERE userid = ?', undef, $old_id);
diff --git a/contrib/mysqld-watcher.pl b/contrib/mysqld-watcher.pl
index be93dcbb5..5dbbe320a 100755
--- a/contrib/mysqld-watcher.pl
+++ b/contrib/mysqld-watcher.pl
@@ -8,12 +8,12 @@
# mysqld-watcher.pl - a script that watches the running instance of
# mysqld and kills off any long-running SELECTs against the shadow_db
-#
+#
use 5.10.1;
use strict;
use warnings;
-# some configurables:
+# some configurables:
# length of time before a thread is eligible to be killed, in seconds
#
@@ -40,65 +40,70 @@ my $long = {};
# queries so we know which queries are taking too long to run, but complete
# queries with line breaks get missed by this script, so we get abbreviated
# queries as well to make sure we don't miss any.
-foreach my $command ("/opt/mysql/bin/mysqladmin --verbose processlist",
- "/opt/mysql/bin/mysqladmin processlist")
+foreach my $command (
+ "/opt/mysql/bin/mysqladmin --verbose processlist",
+ "/opt/mysql/bin/mysqladmin processlist"
+ )
{
- close(STDIN);
- open(STDIN, "$command |");
+ close(STDIN);
+ open(STDIN, "$command |");
- # iterate through the running threads
- #
- while ( <STDIN> ) {
- my @F = split(/\|/);
+ # iterate through the running threads
+ #
+ while (<STDIN>) {
+ my @F = split(/\|/);
- # if this line is not the correct number of fields, or if the thread-id
- # field contains Id, skip this line. both these cases indicate that this
- # line contains pretty-printing gunk and not thread info.
- #
- next if ( $#F != 9 || $F[1] =~ /Id/);
+ # if this line is not the correct number of fields, or if the thread-id
+ # field contains Id, skip this line. both these cases indicate that this
+ # line contains pretty-printing gunk and not thread info.
+ #
+ next if ($#F != 9 || $F[1] =~ /Id/);
- if ( $F[4] =~ /shadow_bugs/ # shadowbugs database in use
- && $F[5] =~ /Query/ # this is actually a query
- && $F[6] > $long_query_time # this query has taken too long
- && $F[8] =~ /(select|SELECT)/ # only kill a select
- && !defined($long->{$F[1]}) ) # haven't seen this one already
- {
- $long->{$F[1]} = \@F;
- system("/opt/mysql/bin/mysqladmin", "kill", $F[1]);
- }
+ if (
+ $F[4] =~ /shadow_bugs/ # shadowbugs database in use
+ && $F[5] =~ /Query/ # this is actually a query
+ && $F[6] > $long_query_time # this query has taken too long
+ && $F[8] =~ /(select|SELECT)/ # only kill a select
+ && !defined($long->{$F[1]})
+ ) # haven't seen this one already
+ {
+ $long->{$F[1]} = \@F;
+ system("/opt/mysql/bin/mysqladmin", "kill", $F[1]);
}
+ }
}
# send an email message
#
-# should perhaps be moved to somewhere more global for use in bugzilla as a
+# should perhaps be moved to somewhere more global for use in bugzilla as a
# whole; should also do more error-checking
#
sub sendEmail($$$$) {
- ($#_ == 3) || die("sendEmail: invalid number of arguments");
- my ($from, $to, $subject, $body) = @_;
+ ($#_ == 3) || die("sendEmail: invalid number of arguments");
+ my ($from, $to, $subject, $body) = @_;
+
+ open(MTA, "|$mta_program");
+ print MTA "From: $from\n";
+ print MTA "To: $to\n";
+ print MTA "Subject: $subject\n";
+ print MTA "\n";
+ print MTA $body;
+ print MTA "\n";
+ close(MTA);
- open(MTA, "|$mta_program");
- print MTA "From: $from\n";
- print MTA "To: $to\n";
- print MTA "Subject: $subject\n";
- print MTA "\n";
- print MTA $body;
- print MTA "\n";
- close(MTA);
-
}
# if we found anything, kill the database thread and send mail about it
#
if (scalar(keys(%$long))) {
- my $message = "";
- foreach my $process_id (keys(%$long)) {
- my $qry = $long->{$process_id};
- $message .= join(" ", @$qry) . "\n\n";
- }
+ my $message = "";
+ foreach my $process_id (keys(%$long)) {
+ my $qry = $long->{$process_id};
+ $message .= join(" ", @$qry) . "\n\n";
+ }
- # fire off an email telling the maintainer that we had to kill some threads
- #
- sendEmail($mail_from, $mail_to, "long running MySQL thread(s) killed", $message);
+ # fire off an email telling the maintainer that we had to kill some threads
+ #
+ sendEmail($mail_from, $mail_to, "long running MySQL thread(s) killed",
+ $message);
}
diff --git a/contrib/recode.pl b/contrib/recode.pl
index e6da47b92..9dc1d1bf5 100755
--- a/contrib/recode.pl
+++ b/contrib/recode.pl
@@ -32,21 +32,26 @@ use constant MAX_STRING_LEN => 25;
# For certain tables, we can't automatically determine their Primary Key.
# So, we specify it here as a string.
use constant SPECIAL_KEYS => {
- # bugs_activity since 4.4 has a unique primary key added
- bugs_activity => 'bug_id,bug_when,fieldid',
- profile_setting => 'user_id,setting_name',
- # profiles_activity since 4.4 has a unique primary key added
- profiles_activity => 'userid,profiles_when,fieldid',
- setting_value => 'name,value',
- # longdescs didn't used to have a PK, before 2.20.
- longdescs => 'bug_id,bug_when',
- # The 2.16 versions table lacked a PK
- versions => 'product_id,value',
- # These are all for earlier versions of Bugzilla. On a modern
- # version of Bugzilla, this script will ignore these (thanks to
- # code further down).
- components => 'program,value',
- products => 'product',
+
+ # bugs_activity since 4.4 has a unique primary key added
+ bugs_activity => 'bug_id,bug_when,fieldid',
+ profile_setting => 'user_id,setting_name',
+
+ # profiles_activity since 4.4 has a unique primary key added
+ profiles_activity => 'userid,profiles_when,fieldid',
+ setting_value => 'name,value',
+
+ # longdescs didn't used to have a PK, before 2.20.
+ longdescs => 'bug_id,bug_when',
+
+ # The 2.16 versions table lacked a PK
+ versions => 'product_id,value',
+
+ # These are all for earlier versions of Bugzilla. On a modern
+ # version of Bugzilla, this script will ignore these (thanks to
+ # code further down).
+ components => 'program,value',
+ products => 'product',
};
###############
@@ -55,18 +60,18 @@ use constant SPECIAL_KEYS => {
# "truncate" is a file operation in perl, so we can't use that name.
sub trunc {
- my ($str) = @_;
- my $truncated = substr($str, 0, MAX_STRING_LEN);
- if (length($truncated) ne length($str)) {
- $truncated .= '...';
- }
- return $truncated;
+ my ($str) = @_;
+ my $truncated = substr($str, 0, MAX_STRING_LEN);
+ if (length($truncated) ne length($str)) {
+ $truncated .= '...';
+ }
+ return $truncated;
}
sub is_valid_utf8 {
- my ($str) = @_;
- Encode::_utf8_on($str);
- return is_utf8($str, 1);
+ my ($str) = @_;
+ Encode::_utf8_on($str);
+ return is_utf8($str, 1);
}
###############
@@ -75,170 +80,172 @@ sub is_valid_utf8 {
my %switch;
GetOptions(\%switch, 'dry-run', 'guess', 'charset=s', 'show-failures',
- 'overrides=s', 'help|h');
+ 'overrides=s', 'help|h');
-pod2usage({ -verbose => 1 }) if $switch{'help'};
+pod2usage({-verbose => 1}) if $switch{'help'};
# You have to specify at least one of these switches.
-pod2usage({ -verbose => 0 }) if (!$switch{'charset'} && !$switch{'guess'});
+pod2usage({-verbose => 0}) if (!$switch{'charset'} && !$switch{'guess'});
if (exists $switch{'charset'}) {
- $switch{'charset'} = resolve_alias($switch{'charset'})
- || die "'$switch{charset}' is not a valid charset.";
+ $switch{'charset'} = resolve_alias($switch{'charset'})
+ || die "'$switch{charset}' is not a valid charset.";
}
if ($switch{'guess'}) {
- if (!eval { require Encode::Detect::Detector }) {
- my $root = ROOT_USER;
- print STDERR <<EOT;
+ if (!eval { require Encode::Detect::Detector }) {
+ my $root = ROOT_USER;
+ print STDERR <<EOT;
Using --guess requires that Encode::Detect be installed. To install
Encode::Detect, run the following command:
$^X install-module.pl Encode::Detect
EOT
- exit;
- }
+ exit;
+ }
}
my %overrides;
if (exists $switch{'overrides'}) {
- my $file = new IO::File($switch{'overrides'}, 'r')
- || die "$switch{overrides}: $!";
- my @lines = $file->getlines();
- $file->close();
- foreach my $line (@lines) {
- chomp($line);
- my ($digest, $encoding) = split(' ', $line);
- $overrides{$digest} = $encoding;
- }
+ my $file = new IO::File($switch{'overrides'}, 'r')
+ || die "$switch{overrides}: $!";
+ my @lines = $file->getlines();
+ $file->close();
+ foreach my $line (@lines) {
+ chomp($line);
+ my ($digest, $encoding) = split(' ', $line);
+ $overrides{$digest} = $encoding;
+ }
}
my $dbh = Bugzilla->dbh;
if ($dbh->isa('Bugzilla::DB::Mysql')) {
- # Get the actual current encoding of the DB.
- my $collation_data = $dbh->selectrow_arrayref(
- "SHOW VARIABLES LIKE 'character_set_database'");
- my $db_charset = $collation_data->[1];
- # Set our connection encoding to *that* encoding, so that MySQL
- # correctly accepts our changes.
- $dbh->do("SET NAMES $db_charset");
- # Make the database give us raw bytes.
- $dbh->do('SET character_set_results = NULL')
+
+ # Get the actual current encoding of the DB.
+ my $collation_data
+ = $dbh->selectrow_arrayref("SHOW VARIABLES LIKE 'character_set_database'");
+ my $db_charset = $collation_data->[1];
+
+ # Set our connection encoding to *that* encoding, so that MySQL
+ # correctly accepts our changes.
+ $dbh->do("SET NAMES $db_charset");
+
+ # Make the database give us raw bytes.
+ $dbh->do('SET character_set_results = NULL');
}
$dbh->begin_work;
foreach my $table ($dbh->bz_table_list_real) {
- my @columns = $dbh->bz_table_columns($table);
-
- my $pk = SPECIAL_KEYS->{$table};
- if ($pk) {
- # Assure that we're on a version of Bugzilla where those keys
- # actually exist.
- foreach my $column (split ',', $pk) {
- $pk = undef if !$dbh->bz_column_info($table, $column);
- }
+ my @columns = $dbh->bz_table_columns($table);
+
+ my $pk = SPECIAL_KEYS->{$table};
+ if ($pk) {
+
+ # Assure that we're on a version of Bugzilla where those keys
+ # actually exist.
+ foreach my $column (split ',', $pk) {
+ $pk = undef if !$dbh->bz_column_info($table, $column);
}
+ }
- # Figure out the primary key.
+ # Figure out the primary key.
+ foreach my $column (@columns) {
+ my $def = $dbh->bz_column_info($table, $column);
+ $pk = $column if $def->{PRIMARYKEY};
+ }
+
+ # If there's no PK, it's defined by a UNIQUE index.
+ if (!$pk) {
foreach my $column (@columns) {
- my $def = $dbh->bz_column_info($table, $column);
- $pk = $column if $def->{PRIMARYKEY};
- }
- # If there's no PK, it's defined by a UNIQUE index.
- if (!$pk) {
- foreach my $column (@columns) {
- my $index = $dbh->bz_index_info($table, "${table}_${column}_idx");
- if ($index && ref($index) eq 'HASH') {
- $pk = join(',', @{$index->{FIELDS}})
- if $index->{TYPE} eq 'UNIQUE';
- }
- }
+ my $index = $dbh->bz_index_info($table, "${table}_${column}_idx");
+ if ($index && ref($index) eq 'HASH') {
+ $pk = join(',', @{$index->{FIELDS}}) if $index->{TYPE} eq 'UNIQUE';
+ }
}
+ }
- foreach my $column (@columns) {
- my $def = $dbh->bz_column_info($table, $column);
- # If this is a text column, it may need work.
- if ($def->{TYPE} =~ /text|char/i) {
- # If there's still no PK, we're upgrading from 2.14 or earlier.
- # We can't reliably determine the PK (or at least, I don't want to
- # maintain code to record what the PK was at all points in history).
- # So instead we just use the field itself.
- $pk = $column if !$pk;
-
- print "Converting $table.$column...\n";
- my $sth = $dbh->prepare("SELECT $column, $pk FROM $table
+ foreach my $column (@columns) {
+ my $def = $dbh->bz_column_info($table, $column);
+
+ # If this is a text column, it may need work.
+ if ($def->{TYPE} =~ /text|char/i) {
+
+ # If there's still no PK, we're upgrading from 2.14 or earlier.
+ # We can't reliably determine the PK (or at least, I don't want to
+ # maintain code to record what the PK was at all points in history).
+ # So instead we just use the field itself.
+ $pk = $column if !$pk;
+
+ print "Converting $table.$column...\n";
+ my $sth = $dbh->prepare(
+ "SELECT $column, $pk FROM $table
WHERE $column IS NOT NULL
- AND $column != ''");
-
- my @pk_array = map {"$_ = ?"} split(',', $pk);
- my $pk_where = join(' AND ', @pk_array);
- my $update_sth = $dbh->prepare(
- "UPDATE $table SET $column = ? WHERE $pk_where");
-
- $sth->execute();
-
- while (my @result = $sth->fetchrow_array) {
- my $data = shift @result;
- # Wide characters cause md5_base64() to die.
- my $digest_data = utf8::is_utf8($data)
- ? Encode::encode_utf8($data) : $data;
- my $digest = md5_base64($digest_data);
-
- my @primary_keys = reverse split(',', $pk);
- # We copy the array so that we can pop things from it without
- # affecting the original.
- my @pk_data = @result;
- my $pk_line = join (', ',
- map { "$_ = " . pop @pk_data } @primary_keys);
-
- my $encoding;
- if ($switch{'guess'}) {
- $encoding = detect_encoding($data);
-
- # We only show failures if they don't appear to be
- # ASCII.
- if ($switch{'show-failures'} && !$encoding
- && !is_valid_utf8($data))
- {
- my $truncated = trunc($data);
- print "Row: [$pk_line]\n",
- "Failed to guess: Key: $digest",
- " DATA: $truncated\n";
- }
-
- # If we fail a guess, and the data is valid UTF-8,
- # just assume we failed because it's UTF-8.
- next if is_valid_utf8($data);
- }
-
- # If we couldn't detect the charset (or were instructed
- # not to try), we fall back to --charset. If there's no
- # fallback, we just do nothing.
- if (!$encoding && $switch{'charset'}) {
- $encoding = $switch{'charset'};
- }
-
- $encoding = $overrides{$digest} if $overrides{$digest};
-
- # We only fix it if it's not ASCII or UTF-8 already.
- if ($encoding && !grep($_ eq $encoding, IGNORE_ENCODINGS)) {
- my $decoded = encode('utf8', decode($encoding, $data));
- if ($switch{'dry-run'} && $data ne $decoded) {
- print "Row: [$pk_line]\n",
- "From: [" . trunc($data) . "] Key: $digest\n",
- "To: [" . trunc($decoded) . "]",
- " Encoding : $encoding\n";
- }
- else {
- $update_sth->execute($decoded, @result);
- }
- }
- } # while (my @result = $sth->fetchrow_array)
- } # if ($column->{TYPE} =~ /text|char/i)
- } # foreach my $column (@columns)
+ AND $column != ''"
+ );
+
+ my @pk_array = map {"$_ = ?"} split(',', $pk);
+ my $pk_where = join(' AND ', @pk_array);
+ my $update_sth = $dbh->prepare("UPDATE $table SET $column = ? WHERE $pk_where");
+
+ $sth->execute();
+
+ while (my @result = $sth->fetchrow_array) {
+ my $data = shift @result;
+
+ # Wide characters cause md5_base64() to die.
+ my $digest_data = utf8::is_utf8($data) ? Encode::encode_utf8($data) : $data;
+ my $digest = md5_base64($digest_data);
+
+ my @primary_keys = reverse split(',', $pk);
+
+ # We copy the array so that we can pop things from it without
+ # affecting the original.
+ my @pk_data = @result;
+ my $pk_line = join(', ', map { "$_ = " . pop @pk_data } @primary_keys);
+
+ my $encoding;
+ if ($switch{'guess'}) {
+ $encoding = detect_encoding($data);
+
+ # We only show failures if they don't appear to be
+ # ASCII.
+ if ($switch{'show-failures'} && !$encoding && !is_valid_utf8($data)) {
+ my $truncated = trunc($data);
+ print "Row: [$pk_line]\n", "Failed to guess: Key: $digest",
+ " DATA: $truncated\n";
+ }
+
+ # If we fail a guess, and the data is valid UTF-8,
+ # just assume we failed because it's UTF-8.
+ next if is_valid_utf8($data);
+ }
+
+ # If we couldn't detect the charset (or were instructed
+ # not to try), we fall back to --charset. If there's no
+ # fallback, we just do nothing.
+ if (!$encoding && $switch{'charset'}) {
+ $encoding = $switch{'charset'};
+ }
+
+ $encoding = $overrides{$digest} if $overrides{$digest};
+
+ # We only fix it if it's not ASCII or UTF-8 already.
+ if ($encoding && !grep($_ eq $encoding, IGNORE_ENCODINGS)) {
+ my $decoded = encode('utf8', decode($encoding, $data));
+ if ($switch{'dry-run'} && $data ne $decoded) {
+ print "Row: [$pk_line]\n", "From: [" . trunc($data) . "] Key: $digest\n",
+ "To: [" . trunc($decoded) . "]", " Encoding : $encoding\n";
+ }
+ else {
+ $update_sth->execute($decoded, @result);
+ }
+ }
+ } # while (my @result = $sth->fetchrow_array)
+ } # if ($column->{TYPE} =~ /text|char/i)
+ } # foreach my $column (@columns)
}
$dbh->commit;
diff --git a/contrib/sendbugmail.pl b/contrib/sendbugmail.pl
index 223d91f6c..b1b5fa8a5 100755
--- a/contrib/sendbugmail.pl
+++ b/contrib/sendbugmail.pl
@@ -20,16 +20,16 @@ use Bugzilla::User;
my $dbh = Bugzilla->dbh;
sub usage {
- say STDERR "Usage: $0 bug_id user_email";
- exit;
+ say STDERR "Usage: $0 bug_id user_email";
+ exit;
}
if (($#ARGV < 1) || ($#ARGV > 2)) {
- usage();
+ usage();
}
# Get the arguments.
-my $bugnum = $ARGV[0];
+my $bugnum = $ARGV[0];
my $changer = $ARGV[1];
# Validate the bug number.
@@ -40,8 +40,8 @@ if (!($bugnum =~ /^(\d+)$/)) {
detaint_natural($bugnum);
-my ($id) = $dbh->selectrow_array("SELECT bug_id FROM bugs WHERE bug_id = ?",
- undef, $bugnum);
+my ($id) = $dbh->selectrow_array("SELECT bug_id FROM bugs WHERE bug_id = ?",
+ undef, $bugnum);
if (!$id) {
say STDERR "Bug number $bugnum does not exist.";
@@ -51,25 +51,26 @@ if (!$id) {
# Validate the changer address.
my $match = Bugzilla->params->{'emailregexp'};
if ($changer !~ /$match/) {
- say STDERR "Changer \"$changer\" doesn't match email regular expression.";
- usage();
+ say STDERR "Changer \"$changer\" doesn't match email regular expression.";
+ usage();
}
-my $changer_user = new Bugzilla::User({ name => $changer });
+my $changer_user = new Bugzilla::User({name => $changer});
unless ($changer_user) {
- say STDERR "\"$changer\" is not a valid user.";
- usage();
+ say STDERR "\"$changer\" is not a valid user.";
+ usage();
}
# Send the email.
-my $outputref = Bugzilla::BugMail::Send($bugnum, {'changer' => $changer_user });
+my $outputref = Bugzilla::BugMail::Send($bugnum, {'changer' => $changer_user});
# Report the results.
my $sent = scalar(@{$outputref->{sent}});
if ($sent) {
- say "email sent to $sent recipients:";
-} else {
- say "No email sent.";
+ say "email sent to $sent recipients:";
+}
+else {
+ say "No email sent.";
}
foreach my $sent (@{$outputref->{sent}}) {
@@ -78,12 +79,12 @@ foreach my $sent (@{$outputref->{sent}}) {
# This document is copyright (C) 2004 Perforce Software, Inc. All rights
# reserved.
-#
+#
# Redistribution and use of this document in any form, with or without
# modification, is permitted provided that redistributions of this
# document retain the above copyright notice, this condition and the
# following disclaimer.
-#
+#
# THIS DOCUMENT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
diff --git a/contrib/sendunsentbugmail.pl b/contrib/sendunsentbugmail.pl
index b9034aa8d..58bde594c 100755
--- a/contrib/sendunsentbugmail.pl
+++ b/contrib/sendunsentbugmail.pl
@@ -19,28 +19,28 @@ use Bugzilla::BugMail;
my $dbh = Bugzilla->dbh;
my $list = $dbh->selectcol_arrayref(
- 'SELECT bug_id FROM bugs
+ 'SELECT bug_id FROM bugs
WHERE (lastdiffed IS NULL OR lastdiffed < delta_ts)
AND delta_ts < '
- . $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE') .
- ' ORDER BY bug_id');
+ . $dbh->sql_date_math('NOW()', '-', 30, 'MINUTE') . ' ORDER BY bug_id'
+);
if (scalar(@$list) > 0) {
- say "OK, now attempting to send unsent mail";
- say scalar(@$list) . " bugs found with possibly unsent mail.\n";
- foreach my $bugid (@$list) {
- my $start_time = time;
- say "Sending mail for bug $bugid...";
- my $outputref = Bugzilla::BugMail::Send($bugid);
- if ($ARGV[0] && $ARGV[0] eq "--report") {
- say "Mail sent to:";
- say $_ foreach (sort @{$outputref->{sent}});
- }
- else {
- my $sent = scalar @{$outputref->{sent}};
- say "$sent mails sent.";
- say "Took " . (time - $start_time) . " seconds.\n";
- }
+ say "OK, now attempting to send unsent mail";
+ say scalar(@$list) . " bugs found with possibly unsent mail.\n";
+ foreach my $bugid (@$list) {
+ my $start_time = time;
+ say "Sending mail for bug $bugid...";
+ my $outputref = Bugzilla::BugMail::Send($bugid);
+ if ($ARGV[0] && $ARGV[0] eq "--report") {
+ say "Mail sent to:";
+ say $_ foreach (sort @{$outputref->{sent}});
}
- say "Unsent mail has been sent.";
+ else {
+ my $sent = scalar @{$outputref->{sent}};
+ say "$sent mails sent.";
+ say "Took " . (time - $start_time) . " seconds.\n";
+ }
+ }
+ say "Unsent mail has been sent.";
}
diff --git a/contrib/syncLDAP.pl b/contrib/syncLDAP.pl
index f618624ec..0ffcba5be 100755
--- a/contrib/syncLDAP.pl
+++ b/contrib/syncLDAP.pl
@@ -19,47 +19,49 @@ use Bugzilla::User;
my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
-my $readonly = 0;
+my $readonly = 0;
my $nodisable = 0;
-my $noupdate = 0;
-my $nocreate = 0;
-my $quiet = 0;
+my $noupdate = 0;
+my $nocreate = 0;
+my $quiet = 0;
###
# Do some preparations
###
-foreach my $arg (@ARGV)
-{
- if($arg eq '-r') {
- $readonly = 1;
- }
- elsif($arg eq '-d') {
- $nodisable = 1;
- }
- elsif($arg eq '-u') {
- $noupdate = 1;
- }
- elsif($arg eq '-c') {
- $nocreate = 1;
- }
- elsif($arg eq '-q') {
- $quiet = 1;
- }
- else {
- print "LDAP Sync Script\n";
- print "Syncronizes the users table from the LDAP server with the Bugzilla users.\n";
- print "Takes mail-attribute from preferences and description from 'cn' or,\n";
- print "if not available, from the uid-attribute.\n\n";
- print "usage:\n syncLDAP.pl [options]\n\n";
- print "options:\n";
- print " -r Readonly, do not make changes to Bugzilla tables\n";
- print " -d No disable, don't disable login by users who are not in LDAP\n";
- print " -u No update, don't update users, which have different description in LDAP\n";
- print " -c No create, don't create users, which are in LDAP but not in Bugzilla\n";
- print " -q Quiet mode, give less output\n";
- print "\n";
- exit;
- }
+foreach my $arg (@ARGV) {
+ if ($arg eq '-r') {
+ $readonly = 1;
+ }
+ elsif ($arg eq '-d') {
+ $nodisable = 1;
+ }
+ elsif ($arg eq '-u') {
+ $noupdate = 1;
+ }
+ elsif ($arg eq '-c') {
+ $nocreate = 1;
+ }
+ elsif ($arg eq '-q') {
+ $quiet = 1;
+ }
+ else {
+ print "LDAP Sync Script\n";
+ print
+ "Syncronizes the users table from the LDAP server with the Bugzilla users.\n";
+ print "Takes mail-attribute from preferences and description from 'cn' or,\n";
+ print "if not available, from the uid-attribute.\n\n";
+ print "usage:\n syncLDAP.pl [options]\n\n";
+ print "options:\n";
+ print " -r Readonly, do not make changes to Bugzilla tables\n";
+ print " -d No disable, don't disable login by users who are not in LDAP\n";
+ print
+ " -u No update, don't update users, which have different description in LDAP\n";
+ print
+ " -c No create, don't create users, which are in LDAP but not in Bugzilla\n";
+ print " -q Quiet mode, give less output\n";
+ print "\n";
+ exit;
+ }
}
my %ldap_users;
@@ -67,13 +69,18 @@ my %ldap_users;
###
# Get current bugzilla users
###
-my %bugzilla_users = %{ $dbh->selectall_hashref(
- 'SELECT login_name AS new_login_name, realname, disabledtext ' .
- 'FROM profiles', 'new_login_name') };
+my %bugzilla_users = %{
+ $dbh->selectall_hashref(
+ 'SELECT login_name AS new_login_name, realname, disabledtext '
+ . 'FROM profiles',
+ 'new_login_name'
+ )
+};
foreach my $login_name (keys %bugzilla_users) {
- # remove whitespaces
- $bugzilla_users{$login_name}{'realname'} =~ s/^\s+|\s+$//g;
+
+ # remove whitespaces
+ $bugzilla_users{$login_name}{'realname'} =~ s/^\s+|\s+$//g;
}
###
@@ -81,72 +88,79 @@ foreach my $login_name (keys %bugzilla_users) {
###
my $LDAPserver = Bugzilla->params->{"LDAPserver"};
if ($LDAPserver eq "") {
- print "No LDAP server defined in bugzilla preferences.\n";
- exit;
+ print "No LDAP server defined in bugzilla preferences.\n";
+ exit;
}
my $LDAPconn;
-if($LDAPserver =~ /:\/\//) {
- # if the "LDAPserver" parameter is in uri scheme
- $LDAPconn = Net::LDAP->new($LDAPserver, version => 3);
-} else {
- my $LDAPport = "389"; # default LDAP port
- if($LDAPserver =~ /:/) {
- ($LDAPserver, $LDAPport) = split(":",$LDAPserver);
- }
- $LDAPconn = Net::LDAP->new($LDAPserver, port => $LDAPport, version => 3);
+if ($LDAPserver =~ /:\/\//) {
+
+ # if the "LDAPserver" parameter is in uri scheme
+ $LDAPconn = Net::LDAP->new($LDAPserver, version => 3);
+}
+else {
+ my $LDAPport = "389"; # default LDAP port
+ if ($LDAPserver =~ /:/) {
+ ($LDAPserver, $LDAPport) = split(":", $LDAPserver);
+ }
+ $LDAPconn = Net::LDAP->new($LDAPserver, port => $LDAPport, version => 3);
}
-if(!$LDAPconn) {
- print "Connecting to LDAP server failed. Check LDAPserver setting.\n";
- exit;
+if (!$LDAPconn) {
+ print "Connecting to LDAP server failed. Check LDAPserver setting.\n";
+ exit;
}
my $mesg;
if (Bugzilla->params->{"LDAPbinddn"}) {
- my ($LDAPbinddn,$LDAPbindpass) = split(":",Bugzilla->params->{"LDAPbinddn"});
- $mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass);
+ my ($LDAPbinddn, $LDAPbindpass) = split(":", Bugzilla->params->{"LDAPbinddn"});
+ $mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass);
}
else {
- $mesg = $LDAPconn->bind();
+ $mesg = $LDAPconn->bind();
}
-if($mesg->code) {
- print "Binding to LDAP server failed: " . $mesg->error . "\nCheck LDAPbinddn setting.\n";
- exit;
+if ($mesg->code) {
+ print "Binding to LDAP server failed: "
+ . $mesg->error
+ . "\nCheck LDAPbinddn setting.\n";
+ exit;
}
# We've got our anonymous bind; let's look up the users.
-$mesg = $LDAPconn->search( base => Bugzilla->params->{"LDAPBaseDN"},
- scope => "sub",
- filter => '(&(' . Bugzilla->params->{"LDAPuidattribute"} . "=*)" . Bugzilla->params->{"LDAPfilter"} . ')',
- );
-
-
-if(! $mesg->count) {
- print "LDAP lookup failure. Check LDAPBaseDN setting.\n";
- exit;
+$mesg = $LDAPconn->search(
+ base => Bugzilla->params->{"LDAPBaseDN"},
+ scope => "sub",
+ filter => '(&('
+ . Bugzilla->params->{"LDAPuidattribute"} . "=*)"
+ . Bugzilla->params->{"LDAPfilter"} . ')',
+);
+
+
+if (!$mesg->count) {
+ print "LDAP lookup failure. Check LDAPBaseDN setting.\n";
+ exit;
}
-
-my %val = %{ $mesg->as_struct };
-
-while( my ($key, $value) = each(%val) ) {
-
- my @login_name = @{ $value->{Bugzilla->params->{"LDAPmailattribute"}} };
- my @realname = @{ $value->{"cn"} };
-
- # no mail entered? go to next
- if(! @login_name) {
- print "$key has no valid mail address\n";
- next;
- }
-
- # no cn entered? use uid instead
- if(! @realname) {
- @realname = @{ $value->{Bugzilla->params->{"LDAPuidattribute"}} };
- }
-
- my $login = shift @login_name;
- my $real = shift @realname;
- $ldap_users{$login} = { realname => $real };
+
+my %val = %{$mesg->as_struct};
+
+while (my ($key, $value) = each(%val)) {
+
+ my @login_name = @{$value->{Bugzilla->params->{"LDAPmailattribute"}}};
+ my @realname = @{$value->{"cn"}};
+
+ # no mail entered? go to next
+ if (!@login_name) {
+ print "$key has no valid mail address\n";
+ next;
+ }
+
+ # no cn entered? use uid instead
+ if (!@realname) {
+ @realname = @{$value->{Bugzilla->params->{"LDAPuidattribute"}}};
+ }
+
+ my $login = shift @login_name;
+ my $real = shift @realname;
+ $ldap_users{$login} = {realname => $real};
}
print "\n" unless $quiet;
@@ -159,120 +173,125 @@ my %update_users;
my %create_users;
print "Bugzilla-Users: \n" unless $quiet;
-while( my ($key, $value) = each(%bugzilla_users) ) {
- print " " . $key . " '" . $value->{'realname'} . "' " . $value->{'disabledtext'} ."\n" unless $quiet==1;
- if(!exists $ldap_users{$key}){
- if($value->{'disabledtext'} eq '') {
- $disable_users{$key} = $value;
- }
+while (my ($key, $value) = each(%bugzilla_users)) {
+ print " "
+ . $key . " '"
+ . $value->{'realname'} . "' "
+ . $value->{'disabledtext'} . "\n"
+ unless $quiet == 1;
+ if (!exists $ldap_users{$key}) {
+ if ($value->{'disabledtext'} eq '') {
+ $disable_users{$key} = $value;
+ }
}
}
print "\nLDAP-Users: \n" unless $quiet;
-while( my ($key, $value) = each(%ldap_users) ) {
- print " " . $key . " '" . $value->{'realname'} . "'\n" unless $quiet==1;
- if(!defined $bugzilla_users{$key}){
+while (my ($key, $value) = each(%ldap_users)) {
+ print " " . $key . " '" . $value->{'realname'} . "'\n" unless $quiet == 1;
+ if (!defined $bugzilla_users{$key}) {
$create_users{$key} = $value;
}
- else {
+ else {
my $bugzilla_user_value = $bugzilla_users{$key};
- if($bugzilla_user_value->{'realname'} ne $value->{'realname'}) {
+ if ($bugzilla_user_value->{'realname'} ne $value->{'realname'}) {
$update_users{$key} = $value;
}
}
}
print "\nDetecting email changes: \n" unless $quiet;
-while( my ($create_key, $create_value) = each(%create_users) ) {
- while( my ($disable_key, $disable_value) = each(%disable_users) ) {
- if($create_value->{'realname'} eq $disable_value->{'realname'}) {
- print " " . $disable_key . " => " . $create_key ."'\n" unless $quiet==1;
- $update_users{$disable_key} = { realname => $create_value->{'realname'},
- new_login_name => $create_key };
- delete $create_users{$create_key};
- delete $disable_users{$disable_key};
+while (my ($create_key, $create_value) = each(%create_users)) {
+ while (my ($disable_key, $disable_value) = each(%disable_users)) {
+ if ($create_value->{'realname'} eq $disable_value->{'realname'}) {
+ print " " . $disable_key . " => " . $create_key . "'\n" unless $quiet == 1;
+ $update_users{$disable_key}
+ = {realname => $create_value->{'realname'}, new_login_name => $create_key};
+ delete $create_users{$create_key};
+ delete $disable_users{$disable_key};
}
}
}
-if($quiet == 0) {
- print "\nUsers to disable login for: \n";
- while( my ($key, $value) = each(%disable_users) ) {
- print " " . $key . " '" . $value->{'realname'} . "'\n";
- }
-
- print "\nUsers to update: \n";
- while( my ($key, $value) = each(%update_users) ) {
- print " " . $key . " '" . $value->{'realname'} . "' ";
- if(defined $value->{'new_login_name'}) {
- print "has changed email to " . $value->{'new_login_name'};
- }
- print "\n";
- }
-
- print "\nUsers to create: \n";
- while( my ($key, $value) = each(%create_users) ) {
- print " " . $key . " '" . $value->{'realname'} . "'\n";
- }
-
- print "\n\n";
+if ($quiet == 0) {
+ print "\nUsers to disable login for: \n";
+ while (my ($key, $value) = each(%disable_users)) {
+ print " " . $key . " '" . $value->{'realname'} . "'\n";
+ }
+
+ print "\nUsers to update: \n";
+ while (my ($key, $value) = each(%update_users)) {
+ print " " . $key . " '" . $value->{'realname'} . "' ";
+ if (defined $value->{'new_login_name'}) {
+ print "has changed email to " . $value->{'new_login_name'};
+ }
+ print "\n";
+ }
+
+ print "\nUsers to create: \n";
+ while (my ($key, $value) = each(%create_users)) {
+ print " " . $key . " '" . $value->{'realname'} . "'\n";
+ }
+
+ print "\n\n";
}
###
# now do the DB-Update
###
-if($readonly == 0) {
- print "Performing DB update:\nPhase 1: disabling login for users not in LDAP... " unless $quiet;
+if ($readonly == 0) {
+ print
+ "Performing DB update:\nPhase 1: disabling login for users not in LDAP... "
+ unless $quiet;
- my $sth_disable = $dbh->prepare(
- 'UPDATE profiles
+ my $sth_disable = $dbh->prepare(
+ 'UPDATE profiles
SET disabledtext = ?
- WHERE ' . $dbh->sql_istrcmp('login_name', '?'));
+ WHERE ' . $dbh->sql_istrcmp('login_name', '?')
+ );
- if($nodisable == 0) {
- while( my ($key, $value) = each(%disable_users) ) {
- $sth_disable->execute('auto-disabled by ldap sync', $key);
- }
- print "done!\n" unless $quiet;
- }
- else {
- print "disabled!\n" unless $quiet;
- }
-
- print "Phase 2: updating existing users... " unless $quiet;
-
- if($noupdate == 0) {
- while( my ($key, $value) = each(%update_users) ) {
- my $user = Bugzilla::User->check($key);
- if(defined $value->{'new_login_name'}) {
- $user->set_login($value->{'new_login_name'});
- } else {
- $user->set_name($value->{'realname'});
- }
- $user->update();
+ if ($nodisable == 0) {
+ while (my ($key, $value) = each(%disable_users)) {
+ $sth_disable->execute('auto-disabled by ldap sync', $key);
+ }
+ print "done!\n" unless $quiet;
+ }
+ else {
+ print "disabled!\n" unless $quiet;
+ }
+
+ print "Phase 2: updating existing users... " unless $quiet;
+
+ if ($noupdate == 0) {
+ while (my ($key, $value) = each(%update_users)) {
+ my $user = Bugzilla::User->check($key);
+ if (defined $value->{'new_login_name'}) {
+ $user->set_login($value->{'new_login_name'});
}
- print "done!\n" unless $quiet;
- }
- else {
- print "disabled!\n" unless $quiet;
- }
-
- print "Phase 3: creating new users... " unless $quiet;
- if($nocreate == 0) {
- while( my ($key, $value) = each(%create_users) ) {
- Bugzilla::User->create({
- login_name => $key,
- realname => $value->{'realname'},
- cryptpassword => '*'});
+ else {
+ $user->set_name($value->{'realname'});
}
- print "done!\n" unless $quiet;
- }
- else {
- print "disabled!\n" unless $quiet;
- }
+ $user->update();
+ }
+ print "done!\n" unless $quiet;
+ }
+ else {
+ print "disabled!\n" unless $quiet;
+ }
+
+ print "Phase 3: creating new users... " unless $quiet;
+ if ($nocreate == 0) {
+ while (my ($key, $value) = each(%create_users)) {
+ Bugzilla::User->create(
+ {login_name => $key, realname => $value->{'realname'}, cryptpassword => '*'});
+ }
+ print "done!\n" unless $quiet;
+ }
+ else {
+ print "disabled!\n" unless $quiet;
+ }
}
-else
-{
- print "No changes to DB because readonly mode\n" unless $quiet;
+else {
+ print "No changes to DB because readonly mode\n" unless $quiet;
}