require DBIx::Class::Storage; # loaded for type constraint
use autodie;
use File::Path;
+use DBIx::Class::DeploymentHandler::Types;
+
with 'DBIx::Class::DeploymentHandler::HandlesDeploy';
is => 'rw',
);
+has txn_wrap => (
+ is => 'ro',
+ isa => 'Bool',
+ default => 1,
+);
+
method __ddl_consume_with_prefix($type, $versions, $prefix) {
my $base_dir = $self->upgrade_directory;
);
}
-method _deployment_statements {
- my $dir = $self->upgrade_directory;
- my $schema = $self->schema;
- my $type = $self->storage->sqlt_type;
- my $sqltargs = $self->sqltargs;
- my $version = $self->schema_version;
-
- my @filenames = @{$self->_ddl_schema_consume_filenames($type, $version)};
-
- for my $filename (@filenames) {
- if(-f $filename) {
- my $file;
- open $file, q(<), $filename
- or carp "Can't open $filename ($!)";
- my @rows = <$file>;
- close $file;
- return join '', @rows;
- }
- }
-
- # sources needs to be a parser arg, but for simplicty allow at top level
- # coming in
- $sqltargs->{parser_args}{sources} = delete $sqltargs->{sources}
- if exists $sqltargs->{sources};
-
- my $tr = SQL::Translator->new(
- producer => "SQL::Translator::Producer::${type}",
- %$sqltargs,
- parser => 'SQL::Translator::Parser::DBIx::Class',
- data => $schema,
- );
-
- my $ret = $tr->translate;
-
- $schema->throw_exception( 'Unable to produce deployment statements: ' . $tr->error)
- unless defined $ret;
-
- return $ret;
-}
-
sub _deploy {
my $self = shift;
my $storage = $self->storage;
- my $deploy = sub {
- my $line = shift;
-#< frew> k, also, we filter out comments and transaction stuff and blank lines
-#< frew> is that really necesary?
-#< frew> and what if I want to run my upgrade in a txn? seems like something you'd
-# always want to do really
-#< ribasushi> again - some stuff chokes
-#< frew> ok, so I see filtering out -- and \s*
-#< frew> but I think the txn filtering should be optional and default to NOT filter it
-# out
-#< ribasushi> then you have a problem
-#< frew> tell me
-#< ribasushi> someone runs a deploy in txn_do
-#< ribasushi> the inner begin will blow up
-#< frew> because it's a nested TXN?
-#< ribasushi> (you an't begin twice on most dbs)
-#< ribasushi> right
-#< ribasushi> on sqlite - for sure
-#< frew> so...read the docs and set txn_filter to true?
-#< ribasushi> more like wrap deploy in a txn
-#< frew> I like that better
-#< ribasushi> and make sure the ddl has no literal txns in them
-#< frew> sure
-#< ribasushi> this way you have stuff under control
-#< frew> so we have txn_wrap default to true
-#< frew> and if people wanna do that by hand they can
-
- return if(!$line || $line =~ /^--|^BEGIN TRANSACTION|^COMMIT|^\s+$/);
+ 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
carp "$_ (running '${line}')"
}
$storage->_query_end($line);
- };
- my @statements = $self->_deployment_statements();
- if (@statements > 1) {
- foreach my $statement (@statements) {
- $deploy->( $statement );
- }
- }
- elsif (@statements == 1) {
- foreach my $line ( split(";\n", $statements[0])) {
- $deploy->( $line );
- }
}
+
+ $guard->commit if $self->txn_wrap;
+ return join "\n", @sql;
}
sub prepare_install {
my $sqltargs = $self->sqltargs;
my $version = $schema->schema_version;
- unless( -d $dir ) {
- carp "Upgrade directory $dir does not exist, using ./\n";
- $dir = './';
- }
-
-
my $sqlt = SQL::Translator->new({
add_drop_table => 1,
ignore_constraint_names => 1,
ignore_index_names => 1,
parser => 'SQL::Translator::Parser::DBIx::Class',
- %{$sqltargs || {}}
+ %{$sqltargs}
});
- my $sqlt_schema = $sqlt->translate({ data => $schema })
- or $self->throw_exception ($sqlt->error);
+ my $sqlt_schema = $sqlt->translate( data => $schema )
+ or $self->throw_exception($sqlt->error);
foreach my $db (@$databases) {
$sqlt->reset;
my $sqlt = SQL::Translator->new( $sqltargs );
$sqlt->parser('SQL::Translator::Parser::DBIx::Class');
- my $sqlt_schema = $sqlt->translate({ data => $schema })
+ my $sqlt_schema = $sqlt->translate( data => $schema )
or $self->throw_exception ($sqlt->error);
foreach my $db (@$databases) {
method _read_sql_file($file) {
return unless $file;
- open my $fh, '<', $file or carp("Can't open upgrade file, $file ($!)");
- my @data = split /\n/, join '', <$fh>;
+ open my $fh, '<', $file or carp("Can't open sql file, $file ($!)");
+ my @data = split /;\n/, join '', <$fh>;
close $fh;
@data = grep {
- $_ &&
- !/^--/ &&
- !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/m
- } split /;/,
- join '', @data;
+ $_ && # remove blank lines
+ !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/ # strip txn's
+ } map {
+ s/^\s+//; s/\s+$//; # trim whitespace
+ join '', grep { !/^--/ } split /\n/ # remove comments
+ } @data;
return \@data;
}
}
$self->_filedata($self->_read_sql_file($upgrade_file)); # I don't like this --fREW 2010-02-22
- $self->schema->txn_do(sub { $self->_do_upgrade });
+
+ my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
+ $self->_do_upgrade;
+ $guard->commit if $self->txn_wrap;
}
}
}
$self->_filedata($self->_read_sql_file($upgrade_file)); # I don't like this --fREW 2010-02-22
- $self->schema->txn_do(sub { $self->_do_upgrade });
+ my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
+ $self->_do_upgrade;
+ $guard->commit if $self->txn_wrap;
}
}