tiny bits of cleanup
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / DeployMethod / SQL / Translator.pm
index 172a27c..5084bf8 100644 (file)
@@ -1,20 +1,23 @@
 package DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator;
 use Moose;
+
+use autodie;
+use Carp qw( carp croak );
+
 use Method::Signatures::Simple;
 use Try::Tiny;
+
 use SQL::Translator;
 require SQL::Translator::Diff;
+
 require DBIx::Class::Storage;   # loaded for type constraint
-use autodie;
-use File::Path 'mkpath';
 use DBIx::Class::DeploymentHandler::Types;
-use File::Spec::Functions;
 
+use File::Path 'mkpath';
+use File::Spec::Functions;
 
 with 'DBIx::Class::DeploymentHandler::HandlesDeploy';
 
-use Carp 'carp';
-
 has schema => (
   isa      => 'DBIx::Class::Schema',
   is       => 'ro',
@@ -53,11 +56,6 @@ has databases => (
   default => sub { [qw( MySQL SQLite PostgreSQL )] },
 );
 
-has _filedata => (
-  isa => 'ArrayRef[Str]',
-  is  => 'rw',
-);
-
 has txn_wrap => (
   is => 'ro',
   isa => 'Bool',
@@ -76,20 +74,20 @@ method __ddl_consume_with_prefix($type, $versions, $prefix) {
   if (-d $main) {
     $dir = catfile($main, $prefix, join q(-), @{$versions})
   } elsif (-d $generic) {
-    $dir = catfile($main, $prefix, join q(-), @{$versions})
+    $dir = catfile($generic, $prefix, join q(-), @{$versions});
   } else {
-    die 'PREPARE TO SQL'
+    croak "neither $main or $generic exist; please write/generate some SQL";
   }
 
   opendir my($dh), $dir;
-  my %files = map { $_ => "$dir/$_" } grep { /\.sql$/ && -f "$dir/$_" } readdir($dh);
+  my %files = map { $_ => "$dir/$_" } grep { /\.(?:sql|pl)$/ && -f "$dir/$_" } readdir $dh;
   closedir $dh;
 
   if (-d $common) {
     opendir my($dh), $common;
-    for my $filename (grep { /\.sql$/ && -f "$common/$_" } readdir($dh)) {
+    for my $filename (grep { /\.(?:sql|pl)$/ && -f catfile($common,$_) } readdir $dh) {
       unless ($files{$filename}) {
-        $files{$filename} = "$common/$_";
+        $files{$filename} = catfile($common,$filename);
       }
     }
     closedir $dh;
@@ -134,40 +132,72 @@ method _ddl_schema_down_produce_filename($type, $versions, $dir) {
   return catfile( $dirname, '001-auto.sql');
 }
 
-sub _deploy {
-  my $self = shift;
-  my $storage  = $self->storage;
+method _run_sql_and_perl($filenames) {
+  my @files = @{$filenames};
+  my $storage = $self->storage;
+
 
   my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
 
-  my @sql = map @{$self->_read_sql_file($_)}, @{$self->_ddl_schema_consume_filenames(
-      $self->storage->sqlt_type,
-      $self->schema_version
-    )};
-
-  foreach my $line (@sql) {
-    $storage->_query_start($line);
-    try {
-      # do a dbh_do cycle here, as we need some error checking in
-      # place (even though we will ignore errors)
-      $storage->dbh_do (sub { $_[1]->do($line) });
-    }
-    catch {
-      carp "$_ (running '${line}')"
+  my $sql;
+  for my $filename (@files) {
+    if ($filename =~ /\.sql$/) {
+      my @sql = @{$self->_read_sql_file($filename)};
+      $sql .= join "\n", @sql;
+
+      foreach my $line (@sql) {
+        $storage->_query_start($line);
+        try {
+          # do a dbh_do cycle here, as we need some error checking in
+          # place (even though we will ignore errors)
+          $storage->dbh_do (sub { $_[1]->do($line) });
+        }
+        catch {
+          carp "$_ (running '${line}')"
+        }
+        $storage->_query_end($line);
+      }
+    } elsif ( $filename =~ /^(.+)\.pl$/ ) {
+      my $package = $1;
+      my $filedata = do { local( @ARGV, $/ ) = $filename; <> };
+      # make the package name more palateable to perl
+      $package =~ s/\W/_/g;
+
+      no warnings 'redefine';
+      eval "package $package;\n\n$filedata";
+      use warnings;
+
+      if (my $fn = $package->can('run')) {
+        $fn->($self->schema);
+      } else {
+        carp "$filename should define a run method that takes a schema but it didn't!";
+      }
+    } else {
+      croak "A file got to deploy that wasn't sql or perl!";
     }
-    $storage->_query_end($line);
   }
 
   $guard->commit if $self->txn_wrap;
-  return join "\n", @sql;
+
+  return $sql;
 }
 
-sub prepare_install {
+sub deploy {
   my $self = shift;
+
+  return $self->_run_sql_and_perl($self->_ddl_schema_consume_filenames(
+    $self->storage->sqlt_type,
+    $self->schema_version
+  ));
+}
+
+sub _prepare_install {
+  my $self = shift;
+  my $sqltargs  = { %{$self->sqltargs}, %{shift @_} };
+  my $to_file   = shift;
   my $schema    = $self->schema;
   my $databases = $self->databases;
   my $dir       = $self->upgrade_directory;
-  my $sqltargs  = $self->sqltargs;
   my $version = $schema->schema_version;
 
   my $sqlt = SQL::Translator->new({
@@ -179,14 +209,14 @@ sub prepare_install {
   });
 
   my $sqlt_schema = $sqlt->translate( data => $schema )
-    or $self->throw_exception($sqlt->error);
+    or croak($sqlt->error);
 
   foreach my $db (@$databases) {
     $sqlt->reset;
     $sqlt->{schema} = $sqlt_schema;
     $sqlt->producer($db);
 
-    my $filename = $self->_ddl_schema_produce_filename($db, $version, $dir);
+    my $filename = $self->$to_file($db, $version, $dir);
     if (-e $filename ) {
       carp "Overwriting existing DDL file - $filename";
       unlink $filename;
@@ -197,41 +227,61 @@ sub prepare_install {
       carp("Failed to translate to $db, skipping. (" . $sqlt->error . ")");
       next;
     }
-    my $file;
-    unless( open $file, q(>), $filename ) {
-      $self->throw_exception("Can't open $filename for writing ($!)");
-      next;
-    }
+    open my $file, q(>), $filename;
     print {$file} $output;
     close $file;
   }
 }
 
-sub prepare_upgrade {
-  my ($self, $from_version, $to_version, $version_set) = @_;
+sub _resultsource_install_filename {
+  my ($self, $source_name) = @_;
+  return sub {
+    my ($self, $type, $version) = @_;
+    my $dirname = catfile( $self->upgrade_directory, $type, 'schema', $version );
+    mkpath($dirname) unless -d $dirname;
+
+    return catfile( $dirname, "001-auto-$source_name.sql" );
+  }
+}
 
-  $from_version ||= $self->db_version;
-  $to_version   ||= $self->schema_version;
+sub install_resultsource {
+  my ($self, $source, $version) = @_;
 
-  # for updates prepared automatically (rob's stuff)
-  # one would want to explicitly set $version_set to
-  # [$to_version]
-  $version_set  ||= [$from_version, $to_version];
+  my $rs_install_file =
+    $self->_resultsource_install_filename($source->source_name);
 
+  my $files = [
+     $self->$rs_install_file(
+      $self->storage->sqlt_type,
+      $version,
+    )
+  ];
+  $self->_run_sql_and_perl($files);
+}
+
+sub prepare_resultsource_install {
+  my $self = shift;
+  my $source = shift;
+
+  my $filename = $self->_resultsource_install_filename($source->source_name);
+  $self->_prepare_install({
+      parser_args => { sources => [$source->source_name], }
+    }, $filename);
+}
+
+sub prepare_install {
+  my $self = shift;
+  $self->_prepare_install({}, '_ddl_schema_produce_filename');
+}
+
+sub prepare_upgrade {
+  my ($self, $from_version, $to_version, $version_set) = @_;
   $self->_prepare_changegrade($from_version, $to_version, $version_set, 'up');
 }
 
 sub prepare_downgrade {
   my ($self, $from_version, $to_version, $version_set) = @_;
 
-  $from_version ||= $self->db_version;
-  $to_version   ||= $self->schema_version;
-
-  # for updates prepared automatically (rob's stuff)
-  # one would want to explicitly set $version_set to
-  # [$to_version]
-  $version_set  ||= [$from_version, $to_version];
-
   $self->_prepare_changegrade($from_version, $to_version, $version_set, 'down');
 }
 
@@ -254,7 +304,7 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
 
   $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
   my $sqlt_schema = $sqlt->translate( data => $schema )
-    or $self->throw_exception ($sqlt->error);
+    or croak($sqlt->error);
 
   foreach my $db (@$databases) {
     $sqlt->reset;
@@ -282,10 +332,10 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
       });
 
       $t->parser( $db ) # could this really throw an exception?
-        or $self->throw_exception ($t->error);
+        or croak($t->error);
 
       my $out = $t->translate( $prefilename )
-        or $self->throw_exception ($t->error);
+        or croak($t->error);
 
       $source_schema = $t->schema;
 
@@ -306,11 +356,11 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
       });
 
       $t->parser( $db ) # could this really throw an exception?
-        or $self->throw_exception ($t->error);
+        or croak($t->error);
 
       my $filename = $self->_ddl_schema_produce_filename($db, $to_version, $dir);
       my $out = $t->translate( $filename )
-        or $self->throw_exception ($t->error);
+        or croak($t->error);
 
       $dest_schema = $t->schema;
 
@@ -323,11 +373,7 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
        $dest_schema,   $db,
        $sqltargs
     );
-    my $file;
-    unless(open $file, q(>), $diff_file) {
-      $self->throw_exception("Can't write to $diff_file ($!)");
-      next;
-    }
+    open my $file, q(>), $diff_file;
     print {$file} $diff;
     close $file;
   }
@@ -336,7 +382,7 @@ method _prepare_changegrade($from_version, $to_version, $version_set, $direction
 method _read_sql_file($file) {
   return unless $file;
 
-  open my $fh, '<', $file or carp("Can't open sql file, $file ($!)");
+  open my $fh, '<', $file;
   my @data = split /;\n/, join '', <$fh>;
   close $fh;
 
@@ -351,72 +397,92 @@ method _read_sql_file($file) {
   return \@data;
 }
 
-# these are exactly the same for now
-sub _downgrade_single_step {
+sub downgrade_single_step {
   my $self = shift;
-  my @version_set = @{ shift @_ };
-  my @upgrade_files = @{$self->_ddl_schema_up_consume_filenames(
-    $self->storage->sqlt_type,
-    \@version_set,
-  )};
-
-  for my $upgrade_file (@upgrade_files) {
-    unless (-f $upgrade_file) {
-      # croak?
-      carp "Upgrade not possible, no upgrade file found ($upgrade_file), please create one\n";
-      return;
-    }
+  my $version_set = shift @_;
 
-    $self->_filedata($self->_read_sql_file($upgrade_file)); # I don't like this --fREW 2010-02-22
+  my $sql = $self->_run_sql_and_perl($self->_ddl_schema_down_consume_filenames(
+    $self->storage->sqlt_type,
+    $version_set,
+  ));
 
-    my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
-    $self->_do_upgrade;
-    $guard->commit if $self->txn_wrap;
-  }
+  return ['', $sql];
 }
 
-sub _upgrade_single_step {
+sub upgrade_single_step {
   my $self = shift;
-  my @version_set = @{ shift @_ };
-  my @upgrade_files = @{$self->_ddl_schema_up_consume_filenames(
-    $self->storage->sqlt_type,
-    \@version_set,
-  )};
-
-  for my $upgrade_file (@upgrade_files) {
-    unless (-f $upgrade_file) {
-      # croak?
-      carp "Upgrade not possible, no upgrade file found ($upgrade_file), please create one\n";
-      return;
-    }
+  my $version_set = shift @_;
 
-    $self->_filedata($self->_read_sql_file($upgrade_file)); # I don't like this --fREW 2010-02-22
-    my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
-    $self->_do_upgrade;
-    $guard->commit if $self->txn_wrap;
-  }
+  my $sql = $self->_run_sql_and_perl($self->_ddl_schema_up_consume_filenames(
+    $self->storage->sqlt_type,
+    $version_set,
+  ));
+  return ['', $sql];
 }
 
-method _do_upgrade { $self->_run_upgrade(qr/.*?/) }
+__PACKAGE__->meta->make_immutable;
 
-method _run_upgrade($stm) {
-  return unless $self->_filedata;
-  my @statements = grep { $_ =~ $stm } @{$self->_filedata};
+1;
 
-  for (@statements) {
-    $self->storage->debugobj->query_start($_) if $self->storage->debug;
-    $self->_apply_statement($_);
-    $self->storage->debugobj->query_end($_) if $self->storage->debug;
-  }
-}
+__END__
 
-method _apply_statement($statement) {
-  # croak?
-  $self->storage->dbh->do($_) or carp "SQL was: $_"
-}
+=attr schema
 
-1;
+=attr storage
 
-__END__
+=attr sqltargs
+
+#rename
+
+=attr upgrade_directory
+
+The directory (default C<'sql'>) that upgrades are stored in
+
+=attr databases
+
+The types of databases (default C<< [qw( MySQL SQLite PostgreSQL )] >>) to
+generate files for
+
+=attr txn_wrap
+
+=method __ddl_consume_with_prefix
+
+=method _ddl_schema_consume_filenames
+
+=method _ddl_schema_produce_filename
+
+=method _ddl_schema_up_consume_filenames
+
+=method _ddl_schema_down_consume_filenames
+
+=method _ddl_schema_up_produce_filenames
+
+=method _ddl_schema_down_produce_filenames
+
+=method _resultsource_install_filename
+
+=method _run_sql_and_perl
+
+=method _prepare_install
+
+=method _prepare_changegrade
+
+=method _read_sql_file
+
+=method deploy
+
+=method install_resultsource
+
+=method prepare_resultsouce_install
+
+=method prepare_install
+
+=method prepare_upgrade
+
+=method prepare_downgrade
+
+=method upgrade_single_step
+
+=method downgrade_single_step
 
 vim: ts=2 sw=2 expandtab