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};
my @module_parts = split('::', ref $self);
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};
}

View File

@ -41,6 +41,7 @@ use Bugzilla::Constants;
use Carp qw(confess);
use Digest::MD5 qw(md5_hex);
use Scalar::Util;
use Safe;
# Historical, needed for SCHEMA_VERSION = '1.00'
use Storable qw(dclone freeze thaw);
@ -1340,15 +1341,15 @@ sub new {
=over
=item C<new>
=item C<new($dbh, $driver, $schema)>
Description: Public constructor method used to instantiate objects of this
class. However, it also can be used as a factory method to
instantiate database-specific subclasses when an optional
driver argument is supplied.
Parameters: $driver (optional) - Used to specify the type of database.
This routine C<die>s if no subclass is found for the specified
driver.
Parameters: $dbh - Database handle this schema object is used for.
The Schema subclass is also determined from the type of this object.
Stored as a weak reference inside $self to prevent memory leaks.
$schema (optional) - A reference to a hash. Callers external
to this package should never use this parameter.
Returns: new instance of the Schema class or a database-specific subclass
@ -1356,24 +1357,20 @@ sub new {
=cut
my $this = shift;
my $class = ref($this) || $this;
my $driver = shift;
my $dbh = shift;
my ($driver) = ref($dbh) =~ /^Bugzilla::DB::(.*)$/so;
die "$dbh is not an instance of Bugzilla::DB subclass" unless $driver;
if ($driver) {
(my $subclass = $driver) =~ s/^(\S)/\U$1/;
$class .= '::' . $subclass;
eval "require $class;";
die "The $class class could not be found ($subclass " .
"not supported?): $@" if ($@);
}
die "$class is an abstract base class. Instantiate a subclass instead."
if ($class eq __PACKAGE__);
my $class = 'Bugzilla::DB::Schema::'.$driver;
eval "require $class;";
die "The $class class could not be found ($driver not supported?): $@" if $@;
my $self = {};
my $self = { dbh => $dbh };
Scalar::Util::weaken($self->{dbh});
bless $self, $class;
$self = $self->_initialize(@_);
return($self);
return $self;
} #eosub--new
#--------------------------------------------------------------------------
@ -2452,7 +2449,7 @@ sub serialize_abstract {
=cut
sub deserialize_abstract {
my ($class, $serialized, $version) = @_;
my ($self, $serialized, $version) = @_;
my $thawed_hash;
if (int($version) < 2) {
@ -2465,7 +2462,7 @@ sub deserialize_abstract {
$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 $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';
return($self->SUPER::_get_create_table_ddl($table)
. " ENGINE = $type $charset");
@ -219,12 +219,11 @@ sub get_drop_fk_sql {
my ($self, $table, $column, $references) = @_;
my $fk_name = $self->_get_fk_name($table, $column, $references);
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
# 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.
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));
}
@ -275,10 +274,6 @@ sub get_set_serial_sql {
sub column_info_to_column {
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 $col_name = $column_info->{COLUMN_NAME};
@ -293,7 +288,7 @@ sub column_info_to_column {
# Unfortunately, the only way to definitely solve this is
# to break Schema's standard of not touching the live database
# 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}}) ) {
$column->{PRIMARYKEY} = 1;
}
@ -324,9 +319,8 @@ sub column_info_to_column {
my $default = $column_info->{COLUMN_DEF};
# Schema uses '0' for the defaults for decimal fields.
$default = 0 if $default =~ /^0\.0+$/;
# If we're not a number, we're a string and need to be
# quoted.
$default = $dbh->quote($default) if !($default =~ /^(-)?(\d+)(.\d+)?$/);
# If we're not a number, we're a string and need to be quoted.
$default = $self->{dbh}->quote($default) if !($default =~ /^(-)?(\d+)(.\d+)?$/);
$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
# database, so we have to break the rule here that Schema normally
# doesn't touch the live DB.
my $ref_sth = $dbh->prepare(
my $ref_sth = $self->{dbh}->prepare(
"SELECT $col_name FROM $table LIMIT 1");
$ref_sth->execute;
if ($ref_sth->{mysql_is_auto_increment}->[0]) {

View File

@ -169,8 +169,7 @@ sub get_fk_ddl
. " SET $column = :NEW.$to_column"
. " WHERE $column = :OLD.$to_column;"
. " END ${fk_name}_UC;";
my $dbh = Bugzilla->dbh;
$dbh->do($tr_str);
$self->{dbh}->do($tr_str);
}
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.
# Determine whether column_temp is already exist.
my $dbh = Bugzilla->dbh;
my $column_exist = $dbh->selectcol_arrayref(
my $column_exist = $self->{dbh}->selectcol_arrayref(
"SELECT CNAME FROM COL WHERE TNAME = UPPER(?) AND CNAME = UPPER(?)",
undef, $table, $column . "_temp"
);
@ -432,9 +430,8 @@ sub get_drop_column_ddl
my ($table, $column) = @_;
my @sql;
push @sql, $self->SUPER::get_drop_column_ddl(@_);
my $dbh = Bugzilla->dbh;
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".
" WHERE OBJECT_NAME = ?", undef, $trigger_name
);

View File

@ -57,7 +57,7 @@ sub _initialize
sub _sqlite_create_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'",
undef, $table
);
@ -93,7 +93,7 @@ sub _sqlite_alter_schema
$create_table = join(',', @$create_table) . "\n)";
}
my $dbh = Bugzilla->dbh;
my $dbh = $self->{dbh};
my $random = generate_random_password(5);
my $rename_to = "${table}_$random";
@ -236,7 +236,6 @@ sub get_alter_column_ddl
{
my $self = shift;
my ($table, $column, $new_def, $set_nulls_to) = @_;
my $dbh = Bugzilla->dbh;
my $table_sql = $self->_sqlite_create_table($table);
my $new_ddl = $self->get_type_ddl($new_def);
# When we do ADD COLUMN, columns can show up all on one line separated