Changes + Reverts for 0.11000, see Changes file for info
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Diff.pm
index 5cbb0b0..91b8c1a 100644 (file)
@@ -13,8 +13,8 @@ use base 'Class::Accessor::Fast';
 # Input/option accessors
 __PACKAGE__->mk_accessors(qw/
   ignore_index_names ignore_constraint_names ignore_view_sql
-  ignore_proc_sql output_db source_schema source_db target_schema target_db
-  case_insensitive no_batch_alters ignore_missing_methods
+  ignore_proc_sql output_db source_schema target_schema 
+  case_insensitive no_batch_alters ignore_missing_methods producer_options
 /);
 
 my @diff_arrays = qw/
@@ -45,15 +45,14 @@ sub schema_diff {
     ## _db is the name of the producer/db it came out of/into
     ## results are formatted to the source preferences
 
-    my ($source_schema, $source_db, $target_schema, $target_db, $options) = @_;
+    my ($source_schema, $source_db, $target_schema, $output_db, $options) = @_;
     $options ||= {};
 
     my $obj = SQL::Translator::Diff->new( {
       %$options,
       source_schema => $source_schema,
-      source_db     => $source_db,
       target_schema => $target_schema,
-      target_db     => $target_db
+      output_db     => $output_db
     } );
 
     $obj->compute_differences->produce_diff_sql;
@@ -64,6 +63,7 @@ sub new {
   $values->{$_} ||= [] foreach @diff_arrays;
   $values->{table_diff_hash} = {};
 
+  $values->{producer_options} ||= {};
   $values->{output_db} ||= $values->{source_db};
   return $class->SUPER::new($values);
 }
@@ -180,7 +180,8 @@ sub produce_diff_sql {
           { map {
               $func_map{$_} => $self->table_diff_hash->{$table}{$_}
             } keys %func_map 
-          }
+          }, 
+          $self->producer_options
         );
       }
     } else {
@@ -198,7 +199,10 @@ sub produce_diff_sql {
           if (@{ $flattened_diffs{$_} || [] }) {
             my $meth = $producer_class->can($_);
             
-            $meth ? map { my $sql = $meth->(ref $_ eq 'ARRAY' ? @$_ : $_); $sql ?  ("$sql;") : () } @{ $flattened_diffs{$_} }
+            $meth ? map { 
+                    my $sql = $meth->( (ref $_ eq 'ARRAY' ? @$_ : $_), $self->producer_options );
+                    $sql ?  ("$sql") : (); 
+                  } @{ $flattened_diffs{$_} }
                   : $self->ignore_missing_methods
                   ? "-- $producer_class cant $_"
                   : die "$producer_class cant $_";
@@ -222,39 +226,44 @@ sub produce_diff_sql {
         add_drop_table => 0,
         no_comments => 1,
         # TODO: sort out options
-        quote_table_names => 0,
-        quote_field_names => 0,
+        %{ $self->producer_options }
       );
+      $translator->producer_args->{no_transaction} = 1;
       my $schema = $translator->schema;
 
       $schema->add_table($_) for @tables;
 
       unshift @diffs, 
         # Remove begin/commit here, since we wrap everything in one.
-        grep { $_ !~ /^(?:COMMIT|START(?: TRANSACTION)?|BEGIN(?: TRANSACTION)?);/ } $producer_class->can('produce')->($translator);
+        grep { $_ !~ /^(?:COMMIT|START(?: TRANSACTION)?|BEGIN(?: TRANSACTION)?)/ } $producer_class->can('produce')->($translator);
     }
 
     if (my @tables_to_drop = @{ $self->{tables_to_drop} || []} ) {
       my $meth = $producer_class->can('drop_table');
       
-      push @diffs, $meth ? map( { $meth->($_) } @tables_to_drop )
+      push @diffs, $meth ? ( map { $meth->($_, $self->producer_options) } @tables_to_drop)
                          : $self->ignore_missing_methods
                          ? "-- $producer_class cant drop_table"
                          : die "$producer_class cant drop_table";
     }
 
     if (@diffs) {
-      unshift @diffs, "BEGIN;\n";
-      push    @diffs, "\nCOMMIT;\n";
+      unshift @diffs, "BEGIN";
+      push    @diffs, "\nCOMMIT";
     } else {
-      @diffs = ("-- No differences found\n\n");
+      @diffs = ("-- No differences found");
     }
 
     if ( @diffs ) {
-      if ( $self->target_db !~ /^(?:MySQL|SQLite)$/ ) {
-        unshift(@diffs, "-- Target database @{[$self->target_db]} is untested/unsupported!!!");
+      if ( $self->output_db !~ /^(?:MySQL|SQLite|PostgreSQL)$/ ) {
+        unshift(@diffs, "-- Output database @{[$self->output_db]} is untested/unsupported!!!");
       }
-      return join( "\n", "-- Convert schema '$src_name' to '$tar_name':\n", @diffs);
+
+      my @return = 
+        map { $_ ? ( $_ =~ /;$/xms ? $_ : "$_;\n\n" ) : "\n" }
+        ("-- Convert schema '$src_name' to '$tar_name':", @diffs);
+
+      return wantarray ? @return : join('', @return);
     }
     return undef;
 
@@ -382,10 +391,19 @@ sub diff_table_fields {
 sub diff_table_options {
   my ($self, $src_table, $tar_table) = @_;
 
+  my $cmp = sub {
+    my ($a_name, undef, $b_name, undef) = ( %$a, %$b );
+    $a_name cmp $b_name;
+  };
+  # Need to sort the options so we dont get supruious diffs.
+  my (@src_opts, @tar_opts);
+  @src_opts = sort $cmp $src_table->options;
+  @tar_opts = sort $cmp $tar_table->options;
+
 
   # If there's a difference, just re-set all the options
   push @{ $self->table_diff_hash->{$tar_table}{table_options} }, $tar_table
-    unless $src_table->_compare_objects( scalar $src_table->options, scalar $tar_table->options );
+    unless $src_table->_compare_objects( \@src_opts, \@tar_opts );
 }
 
 1;