Make contrib/bzdbcopy.pl actually work with anything other than Pg,

independent of current localconfig.

Never use Bugzilla->dbh in Bugzilla::DB::Schema, store and use $self->{dbh} instead.
hinted-selects
Vitaliy Filippov 2014-10-27 20:08:52 +03:00
parent c4c2ec3378
commit 921388813f
5 changed files with 28 additions and 41 deletions

View File

@ -1057,7 +1057,7 @@ sub _bz_schema {
return $self->{private_bz_schema} if exists $self->{private_bz_schema}; return $self->{private_bz_schema} if exists $self->{private_bz_schema};
my @module_parts = split('::', ref $self); my @module_parts = split('::', ref $self);
my $module_name = pop @module_parts; my $module_name = pop @module_parts;
$self->{private_bz_schema} = Bugzilla::DB::Schema->new($module_name); $self->{private_bz_schema} = Bugzilla::DB::Schema->new($self);
return $self->{private_bz_schema}; return $self->{private_bz_schema};
} }

View File

@ -41,6 +41,7 @@ use Bugzilla::Constants;
use Carp qw(confess); use Carp qw(confess);
use Digest::MD5 qw(md5_hex); use Digest::MD5 qw(md5_hex);
use Scalar::Util;
use Safe; use Safe;
# Historical, needed for SCHEMA_VERSION = '1.00' # Historical, needed for SCHEMA_VERSION = '1.00'
use Storable qw(dclone freeze thaw); use Storable qw(dclone freeze thaw);
@ -1340,15 +1341,15 @@ sub new {
=over =over
=item C<new> =item C<new($dbh, $driver, $schema)>
Description: Public constructor method used to instantiate objects of this Description: Public constructor method used to instantiate objects of this
class. However, it also can be used as a factory method to class. However, it also can be used as a factory method to
instantiate database-specific subclasses when an optional instantiate database-specific subclasses when an optional
driver argument is supplied. driver argument is supplied.
Parameters: $driver (optional) - Used to specify the type of database. Parameters: $dbh - Database handle this schema object is used for.
This routine C<die>s if no subclass is found for the specified The Schema subclass is also determined from the type of this object.
driver. Stored as a weak reference inside $self to prevent memory leaks.
$schema (optional) - A reference to a hash. Callers external $schema (optional) - A reference to a hash. Callers external
to this package should never use this parameter. to this package should never use this parameter.
Returns: new instance of the Schema class or a database-specific subclass Returns: new instance of the Schema class or a database-specific subclass
@ -1356,24 +1357,20 @@ sub new {
=cut =cut
my $this = shift; my $this = shift;
my $class = ref($this) || $this; my $dbh = shift;
my $driver = shift; my ($driver) = ref($dbh) =~ /^Bugzilla::DB::(.*)$/so;
die "$dbh is not an instance of Bugzilla::DB subclass" unless $driver;
if ($driver) { my $class = 'Bugzilla::DB::Schema::'.$driver;
(my $subclass = $driver) =~ s/^(\S)/\U$1/;
$class .= '::' . $subclass;
eval "require $class;"; eval "require $class;";
die "The $class class could not be found ($subclass " . die "The $class class could not be found ($driver not supported?): $@" if $@;
"not supported?): $@" if ($@);
}
die "$class is an abstract base class. Instantiate a subclass instead."
if ($class eq __PACKAGE__);
my $self = {}; my $self = { dbh => $dbh };
Scalar::Util::weaken($self->{dbh});
bless $self, $class; bless $self, $class;
$self = $self->_initialize(@_); $self = $self->_initialize(@_);
return($self); return $self;
} #eosub--new } #eosub--new
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@ -2452,7 +2449,7 @@ sub serialize_abstract {
=cut =cut
sub deserialize_abstract { sub deserialize_abstract {
my ($class, $serialized, $version) = @_; my ($self, $serialized, $version) = @_;
my $thawed_hash; my $thawed_hash;
if (int($version) < 2) { if (int($version) < 2) {
@ -2465,7 +2462,7 @@ sub deserialize_abstract {
$thawed_hash = ${$cpt->varglob('VAR1')}; $thawed_hash = ${$cpt->varglob('VAR1')};
} }
return $class->new(undef, $thawed_hash); return $self->new($self->{dbh}, $thawed_hash);
} }
##################################################################### #####################################################################

View File

@ -133,7 +133,7 @@ sub _get_create_table_ddl {
my($self, $table) = @_; my($self, $table) = @_;
my $charset = Bugzilla->dbh->bz_db_is_utf8 ? "CHARACTER SET utf8" : ''; my $charset = $self->{dbh}->bz_db_is_utf8 ? "CHARACTER SET utf8" : '';
my $type = grep($_ eq $table, MYISAM_TABLES) ? 'MYISAM' : 'InnoDB'; my $type = grep($_ eq $table, MYISAM_TABLES) ? 'MYISAM' : 'InnoDB';
return($self->SUPER::_get_create_table_ddl($table) return($self->SUPER::_get_create_table_ddl($table)
. " ENGINE = $type $charset"); . " ENGINE = $type $charset");
@ -219,12 +219,11 @@ sub get_drop_fk_sql {
my ($self, $table, $column, $references) = @_; my ($self, $table, $column, $references) = @_;
my $fk_name = $self->_get_fk_name($table, $column, $references); my $fk_name = $self->_get_fk_name($table, $column, $references);
my @sql = ("ALTER TABLE $table DROP FOREIGN KEY $fk_name"); my @sql = ("ALTER TABLE $table DROP FOREIGN KEY $fk_name");
my $dbh = Bugzilla->dbh;
# MySQL requires, and will create, an index on any column with # MySQL requires, and will create, an index on any column with
# an FK. It will name it after the fk, which we never do. # an FK. It will name it after the fk, which we never do.
# So if there's an index named after the fk, we also have to delete it. # So if there's an index named after the fk, we also have to delete it.
if ($dbh->bz_index_info_real($table, $fk_name)) { if ($self->{dbh}->bz_index_info_real($table, $fk_name)) {
push(@sql, $self->get_drop_index_ddl($table, $fk_name)); push(@sql, $self->get_drop_index_ddl($table, $fk_name));
} }
@ -275,10 +274,6 @@ sub get_set_serial_sql {
sub column_info_to_column { sub column_info_to_column {
my ($self, $column_info) = @_; my ($self, $column_info) = @_;
# Unfortunately, we have to break Schema's normal "no database"
# barrier a few times in this function.
my $dbh = Bugzilla->dbh;
my $table = $column_info->{TABLE_NAME}; my $table = $column_info->{TABLE_NAME};
my $col_name = $column_info->{COLUMN_NAME}; my $col_name = $column_info->{COLUMN_NAME};
@ -293,7 +288,7 @@ sub column_info_to_column {
# Unfortunately, the only way to definitely solve this is # Unfortunately, the only way to definitely solve this is
# to break Schema's standard of not touching the live database # to break Schema's standard of not touching the live database
# and check if the index called PRIMARY is on that field. # and check if the index called PRIMARY is on that field.
my $pri_index = $dbh->bz_index_info_real($table, 'PRIMARY'); my $pri_index = $self->{dbh}->bz_index_info_real($table, 'PRIMARY');
if ( $pri_index && grep($_ eq $col_name, @{$pri_index->{FIELDS}}) ) { if ( $pri_index && grep($_ eq $col_name, @{$pri_index->{FIELDS}}) ) {
$column->{PRIMARYKEY} = 1; $column->{PRIMARYKEY} = 1;
} }
@ -324,9 +319,8 @@ sub column_info_to_column {
my $default = $column_info->{COLUMN_DEF}; my $default = $column_info->{COLUMN_DEF};
# Schema uses '0' for the defaults for decimal fields. # Schema uses '0' for the defaults for decimal fields.
$default = 0 if $default =~ /^0\.0+$/; $default = 0 if $default =~ /^0\.0+$/;
# If we're not a number, we're a string and need to be # If we're not a number, we're a string and need to be quoted.
# quoted. $default = $self->{dbh}->quote($default) if !($default =~ /^(-)?(\d+)(.\d+)?$/);
$default = $dbh->quote($default) if !($default =~ /^(-)?(\d+)(.\d+)?$/);
$column->{DEFAULT} = $default; $column->{DEFAULT} = $default;
} }
} }
@ -354,7 +348,7 @@ sub column_info_to_column {
# Unfortunately, the only way to do this in DBI is to query the # Unfortunately, the only way to do this in DBI is to query the
# database, so we have to break the rule here that Schema normally # database, so we have to break the rule here that Schema normally
# doesn't touch the live DB. # doesn't touch the live DB.
my $ref_sth = $dbh->prepare( my $ref_sth = $self->{dbh}->prepare(
"SELECT $col_name FROM $table LIMIT 1"); "SELECT $col_name FROM $table LIMIT 1");
$ref_sth->execute; $ref_sth->execute;
if ($ref_sth->{mysql_is_auto_increment}->[0]) { if ($ref_sth->{mysql_is_auto_increment}->[0]) {

View File

@ -169,8 +169,7 @@ sub get_fk_ddl
. " SET $column = :NEW.$to_column" . " SET $column = :NEW.$to_column"
. " WHERE $column = :OLD.$to_column;" . " WHERE $column = :OLD.$to_column;"
. " END ${fk_name}_UC;"; . " END ${fk_name}_UC;";
my $dbh = Bugzilla->dbh; $self->{dbh}->do($tr_str);
$dbh->do($tr_str);
} }
return $fk_string; return $fk_string;
@ -295,8 +294,7 @@ sub _get_alter_type_sql
{ {
# LONG to VARCHAR or VARCHAR to LONG is not allowed in Oracle, just a way to work around. # LONG to VARCHAR or VARCHAR to LONG is not allowed in Oracle, just a way to work around.
# Determine whether column_temp is already exist. # Determine whether column_temp is already exist.
my $dbh = Bugzilla->dbh; my $column_exist = $self->{dbh}->selectcol_arrayref(
my $column_exist = $dbh->selectcol_arrayref(
"SELECT CNAME FROM COL WHERE TNAME = UPPER(?) AND CNAME = UPPER(?)", "SELECT CNAME FROM COL WHERE TNAME = UPPER(?) AND CNAME = UPPER(?)",
undef, $table, $column . "_temp" undef, $table, $column . "_temp"
); );
@ -432,9 +430,8 @@ sub get_drop_column_ddl
my ($table, $column) = @_; my ($table, $column) = @_;
my @sql; my @sql;
push @sql, $self->SUPER::get_drop_column_ddl(@_); push @sql, $self->SUPER::get_drop_column_ddl(@_);
my $dbh = Bugzilla->dbh;
my $trigger_name = uc($table . "_" . $column); my $trigger_name = uc($table . "_" . $column);
my $exist_trigger = $dbh->selectcol_arrayref( my $exist_trigger = $self->{dbh}->selectcol_arrayref(
"SELECT OBJECT_NAME FROM USER_OBJECTS". "SELECT OBJECT_NAME FROM USER_OBJECTS".
" WHERE OBJECT_NAME = ?", undef, $trigger_name " WHERE OBJECT_NAME = ?", undef, $trigger_name
); );

View File

@ -57,7 +57,7 @@ sub _initialize
sub _sqlite_create_table sub _sqlite_create_table
{ {
my ($self, $table) = @_; my ($self, $table) = @_;
return scalar Bugzilla->dbh->selectrow_array( return scalar $self->{dbh}->selectrow_array(
"SELECT sql FROM sqlite_master WHERE name = ? AND type = 'table'", "SELECT sql FROM sqlite_master WHERE name = ? AND type = 'table'",
undef, $table undef, $table
); );
@ -93,7 +93,7 @@ sub _sqlite_alter_schema
$create_table = join(',', @$create_table) . "\n)"; $create_table = join(',', @$create_table) . "\n)";
} }
my $dbh = Bugzilla->dbh; my $dbh = $self->{dbh};
my $random = generate_random_password(5); my $random = generate_random_password(5);
my $rename_to = "${table}_$random"; my $rename_to = "${table}_$random";
@ -236,7 +236,6 @@ sub get_alter_column_ddl
{ {
my $self = shift; my $self = shift;
my ($table, $column, $new_def, $set_nulls_to) = @_; my ($table, $column, $new_def, $set_nulls_to) = @_;
my $dbh = Bugzilla->dbh;
my $table_sql = $self->_sqlite_create_table($table); my $table_sql = $self->_sqlite_create_table($table);
my $new_ddl = $self->get_type_ddl($new_def); my $new_ddl = $self->get_type_ddl($new_def);
# When we do ADD COLUMN, columns can show up all on one line separated # When we do ADD COLUMN, columns can show up all on one line separated