Add transforms for column renames etc
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / DeployMethod / SQL / Translator.pm
index fc0aa48..3dc9d9b 100644 (file)
@@ -102,10 +102,17 @@ method __ddl_consume_with_prefix($type, $versions, $prefix) {
     croak "neither $main or $generic exist; please write/generate some SQL";
   }
 
-  opendir my($dh), $dir;
-  my %files = map { $_ => "$dir/$_" } grep { /\.(?:sql|pl|sql-\w+)$/ && -f "$dir/$_" } readdir $dh;
-  closedir $dh;
-
+  my %files;
+  try {
+     opendir my($dh), $dir;
+     %files =
+       map { $_ => "$dir/$_" }
+       grep { /\.(?:sql|pl|sql-\w+)$/ && -f "$dir/$_" }
+       readdir $dh;
+     closedir $dh;
+  } catch {
+    die $_ unless $self->ignore_ddl;
+  };
   if (-d $common) {
     opendir my($dh), $common;
     for my $filename (grep { /\.(?:sql|pl)$/ && -f catfile($common,$_) } readdir $dh) {
@@ -127,8 +134,36 @@ method _ddl_schema_consume_filenames($type, $version) {
   $self->__ddl_consume_with_prefix($type, [ $version ], 'schema')
 }
 
+method _ddl_protoschema_up_consume_filenames($versions) {
+  my $base_dir = $self->script_directory;
+
+  my $dir = catfile( $base_dir, '_protoschema', 'up', join q(-), @{$versions});
+
+  return [] unless -d $dir;
+
+  opendir my($dh), $dir;
+  my %files = map { $_ => "$dir/$_" } grep { /\.pl$/ && -f "$dir/$_" } readdir $dh;
+  closedir $dh;
+
+  return [@files{sort keys %files}]
+}
+
+method _ddl_protoschema_down_consume_filenames($versions) {
+  my $base_dir = $self->script_directory;
+
+  my $dir = catfile( $base_dir, '_protoschema', 'down', join q(-), @{$versions});
+
+  return [] unless -d $dir;
+
+  opendir my($dh), $dir;
+  my %files = map { $_ => "$dir/$_" } grep { /\.pl$/ && -f "$dir/$_" } readdir $dh;
+  closedir $dh;
+
+  return [@files{sort keys %files}]
+}
+
 method _ddl_protoschema_produce_filename($version) {
-  my $dirname = catfile( $self->script_directory, '_protoschema', $version );
+  my $dirname = catfile( $self->script_directory, '_protoschema', 'schema',  $version );
   mkpath($dirname) unless -d $dirname;
 
   return catfile( $dirname, '001-auto.yml' );
@@ -214,13 +249,18 @@ method _run_perl($filename) {
   }
 }
 
-method _run_sql_and_perl($filenames) {
+method _run_sql_and_perl($filenames, $sql_to_run) {
   my @files   = @{$filenames};
   my $guard   = $self->schema->txn_scope_guard if $self->txn_wrap;
 
-  my $sql = '';
+  $self->_run_sql_array($sql_to_run) if $self->ignore_ddl;
+
+  my $sql = ($sql_to_run)?join ";\n", @$sql_to_run:'';
+  FILENAME:
   for my $filename (@files) {
-    if ($filename =~ /\.sql$/) {
+    if ($self->ignore_ddl && $filename =~ /^[^_]*-auto.*\.sql$/) {
+      next FILENAME
+    } elsif ($filename =~ /\.sql$/) {
        $sql .= $self->_run_sql($filename)
     } elsif ( $filename =~ /\.pl$/ ) {
        $self->_run_perl($filename)
@@ -234,18 +274,21 @@ method _run_sql_and_perl($filenames) {
   return $sql;
 }
 
-method _deploy($version) {
-  return $self->_run_sql_and_perl($self->_ddl_schema_consume_filenames(
-    $self->storage->sqlt_type,
-    $version,
-  ));
-}
-
 sub deploy {
   my $self = shift;
   my $version = (shift @_ || {})->{version} || $self->schema_version;
   log_info { "deploying version $version" };
-  $self->_deploy($version);
+  my $sqlt_type = $self->storage->sqlt_type;
+  my $sql;
+  if ($self->ignore_ddl) {
+     $sql = $self->_sql_from_yaml({},
+       '_ddl_protoschema_produce_filename', $sqlt_type
+     );
+  }
+  return $self->_run_sql_and_perl($self->_ddl_schema_consume_filenames(
+    $sqlt_type,
+    $version,
+  ), $sql);
 }
 
 sub preinstall {
@@ -282,7 +325,7 @@ sub preinstall {
   }
 }
 
-method _sqldiff_from_yaml($from_version, $to_version, $db) {
+method _sqldiff_from_yaml($from_version, $to_version, $db, $direction) {
   my $dir       = $self->script_directory;
   my $sqltargs = {
     add_drop_table => 1,
@@ -338,6 +381,13 @@ method _sqldiff_from_yaml($from_version, $to_version, $db) {
     $dest_schema->name( $filename )
       unless $dest_schema->name;
   }
+
+  my $transform_files_method =  "_ddl_protoschema_${direction}_consume_filenames";
+  my $transforms = $self->_coderefs_per_files(
+    $self->$transform_files_method([$from_version, $to_version])
+  );
+  $_->($source_schema, $dest_schema) for @$transforms;
+
   return [SQL::Translator::Diff::schema_diff(
      $source_schema, $db,
      $dest_schema,   $db,
@@ -350,7 +400,7 @@ method _sql_from_yaml($sqltargs, $from_file, $db) {
   my $version   = $self->schema_version;
 
   my $sqlt = SQL::Translator->new({
-    add_drop_table          => 1,
+    add_drop_table          => 0,
     parser                  => 'SQL::Translator::Parser::YAML',
     %{$sqltargs},
     producer => $db,
@@ -468,13 +518,16 @@ sub prepare_downgrade {
   );
 }
 
+method _coderefs_per_files($files) {
+  no warnings 'redefine';
+  [map eval do { local( @ARGV, $/ ) = $_; <> }, @$files]
+}
+
 method _prepare_changegrade($from_version, $to_version, $version_set, $direction) {
   my $schema    = $self->schema;
   my $databases = $self->databases;
   my $dir       = $self->script_directory;
 
-  return if $self->ignore_ddl;
-
   my $schema_version = $self->schema_version;
   my $diff_file_method = "_ddl_schema_${direction}_produce_filename";
   foreach my $db (@$databases) {
@@ -485,7 +538,7 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
     }
 
     open my $file, q(>), $diff_file;
-    print {$file} join ";\n", @{$self->_sqldiff_from_yaml($from_version, $to_version, $db)};
+    print {$file} join ";\n", @{$self->_sqldiff_from_yaml($from_version, $to_version, $db, $direction)};
     close $file;
   }
 }
@@ -513,10 +566,17 @@ sub downgrade_single_step {
   my $version_set = (shift @_)->{version_set};
   Dlog_info { "downgrade_single_step'ing $_" } $version_set;
 
+  my $sqlt_type = $self->storage->sqlt_type;
+  my $sql_to_run;
+  if ($self->ignore_ddl) {
+     $sql_to_run = $self->_sqldiff_from_yaml(
+       $version_set->[0], $version_set->[1], $sqlt_type, 'down',
+     );
+  }
   my $sql = $self->_run_sql_and_perl($self->_ddl_schema_down_consume_filenames(
-    $self->storage->sqlt_type,
+    $sqlt_type,
     $version_set,
-  ));
+  ), $sql_to_run);
 
   return ['', $sql];
 }
@@ -526,10 +586,17 @@ sub upgrade_single_step {
   my $version_set = (shift @_)->{version_set};
   Dlog_info { "upgrade_single_step'ing $_" } $version_set;
 
+  my $sqlt_type = $self->storage->sqlt_type;
+  my $sql_to_run;
+  if ($self->ignore_ddl) {
+     $sql_to_run = $self->_sqldiff_from_yaml(
+       $version_set->[0], $version_set->[1], $sqlt_type, 'up',
+     );
+  }
   my $sql = $self->_run_sql_and_perl($self->_ddl_schema_up_consume_filenames(
-    $self->storage->sqlt_type,
+    $sqlt_type,
     $version_set,
-  ));
+  ), $sql_to_run);
   return ['', $sql];
 }