]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
refactor Bugzilla::DB to not subclass DBI
authorDylan William Hardison <dylan@hardison.net>
Sun, 7 Jul 2019 20:28:28 +0000 (16:28 -0400)
committerDylan William Hardison <dylan@hardison.net>
Sun, 7 Jul 2019 23:26:39 +0000 (19:26 -0400)
Bugzilla/DB.pm
Bugzilla/DB/Mysql.pm
Bugzilla/DB/Oracle.pm
Bugzilla/DB/Pg.pm
Bugzilla/DB/Sqlite.pm
Bugzilla/JobQueue.pm

index b9b6db2ba52c4c0c2dada4e4584d70603068fe93..2b89d781f079be05fa0722723e313206407484b0 100644 (file)
@@ -8,13 +8,18 @@
 package Bugzilla::DB;
 
 use 5.10.1;
-use strict;
-use warnings;
+use Moo;
 
 use DBI;
 
-# Inherit the DB class from DBI::db.
-use base qw(DBI::db);
+has 'dbh' => (
+  is      => 'lazy',
+  handles => [qw[
+    begin_work column_info commit disconnect do errstr get_info last_insert_id ping prepare
+    primary_key quote_identifier rollback selectall_arrayref selectall_hashref
+    selectcol_arrayref selectrow_array selectrow_arrayref selectrow_hashref table_info
+  ]],
+);
 
 use Bugzilla::Constants;
 use Bugzilla::Mailer;
@@ -29,6 +34,8 @@ use Bugzilla::Version;
 use List::Util qw(max);
 use Storable qw(dclone);
 
+has [qw(dsn user pass attrs)] => (is => 'ro', required => 1,);
+
 #####################################################################
 # Constants
 #####################################################################
@@ -88,7 +95,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;
 }
@@ -1299,9 +1306,10 @@ 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_dbh {
+  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)
@@ -1323,20 +1331,23 @@ 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)
+  my $dbh = 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;
+  $dbh->{RaiseError} = 1;
 
-  bless($self, $class);
-
-  return $self;
+  return $dbh;
 }
 
 #####################################################################
index 8c53da7a3d0c2d86a0226a0d82cdb67405e31bd1..1cf0ee5d7e6bce6c488a6202cb38cc5b408d95d2 100644 (file)
@@ -22,10 +22,9 @@ For interface details see L<Bugzilla::DB> and L<DBI>.
 package Bugzilla::DB::Mysql;
 
 use 5.10.1;
-use strict;
-use warnings;
+use Moo;
 
-use base qw(Bugzilla::DB);
+extends qw(Bugzilla::DB);
 
 use Bugzilla::Constants;
 use Bugzilla::Install::Util qw(install_string);
@@ -43,7 +42,7 @@ use constant MAX_COMMENTS => 50;
 
 use constant FULLTEXT_OR => '|';
 
-sub new {
+sub BUILDARGS {
   my ($class, $params) = @_;
   my ($user, $pass, $host, $dbname, $port, $sock)
     = @$params{qw(db_user db_pass db_host db_name db_port db_sock)};
@@ -53,12 +52,7 @@ sub new {
   $dsn .= ";port=$port"         if $port;
   $dsn .= ";mysql_socket=$sock" if $sock;
 
-  my %attrs = (
-    mysql_enable_utf8 => Bugzilla->params->{'utf8'},
-
-    # Needs to be explicitly specified for command-line processes.
-    mysql_auto_reconnect => 1,
-  );
+  my %attrs = (mysql_enable_utf8 => Bugzilla->params->{'utf8'},);
 
   # MySQL SSL options
   my ($ssl_ca_file, $ssl_ca_path, $ssl_cert, $ssl_key) = @$params{
@@ -73,25 +67,19 @@ sub new {
     $attrs{'mysql_ssl_client_key'}  = $ssl_key if $ssl_key;
   }
 
-  my $self = $class->db_new(
-    {dsn => $dsn, user => $user, pass => $pass, attrs => \%attrs});
+  return {dsn => $dsn, user => $user, pass => $pass, attrs => \%attrs};
+}
+
+sub on_dbi_connected {
+  my ($class, $dbh) = @_;
 
   # This makes sure that if the tables are encoded as UTF-8, we
   # return their data correctly.
-  $self->do("SET NAMES utf8") if Bugzilla->params->{'utf8'};
-
-  # 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);
+  $dbh->do("SET NAMES utf8") if Bugzilla->params->{'utf8'};
 
   # Check for MySQL modes.
   my ($var, $sql_mode)
-    = $self->selectrow_array("SHOW VARIABLES LIKE 'sql\\_mode'");
+    = $dbh->selectrow_array("SHOW VARIABLES LIKE 'sql\\_mode'");
 
   # Disable ANSI and strict modes, else Bugzilla will crash.
   if ($sql_mode) {
@@ -104,19 +92,17 @@ sub new {
         split(/,/, $sql_mode));
 
     if ($sql_mode ne $new_sql_mode) {
-      $self->do("SET SESSION sql_mode = ?", undef, $new_sql_mode);
+      $dbh->do("SET SESSION sql_mode = ?", undef, $new_sql_mode);
     }
   }
 
   # Allow large GROUP_CONCATs (largely for inserting comments
   # into bugs_fulltext).
-  $self->do('SET SESSION group_concat_max_len = 128000000');
+  $dbh->do('SET SESSION group_concat_max_len = 128000000');
 
   # MySQL 5.5.2 and older have this variable set to true, which causes
   # trouble, see bug 870369.
-  $self->do('SET SESSION sql_auto_is_null = 0');
-
-  return $self;
+  $dbh->do('SET SESSION sql_auto_is_null = 0');
 }
 
 # when last_insert_id() is supported on MySQL by lowest DBI/DBD version
index 48b2a3ef40cf42988009a2e9a2cf4ba2a5c5156b..73ffb4b455803fc3c0d87c8a931243292f4f1081 100644 (file)
@@ -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 base 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 {
index bf69e2a0a39f1e116650ff9b1c995bf8ee41ced6..ec4bf3f46568721cdef2e08d698d72851ba782a1 100644 (file)
@@ -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 base 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
index 8f1687cc8bf1a1437cabcb270036ad3083c88132..26741c4dee0e7f727aa46c59f8e7128a3b9aa0be 100644 (file)
@@ -8,10 +8,9 @@
 package Bugzilla::DB::Sqlite;
 
 use 5.10.1;
-use strict;
-use warnings;
+use Moo;
 
-use base 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
index e481820078fd2f8bb749edff20e036cc5ca004cd..4777e6b0cae0c5acae0f71c35180e0957b83fe7d 100644 (file)
@@ -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_',