I have no idea why this stupid thing is not working
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / DeployMethod / SQL / Translator.pm
CommitLineData
45d0d9d5 1package DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator;
334bced5 2use Moose;
9af9d0b2 3
9a3a62f1 4# ABSTRACT: Manage your SQL and Perl migrations in nicely laid out directories
5
9af9d0b2 6use autodie;
7use Carp qw( carp croak );
8
2e68a8e1 9use Method::Signatures::Simple;
7f50d101 10use Try::Tiny;
9af9d0b2 11
d23c7c77 12use SQL::Translator;
13require SQL::Translator::Diff;
9af9d0b2 14
d23c7c77 15require DBIx::Class::Storage; # loaded for type constraint
41863428 16use DBIx::Class::DeploymentHandler::Types;
17
9af9d0b2 18use File::Path 'mkpath';
19use File::Spec::Functions;
2e68a8e1 20
7521a845 21with 'DBIx::Class::DeploymentHandler::HandlesDeploy';
3c1b5ee8 22
d54b8d69 23has schema => (
24 isa => 'DBIx::Class::Schema',
25 is => 'ro',
26 required => 1,
d54b8d69 27);
28
334bced5 29has storage => (
30 isa => 'DBIx::Class::Storage',
31 is => 'ro',
32 lazy_build => 1,
33);
34
2eaf903b 35method _build_storage {
36 my $s = $self->schema->storage;
37 $s->_determine_driver;
38 $s
39}
40
02a7b8ac 41has sql_translator_args => (
334bced5 42 isa => 'HashRef',
43 is => 'ro',
44 default => sub { {} },
45);
46has upgrade_directory => (
47 isa => 'Str',
48 is => 'ro',
49 required => 1,
50 default => 'sql',
51);
52
334bced5 53has databases => (
54 coerce => 1,
55 isa => 'DBIx::Class::DeploymentHandler::Databases',
56 is => 'ro',
57 default => sub { [qw( MySQL SQLite PostgreSQL )] },
58);
59
a7d53deb 60has txn_wrap => (
61 is => 'ro',
62 isa => 'Bool',
63 default => 1,
64);
65
73caa630 66has schema_version => (
67 is => 'ro',
68 lazy_build => 1,
69);
70
71method _build_schema_version { $self->schema->schema_version }
72
76d311e7 73method __ddl_consume_with_prefix($type, $versions, $prefix) {
262166c1 74 my $base_dir = $self->upgrade_directory;
75
76d08d08 76 my $main = catfile( $base_dir, $type );
77 my $generic = catfile( $base_dir, '_generic' );
78 my $common =
79 catfile( $base_dir, '_common', $prefix, join q(-), @{$versions} );
262166c1 80
81 my $dir;
82 if (-d $main) {
76d08d08 83 $dir = catfile($main, $prefix, join q(-), @{$versions})
262166c1 84 } elsif (-d $generic) {
9af9d0b2 85 $dir = catfile($generic, $prefix, join q(-), @{$versions});
262166c1 86 } else {
9af9d0b2 87 croak "neither $main or $generic exist; please write/generate some SQL";
262166c1 88 }
89
90 opendir my($dh), $dir;
41219a5d 91 my %files = map { $_ => "$dir/$_" } grep { /\.(?:sql|pl)$/ && -f "$dir/$_" } readdir $dh;
262166c1 92 closedir $dh;
93
94 if (-d $common) {
95 opendir my($dh), $common;
41219a5d 96 for my $filename (grep { /\.(?:sql|pl)$/ && -f catfile($common,$_) } readdir $dh) {
262166c1 97 unless ($files{$filename}) {
9af9d0b2 98 $files{$filename} = catfile($common,$filename);
262166c1 99 }
100 }
101 closedir $dh;
102 }
103
104 return [@files{sort keys %files}]
105}
3c1b5ee8 106
bf7a4e56 107method _ddl_preinstall_consume_filenames($type, $version) {
108 $self->__ddl_consume_with_prefix($type, [ $version ], 'preinstall')
109}
110
76d311e7 111method _ddl_schema_consume_filenames($type, $version) {
112 $self->__ddl_consume_with_prefix($type, [ $version ], 'schema')
3c1b5ee8 113}
114
76d311e7 115method _ddl_schema_produce_filename($type, $version) {
76d08d08 116 my $dirname = catfile( $self->upgrade_directory, $type, 'schema', $version );
117 mkpath($dirname) unless -d $dirname;
d54b8d69 118
76d08d08 119 return catfile( $dirname, '001-auto.sql' );
d54b8d69 120}
121
76d311e7 122method _ddl_schema_up_consume_filenames($type, $versions) {
123 $self->__ddl_consume_with_prefix($type, $versions, 'up')
3c1b5ee8 124}
125
76d311e7 126method _ddl_schema_down_consume_filenames($type, $versions) {
127 $self->__ddl_consume_with_prefix($type, $versions, 'down')
a41a04e5 128}
129
76d311e7 130method _ddl_schema_up_produce_filename($type, $versions) {
131 my $dir = $self->upgrade_directory;
132
76d08d08 133 my $dirname = catfile( $dir, $type, 'up', join q(-), @{$versions});
134 mkpath($dirname) unless -d $dirname;
a41a04e5 135
76d08d08 136 return catfile( $dirname, '001-auto.sql'
a41a04e5 137 );
138}
139
76d311e7 140method _ddl_schema_down_produce_filename($type, $versions, $dir) {
76d08d08 141 my $dirname = catfile( $dir, $type, 'down', join q(-), @{$versions} );
142 mkpath($dirname) unless -d $dirname;
24f4524b 143
76d08d08 144 return catfile( $dirname, '001-auto.sql');
24f4524b 145}
146
41219a5d 147method _run_sql_and_perl($filenames) {
148 my @files = @{$filenames};
149 my $storage = $self->storage;
2e68a8e1 150
c8a2f7bd 151
a7d53deb 152 my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
153
41219a5d 154 my $sql;
155 for my $filename (@files) {
156 if ($filename =~ /\.sql$/) {
157 my @sql = @{$self->_read_sql_file($filename)};
158 $sql .= join "\n", @sql;
159
160 foreach my $line (@sql) {
161 $storage->_query_start($line);
162 try {
163 # do a dbh_do cycle here, as we need some error checking in
164 # place (even though we will ignore errors)
165 $storage->dbh_do (sub { $_[1]->do($line) });
166 }
167 catch {
168 carp "$_ (running '${line}')"
169 }
170 $storage->_query_end($line);
171 }
0841a743 172 } elsif ( $filename =~ /^(.+)\.pl$/ ) {
173 my $package = $1;
174 my $filedata = do { local( @ARGV, $/ ) = $filename; <> };
175 # make the package name more palateable to perl
176 $package =~ s/\W/_/g;
177
178 no warnings 'redefine';
179 eval "package $package;\n\n$filedata";
180 use warnings;
181
98c9484a 182 if (my $fn = $package->can('run')) {
183 $fn->($self->schema);
184 } else {
185 carp "$filename should define a run method that takes a schema but it didn't!";
186 }
41219a5d 187 } else {
bf7a4e56 188 croak "A file ($filename) got to deploy that wasn't sql or perl!";
2e68a8e1 189 }
2e68a8e1 190 }
a7d53deb 191
192 $guard->commit if $self->txn_wrap;
41219a5d 193
194 return $sql;
195}
196
197sub deploy {
198 my $self = shift;
92c34cab 199 my $version = shift || $self->schema_version;
41219a5d 200
201 return $self->_run_sql_and_perl($self->_ddl_schema_consume_filenames(
202 $self->storage->sqlt_type,
92c34cab 203 $version,
41219a5d 204 ));
2e68a8e1 205}
206
bf7a4e56 207sub preinstall_scripts {
208 my $self = shift;
209 my $version = shift || $self->schema_version;
210
211 my @files = @{$self->_ddl_preinstall_consume_filenames(
212 $self->storage->sqlt_type,
213 $version,
214 )};
215
216 for my $filename (@files) {
217 # We ignore sql for now (till I figure out what to do with it)
218 if ( $filename =~ /^(.+)\.pl$/ ) {
219 my $package = $1;
220 my $filedata = do { local( @ARGV, $/ ) = $filename; <> };
221 # make the package name more palateable to perl
222 $package =~ s/\W/_/g;
223
224 no warnings 'redefine';
225 eval "package $package;\n\n$filedata";
226 use warnings;
227 if (my $fn = $package->can('run')) {
228 $fn->()
229 } else {
230 carp "$filename should define a run sub but it didn't!";
231 }
232 } else {
233 croak "A file ($filename) got to preinstall_scripts that wasn't sql or perl!";
234 }
235 }
236}
237
c8a2f7bd 238sub _prepare_install {
73caa630 239 my $self = shift;
02a7b8ac 240 my $sqltargs = { %{$self->sql_translator_args}, %{shift @_} };
c8a2f7bd 241 my $to_file = shift;
2e68a8e1 242 my $schema = $self->schema;
243 my $databases = $self->databases;
244 my $dir = $self->upgrade_directory;
73caa630 245 my $version = $self->schema_version;
d54b8d69 246
9600776d 247 my $sqlt = SQL::Translator->new({
d54b8d69 248 add_drop_table => 1,
2e68a8e1 249 ignore_constraint_names => 1,
d54b8d69 250 ignore_index_names => 1,
251 parser => 'SQL::Translator::Parser::DBIx::Class',
3aaf766f 252 %{$sqltargs}
9600776d 253 });
2e68a8e1 254
d53e0bfc 255 my $sqlt_schema = $sqlt->translate( data => $schema )
387b11d2 256 or croak($sqlt->error);
2e68a8e1 257
258 foreach my $db (@$databases) {
259 $sqlt->reset;
260 $sqlt->{schema} = $sqlt_schema;
261 $sqlt->producer($db);
262
c8a2f7bd 263 my $filename = $self->$to_file($db, $version, $dir);
9600776d 264 if (-e $filename ) {
2e68a8e1 265 carp "Overwriting existing DDL file - $filename";
266 unlink $filename;
267 }
268
269 my $output = $sqlt->translate;
270 if(!$output) {
271 carp("Failed to translate to $db, skipping. (" . $sqlt->error . ")");
272 next;
273 }
387b11d2 274 open my $file, q(>), $filename;
2e68a8e1 275 print {$file} $output;
276 close $file;
277 }
278}
279
c8a2f7bd 280sub _resultsource_install_filename {
281 my ($self, $source_name) = @_;
282 return sub {
283 my ($self, $type, $version) = @_;
284 my $dirname = catfile( $self->upgrade_directory, $type, 'schema', $version );
285 mkpath($dirname) unless -d $dirname;
286
287 return catfile( $dirname, "001-auto-$source_name.sql" );
288 }
289}
290
291sub install_resultsource {
292 my ($self, $source, $version) = @_;
293
294 my $rs_install_file =
295 $self->_resultsource_install_filename($source->source_name);
296
297 my $files = [
298 $self->$rs_install_file(
299 $self->storage->sqlt_type,
300 $version,
301 )
302 ];
303 $self->_run_sql_and_perl($files);
304}
305
306sub prepare_resultsource_install {
307 my $self = shift;
308 my $source = shift;
309
310 my $filename = $self->_resultsource_install_filename($source->source_name);
311 $self->_prepare_install({
312 parser_args => { sources => [$source->source_name], }
313 }, $filename);
314}
315
91557c90 316sub prepare_deploy {
c8a2f7bd 317 my $self = shift;
318 $self->_prepare_install({}, '_ddl_schema_produce_filename');
319}
320
a41a04e5 321sub prepare_upgrade {
9600776d 322 my ($self, $from_version, $to_version, $version_set) = @_;
76d311e7 323 $self->_prepare_changegrade($from_version, $to_version, $version_set, 'up');
324}
325
326sub prepare_downgrade {
327 my ($self, $from_version, $to_version, $version_set) = @_;
328
76d311e7 329 $self->_prepare_changegrade($from_version, $to_version, $version_set, 'down');
330}
331
332method _prepare_changegrade($from_version, $to_version, $version_set, $direction) {
2e68a8e1 333 my $schema = $self->schema;
334 my $databases = $self->databases;
335 my $dir = $self->upgrade_directory;
02a7b8ac 336 my $sqltargs = $self->sql_translator_args;
2e68a8e1 337
73caa630 338 my $schema_version = $self->schema_version;
2e68a8e1 339
340 $sqltargs = {
341 add_drop_table => 1,
342 ignore_constraint_names => 1,
343 ignore_index_names => 1,
344 %{$sqltargs}
345 };
346
347 my $sqlt = SQL::Translator->new( $sqltargs );
348
349 $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
d53e0bfc 350 my $sqlt_schema = $sqlt->translate( data => $schema )
387b11d2 351 or croak($sqlt->error);
2e68a8e1 352
353 foreach my $db (@$databases) {
354 $sqlt->reset;
355 $sqlt->{schema} = $sqlt_schema;
356 $sqlt->producer($db);
357
76d311e7 358 my $prefilename = $self->_ddl_schema_produce_filename($db, $from_version, $dir);
2e68a8e1 359 unless(-e $prefilename) {
360 carp("No previous schema file found ($prefilename)");
361 next;
362 }
76d311e7 363 my $diff_file_method = "_ddl_schema_${direction}_produce_filename";
364 my $diff_file = $self->$diff_file_method($db, $version_set, $dir );
2e68a8e1 365 if(-e $diff_file) {
76d311e7 366 carp("Overwriting existing $direction-diff file - $diff_file");
2e68a8e1 367 unlink $diff_file;
368 }
369
370 my $source_schema;
371 {
372 my $t = SQL::Translator->new({
373 %{$sqltargs},
374 debug => 0,
375 trace => 0,
376 });
377
378 $t->parser( $db ) # could this really throw an exception?
387b11d2 379 or croak($t->error);
2e68a8e1 380
381 my $out = $t->translate( $prefilename )
387b11d2 382 or croak($t->error);
2e68a8e1 383
384 $source_schema = $t->schema;
385
386 $source_schema->name( $prefilename )
387 unless $source_schema->name;
388 }
389
390 # The "new" style of producers have sane normalization and can support
391 # diffing a SQL file against a DBIC->SQLT schema. Old style ones don't
392 # And we have to diff parsed SQL against parsed SQL.
393 my $dest_schema = $sqlt_schema;
394
395 unless ( "SQL::Translator::Producer::$db"->can('preprocess_schema') ) {
396 my $t = SQL::Translator->new({
397 %{$sqltargs},
398 debug => 0,
399 trace => 0,
400 });
401
402 $t->parser( $db ) # could this really throw an exception?
387b11d2 403 or croak($t->error);
2e68a8e1 404
76d311e7 405 my $filename = $self->_ddl_schema_produce_filename($db, $to_version, $dir);
2e68a8e1 406 my $out = $t->translate( $filename )
387b11d2 407 or croak($t->error);
2e68a8e1 408
409 $dest_schema = $t->schema;
410
411 $dest_schema->name( $filename )
412 unless $dest_schema->name;
413 }
414
415 my $diff = SQL::Translator::Diff::schema_diff(
416 $source_schema, $db,
417 $dest_schema, $db,
418 $sqltargs
419 );
387b11d2 420 open my $file, q(>), $diff_file;
2e68a8e1 421 print {$file} $diff;
422 close $file;
423 }
424}
425
334bced5 426method _read_sql_file($file) {
427 return unless $file;
428
aabd4237 429 open my $fh, '<', $file;
0d19af1d 430 my @data = split /;\n/, join '', <$fh>;
334bced5 431 close $fh;
432
433 @data = grep {
0d19af1d 434 $_ && # remove blank lines
435 !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/ # strip txn's
436 } map {
437 s/^\s+//; s/\s+$//; # trim whitespace
438 join '', grep { !/^--/ } split /\n/ # remove comments
439 } @data;
334bced5 440
441 return \@data;
442}
443
7d2a6974 444sub downgrade_single_step {
76d311e7 445 my $self = shift;
627581cd 446 my $version_set = shift @_;
41219a5d 447
448 my $sql = $self->_run_sql_and_perl($self->_ddl_schema_down_consume_filenames(
76d311e7 449 $self->storage->sqlt_type,
627581cd 450 $version_set,
41219a5d 451 ));
3249629f 452
41219a5d 453 return ['', $sql];
76d311e7 454}
455
7d2a6974 456sub upgrade_single_step {
7521a845 457 my $self = shift;
627581cd 458 my $version_set = shift @_;
41219a5d 459
460 my $sql = $self->_run_sql_and_perl($self->_ddl_schema_up_consume_filenames(
334bced5 461 $self->storage->sqlt_type,
627581cd 462 $version_set,
41219a5d 463 ));
464 return ['', $sql];
334bced5 465}
466
aabd4237 467__PACKAGE__->meta->make_immutable;
468
2e68a8e1 4691;
e051bb00 470
e52174e3 471# vim: ts=2 sw=2 expandtab
472
e051bb00 473__END__
474
bcc72297 475=head1 DESCRIPTION
476
477This class is the meat of L<DBIx::Class::DeploymentHandler>. It takes care of
478generating sql files representing schemata as well as sql files to move from
479one version of a schema to the rest. One of the hallmark features of this
480class is that it allows for multiple sql files for deploy and upgrade, allowing
481developers to fine tune deployment. In addition it also allows for perl files
482to be run at any stage of the process.
483
484For basic usage see L<DBIx::Class::DeploymentHandler::HandlesDeploy>. What's
485documented here is extra fun stuff or private methods.
486
487=head1 DIRECTORY LAYOUT
488
92c34cab 489Arguably this is the best feature of L<DBIx::Class::DeploymentHandler>. It's
490heavily based upon L<DBIx::Migration::Directories>, but has some extensions and
491modifications, so even if you are familiar with it, please read this. I feel
492like the best way to describe the layout is with the following example:
493
494 $sql_migration_dir
495 |- SQLite
496 | |- down
497 | | `- 1-2
498 | | `- 001-auto.sql
499 | |- schema
500 | | `- 1
501 | | `- 001-auto.sql
502 | `- up
503 | |- 1-2
504 | | `- 001-auto.sql
505 | `- 2-3
506 | `- 001-auto.sql
507 |- _common
508 | |- down
509 | | `- 1-2
510 | | `- 002-remove-customers.pl
511 | `- up
512 | `- 1-2
513 | `- 002-generate-customers.pl
514 |- _generic
515 | |- down
516 | | `- 1-2
517 | | `- 001-auto.sql
518 | |- schema
519 | | `- 1
520 | | `- 001-auto.sql
521 | `- up
522 | `- 1-2
523 | |- 001-auto.sql
524 | `- 002-create-stored-procedures.sql
525 `- MySQL
526 |- down
527 | `- 1-2
528 | `- 001-auto.sql
529 |- schema
530 | `- 1
531 | `- 001-auto.sql
532 `- up
533 `- 1-2
534 `- 001-auto.sql
535
536So basically, the code
537
538 $dm->deploy(1)
539
540on an C<SQLite> database that would simply run
541C<$sql_migration_dir/SQLite/schema/1/001-auto.sql>. Next,
542
543 $dm->upgrade_single_step([1,2])
544
545would run C<$sql_migration_dir/SQLite/up/1-2/001-auto.sql> followed by
546C<$sql_migration_dir/_common/up/1-2/002-generate-customers.pl>.
547
548Now, a C<.pl> file doesn't have to be in the C<_common> directory, but most of
549the time it probably should be, since perl scripts will mostly be database
550independent.
551
552C<_generic> exists for when you for some reason are sure that your SQL is
553generic enough to run on all databases. Good luck with that one.
554
555=head1 PERL SCRIPTS
556
557A perl script for this tool is very simple. It merely needs to contain a
558sub called C<run> that takes a L<DBIx::Class::Schema> as it's only argument.
559A very basic perl script might look like:
560
561 #!perl
562
563 use strict;
564 use warnings;
565
566 sub run {
567 my $schema = shift;
568
569 $schema->resultset('Users')->create({
570 name => 'root',
571 password => 'root',
572 })
573 }
bcc72297 574
eb28403b 575=attr schema
a65184c8 576
bcc72297 577The L<DBIx::Class::Schema> (B<required>) that is used to talk to the database
578and generate the DDL.
579
eb28403b 580=attr storage
a65184c8 581
bcc72297 582The L<DBIx::Class::Storage> that is I<actually> used to talk to the database
583and generate the DDL. This is automatically created with L</_build_storage>.
584
02a7b8ac 585=attr sql_translator_args
cfc9edf9 586
02a7b8ac 587The arguments that get passed to L<SQL::Translator> when it's used.
a65184c8 588
eb28403b 589=attr upgrade_directory
cfc9edf9 590
591The directory (default C<'sql'>) that upgrades are stored in
592
eb28403b 593=attr databases
cfc9edf9 594
595The types of databases (default C<< [qw( MySQL SQLite PostgreSQL )] >>) to
596generate files for
597
eb28403b 598=attr txn_wrap
599
bcc72297 600Set to true (which is the default) to wrap all upgrades and deploys in a single
601transaction.
602
73caa630 603=attr schema_version
604
605The version the schema on your harddrive is at. Defaults to
606C<< $self->schema->schema_version >>.
607
eb28403b 608=method __ddl_consume_with_prefix
a65184c8 609
bcc72297 610 $dm->__ddl_consume_with_prefix( 'SQLite', [qw( 1.00 1.01 )], 'up' )
611
612This is the meat of the multi-file upgrade/deploy stuff. It returns a list of
613files in the order that they should be run for a generic "type" of upgrade.
614You should not be calling this in user code.
615
eb28403b 616=method _ddl_schema_consume_filenames
a65184c8 617
bcc72297 618 $dm->__ddl_schema_consume_filenames( 'SQLite', [qw( 1.00 )] )
619
620Just a curried L</__ddl_consume_with_prefix>. Get's a list of files for an
621initial deploy.
622
eb28403b 623=method _ddl_schema_produce_filename
a65184c8 624
bcc72297 625 $dm->__ddl_schema_produce_filename( 'SQLite', [qw( 1.00 )] )
626
627Returns a single file in which an initial schema will be stored.
628
eb28403b 629=method _ddl_schema_up_consume_filenames
a65184c8 630
bcc72297 631 $dm->_ddl_schema_up_consume_filenames( 'SQLite', [qw( 1.00 )] )
632
633Just a curried L</__ddl_consume_with_prefix>. Get's a list of files for an
634upgrade.
635
eb28403b 636=method _ddl_schema_down_consume_filenames
a65184c8 637
bcc72297 638 $dm->_ddl_schema_down_consume_filenames( 'SQLite', [qw( 1.00 )] )
639
640Just a curried L</__ddl_consume_with_prefix>. Get's a list of files for a
641downgrade.
642
eb28403b 643=method _ddl_schema_up_produce_filenames
a65184c8 644
bcc72297 645 $dm->_ddl_schema_up_produce_filename( 'SQLite', [qw( 1.00 1.01 )] )
646
647Returns a single file in which the sql to upgrade from one schema to another
648will be stored.
649
650=method _ddl_schema_down_produce_filename
651
652 $dm->_ddl_schema_down_produce_filename( 'SQLite', [qw( 1.00 1.01 )] )
653
654Returns a single file in which the sql to downgrade from one schema to another
655will be stored.
a65184c8 656
eb28403b 657=method _resultsource_install_filename
a65184c8 658
bcc72297 659 my $filename_fn = $dm->_resultsource_install_filename('User');
660 $dm->$filename_fn('SQLite', '1.00')
661
662Returns a function which in turn returns a single filename used to install a
663single resultsource. Weird interface is convenient for me. Deal with it.
664
eb28403b 665=method _run_sql_and_perl
666
bcc72297 667 $dm->_run_sql_and_perl([qw( list of filenames )])
a65184c8 668
bcc72297 669Simply put, this runs the list of files passed to it. If the file ends in
670C<.sql> it runs it as sql and if it ends in C<.pl> it runs it as a perl file.
a65184c8 671
bcc72297 672Depending on L</txn_wrap> all of the files run will be wrapped in a single
673transaction.
eb28403b 674
bcc72297 675=method _prepare_install
a65184c8 676
bcc72297 677 $dm->_prepare_install({ add_drop_table => 0 }, sub { 'file_to_create' })
a65184c8 678
bcc72297 679Generates the sql file for installing the database. First arg is simply
680L<SQL::Translator> args and the second is a coderef that returns the filename
681to store the sql in.
a65184c8 682
bcc72297 683=method _prepare_changegrade
684
685 $dm->_prepare_changegrade('1.00', '1.01', [qw( 1.00 1.01)], 'up')
a65184c8 686
bcc72297 687Generates the sql file for migrating from one schema version to another. First
688arg is the version to start from, second is the version to go to, third is the
689L<version set|DBIx::Class::DeploymentHandler/VERSION SET>, and last is the
690direction of the changegrade, be it 'up' or 'down'.
a65184c8 691
bcc72297 692=method _read_sql_file
a65184c8 693
bcc72297 694 $dm->_read_sql_file('foo.sql')
a65184c8 695
bcc72297 696Reads a sql file and returns lines in an C<ArrayRef>. Strips out comments,
697transactions, and blank lines.
eb28403b 698