Commit 1015a17e authored by Dylan William Hardison's avatar Dylan William Hardison Committed by Давид Добряков

Synthesis #1: Adopt utf8mb4 and DBIx::Connector (#79)

* use base to make merging with bmo easier * Revert "Bug 1497042 - Enclose table names in CREATE queries" This reverts commit 62d5637a. * refactor Bugzilla::DB to not subclass DBI * use DBIx::Connector to manage database connections * Ensure we always call DBIx::Connector->dbh before any DBI method The code didn't allow a way of doing this without a lot of work. So I had to take the following approach: The 'dbh' attribute is now a method that delegates to DBIx::Connector's dbh method. Per the docs, ->dbh() "Returns the connection's database handle. It will use a an existing handle if there is one, if the process has not been forked or a new thread spawned, and if the database is pingable. Otherwise, it will instantiate, cache, and return a new handle." Then there is the matter of the 'handles' on dbh. I've used Package::Stash to insert proxy methods into the class when it is loaded. * Bug 1328659 - Add support for utf8=utf8mb4 (switches to dynamic/compressed row format, and changes charset to utf8mb4) * add deps * add prepare_cached to the list of delegated methods. This was added in bug 340160 * improve the migration to compressed/dynamic rows, skip views * add missing semicolon * remove pre-utf8mb4 emoji support * fix small issue * add debugging fatal error
parent 6af866c2
......@@ -701,7 +701,6 @@ sub _cleanup {
foreach my $dbh ($main, $shadow) {
next if !$dbh;
$dbh->bz_rollback_transaction() if $dbh->bz_in_transaction;
$dbh->disconnect;
}
my $smtp = $cache->{smtp};
$smtp->disconnect if $smtp;
......
......@@ -48,7 +48,7 @@ use File::Copy;
use List::Util qw(max);
use Storable qw(dclone);
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
###############################
#### Initialization ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Login);
use base qw(Bugzilla::Auth::Login);
use constant user_can_create_account => 1;
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Login);
use base qw(Bugzilla::Auth::Login);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Verify);
use base qw(Bugzilla::Auth::Verify);
use Bugzilla::Constants;
use Bugzilla::Token;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Auth::Verify);
use base qw(Bugzilla::Auth::Verify);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -36,7 +36,7 @@ use List::Util qw(min max first);
use Storable qw(dclone);
use Scalar::Util qw(blessed);
use parent qw(Bugzilla::Object Exporter);
use base qw(Bugzilla::Object Exporter);
@Bugzilla::Bug::EXPORT = qw(
bug_alias_to_id
LogActivityEntry
......@@ -3772,17 +3772,6 @@ sub comments {
foreach my $comment (@{$self->{'comments'}}) {
$comment->{count} = $count++;
$comment->{bug} = $self;
# XXX - hack for MySQL. Convert [U+....] back into its Unicode
# equivalent for characters above U+FFFF as MySQL older than 5.5.3
# cannot store them, see Bugzilla::Comment::_check_thetext().
if ($is_mysql) {
# Perl 5.13.8 and older complain about non-characters.
no warnings 'utf8';
$comment->{thetext}
=~ s/\x{FDD0}\[U\+((?:[1-9A-F]|10)[0-9A-F]{4})\]\x{FDD1}/chr(hex $1)/eg;
}
}
# Some bugs may have no comments when upgrading old installations.
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Util;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
use Bugzilla::Error;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl::Bugzilla);
use base qw(Bugzilla::BugUrl::Bugzilla);
use Bugzilla::Error;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::BugUrl);
use base qw(Bugzilla::BugUrl);
###############################
#### Methods ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
#####################################################################
# Overriden Constants that are used as methods
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(CGI);
use base qw(CGI);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -17,7 +17,7 @@ use Bugzilla::Util;
use Bugzilla::Error;
use Bugzilla::Product;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object Exporter);
use base qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object Exporter);
@Bugzilla::Classification::EXPORT = qw(sort_products_by_classification);
###############################
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Attachment;
use Bugzilla::Comment::TagWeights;
......@@ -450,20 +450,6 @@ sub _check_thetext {
$thetext =~ s/\s*$//s;
$thetext =~ s/\r\n?/\n/g; # Get rid of \r.
# Characters above U+FFFF cannot be stored by MySQL older than 5.5.3 as they
# require the new utf8mb4 character set. Other DB servers are handling them
# without any problem. So we need to replace these characters if we use MySQL,
# else the comment is truncated.
# XXX - Once we use utf8mb4 for comments, this hack for MySQL can go away.
state $is_mysql = Bugzilla->dbh->isa('Bugzilla::DB::Mysql') ? 1 : 0;
if ($is_mysql) {
# Perl 5.13.8 and older complain about non-characters.
no warnings 'utf8';
$thetext
=~ s/([\x{10000}-\x{10FFFF}])/"\x{FDD0}[" . uc(sprintf('U+%04x', ord($1))) . "]\x{FDD1}"/eg;
}
ThrowUserError('comment_too_long') if length($thetext) > MAX_COMMENT_LENGTH;
return $thetext;
}
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use base qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
use autodie qw(:default);
use Bugzilla::Constants;
......@@ -341,6 +341,8 @@ sub read_param_file {
die "The $file file does not exist."
. ' You probably need to run checksetup.pl.',;
}
die "the param utf8 must be set to utf8mb4" unless $params{utf8} eq 'utf8mb4';
return \%params;
}
......
......@@ -20,7 +20,7 @@ use Bugzilla::Field;
use Bugzilla::Group;
use Bugzilla::Status;
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Config::Common::EXPORT
= qw(check_multi check_numeric check_regexp check_url check_group
check_sslbase check_priority check_severity check_platform
......@@ -123,15 +123,16 @@ sub check_ip {
}
sub check_utf8 {
my $utf8 = shift;
my ($utf8, $entry) = @_;
# You cannot turn off the UTF-8 parameter if you've already converted
# your tables to utf-8.
my $dbh = Bugzilla->dbh;
if ($dbh->isa('Bugzilla::DB::Mysql') && $dbh->bz_db_is_utf8 && !$utf8) {
return "You cannot disable UTF-8 support, because your MySQL database"
. " is encoded in UTF-8";
# You cannot turn off the UTF-8 parameter.
if (!$utf8) {
return "You cannot disable UTF-8 support.";
}
elsif ($entry eq 'utf8mb4' && $utf8 ne 'utf8mb4') {
return "You cannot disable UTF8-MB4 support.";
}
return "";
}
......
......@@ -24,7 +24,13 @@ use constant get_param_list => (
checker => \&check_email
},
{name => 'utf8', type => 'b', default => '0', checker => \&check_utf8},
{
name => 'utf8',
type => 's',
choices => ['1', 'utf8', 'utf8mb4'],
default => 'utf8',
checker => \&check_utf8
},
{name => 'shutdownhtml', type => 'l', default => ''},
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
# For bz_locations
use File::Basename;
......
......@@ -8,13 +8,13 @@
package Bugzilla::DB;
use 5.10.1;
use strict;
use warnings;
use Moo;
use DBI;
use DBIx::Connector;
our %Connector;
# Inherit the DB class from DBI::db.
use parent -norequire, qw(DBI::db);
has 'connector' => (is => 'lazy', handles => [qw( dbh )],);
use Bugzilla::Constants;
use Bugzilla::Mailer;
......@@ -29,6 +29,32 @@ use Bugzilla::Version;
use List::Util qw(max);
use Storable qw(dclone);
has [qw(dsn user pass attrs)] => (is => 'ro', required => 1,);
# Install proxy methods to the DBI object.
# We can't use handles() as DBIx::Connector->dbh has to be called each
# time we need a DBI handle to ensure the connection is alive.
{
my @DBI_METHODS = qw(
begin_work column_info commit disconnect do errstr get_info last_insert_id
ping prepare prepare_cached primary_key quote_identifier rollback
selectall_arrayref selectall_hashref selectcol_arrayref selectrow_array
selectrow_arrayref selectrow_hashref table_info
);
my $stash = Package::Stash->new(__PACKAGE__);
foreach my $method (@DBI_METHODS) {
my $symbol = '&' . $method;
$stash->add_symbol(
$symbol => sub {
my $self = shift;
return $self->dbh->$method(@_);
}
);
}
}
#####################################################################
# Constants
#####################################################################
......@@ -88,7 +114,7 @@ use constant INDEX_DROPS_REQUIRE_FK_DROPS => 1;
sub quote {
my $self = shift;
my $retval = $self->SUPER::quote(@_);
my $retval = $self->dbh->quote(@_);
trick_taint($retval) if defined $retval;
return $retval;
}
......@@ -130,9 +156,7 @@ sub _connect {
"'$driver' is not a valid choice for \$db_driver in " . " localconfig: " . $@);
# instantiate the correct DB specific module
my $dbh = $pkg_module->new($params);
return $dbh;
return $pkg_module->new($params);
}
sub _handle_error {
......@@ -200,7 +224,6 @@ sub bz_check_server_version {
my ($self, $db, $output) = @_;
my $sql_vers = $self->bz_server_version;
$self->disconnect;
my $sql_want = $db->{db_version};
my $version_ok = vers_cmp($sql_vers, $sql_want) > -1 ? 1 : 0;
......@@ -261,7 +284,6 @@ sub bz_create_database {
}
}
$dbh->disconnect;
}
# A helper for bz_create_database and bz_check_requirements.
......@@ -270,6 +292,7 @@ sub _get_no_db_connection {
my $dbh;
my %connect_params = %{Bugzilla->localconfig};
$connect_params{db_name} = '';
local %Connector = ();
my $conn_success = eval { $dbh = _connect(\%connect_params); };
if (!$conn_success) {
my $driver = $connect_params{db_driver};
......@@ -1299,14 +1322,15 @@ sub bz_rollback_transaction {
# Subclass Helpers
#####################################################################
sub db_new {
my ($class, $params) = @_;
my ($dsn, $user, $pass, $override_attrs) = @$params{qw(dsn user pass attrs)};
sub _build_connector {
my ($self) = @_;
my ($dsn, $user, $pass, $override_attrs)
= map { $self->$_ } qw(dsn user pass attrs);
# set up default attributes used to connect to the database
# (may be overridden by DB driver implementations)
my $attributes = {
RaiseError => 0,
RaiseError => 1,
AutoCommit => 1,
PrintError => 0,
ShowErrorStatement => 1,
......@@ -1323,20 +1347,14 @@ sub db_new {
$attributes->{$key} = $override_attrs->{$key};
}
}
my $class = ref $self;
if ($class->can('on_dbi_connected')) {
$attributes->{Callbacks}
= {connected => sub { $class->on_dbi_connected(@_); return },};
}
# connect using our known info to the specified db
my $self = DBI->connect($dsn, $user, $pass, $attributes)
or die "\nCan't connect to the database.\nError: $DBI::errstr\n"
. " Is your database installed and up and running?\n Do you have"
. " the correct username and password selected in localconfig?\n\n";
# RaiseError was only set to 0 so that we could catch the
# above "die" condition.
$self->{RaiseError} = 1;
bless($self, $class);
return $self;
return $Connector{"$user.$dsn"}
//= DBIx::Connector->new($dsn, $user, $pass, $attributes);
}
#####################################################################
......
......@@ -22,10 +22,9 @@ For interface details see L<Bugzilla::DB> and L<DBI>.
package Bugzilla::DB::Oracle;
use 5.10.1;
use strict;
use warnings;
use Moo;
use parent qw(Bugzilla::DB);
extends qw(Bugzilla::DB);
use DBD::Oracle;
use DBD::Oracle qw(:ora_types);
......@@ -46,7 +45,7 @@ use constant BLOB_TYPE => {ora_type => ORA_BLOB};
use constant MIN_LONG_READ_LEN => 32 * 1024;
use constant FULLTEXT_OR => ' OR ';
sub new {
sub BUILDARGS {
my ($class, $params) = @_;
my ($user, $pass, $host, $dbname, $port)
= @$params{qw(db_user db_pass db_host db_name db_port)};
......@@ -66,24 +65,21 @@ sub new {
LongReadLen =>
max(Bugzilla->params->{'maxattachmentsize'} || 0, MIN_LONG_READ_LEN) * 1024,
};
my $self = $class->db_new(
{dsn => $dsn, user => $user, pass => $pass, attrs => $attrs});
# Needed by TheSchwartz
$self->{private_bz_dsn} = $dsn;
return {dsn => $dsn, user => $user, pass => $pass, attrs => $attrs};
}
bless($self, $class);
sub on_dbi_connected {
my ($class, $dbh) = @_;
# Set the session's default date format to match MySQL
$self->do("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
$self->do("ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS'");
$self->do("ALTER SESSION SET NLS_LENGTH_SEMANTICS='CHAR'")
$dbh->do("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
$dbh->do("ALTER SESSION SET NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS'");
$dbh->do("ALTER SESSION SET NLS_LENGTH_SEMANTICS='CHAR'")
if Bugzilla->params->{'utf8'};
# To allow case insensitive query.
$self->do("ALTER SESSION SET NLS_COMP='ANSI'");
$self->do("ALTER SESSION SET NLS_SORT='BINARY_AI'");
return $self;
$dbh->do("ALTER SESSION SET NLS_COMP='ANSI'");
$dbh->do("ALTER SESSION SET NLS_SORT='BINARY_AI'");
}
sub bz_last_key {
......@@ -752,7 +748,7 @@ use 5.10.1;
use strict;
use warnings;
use parent -norequire, qw(DBI::st);
use base -norequire, qw(DBI::st);
sub fetchrow_arrayref {
my $self = shift;
......
......@@ -22,19 +22,18 @@ For interface details see L<Bugzilla::DB> and L<DBI>.
package Bugzilla::DB::Pg;
use 5.10.1;
use strict;
use warnings;
use Moo;
use Bugzilla::Error;
use Bugzilla::Version;
use DBD::Pg;
# This module extends the DB interface via inheritance
use parent qw(Bugzilla::DB);
extends qw(Bugzilla::DB);
use constant BLOB_TYPE => {pg_type => DBD::Pg::PG_BYTEA};
sub new {
sub BUILDARGS {
my ($class, $params) = @_;
my ($user, $pass, $host, $dbname, $port)
= @$params{qw(db_user db_pass db_host db_name db_port)};
......@@ -55,19 +54,7 @@ sub new {
my $attrs = {pg_enable_utf8 => Bugzilla->params->{'utf8'}};
my $self = $class->db_new(
{dsn => $dsn, user => $user, pass => $pass, attrs => $attrs});
# all class local variables stored in DBI derived class needs to have
# a prefix 'private_'. See DBI documentation.
$self->{private_bz_tables_locked} = "";
# Needed by TheSchwartz
$self->{private_bz_dsn} = $dsn;
bless($self, $class);
return $self;
return {dsn => $dsn, user => $user, pass => $pass, attrs => $attrs};
}
# if last_insert_id is supported on PostgreSQL by lowest DBI/DBD version
......
......@@ -19,7 +19,7 @@ use warnings;
use Bugzilla::Error;
use parent qw(Bugzilla::DB::Schema);
use base qw(Bugzilla::DB::Schema);
# This is for column_info_to_column, to know when a tinyint is a
# boolean and when it's really a tinyint. This only has to be accurate
......@@ -85,8 +85,6 @@ use constant REVERSE_MAPPING => {
# as in their db-specific version, so no reverse mapping is needed.
};
use constant MYISAM_TABLES => qw();
#------------------------------------------------------------------------------
sub _initialize {
......@@ -128,20 +126,16 @@ sub _initialize {
#------------------------------------------------------------------------------
sub _get_create_table_ddl {
# Extend superclass method to specify the MYISAM storage engine.
# Returns a "create table" SQL statement.
my ($self, $table) = @_;
my $charset = Bugzilla->dbh->bz_db_is_utf8 ? "CHARACTER SET utf8" : '';
my $type = grep($_ eq $table, MYISAM_TABLES) ? 'MYISAM' : 'InnoDB';
my $ddl = $self->SUPER::_get_create_table_ddl($table);
$ddl =~ s/CREATE TABLE (.*) \(/CREATE TABLE `$1` (/;
$ddl .= " ENGINE = $type $charset";
return $ddl;
my $charset = Bugzilla::DB::Mysql->utf8_charset;
my $collate = Bugzilla::DB::Mysql->utf8_collate;
my $row_format = Bugzilla::DB::Mysql->default_row_format($table);
my @parts = (
$self->SUPER::_get_create_table_ddl($table), 'ENGINE = InnoDB',
"CHARACTER SET $charset COLLATE $collate", "ROW_FORMAT=$row_format",
);
return join(' ', @parts);
} #eosub--_get_create_table_ddl
#------------------------------------------------------------------------------
......@@ -155,7 +149,7 @@ sub _get_create_index_ddl {
my $sql = "CREATE ";
$sql .= "$index_type "
if ($index_type eq 'UNIQUE' || $index_type eq 'FULLTEXT');
$sql .= "INDEX \`$index_name\` ON \`$table_name\` \("
$sql .= "INDEX \`$index_name\` ON $table_name \("
. join(", ", @$index_fields) . "\)";
return ($sql);
......@@ -169,10 +163,9 @@ sub get_create_database_sql {
# We only create as utf8 if we have no params (meaning we're doing
# a new installation) or if the utf8 param is on.
my $create_utf8
= Bugzilla->params->{'utf8'} || !defined Bugzilla->params->{'utf8'};
my $charset = $create_utf8 ? "CHARACTER SET utf8" : '';
return ("CREATE DATABASE $name $charset");
my $charset = Bugzilla::DB::Mysql->utf8_charset;
my $collate = Bugzilla::DB::Mysql->utf8_collate;
return ("CREATE DATABASE $name CHARACTER SET $charset COLLATE $collate");
}
# MySQL has a simpler ALTER TABLE syntax than ANSI.
......
......@@ -17,7 +17,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);
use base qw(Bugzilla::DB::Schema);
use Carp qw(confess);
use Bugzilla::Util;
......
......@@ -17,7 +17,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);
use base qw(Bugzilla::DB::Schema);
use Storable qw(dclone);
#------------------------------------------------------------------------------
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::DB::Schema);
use base qw(Bugzilla::DB::Schema);
use Bugzilla::Error;
use Bugzilla::Util qw(generate_random_password);
......
......@@ -8,10 +8,9 @@
package Bugzilla::DB::Sqlite;
use 5.10.1;
use strict;
use warnings;
use Moo;
use parent qw(Bugzilla::DB);
extends qw(Bugzilla::DB);
use Bugzilla::Constants;
use Bugzilla::Error;
......@@ -69,7 +68,7 @@ sub _sqlite_position_ci {
# Constructor #
###############
sub new {
sub BUILDARGS {
my ($class, $params) = @_;
my $db_name = $params->{db_name};
......@@ -99,11 +98,11 @@ sub new {
sqlite_unicode => Bugzilla->params->{'utf8'},
};
my $self
= $class->db_new({dsn => $dsn, user => '', pass => '', attrs => $attrs});
return {dsn => $dsn, user => '', pass => '', attrs => $attrs};
}
# Needed by TheSchwartz
$self->{private_bz_dsn} = $dsn;
sub on_dbi_connected {
my ($class, $dbh) = @_;
my %pragmas = (
......@@ -129,12 +128,12 @@ sub new {
);
while (my ($name, $value) = each %pragmas) {
$self->do("PRAGMA $name = $value");
$dbh->do("PRAGMA $name = $value");
}
$self->sqlite_create_collation('bugzilla', \&_sqlite_collate_ci);
$self->sqlite_create_function('position', 2, \&_sqlite_position);
$self->sqlite_create_function('iposition', 2, \&_sqlite_position_ci);
$dbh->sqlite_create_collation('bugzilla', \&_sqlite_collate_ci);
$dbh->sqlite_create_function('position', 2, \&_sqlite_position);
$dbh->sqlite_create_function('iposition', 2, \&_sqlite_position_ci);
# SQLite has a "substr" function, but other DBs call it "SUBSTRING"
# so that's what we use, and I don't know of any way in SQLite to
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError);
......
......@@ -245,7 +245,7 @@ F<extensions/Foo.pm>:
package Bugzilla::Extension::Foo
use strict;
use parent qw(Bugzilla::Extension);
use base qw(Bugzilla::Extension);
our $VERSION = '0.02';
use constant NAME => 'Foo';
......
......@@ -61,7 +61,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter Bugzilla::Object);
use base qw(Exporter Bugzilla::Object);
@Bugzilla::Field::EXPORT = qw(check_field get_field_id get_legal_field_values);
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use base qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use Bugzilla::Config qw(SetParam write_params);
use Bugzilla::Constants;
......@@ -99,7 +99,7 @@ sub type {
if (!defined *{"${package}::DB_TABLE"}) {
eval <<EOC;
package $package;
use parent qw(Bugzilla::Field::Choice);
use base qw(Bugzilla::Field::Choice);
use constant DB_TABLE => '$field_name';
EOC
}
......
......@@ -51,7 +51,7 @@ use Bugzilla::Mailer;
use Bugzilla::Constants;
use Bugzilla::Field;
use parent qw(Bugzilla::Object Exporter);
use base qw(Bugzilla::Object Exporter);
@Bugzilla::Flag::EXPORT = qw(SKIP_REQUESTEE_ON_ERROR);
###############################
......
......@@ -43,7 +43,7 @@ use Bugzilla::Group;
use Email::Address;
use List::MoreUtils qw(uniq);
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
###############################
#### Initialization ####
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT = qw(
BZ_LIB
......
......@@ -34,7 +34,7 @@ use File::Spec;
use IO::File;
use POSIX ();
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT = qw(
update_filesystem
create_htaccess
......
......@@ -28,7 +28,7 @@ use File::Basename qw(dirname);
use Safe;
use Term::ANSIColor;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT_OK = qw(
read_localconfig
......
......@@ -23,7 +23,7 @@ use Bugzilla::Install::Util qw(install_string bin_loc
use List::Util qw(max);
use Term::ANSIColor;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT = qw(
REQUIRED_MODULES
OPTIONAL_MODULES
......@@ -64,11 +64,11 @@ use constant APACHE => qw(apachectl httpd apache2 apache);
# If we don't find any of the above binaries in the normal PATH,
# these are extra places we look.
use constant APACHE_PATH => [qw(
/usr/sbin
/usr/local/sbin
/usr/libexec
/usr/local/libexec
)];
/usr/sbin
/usr/local/sbin
/usr/libexec
/usr/local/libexec
)];
# The below two constants are subroutines so that they can implement
# a hook. Other than that they are actually constants.
......@@ -114,6 +114,10 @@ sub REQUIRED_MODULES {
version => ($^V >= v5.13.3) ? '1.614' : '1.54'
},
{package => 'DBIx-Connector', module => 'DBIx::Connector', version => '0.56',},
{package => 'Moo', module => 'Moo', version => '2.003004',},
# 2.24 contains several useful text virtual methods.
{package => 'Template-Toolkit', module => 'Template', version => '2.24'},
......@@ -747,7 +751,7 @@ sub have_vers {
my $blacklisted;
if ($vok && $params->{blacklist}) {
$blacklisted = grep($vnum =~ /$_/, @{$params->{blacklist}});
$vok = 0 if $blacklisted;
$vok = 0 if $blacklisted;
}
if ($output) {
......
......@@ -25,7 +25,7 @@ use Scalar::Util qw(tainted);
use Term::ANSIColor qw(colored);
use PerlIO;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT_OK = qw(
bin_loc
get_version_and_os
......
......@@ -12,7 +12,7 @@ use strict;
use warnings;
use Bugzilla::BugMail;
BEGIN { eval "use parent qw(Bugzilla::Job::Mailer)"; }
BEGIN { eval "use base qw(Bugzilla::Job::Mailer)"; }
sub work {
my ($class, $job) = @_;
......
......@@ -12,7 +12,7 @@ use strict;
use warnings;
use Bugzilla::Mailer;
BEGIN { eval "use parent qw(TheSchwartz::Worker)"; }
BEGIN { eval "use base qw(TheSchwartz::Worker)"; }
# The longest we expect a job to possibly take, in seconds.
use constant grab_for => 300;
......
......@@ -56,7 +56,7 @@ sub new {
# to write to it.
my $self = $class->SUPER::new(
databases => [{
dsn => Bugzilla->dbh_main->{private_bz_dsn},
dsn => Bugzilla->dbh_main->dsn,
user => $lc->{db_user},
pass => $lc->{db_pass},
prefix => 'ts_',
......
......@@ -23,7 +23,7 @@ use Pod::Usage;
use Bugzilla::Constants;
use Bugzilla::JobQueue;
use Bugzilla::Util qw(get_text);
BEGIN { eval "use parent qw(Daemon::Generic)"; }
BEGIN { eval "use base qw(Daemon::Generic)"; }
our $VERSION = BUGZILLA_VERSION;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Error;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Email::MIME);
use base qw(Email::MIME);
sub new {
my ($class, $msg) = @_;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Mailer::EXPORT = qw(MessageToMTA build_thread_marker generate_email);
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Migrate);
use base qw(Bugzilla::Migrate);
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(indicate_progress);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use base qw(Bugzilla::Field::ChoiceInterface Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Util;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
use Bugzilla::Constants qw(ON_WINDOWS);
use Math::Random::ISAAC;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::CGI;
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Search::EXPORT = qw(
IsValidQueryType
split_order_term
......@@ -1790,7 +1790,6 @@ sub _handle_chart {
$field = FIELD_MAP->{$field} || $field;
my ($string_value, $orig_value);
state $is_mysql = $dbh->isa('Bugzilla::DB::Mysql') ? 1 : 0;
if (ref $value eq 'ARRAY') {
......@@ -1799,17 +1798,11 @@ sub _handle_chart {
@$value = grep { defined $_ and $_ ne '' } @$value;
return if !@$value;
$orig_value = join(',', @$value);
if ($field eq 'longdesc' && $is_mysql) {
@$value = map { _convert_unicode_characters($_) } @$value;
}
$string_value = join(',', @$value);
}
else {
return if $value eq '';
$orig_value = $value;
if ($field eq 'longdesc' && $is_mysql) {
$value = _convert_unicode_characters($value);
}
$string_value = $value;
}
......@@ -1870,19 +1863,6 @@ sub _handle_chart {
$condition->translated(\%search_args);
}
# XXX - This is a hack for MySQL which doesn't understand Unicode characters
# above U+FFFF, see Bugzilla::Comment::_check_thetext(). This hack can go away
# once we require MySQL 5.5.3 and use utf8mb4.
sub _convert_unicode_characters {
my $string = shift;
# Perl 5.13.8 and older complain about non-characters.
no warnings 'utf8';
$string
=~ s/([\x{10000}-\x{10FFFF}])/"\x{FDD0}[" . uc(sprintf('U+%04x', ord($1))) . "]\x{FDD1}"/eg;
return $string;
}
##################################
# do_search_function And Helpers #
##################################
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Search::Clause);
use base qw(Bugzilla::Search::Clause);
use Bugzilla::Error;
use Bugzilla::Search::Condition qw(condition);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT_OK = qw(condition);
sub new {
......
......@@ -22,7 +22,7 @@ use List::Util qw(min max);
use List::MoreUtils qw(firstidx);
use Text::ParseWords qw(parse_line);
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Search::Quicksearch::EXPORT = qw(quicksearch);
# Custom mappings for some fields.
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::CGI;
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Email::Sender::Transport::Sendmail);
use base qw(Email::Sender::Transport::Sendmail);
use Email::Sender::Failure;
......
......@@ -15,7 +15,7 @@ use warnings;
# ChoiceInterface, because a bug status literally is a special type
# of Field::Choice, not just an object that happens to have the same
# methods.
use parent qw(Bugzilla::Field::Choice Exporter);
use base qw(Bugzilla::Field::Choice Exporter);
@Bugzilla::Status::EXPORT = qw(
BUG_STATE_OPEN
SPECIAL_STATUS_WORKFLOW_ACTIONS
......
......@@ -37,7 +37,7 @@ use IO::Dir;
use List::MoreUtils qw(firstidx);
use Scalar::Util qw(blessed);
use parent qw(Template);
use base qw(Template);
use constant FORMAT_TRIPLE => '%19s|%-28s|%-28s';
use constant FORMAT_3_SIZE => [19, 28, 28];
......
......@@ -12,7 +12,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Template::Context);
use base qw(Template::Context);
use Bugzilla::Hook;
use Scalar::Util qw(blessed);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Template::Plugin);
use base qw(Template::Plugin);
use Bugzilla;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Template::Plugin);
use base qw(Template::Plugin);
use Bugzilla::Constants;
use Bugzilla::Install::Util qw(template_include_path);
......
......@@ -22,7 +22,7 @@ use Date::Parse;
use File::Basename;
use Digest::SHA qw(hmac_sha256_base64);
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Token::EXPORT = qw(issue_api_token issue_session_token
check_token_data delete_token
......
......@@ -31,7 +31,7 @@ use Storable qw(dclone);
use URI;
use URI::QueryParam;
use parent qw(Bugzilla::Object Exporter);
use base qw(Bugzilla::Object Exporter);
@Bugzilla::User::EXPORT = qw(is_available_username
login_to_id validate_password validate_password_check
USER_MATCH_MULTIPLE USER_MATCH_FAILED USER_MATCH_SUCCESS
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::User;
use Bugzilla::Util qw(generate_random_password trim);
......
......@@ -12,7 +12,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
# Module stuff
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::User::Setting);
use base qw(Bugzilla::User::Setting);
use Bugzilla::Constants;
......
......@@ -12,7 +12,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::User::Setting);
use base qw(Bugzilla::User::Setting);
use Bugzilla::Constants;
use File::Spec::Functions;
......
......@@ -13,7 +13,7 @@ use warnings;
use DateTime::TimeZone;
use parent qw(Bugzilla::User::Setting);
use base qw(Bugzilla::User::Setting);
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT = qw(detect_platform detect_op_sys);
use Bugzilla::Field;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
@Bugzilla::Util::EXPORT = qw(trick_taint detaint_natural detaint_signed
html_quote url_quote xml_quote
css_class_quote html_light_quote
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object Exporter);
use base qw(Bugzilla::Object Exporter);
@Bugzilla::Version::EXPORT = qw(vers_cmp);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Comment;
use Bugzilla::Comment::TagWeights;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Bug;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Constants;
use Bugzilla::Util qw(datetime_from);
use Bugzilla::WebService::Util qw(validate filter_wants);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw (Bugzilla::WebService);
use base qw (Bugzilla::WebService);
use Bugzilla::Classification;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Exporter);
use base qw(Exporter);
our @EXPORT = qw(
WS_ERROR_CODE
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Component;
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::WebService::Util qw(validate translate params_to_objects);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Product;
use Bugzilla::User;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService::Server::JSONRPC);
use base qw(Bugzilla::WebService::Server::JSONRPC);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -132,7 +132,7 @@ use 5.10.1;
use strict;
use warnings;
# We can't use "use parent" because XMLRPC::Serializer doesn't return
# We can't use "use base" because XMLRPC::Serializer doesn't return
# a true value.
use XMLRPC::Lite;
our @ISA = qw(XMLRPC::Deserializer);
......@@ -287,7 +287,7 @@ use warnings;
use Scalar::Util qw(blessed reftype);
# We can't use "use parent" because XMLRPC::Serializer doesn't return
# We can't use "use base" because XMLRPC::Serializer doesn't return
# a true value.
use XMLRPC::Lite;
our @ISA = qw(XMLRPC::Serializer);
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::WebService);
use base qw(Bugzilla::WebService);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -18,7 +18,7 @@ use Bugzilla::Error;
use Storable qw(dclone);
use List::MoreUtils qw(any none);
use parent qw(Exporter);
use base qw(Exporter);
# We have to "require", not "use" this, because otherwise it tries to
# use features of Test::More during import().
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Error;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
use Bugzilla::Search::Saved;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Bugzilla::Object);
use base qw(Bugzilla::Object);
use Bugzilla::Constants;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Pod::Simple::HTML);
use base qw(Pod::Simple::HTML);
# Without this constant, HTMLBatch will throw undef warnings.
use constant VERSION => $Pod::Simple::HTML::VERSION;
......
......@@ -11,7 +11,7 @@ use 5.10.1;
use strict;
use warnings;
use parent qw(Pod::Simple::HTMLBatch);
use base qw(Pod::Simple::HTMLBatch);
# This is the same hack that HTMLBatch does to "import" this subroutine.
BEGIN { *esc = \&Pod::Simple::HTML::esc }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment