From: Matt S Trout Date: Sat, 21 Jan 2006 23:44:21 +0000 (+0000) Subject: columns_info_for from zby, fixes to per-db tests X-Git-Tag: v0.05005~117^2~18 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a953d8d9fc96fd74a0a0fe02af3e1469285d1f50;p=dbsrgits%2FDBIx-Class.git columns_info_for from zby, fixes to per-db tests --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index cfe45ce..fdcbb32 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -253,6 +253,7 @@ Returns the next element in the resultset (undef is there is none). sub next { my ($self) = @_; my @row = $self->cursor->next; +# warn Dumper(\@row); use Data::Dumper; return unless (@row); return $self->_construct_object(@row); } diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index bc71706..d5f878f 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -108,6 +108,21 @@ Returns the column metadata hashref for a column. sub column_info { my ($self, $column) = @_; croak "No such column $column" unless exists $self->_columns->{$column}; + if ( (! $self->_columns->{$column}->{data_type}) + && $self->schema && $self->storage() ){ + my $info; +############ eval for the case of storage without table + eval{ + $info = $self->storage->columns_info_for ( $self->from() ); + }; + if ( ! $@ ){ + for my $col ( keys %{$self->_columns} ){ + for my $i ( keys %{$info->{$col}} ){ + $self->_columns()->{$col}->{$i} = $info->{$col}->{$i}; + } + } + } + } return $self->_columns->{$column}; } diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index c9db108..53c5f37 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -295,6 +295,34 @@ sub sth { return $self->dbh->prepare_cached($sql, {}, 3); } +=head2 columns_info_for + +Returns database type info for a given table columns. + +=cut + +sub columns_info_for { + my ($self, $table) = @_; + my $sth = $self->dbh->prepare("SELECT * FROM $table WHERE 1=0"); + $sth->execute; + my %result; + my @columns = @{$sth->{NAME}}; + for my $i ( 0 .. $#columns ){ + my $type = $sth->{TYPE}->[$i]; + my $info = $self->dbh->type_info($type); + my %column_info; + if ( $info ){ + $column_info{data_type} = $info->{TYPE_NAME}; + $column_info{size} = $info->{COLUMN_SIZE}; + $column_info{is_nullable} = $info->{NULLABLE}; + }else{ + $column_info{data_type} = $type; + } + $result{$columns[$i]} = \%column_info; + } + return \%result; +} + 1; =head1 AUTHORS diff --git a/t/run/01core.tl b/t/run/01core.tl index 1fbb4eb..ddae2c4 100644 --- a/t/run/01core.tl +++ b/t/run/01core.tl @@ -1,7 +1,7 @@ sub run_tests { my $schema = shift; -plan tests => 34; +plan tests => 36; my @art = $schema->resultset("Artist")->search({ }, { order_by => 'name DESC'}); @@ -140,6 +140,11 @@ cmp_ok($rel_rs->count, '==', 5, 'Related search ok'); cmp_ok($or_rs->next->cdid, '==', $rel_rs->next->cdid, 'Related object ok'); + +ok($schema->storage(), 'Storage available'); + +my $typeinfo = $schema->source("Artist")->column_info('artistid'); +is($typeinfo->{data_type}, 'INTEGER', 'column_info ok'); } 1; diff --git a/t/run/04db.tl b/t/run/04db.tl index e3b5cbb..452c0b9 100644 --- a/t/run/04db.tl +++ b/t/run/04db.tl @@ -1,7 +1,7 @@ sub run_tests { my $schema = shift; -plan tests => 2; +plan tests => 3; # add some rows inside a transaction and commit it # XXX: Is storage->dbh the only way to get a dbh? @@ -28,6 +28,17 @@ $schema->storage->txn_rollback; ($artist) = $schema->resultset("Artist")->search( artistid => 25 ); is($artist, undef, "Rollback ok"); +my $type_info = $schema->storage->columns_info_for('artist'); +my $test_type_info = { + 'artistid' => { + 'data_type' => 'INTEGER' + }, + 'name' => { + 'data_type' => 'VARCHAR' + } +}; +is_deeply($type_info, $test_type_info, 'columns_info_for - column data types'); + } 1; diff --git a/t/run/11mysql.tl b/t/run/11mysql.tl index da08ea0..a78bfec 100644 --- a/t/run/11mysql.tl +++ b/t/run/11mysql.tl @@ -8,11 +8,11 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/}; plan skip_all, 'Set $ENV{DBICTEST_MYSQL_DSN}, _USER and _PASS to run this test' unless ($dsn && $user); -plan tests => 4; +plan tests => 5; DBICTest::Schema->compose_connection('MySQLTest' => $dsn, $user, $pass); -my $dbh = MySQLTest::Artist->storage->dbh; +my $dbh = MySQLTest->schema->storage->dbh; $dbh->do("DROP TABLE IF EXISTS artist;"); @@ -41,6 +41,25 @@ $it->next; $it->next; is( $it->next, undef, "next past end of resultset ok" ); +my $test_type_info = { + 'artistid' => { + 'data_type' => 'integer', + 'is_nullable' => 1, + 'size' => 10 + }, + 'name' => { + 'data_type' => 'varchar', + 'is_nullable' => 1, + 'size' => 255 + } +}; + + +my $type_info = MySQLTest::Artist->storage->columns_info_for('artist'); +is_deeply($type_info, $test_type_info, 'columns_info_for - column data types'); + + + # clean up our mess $dbh->do("DROP TABLE artist"); diff --git a/t/run/12pg.tl b/t/run/12pg.tl index f83eb46..c39dab5 100644 --- a/t/run/12pg.tl +++ b/t/run/12pg.tl @@ -8,11 +8,11 @@ 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 => 2; +plan tests => 3; DBICTest::Schema->compose_connection('PgTest' => $dsn, $user, $pass); -my $dbh = PgTest::Artist->storage->dbh; +my $dbh = PgTest->schema->storage->dbh; $dbh->do("CREATE TABLE artist (artistid serial PRIMARY KEY, name VARCHAR(255));"); @@ -26,6 +26,22 @@ $new = PgTest::Artist->create({ name => 'bar' }); is($new->artistid, 2, "Auto-PK worked"); +my $test_type_info = { + 'artistid' => { + 'data_type' => 'int4', + 'is_nullable' => 1, + 'size' => 10 + }, + 'name' => { + 'data_type' => 'text', + 'is_nullable' => 1, + 'size' => 4096 + } +}; + +my $type_info = PgTest->schema->storage->columns_info_for('artist'); +is_deeply($type_info, $test_type_info, 'columns_info_for - column data types'); + $dbh->do("DROP TABLE artist;"); } diff --git a/t/run/13oracle.tl b/t/run/13oracle.tl index 5c7b3ee..e169995 100644 --- a/t/run/13oracle.tl +++ b/t/run/13oracle.tl @@ -11,7 +11,7 @@ plan tests => 4; DBICTest::Schema->compose_connection('OraTest' => $dsn, $user, $pass); -my $dbh = OraTest::Artist->storage->dbh; +my $dbh = OraTest->schema->storage->dbh; eval { $dbh->do("DROP SEQUENCE artist_seq"); diff --git a/t/run/14mssql.tl b/t/run/14mssql.tl index bfb249b..4a9e696 100644 --- a/t/run/14mssql.tl +++ b/t/run/14mssql.tl @@ -12,7 +12,7 @@ plan tests => 4; $schema->resultset("Schema")->compose_connection( 'MSSQLTest' => $dsn, $user, $pass ); -my $dbh = MSSQLTest::Artist->storage->dbh; +my $dbh = MSSQLTest->schema->storage->dbh; $dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL DROP TABLE artist");