initial batch_alter_table for ::Producer::PostgreSQL
Peter Mottram [Fri, 22 Aug 2014 09:38:20 +0000 (11:38 +0200)]
lib/SQL/Translator/Producer/PostgreSQL.pm
t/30sqlt-new-diff-pgsql.t

index 5f898ac..1843883 100644 (file)
@@ -1019,6 +1019,72 @@ sub drop_table {
     return $out;
 }
 
+sub batch_alter_table {
+  my ( $table, $diff_hash, $options ) = @_;
+  my $qt = $options->{quote_table_names} || '';
+  $generator->quote_chars([$qt]);
+
+  # as long as we're not renaming the table we don't need to be here
+  if ( @{$diff_hash->{rename_table}} == 0 ) {
+    return map {
+      if (@{ $diff_hash->{$_} || [] }) {
+        my $meth = __PACKAGE__->can($_) or die __PACKAGE__ . " cant $_";
+        map { $meth->( (ref $_ eq 'ARRAY' ? @$_ : $_), $options ) }
+          @{ $diff_hash->{$_} }
+      }
+      else { () }
+    } qw/alter_drop_constraint
+      alter_drop_index
+      drop_field
+      add_field
+      alter_field
+      rename_field
+      alter_create_index
+      alter_create_constraint
+      alter_table/;
+  }
+
+  # first we need to perform drops which are on old table
+  my @sql = map {
+    if (@{ $diff_hash->{$_} || [] }) {
+      my $meth = __PACKAGE__->can($_) or die __PACKAGE__ . " cant $_";
+      map { $meth->( (ref $_ eq 'ARRAY' ? @$_ : $_), $options ) }
+        @{ $diff_hash->{$_} }
+    }
+    else { () }
+  } qw/alter_drop_constraint
+    alter_drop_index
+    drop_field/;
+
+  # next comes the rename_table
+  my $old_table = $diff_hash->{rename_table}[0][0];
+  push @sql, rename_table( $old_table, $table, $options );
+
+  # for alter_field (and so also rename_field) we need to make sure old
+  # field has table name set to new table otherwise calling alter_field dies
+  $diff_hash->{alter_field} =
+    [map { $_->[0]->table($table) && $_ } @{$diff_hash->{alter_field}}];
+  $diff_hash->{rename_field} =
+    [map { $_->[0]->table($table) && $_ } @{$diff_hash->{rename_field}}];
+
+  # now add everything else
+  push @sql, map {
+    if (@{ $diff_hash->{$_} || [] }) {
+      my $meth = __PACKAGE__->can($_) or die __PACKAGE__ . " cant $_";
+      map { $meth->( (ref $_ eq 'ARRAY' ? @$_ : $_), $options ) }
+        @{ $diff_hash->{$_} }
+    }
+    else { () }
+  } qw/add_field
+    alter_field
+    rename_field
+    alter_create_index
+    alter_create_constraint
+    alter_table/;
+
+  return @sql;
+}
+
 1;
 
 # -------------------------------------------------------------------
index ba61ee5..716af4b 100644 (file)
@@ -55,18 +55,21 @@ CREATE TABLE added (
   id bigint
 );
 
-ALTER TABLE old_name RENAME TO new_name;
-
 ALTER TABLE employee DROP CONSTRAINT FK5302D47D93FE702E;
 
-ALTER TABLE person DROP CONSTRAINT UC_age_name;
+ALTER TABLE employee DROP COLUMN job_title;
 
-DROP INDEX u_name;
+ALTER TABLE employee ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id)
+  REFERENCES person (person_id) DEFERRABLE;
 
-ALTER TABLE employee DROP COLUMN job_title;
+ALTER TABLE old_name RENAME TO new_name;
 
 ALTER TABLE new_name ADD COLUMN new_field integer;
 
+ALTER TABLE person DROP CONSTRAINT UC_age_name;
+
+DROP INDEX u_name;
+
 ALTER TABLE person ADD COLUMN is_rock_star smallint DEFAULT 1;
 
 ALTER TABLE person ALTER COLUMN person_id TYPE serial;
@@ -85,9 +88,6 @@ ALTER TABLE person RENAME COLUMN description TO physical_description;
 
 ALTER TABLE person ADD CONSTRAINT unique_name UNIQUE (name);
 
-ALTER TABLE employee ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id)
-  REFERENCES person (person_id) DEFERRABLE;
-
 ALTER TABLE person ADD CONSTRAINT UC_person_id UNIQUE (person_id);
 
 ALTER TABLE person ADD CONSTRAINT UC_age_name UNIQUE (age, name);
@@ -118,14 +118,14 @@ CREATE TABLE added (
   id bigint
 );
 
-ALTER TABLE old_name RENAME TO new_name;
-
-ALTER TABLE person DROP CONSTRAINT UC_age_name;
-
 ALTER TABLE employee DROP COLUMN job_title;
 
+ALTER TABLE old_name RENAME TO new_name;
+
 ALTER TABLE new_name ADD COLUMN new_field integer;
 
+ALTER TABLE person DROP CONSTRAINT UC_age_name;
+
 ALTER TABLE person ADD COLUMN is_rock_star smallint DEFAULT 1;
 
 ALTER TABLE person ALTER COLUMN person_id TYPE serial;