columns_info_for upgrades, related test updates, related DB2 fix
Brandon L. Black [Wed, 15 Mar 2006 13:13:56 +0000 (13:13 +0000)]
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/DB2.pm
t/run/04db.tl
t/run/11mysql.tl
t/run/12pg.tl
t/run/145db2.tl

index 4ee25cc..ac29900 100644 (file)
@@ -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;
index a6e1452..60a515b 100644 (file)
@@ -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) = @_;
index 5adf439..424948c 100644 (file)
@@ -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');
index 234474f..15664d9 100644 (file)
@@ -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,
     },
 };
 
index 5ffef5c..ee3e819 100644 (file)
@@ -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;");
 
index 4c860bf..aa721b1 100644 (file)
@@ -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 
     },