X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSchema%2FLoader%2FDBI.pm;h=09155748a62daf689c7c30214fe56a0f4e42ffe2;hb=8990a2b23d98bcb87da292ee3731de3ac4f1b86f;hp=7e99a81328a65296d904ddf7df845dcfda038d1b;hpb=0f8448322561029d7265adc51484136b2433ad28;p=dbsrgits%2FDBIx-Class-Schema-Loader.git diff --git a/lib/DBIx/Class/Schema/Loader/DBI.pm b/lib/DBIx/Class/Schema/Loader/DBI.pm index 7e99a81..0915574 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI.pm @@ -6,10 +6,11 @@ use base qw/DBIx::Class::Schema::Loader::Base/; use mro 'c3'; use Try::Tiny; use List::MoreUtils 'any'; +use Carp::Clan qw/^DBIx::Class/; use namespace::clean; use DBIx::Class::Schema::Loader::Table (); -our $VERSION = '0.07014'; +our $VERSION = '0.07028'; __PACKAGE__->mk_group_accessors('simple', qw/ _disable_pk_detection @@ -53,9 +54,10 @@ sub new { my $driver = $self->dbh->{Driver}->{Name}; my $subclass = 'DBIx::Class::Schema::Loader::DBI::' . $driver; - if ($self->load_optional_class($subclass)) { - bless $self, $subclass unless $self->isa($subclass); + if ((not $self->isa($subclass)) && $self->load_optional_class($subclass)) { + bless $self, $subclass; $self->_rebless; + Class::C3::reinitialize() if $] < 5.009005; } } @@ -65,7 +67,7 @@ sub new { $self->_setup; - $self; + return $self; } sub _build_quote_char { @@ -256,10 +258,12 @@ sub _table_columns { my $sth = $self->_sth_for($table, undef, \'1 = 0'); $sth->execute; - my $retval = $self->preserve_case ? \@{$sth->{NAME}} : \@{$sth->{NAME_lc}}; + + my $retval = [ map $self->_lc($_), @{$sth->{NAME}} ]; + $sth->finish; - $retval; + return $retval; } # Returns arrayref of pk col names @@ -323,32 +327,53 @@ sub _table_uniq_info { sub _table_comment { my ($self, $table) = @_; + my $dbh = $self->dbh; my $comments_table = $table->clone; $comments_table->name($self->table_comments_table); - my ($comment) = try { $self->dbh->selectrow_array(<<"EOF") }; + my ($comment) = + (exists $self->_tables->{$comments_table->sql_name} || undef) + && try { $dbh->selectrow_array(<<"EOF") }; SELECT comment_text FROM @{[ $comments_table->sql_name ]} -WHERE table_name = @{[ $self->dbh->quote($table->name) ]} +WHERE table_name = @{[ $dbh->quote($table->name) ]} EOF + # Failback: try the REMARKS column on table_info + if (!$comment && $dbh->can('table_info')) { + my $sth = $self->_dbh_table_info( $dbh, undef, $table->schema, $table->name ); + my $info = $sth->fetchrow_hashref(); + $comment = $info->{REMARKS}; + } + return $comment; } sub _column_comment { my ($self, $table, $column_number, $column_name) = @_; + my $dbh = $self->dbh; my $comments_table = $table->clone; $comments_table->name($self->column_comments_table); - my ($comment) = try { $self->dbh->selectrow_array(<<"EOF") }; + my ($comment) = + (exists $self->_tables->{$comments_table->sql_name} || undef) + && try { $dbh->selectrow_array(<<"EOF") }; SELECT comment_text FROM @{[ $comments_table->sql_name ]} -WHERE table_name = @{[ $self->dbh->quote($table->name) ]} -AND column_name = @{[ $self->dbh->quote($column_name) ]} +WHERE table_name = @{[ $dbh->quote($table->name) ]} +AND column_name = @{[ $dbh->quote($column_name) ]} EOF - + + # Failback: try the REMARKS column on column_info + if (!$comment && $dbh->can('column_info')) { + if (my $sth = try { $self->_dbh_column_info( $dbh, undef, $table->schema, $table->name, $column_name ) }) { + my $info = $sth->fetchrow_hashref(); + $comment = $info->{REMARKS}; + } + } + return $comment; } @@ -379,10 +404,11 @@ sub _table_fk_info { my $uk_col = $self->_lc($raw_rel->[3]); my $fk_scm = $raw_rel->[5]; my $fk_col = $self->_lc($raw_rel->[7]); + my $key_seq = $raw_rel->[8] - 1; my $relid = ($raw_rel->[11] || ( "__dcsld__" . $i++ )); foreach my $var ($uk_scm, $uk_tbl, $uk_col, $fk_scm, $fk_col, $relid) { - $var =~ s/[\Q$self->{quote_char}\E]//g; + $var =~ s/[\Q$self->{quote_char}\E]//g if defined $var; } if ($self->db_schema && $self->db_schema->[0] ne '%' @@ -399,15 +425,18 @@ sub _table_fk_info { ignore_schema => 1 )), ); - $rels{$relid}{cols}{$uk_col} = $fk_col; + + # Add this data IN ORDER + $rels{$relid}{rcols}[$key_seq] = $uk_col; + $rels{$relid}{lcols}[$key_seq] = $fk_col; } $sth->finish; my @rels; foreach my $relid (keys %rels) { push(@rels, { - remote_columns => [ keys %{$rels{$relid}->{cols}} ], - local_columns => [ values %{$rels{$relid}->{cols}} ], + remote_columns => [ grep defined, @{ $rels{$relid}{rcols} } ], + local_columns => [ grep defined, @{ $rels{$relid}{lcols} } ], remote_table => $rels{$relid}->{tbl}, }); } @@ -423,9 +452,10 @@ sub _columns_info_for { my %result; - if ($dbh->can('column_info')) { - my $sth = $self->_dbh_column_info($dbh, undef, $table->schema, $table->name, '%' ); - while ( my $info = $sth->fetchrow_hashref() ){ + if (my $sth = try { $self->_dbh_column_info($dbh, undef, $table->schema, $table->name, '%' ) }) { + COL_INFO: while (my $info = try { $sth->fetchrow_hashref } catch { +{} }) { + next COL_INFO unless %$info; + my $column_info = {}; $column_info->{data_type} = lc $info->{TYPE_NAME}; @@ -443,8 +473,6 @@ sub _columns_info_for { my $col_name = $info->{COLUMN_NAME}; $col_name =~ s/^\"(.*)\"$/$1/; - $col_name = $self->_lc($col_name); - my $extra_info = $self->_extra_column_info( $table, $col_name, $column_info, $info ) || {}; @@ -453,8 +481,6 @@ sub _columns_info_for { $result{$col_name} = $column_info; } $sth->finish; - - return \%result if %result; } my $sth = $self->_sth_for($table, undef, \'1 = 0'); @@ -462,7 +488,9 @@ sub _columns_info_for { my @columns = @{ $sth->{NAME} }; - for my $i (0 .. $#columns) { + COL: for my $i (0 .. $#columns) { + next COL if %{ $result{ $columns[$i] }||{} }; + my $column_info = {}; $column_info->{data_type} = lc $sth->{TYPE}[$i]; @@ -485,7 +513,7 @@ sub _columns_info_for { my $extra_info = $self->_extra_column_info($table, $columns[$i], $column_info, $sth) || {}; $column_info = { %$column_info, %$extra_info }; - $result{ $self->_lc($columns[$i]) } = $column_info; + $result{ $columns[$i] } = $column_info; } $sth->finish; @@ -499,6 +527,32 @@ sub _columns_info_for { } } + # check for instances of the same column name with different case in preserve_case=0 mode + if (not $self->preserve_case) { + my %lc_colnames; + + foreach my $col (keys %result) { + push @{ $lc_colnames{lc $col} }, $col; + } + + if (keys %lc_colnames != keys %result) { + my @offending_colnames = map @$_, grep @$_ > 1, values %lc_colnames; + + my $offending_colnames = join ", ", map "'$_'", @offending_colnames; + + croak "columns $offending_colnames in table @{[ $table->sql_name ]} collide in preserve_case=0 mode. preserve_case=1 mode required"; + } + + # apply lowercasing + my %lc_result; + + while (my ($col, $info) = each %result) { + $lc_result{ $self->_lc($col) } = $info; + } + + %result = %lc_result; + } + return \%result; } @@ -516,6 +570,13 @@ sub _dbh_type_info_type_name { # do not use this, override _columns_info_for instead sub _extra_column_info {} +# override to mask warnings if needed +sub _dbh_table_info { + my ($self, $dbh) = (shift, shift); + + return $dbh->table_info(@_); +} + # override to mask warnings if needed (see mysql) sub _dbh_column_info { my ($self, $dbh) = (shift, shift);