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