Add method which we can use for deploying without ddl
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / DeployMethod / SQL / Translator.pm
index c298cdd..1a1fda8 100644 (file)
@@ -6,7 +6,7 @@ use Moose;
 use autodie;
 use Carp qw( carp croak );
 use DBIx::Class::DeploymentHandler::Logger;
-use Log::Contextual qw(:log :dlog), -default_logger =>
+use Log::Contextual qw(:log :dlog), -package_logger =>
   DBIx::Class::DeploymentHandler::Logger->new({
     env_prefix => 'DBICDH'
   });
@@ -96,7 +96,11 @@ method __ddl_consume_with_prefix($type, $versions, $prefix) {
   if (-d $main) {
     $dir = catfile($main, $prefix, join q(-), @{$versions})
   } else {
-    croak "$main does not exist; please write/generate some SQL";
+    if ($self->ignore_ddl) {
+      return []
+    } else {
+      croak "$main does not exist; please write/generate some SQL"
+    }
   }
 
   my %files;
@@ -123,14 +127,27 @@ method __ddl_consume_with_prefix($type, $versions, $prefix) {
   return [@files{sort keys %files}]
 }
 
-method _ddl_preinstall_consume_filenames($type, $version) {
-  $self->__ddl_consume_with_prefix($type, [ $version ], 'preinstall')
+method _ddl_initialize_consume_filenames($type, $version) {
+  $self->__ddl_consume_with_prefix($type, [ $version ], 'initialize')
 }
 
 method _ddl_schema_consume_filenames($type, $version) {
   $self->__ddl_consume_with_prefix($type, [ $version ], 'deploy')
 }
 
+method _ddl_protoschema_deploy_consume_filenames($version) {
+  my $base_dir = $self->script_directory;
+
+  my $dir = catfile( $base_dir, '_source', 'deploy', $version);
+  return [] unless -d $dir;
+
+  opendir my($dh), $dir;
+  my %files = map { $_ => "$dir/$_" } grep { /\.yml$/ && -f "$dir/$_" } readdir $dh;
+  closedir $dh;
+
+  return [@files{sort keys %files}]
+}
+
 method _ddl_protoschema_upgrade_consume_filenames($versions) {
   my $base_dir = $self->script_directory;
 
@@ -217,7 +234,7 @@ method _run_sql_array($sql) {
     }
     catch {
       die "$_ (running line '$line')"
-    }
+    };
     $storage->_query_end($line);
   }
   return join "\n", @$sql
@@ -288,14 +305,14 @@ sub deploy {
   ), $sql);
 }
 
-sub preinstall {
+sub initialize {
   my $self         = shift;
   my $args         = shift;
   my $version      = $args->{version}      || $self->schema_version;
-  log_info { "preinstalling version $version" };
+  log_info { "initializing version $version" };
   my $storage_type = $args->{storage_type} || $self->storage->sqlt_type;
 
-  my @files = @{$self->_ddl_preinstall_consume_filenames(
+  my @files = @{$self->_ddl_initialize_consume_filenames(
     $storage_type,
     $version,
   )};
@@ -317,7 +334,7 @@ sub preinstall {
         carp "$filename should define an anonymous sub but it didn't!";
       }
     } else {
-      croak "A file ($filename) got to preinstall_scripts that wasn't sql or perl!";
+      croak "A file ($filename) got to initialize_scripts that wasn't sql or perl!";
     }
   }
 }
@@ -451,7 +468,7 @@ sub _resultsource_protoschema_filename {
   my ($self, $source_name) = @_;
   return sub {
     my ($self, $version) = @_;
-    my $dirname = catfile( $self->script_directory, '_source', $version );
+    my $dirname = catfile( $self->script_directory, '_source', 'deploy', $version );
     mkpath($dirname) unless -d $dirname;
 
     return catfile( $dirname, "001-auto-$source_name.yml" );
@@ -491,7 +508,10 @@ sub prepare_resultsource_install {
 sub prepare_deploy {
   log_info { 'preparing deploy' };
   my $self = shift;
-  $self->prepare_protoschema({}, '_ddl_protoschema_produce_filename');
+  $self->prepare_protoschema({
+      # Exclude __VERSION so that it gets installed separately
+      parser_args => { sources => [grep { $_ ne '__VERSION' } $self->schema->sources], }
+  }, '_ddl_protoschema_produce_filename');
   $self->_prepare_install({}, '_ddl_protoschema_produce_filename', '_ddl_schema_produce_filename');
 }
 
@@ -650,10 +670,11 @@ documented here is extra fun stuff or private methods.
 
 =head1 DIRECTORY LAYOUT
 
-Arguably this is the best feature of L<DBIx::Class::DeploymentHandler>.  It's
-heavily based upon L<DBIx::Migration::Directories>, but has some extensions and
-modifications, so even if you are familiar with it, please read this.  I feel
-like the best way to describe the layout is with the following example:
+Arguably this is the best feature of L<DBIx::Class::DeploymentHandler>.
+It's spiritually based upon L<DBIx::Migration::Directories>, but has a
+lot of extensions and modifications, so even if you are familiar with it,
+please read this.  I feel like the best way to describe the layout is with
+the following example:
 
  $sql_migration_dir
  |- _source
@@ -687,7 +708,7 @@ like the best way to describe the layout is with the following example:
     |- downgrade
     |  `- 2-1
     |     `- 001-auto.sql
-    |- preinstall
+    |- initialize
     |  `- 1
     |     |- 001-create_database.pl
     |     `- 002-create_users_and_permissions.pl
@@ -711,13 +732,13 @@ would run C<$sql_migration_dir/SQLite/upgrade/1-2/001-auto.sql> followed by
 C<$sql_migration_dir/_common/upgrade/1-2/002-generate-customers.pl>.
 
 C<.pl> files don't have to be in the C<_common> directory, but most of the time
-they should be, because perl scripts are generally be database independent.
+they should be, because perl scripts are generally database independent.
 
-Note that unlike most steps in the process, C<preinstall> will not run SQL, as
-there may not even be an database at preinstall time.  It will run perl scripts
+Note that unlike most steps in the process, C<initialize> will not run SQL, as
+there may not even be an database at initialize time.  It will run perl scripts
 just like the other steps in the process, but nothing is passed to them.
 Until people have used this more it will remain freeform, but a recommended use
-of preinstall is to have it prompt for username and password, and then call the
+of initialize is to have it prompt for username and password, and then call the
 appropriate C<< CREATE DATABASE >> commands etc.
 
 =head2 Directory Specification
@@ -730,6 +751,17 @@ The following subdirectories are recognized by this DeployMethod:
 
 =over 2
 
+=item C<deploy> This directory merely contains directories named after schema
+versions, which in turn contain C<yaml> files that are serialized versions
+of the schema at that version.  These files are not for editing by hand.
+
+=back
+
+=item C<_preprocess_schema> This directory can contain the following
+directories:
+
+=over 2
+
 =item C<downgrade> This directory merely contains directories named after
 migrations, which are of the form C<$from_version-$to_version>.  Inside of
 these directories you may put Perl scripts which are to return a subref
@@ -742,10 +774,6 @@ these directories you may put Perl scripts which are to return a subref
 that takes the arguments C<< $from_schema, $to_schema >>, which are
 L<SQL::Translator::Schema> objects.
 
-=item C<deploy> This directory merely contains directories named after schema
-versions, which in turn contain C<yaml> files that are serialized versions
-of the schema at that version.  These files are not for editing by hand.
-
 =back
 
 =item C<$storage_type> This is a set of scripts that gets run depending on what
@@ -756,7 +784,7 @@ already have.  This directory can containt the following directories itself:
 
 =over 2
 
-=item C<preinstall> Gets run before the C<deploy> is C<deploy>ed.  Has the
+=item C<initialize> Gets run before the C<deploy> is C<deploy>ed.  Has the
 same structure as the C<deploy> subdirectory as well; that is, it has a
 directory for each schema version.  Unlike C<deploy>, C<upgrade>, and C<downgrade>
 though, it can only run C<.pl> files, and the coderef in the perl files get
@@ -804,6 +832,14 @@ A very basic perl script might look like:
    })
  }
 
+=attr ignore_ddl
+
+This attribute will, when set to true (default is false), cause the DM to use
+L<SQL::Translator> to use the C<_source>'s serialized SQL::Translator::Schema
+instead of any pregenerated SQL.  If you have a development server this is
+probably the best plan of action as you will not be putting as many generated
+files in your version control.  Goes well with with C<databases> of C<[]>.
+
 =attr schema
 
 The L<DBIx::Class::Schema> (B<required>) that is used to talk to the database
@@ -836,98 +872,3 @@ transaction.
 
 The version the schema on your harddrive is at.  Defaults to
 C<< $self->schema->schema_version >>.
-
-=begin comment
-
-=head2 __ddl_consume_with_prefix
-
- $dm->__ddl_consume_with_prefix( 'SQLite', [qw( 1.00 1.01 )], 'upgrade' )
-
-This is the meat of the multi-file upgrade/deploy stuff.  It returns a list of
-files in the order that they should be run for a generic "type" of upgrade.
-You should not be calling this in user code.
-
-=head2 _ddl_schema_consume_filenames
-
- $dm->__ddl_schema_consume_filenames( 'SQLite', [qw( 1.00 )] )
-
-Just a curried L</__ddl_consume_with_prefix>.  Get's a list of files for an
-initial deploy.
-
-=head2 _ddl_schema_produce_filename
-
- $dm->__ddl_schema_produce_filename( 'SQLite', [qw( 1.00 )] )
-
-Returns a single file in which an initial schema will be stored.
-
-=head2 _ddl_schema_up_consume_filenames
-
- $dm->_ddl_schema_up_consume_filenames( 'SQLite', [qw( 1.00 )] )
-
-Just a curried L</__ddl_consume_with_prefix>.  Get's a list of files for an
-upgrade.
-
-=head2 _ddl_schema_down_consume_filenames
-
- $dm->_ddl_schema_down_consume_filenames( 'SQLite', [qw( 1.00 )] )
-
-Just a curried L</__ddl_consume_with_prefix>.  Get's a list of files for a
-downgrade.
-
-=head2 _ddl_schema_up_produce_filenames
-
- $dm->_ddl_schema_up_produce_filename( 'SQLite', [qw( 1.00 1.01 )] )
-
-Returns a single file in which the sql to upgrade from one schema to another
-will be stored.
-
-=head2 _ddl_schema_down_produce_filename
-
- $dm->_ddl_schema_down_produce_filename( 'SQLite', [qw( 1.00 1.01 )] )
-
-Returns a single file in which the sql to downgrade from one schema to another
-will be stored.
-
-=head2 _resultsource_install_filename
-
- my $filename_fn = $dm->_resultsource_install_filename('User');
- $dm->$filename_fn('SQLite', '1.00')
-
-Returns a function which in turn returns a single filename used to install a
-single resultsource.  Weird interface is convenient for me.  Deal with it.
-
-=head2 _run_sql_and_perl
-
- $dm->_run_sql_and_perl([qw( list of filenames )])
-
-Simply put, this runs the list of files passed to it.  If the file ends in
-C<.sql> it runs it as sql and if it ends in C<.pl> it runs it as a perl file.
-
-Depending on L</txn_wrap> all of the files run will be wrapped in a single
-transaction.
-
-=head2 _prepare_install
-
- $dm->_prepare_install({ add_drop_table => 0 }, sub { 'file_to_create' })
-
-Generates the sql file for installing the database.  First arg is simply
-L<SQL::Translator> args and the second is a coderef that returns the filename
-to store the sql in.
-
-=head2 _prepare_changegrade
-
- $dm->_prepare_changegrade('1.00', '1.01', [qw( 1.00 1.01)], 'upgrade')
-
-Generates the sql file for migrating from one schema version to another.  First
-arg is the version to start from, second is the version to go to, third is the
-L<version set|DBIx::Class::DeploymentHandler/VERSION SET>, and last is the
-direction of the changegrade, be it 'upgrade' or 'downgrade'.
-
-=head2 _read_sql_file
-
- $dm->_read_sql_file('foo.sql')
-
-Reads a sql file and returns lines in an C<ArrayRef>.  Strips out comments,
-transactions, and blank lines.
-
-=end comment