columns_info_for from zby, fixes to per-db tests
Matt S Trout [Sat, 21 Jan 2006 23:44:21 +0000 (23:44 +0000)]
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Storage/DBI.pm
t/run/01core.tl
t/run/04db.tl
t/run/11mysql.tl
t/run/12pg.tl
t/run/13oracle.tl
t/run/14mssql.tl

index cfe45ce..fdcbb32 100644 (file)
@@ -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);
 }
index bc71706..d5f878f 100644 (file)
@@ -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};
 }
 
index c9db108..53c5f37 100644 (file)
@@ -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
index 1fbb4eb..ddae2c4 100644 (file)
@@ -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;
index e3b5cbb..452c0b9 100644 (file)
@@ -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;
index da08ea0..a78bfec 100644 (file)
@@ -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");
 
index f83eb46..c39dab5 100644 (file)
@@ -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;");
 
 }
index 5c7b3ee..e169995 100644 (file)
@@ -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");
index bfb249b..4a9e696 100644 (file)
@@ -12,7 +12,7 @@ plan tests => 4;
 \r
 $schema->resultset("Schema")->compose_connection( 'MSSQLTest' => $dsn, $user, $pass );\r
 \r
-my $dbh = MSSQLTest::Artist->storage->dbh;\r
+my $dbh = MSSQLTest->schema->storage->dbh;\r
 \r
 $dbh->do("IF OBJECT_ID('artist', 'U') IS NOT NULL\r
     DROP TABLE artist");\r