From: Brandon L. Black Date: Wed, 15 Mar 2006 13:13:56 +0000 (+0000) Subject: columns_info_for upgrades, related test updates, related DB2 fix X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=fc22fbac7c99f1ee8a52e529a6ce4ee35fd5d4a9;p=dbsrgits%2FDBIx-Class-Historic.git columns_info_for upgrades, related test updates, related DB2 fix --- diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 4ee25cc..ac29900 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -518,25 +518,41 @@ Returns database type info for a given table columns. =cut +# override this in a subclass if your DBD ->can('column_info'), +# but the call itself is horribly broken. +sub _column_info_broken { 0 } + sub columns_info_for { my ($self, $table) = @_; + my %result; - if ( $self->dbh->can( 'column_info' ) ){ + if ( $self->dbh->can( 'column_info' ) && !$self->_column_info_broken){ my $sth = $self->dbh->column_info( undef, undef, $table, '%' ); $sth->execute(); while ( my $info = $sth->fetchrow_hashref() ){ my %column_info; $column_info{data_type} = $info->{TYPE_NAME}; $column_info{size} = $info->{COLUMN_SIZE}; - $column_info{is_nullable} = $info->{NULLABLE}; + $column_info{is_nullable} = $info->{NULLABLE} ? 1 : 0; + $column_info{default_value} = $info->{COLUMN_DEF}; $result{$info->{COLUMN_NAME}} = \%column_info; } } else { my $sth = $self->dbh->prepare("SELECT * FROM $table WHERE 1=0"); $sth->execute; - my @columns = @{$sth->{NAME}}; + my @columns = @{$sth->{NAME_lc}}; for my $i ( 0 .. $#columns ){ - $result{$columns[$i]}{data_type} = $sth->{TYPE}->[$i]; + my %column_info; + my $type_num = $sth->{TYPE}->[$i]; + my $type_name; + if(defined $type_num && $self->dbh->can('type_info')) { + my $type_info = $self->dbh->type_info($type_num); + $type_name = $type_info->{TYPE_NAME} if $type_info; + } + $column_info{data_type} = $type_name ? $type_name : $type_num; + $column_info{size} = $sth->{PRECISION}->[$i]; + $column_info{is_nullable} = $sth->{NULLABLE}->[$i] ? 1 : 0; + $result{$columns[$i]} = \%column_info; } } return \%result; diff --git a/lib/DBIx/Class/Storage/DBI/DB2.pm b/lib/DBIx/Class/Storage/DBI/DB2.pm index a6e1452..60a515b 100644 --- a/lib/DBIx/Class/Storage/DBI/DB2.pm +++ b/lib/DBIx/Class/Storage/DBI/DB2.pm @@ -7,6 +7,8 @@ use base qw/DBIx::Class::Storage::DBI/; # __PACKAGE__->load_components(qw/PK::Auto/); +sub _column_info_broken { 1 } + sub last_insert_id { my ($self) = @_; diff --git a/t/run/04db.tl b/t/run/04db.tl index 5adf439..424948c 100644 --- a/t/run/04db.tl +++ b/t/run/04db.tl @@ -31,10 +31,14 @@ is($artist, undef, "Rollback ok"); my $type_info = $schema->storage->columns_info_for('artist'); my $test_type_info = { 'artistid' => { - 'data_type' => 'INTEGER' + 'data_type' => 'INTEGER', + 'is_nullable' => 0, + 'size' => undef, }, 'name' => { - 'data_type' => 'varchar' + 'data_type' => 'varchar', + 'is_nullable' => 0, + 'size' => undef, } }; is_deeply($type_info, $test_type_info, 'columns_info_for - column data types'); diff --git a/t/run/11mysql.tl b/t/run/11mysql.tl index 234474f..15664d9 100644 --- a/t/run/11mysql.tl +++ b/t/run/11mysql.tl @@ -45,17 +45,20 @@ my $test_type_info = { 'artistid' => { 'data_type' => 'INT', 'is_nullable' => 0, - 'size' => 11 + 'size' => 11, + 'default_value' => undef, }, 'name' => { 'data_type' => 'VARCHAR', 'is_nullable' => 1, - 'size' => 255 + 'size' => 255, + 'default_value' => undef, }, 'charfield' => { 'data_type' => 'VARCHAR', 'is_nullable' => 1, - 'size' => 10 + 'size' => 10, + 'default_value' => undef, }, }; diff --git a/t/run/12pg.tl b/t/run/12pg.tl index 5ffef5c..ee3e819 100644 --- a/t/run/12pg.tl +++ b/t/run/12pg.tl @@ -8,7 +8,7 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/}; plan skip_all, 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test' . ' (note: creates and drops a table named artist!)' unless ($dsn && $user); -plan tests => 3; +plan tests => 4; DBICTest::Schema->compose_connection('PgTest' => $dsn, $user, $pass); @@ -30,22 +30,30 @@ my $test_type_info = { 'artistid' => { 'data_type' => 'integer', 'is_nullable' => 0, - 'size' => 4 + 'size' => 4, }, 'name' => { 'data_type' => 'character varying', 'is_nullable' => 1, - 'size' => 255 + 'size' => 255, + 'default_value' => undef, }, 'charfield' => { 'data_type' => 'character', 'is_nullable' => 1, - 'size' => 10 + 'size' => 10, + 'default_value' => undef, }, }; + my $type_info = PgTest->schema->storage->columns_info_for('artist'); -is_deeply($type_info, $test_type_info, 'columns_info_for - column data types'); +my $artistid_defval = delete $type_info->{artistid}->{default_value}; +like($artistid_defval, + qr/^nextval\('public\.artist_artistid_seq'::(?:text|regclass)\)/, + 'columns_info_for - sequence matches Pg get_autoinc_seq expectations'); +is_deeply($type_info, $test_type_info, + 'columns_info_for - column data types'); $dbh->do("DROP TABLE artist;"); diff --git a/t/run/145db2.tl b/t/run/145db2.tl index 4c860bf..aa721b1 100644 --- a/t/run/145db2.tl +++ b/t/run/145db2.tl @@ -8,13 +8,16 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_DB2_${_}" } qw/DSN USER PASS/}; plan skip_all, 'Set $ENV{DBICTEST_DB2_DSN}, _USER and _PASS to run this test' unless ($dsn && $user); -plan tests => 5; +plan tests => 6; DBICTest::Schema->compose_connection('DB2Test' => $dsn, $user, $pass); my $dbh = DB2Test->schema->storage->dbh; -$dbh->do("DROP TABLE artist;"); +{ + local $SIG{__WARN__} = sub {}; + $dbh->do("DROP TABLE artist;"); +} $dbh->do("CREATE TABLE artist (artistid INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), name VARCHAR(255), charfield CHAR(10));"); @@ -36,16 +39,16 @@ my $it = DB2Test::Artist->search( {}, } ); is( $it->count, 3, "LIMIT count ok" ); -is( $it->next->name, "Artist 2", "iterator->next ok" ); -$it->next; +is( $it->next->name, "foo", "iterator->next ok" ); $it->next; +is( $it->next->name, "Artist 2", "iterator->next ok" ); is( $it->next, undef, "next past end of resultset ok" ); my $test_type_info = { 'artistid' => { 'data_type' => 'INTEGER', 'is_nullable' => 0, - 'size' => 11 + 'size' => 10 }, 'name' => { 'data_type' => 'VARCHAR', @@ -53,7 +56,7 @@ my $test_type_info = { 'size' => 255 }, 'charfield' => { - 'data_type' => 'VARCHAR', + 'data_type' => 'CHAR', 'is_nullable' => 1, 'size' => 10 },