Fix Pg diff issue with drop constraint on primary keys
William Wolf [Sat, 2 Jun 2012 04:07:46 +0000 (00:07 -0400)]
AUTHORS
Changes
lib/SQL/Translator/Producer/PostgreSQL.pm
t/47postgres-producer.t

diff --git a/AUTHORS b/AUTHORS
index 8e1cff9..9f55f2a 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -54,6 +54,7 @@ The following people have contributed to the SQLFairy project:
 -   Tina Müller <tinita@cpan.org>
 -   Vincent Bachelier <geistteufel@yahoo.fr>
 -   Wallace Reis <wreis@cpan.org>
+-   William Wolf <throughnothing@gmail.com>
 -   Ying Zhang <zyolive@yahoo.com>
 
 If you would like to contribute to the project, you can send patches
diff --git a/Changes b/Changes
index f8e590e..b9d3707 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,7 @@
 * Allow both single and double quotes for values in MySQL parser
 * Fix diff for altering two things per column - add ; at the end
 * Call all diff methods in list context (it can be merged later)
+* Fix Pg diff issue with drop constraint on primary keys
 
 # ----------------------------------------------------------
 # 0.11016 2012-10-09
index 16307bf..ad1f98c 100644 (file)
@@ -968,17 +968,25 @@ sub alter_drop_constraint {
     my $qc = $options->{quote_field_names} || '';
     $generator->quote_chars([$qt]);
 
+    # attention: Postgres  has a very special naming structure for naming
+    # foreign keys and primary keys.  It names them using the name of the
+    # table as prefix and fkey or pkey as suffix, concatenated by an underscore
+    my $c_name;
+    if( $c->name ) {
+        # Already has a name, just quote it
+        $c_name = $qc . $c->name . $qc;
+    } elsif ( $c->type eq FOREIGN_KEY ) {
+        # Doesn't have a name, and is foreign key, append '_fkey'
+        $c_name = $qc . $c->table->name . '_' .
+                    ($c->fields)[0] . '_fkey' . $qc;
+    } elsif ( $c->type eq PRIMARY_KEY ) {
+        # Doesn't have a name, and is primary key, append '_pkey'
+        $c_name = $qc . $c->table->name . '_pkey' . $qc;
+    }
+
     return sprintf(
         'ALTER TABLE %s DROP CONSTRAINT %s',
-        $generator->quote($c->table->name),
-        # attention: Postgres  has a very special naming structure
-        # for naming foreign keys, it names them uses the name of
-        # the table as prefix and fkey as suffix, concatenated by a underscore
-        $c->type eq FOREIGN_KEY
-            ? $c->name
-                ? $qc . $c->name . $qc
-                : $qc . $c->table->name . '_' . ($c->fields)[0] . '_fkey' . $qc
-            : $qc . $c->name . $qc
+        $qt . $c->table->name . $qt, $c_name
     );
 }
 
index 506cd09..0e6e681 100644 (file)
@@ -14,7 +14,7 @@ use FindBin qw/$Bin/;
 #=============================================================================
 
 BEGIN {
-    maybe_plan(53,
+    maybe_plan(57,
         'SQL::Translator::Producer::PostgreSQL',
         'Test::Differences',
     )
@@ -143,13 +143,45 @@ for my $name ( 'foo', undef ) {
     }
     else {
         is($fk_constraint_fk_ref->[0], 'ALTER TABLE mytable ADD FOREIGN KEY (myfield)
-  REFERENCES mytable2 (myfield_2) DEFERRABLE', 'Create named Foreign Key Constraint works');
+  REFERENCES mytable2 (myfield_2) DEFERRABLE', 'Create un-named Foreign Key Constraint works');
 
         my $alter_fk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($fk_constraint);
-        is($alter_fk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_myfield_fkey', 'Alter drop named Foreign Key constraint works');
+        is($alter_fk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_myfield_fkey', 'Alter drop un-named Foreign Key constraint works');
     }
 }
 
+# check named, and unnamed primary keys
+for my $name ( 'foo', undef ) {
+    my $pk_constraint = SQL::Translator::Schema::Constraint->new(
+        table => $table,
+        name   => $name,
+        fields => [qw(myfield)],
+        type   => 'PRIMARY_KEY',
+    );
+    my $pk_constraint_2 = SQL::Translator::Schema::Constraint->new(
+        table => $table,
+        name   => $name,
+        fields => [qw(myfield)],
+        type   => 'PRIMARY_KEY',
+    );
+
+    my  ($pk_constraint_def_ref, $pk_constraint_pk_ref ) = SQL::Translator::Producer::PostgreSQL::create_constraint($pk_constraint);
+
+    if ( $name ) {
+        is($pk_constraint_def_ref->[0], "CONSTRAINT $name PRIMARY KEY (myfield)", 'Create Primary Key Constraint works');
+
+        # ToDo: may we should check if the constraint name was valid, or if next
+        #       unused_name created has choosen a different one
+        my $alter_pk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($pk_constraint);
+        is($alter_pk_constraint, "ALTER TABLE mytable DROP CONSTRAINT $name", 'Alter drop Primary Key constraint works');
+    }
+    else {
+        is($pk_constraint_def_ref->[0], 'PRIMARY KEY (myfield)', 'Create un-named Primary Key Constraint works');
+
+        my $alter_pk_constraint = SQL::Translator::Producer::PostgreSQL::alter_drop_constraint($pk_constraint);
+        is($alter_pk_constraint, 'ALTER TABLE mytable DROP CONSTRAINT mytable_pkey', 'Alter drop un-named Foreign Key constraint works');
+    }
+}
 
 my $alter_field = SQL::Translator::Producer::PostgreSQL::alter_field($field1,
                                                                 $field2);