Merge 'trunk' into 'pg_unqualified_schema'
Peter Rabbitson [Wed, 4 Nov 2009 09:32:47 +0000 (09:32 +0000)]
r7820@Thesaurus (orig r7808):  caelum | 2009-10-21 03:10:39 +0200
add test for populate with literal sql mixed with binds, improve error messages
r7823@Thesaurus (orig r7811):  ribasushi | 2009-10-21 16:33:45 +0200
Show what's wrong with the current populate code
r7824@Thesaurus (orig r7812):  caelum | 2009-10-22 11:10:38 +0200
stringify values passed to populate/insert_bulk
r7825@Thesaurus (orig r7813):  ribasushi | 2009-10-22 13:17:41 +0200
Some smoker run the suite for 30 *minutes* - the timeout seems to be too short for them (boggle)
r7826@Thesaurus (orig r7814):  caelum | 2009-10-22 14:41:37 +0200
a few extra tests can never hurt, right? :)
r7827@Thesaurus (orig r7815):  ribasushi | 2009-10-23 10:51:05 +0200
Prevent sqlt from failing silently
r7828@Thesaurus (orig r7816):  ribasushi | 2009-10-23 10:52:49 +0200
{ is_foreign_key_constraint => 0, on_delete => undef } is a valid construct - no need to carp
r7832@Thesaurus (orig r7820):  robkinyon | 2009-10-26 20:11:22 +0100
Fixed bad if-check in columns()
r7840@Thesaurus (orig r7828):  caelum | 2009-10-31 14:01:56 +0100
change repository in meta to point to real svn url rather than svnweb
r7842@Thesaurus (orig r7830):  caelum | 2009-10-31 21:04:39 +0100
pass sqlite_version to SQLT
r7843@Thesaurus (orig r7831):  caelum | 2009-10-31 21:22:37 +0100
fix regex to numify sqlite_version
r7844@Thesaurus (orig r7832):  caelum | 2009-10-31 23:59:19 +0100
work-around disconnect bug with DBD::Pg 2.15.1

Changes
lib/DBIx/Class/Storage/DBI/Pg.pm
t/72pg.t

diff --git a/Changes b/Changes
index c0a3163..f76cc0a 100644 (file)
--- a/Changes
+++ b/Changes
@@ -20,6 +20,9 @@ Revision history for DBIx::Class
         - Fixed on_connect_do/call regression when used with a coderef
           connector (RT #50003)
         - A couple of fixes to Ordered to remedy subclassing issues
+        - Fixed another lingering problem with PostgreSQL
+          auto-increment support and its interaction with multiple
+          schemas
 
 0.08112 2009-09-21 10:57:00 (UTC)
         - Remove the recommends from Makefile.PL, DBIx::Class is not
index 92f1a78..6397e45 100644 (file)
@@ -61,19 +61,12 @@ sub _dbh_get_autoinc_seq {
     ( $schema, $table ) = ( $1, $2 );
   }
 
-### XXX This is unsafe in DBD::Pg 2.15.1, it can disconnect for some reason
-###
-  # use DBD::Pg to fetch the column info if it is recent enough to
-  # work. otherwise, use custom SQL
-#  my $seq_expr =  $DBD::Pg::VERSION >= 2.015001
-#      ? eval{ $dbh->column_info(undef,$schema,$table,$col)->fetchrow_hashref->{COLUMN_DEF} }
-#      : $self->_dbh_get_column_default( $dbh, $schema, $table, $col );
-
+  # get the column default using a Postgres-specific pg_catalog query
   my $seq_expr = $self->_dbh_get_column_default( $dbh, $schema, $table, $col );
 
   # if no default value is set on the column, or if we can't parse the
   # default value as a sequence, throw.
-  unless ( defined $seq_expr and $seq_expr =~ /^nextval\(+'([^']+)'::(?:text|regclass)\)/i ){
+  unless ( defined $seq_expr and $seq_expr =~ /^nextval\(+'([^']+)'::(?:text|regclass)\)/i ) {
     $seq_expr = '' unless defined $seq_expr;
     $schema = "$schema." if defined $schema && length $schema;
     $self->throw_exception( "no sequence found for $schema$table.$col, check table definition, "
index d6cb0a9..3fdefb7 100644 (file)
--- a/t/72pg.t
+++ b/t/72pg.t
@@ -472,6 +472,7 @@ BEGIN {
 
 my @eapk_schemas;
 BEGIN{ @eapk_schemas = map "dbic_apk_$_", 0..5 }
+my %seqs; #< hash of schema.table.col => currval of its (DBIC) primary key sequence
 
 sub run_extended_apk_tests {
   my $schema = shift;
@@ -489,10 +490,18 @@ sub run_extended_apk_tests {
         for @eapk_schemas;
 
     $dbh->do("CREATE SEQUENCE $eapk_schemas[5].fooseq");
+    $dbh->do("SELECT setval('$eapk_schemas[5].fooseq',400)");
+    $seqs{"$eapk_schemas[1].apk.id2"} = 400;
+
     $dbh->do("CREATE SEQUENCE $eapk_schemas[4].fooseq");
+    $dbh->do("SELECT setval('$eapk_schemas[4].fooseq',300)");
+    $seqs{"$eapk_schemas[3].apk.id2"} = 300;
+
     $dbh->do("CREATE SEQUENCE $eapk_schemas[3].fooseq");
+    $dbh->do("SELECT setval('$eapk_schemas[3].fooseq',200)");
+    $seqs{"$eapk_schemas[4].apk.id2"} = 200;
 
-    $dbh->do("SET search_path = ".join ',', @eapk_schemas );
+    $dbh->do("SET search_path = ".join ',', reverse @eapk_schemas );
   });
 
   # clear our search_path cache
@@ -519,12 +528,14 @@ sub run_extended_apk_tests {
                qualify_table => 4,
              );
 
+  eapk_poke( $schema );
   eapk_poke( $schema, 0 );
   eapk_poke( $schema, 2 );
   eapk_poke( $schema, 4 );
   eapk_poke( $schema, 1 );
   eapk_poke( $schema, 0 );
   eapk_poke( $schema, 1 );
+  eapk_poke( $schema );
   eapk_poke( $schema, 4 );
   eapk_poke( $schema, 3 );
   eapk_poke( $schema, 1 );
@@ -538,8 +549,6 @@ sub run_extended_apk_tests {
 # do a DBIC create on the apk table in the given schema number (which is an
 # index of @eapk_schemas)
 
-my %seqs; #< sanity-check hash of schema.table.col => currval of its sequence
-
 sub eapk_poke {
   my ($s, $schema_num) = @_;
 
@@ -547,7 +556,7 @@ sub eapk_poke {
       ? $eapk_schemas[$schema_num]
       : '';
 
-  my $schema_name_actual = $schema_name || eapk_get_search_path($s)->[0];
+  my $schema_name_actual = $schema_name || eapk_find_visible_schema($s);
 
   $s->source('ExtAPK')->name($schema_name ? $schema_name.'.apk' : 'apk');
   #< clear sequence name cache
@@ -558,12 +567,13 @@ sub eapk_poke {
   lives_ok {
     my $new;
     for my $inc (1,2,3) {
-      $new = $schema->resultset('ExtAPK')->create({});
+      $new = $schema->resultset('ExtAPK')->create({ id1 => 1});
       my $proper_seqval = ++$seqs{"$schema_name_actual.apk.id2"};
       is( $new->id2, $proper_seqval, "$schema_name_actual.apk.id2 correct inc $inc" )
           or eapk_seq_diag($s,$schema_name);
       $new->discard_changes;
-      for my $id (grep $_ ne 'id2', @eapk_id_columns) {
+      is( $new->id1, 1 );
+      for my $id ('id3','id4') {
         my $proper_seqval = ++$seqs{"$schema_name_actual.apk.$id"};
         is( $new->$id, $proper_seqval, "$schema_name_actual.apk.$id correct inc $inc" )
             or eapk_seq_diag($s,$schema_name);
@@ -577,7 +587,7 @@ sub eapk_poke {
 # class
 sub eapk_seq_diag {
     my $s = shift;
-    my $schema = shift || eapk_get_search_path($s)->[0];
+    my $schema = shift || eapk_find_visible_schema($s);
 
     diag "$schema.apk sequences: ",
         join(', ',
@@ -633,13 +643,13 @@ sub eapk_create {
         local $_[1]->{Warn} = 0;
 
         my $id_def = $a{nextval}
-            ? "integer primary key not null default nextval('$a{nextval}'::regclass)"
-            : 'serial primary key';
+            ? "integer not null default nextval('$a{nextval}'::regclass)"
+            : 'serial';
         $dbh->do(<<EOS);
 CREATE TABLE $table_name (
   id1 serial
   , id2 $id_def
-  , id3 serial
+  , id3 serial primary key
   , id4 serial
 )
 EOS
@@ -667,3 +677,19 @@ sub eapk_drop_all {
 
     });
 }
+
+sub eapk_find_visible_schema {
+    my ($s) = @_;
+
+    my ($schema) =
+        $s->storage->dbh_do(sub {
+            $_[1]->selectrow_array(<<EOS);
+SELECT n.nspname
+FROM pg_catalog.pg_namespace n
+JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
+WHERE c.relname = 'apk'
+  AND pg_catalog.pg_table_is_visible(c.oid)
+EOS
+        });
+    return $schema;
+}