Revision history for {{$dist->name}}
{{$NEXT}}
+ - Wrap upgrades, downgrades, and installs in a transaction, as a failure
+ to add a version to the version table should cause a rollback
- Allow user to specify version of schema to install
- Added better sandboxing (stolen straight from Plack::Util) for coderefs
to avoid accidental leakage
Carp::Clan = 0
aliased = 0
Test::Requires = 0.06
+Context::Preserve = 0.01
croak 'Install not possible as versions table already exists in database'
if $self->version_storage_is_installed;
- my $ddl = $self->deploy({ version=> $version });
+ $self->txn_do(sub {
+ my $ddl = $self->deploy({ version=> $version });
- $self->add_database_version({
- version => $self->to_version,
- ddl => $ddl,
+ $self->add_database_version({
+ version => $self->to_version,
+ ddl => $ddl,
+ });
});
}
log_info { 'upgrading' };
my $self = shift;
my $ran_once = 0;
- while ( my $version_list = $self->next_version_set ) {
- $ran_once = 1;
- my ($ddl, $upgrade_sql) = @{
- $self->upgrade_single_step({ version_set => $version_list })
- ||[]};
-
- $self->add_database_version({
- version => $version_list->[-1],
- ddl => $ddl,
- upgrade_sql => $upgrade_sql,
- });
- }
+ $self->txn_do(sub {
+ while ( my $version_list = $self->next_version_set ) {
+ $ran_once = 1;
+ my ($ddl, $upgrade_sql) = @{
+ $self->upgrade_single_step({ version_set => $version_list })
+ ||[]};
+
+ $self->add_database_version({
+ version => $version_list->[-1],
+ ddl => $ddl,
+ upgrade_sql => $upgrade_sql,
+ });
+ }
+ });
log_warn { 'no need to run upgrade' } unless $ran_once;
}
log_info { 'downgrading' };
my $self = shift;
my $ran_once = 0;
- while ( my $version_list = $self->previous_version_set ) {
- $ran_once = 1;
- $self->downgrade_single_step({ version_set => $version_list });
-
- # do we just delete a row here? I think so but not sure
- $self->delete_database_version({ version => $version_list->[0] });
- }
+ $self->txn_do(sub {
+ while ( my $version_list = $self->previous_version_set ) {
+ $ran_once = 1;
+ $self->downgrade_single_step({ version_set => $version_list });
+
+ # do we just delete a row here? I think so but not sure
+ $self->delete_database_version({ version => $version_list->[0] });
+ }
+ });
log_warn { 'no version to run downgrade' } unless $ran_once;
}
See L<DBIx::Class::DeploymentHandler::HandlesDeploy/downgrade_single_step>.
+=head2 txn_do
+
+See L<DBIx::Class::DeploymentHandler::HandlesDeploy/txn_do>.
+
=head1 ORTHODOX METHODS
These methods are not actually B<required> as things will probably still work
DBIx::Class::DeploymentHandler::Logger->new({
env_prefix => 'DBICDH'
});
+use Context::Preserve;
use Try::Tiny;
}
}
-sub _run_sql_and_perl {
- my ($self, $filenames, $sql_to_run, $versions) = @_;
- my @files = @{$filenames};
- my $guard = $self->schema->txn_scope_guard if $self->txn_wrap;
+sub txn_do {
+ my ( $self, $code ) = @_;
+ return $code->() unless $self->txn_wrap;
- $self->_run_sql_array($sql_to_run) if $self->ignore_ddl;
+ my $guard = $self->schema->txn_scope_guard;
- my $sql = ($sql_to_run)?join ";\n", @$sql_to_run:'';
- FILENAME:
- for my $filename (@files) {
- if ($self->ignore_ddl && $filename =~ /^[^_]*-auto.*\.sql$/) {
- next FILENAME
- } elsif ($filename =~ /\.sql$/) {
- $sql .= $self->_run_sql($filename)
- } elsif ( $filename =~ /\.pl$/ ) {
- $self->_run_perl($filename, $versions)
- } else {
- croak "A file ($filename) got to deploy that wasn't sql or perl!";
- }
- }
+ return preserve_context { $code->() } after => sub { $guard->commit };
+}
- $guard->commit if $self->txn_wrap;
+sub _run_sql_and_perl {
+ my ($self, $filenames, $sql_to_run, $versions) = @_;
+ my @files = @{$filenames};
+ $self->txn_do(sub {
+ $self->_run_sql_array($sql_to_run) if $self->ignore_ddl;
+
+ my $sql = ($sql_to_run)?join ";\n", @$sql_to_run:'';
+ FILENAME:
+ for my $filename (@files) {
+ if ($self->ignore_ddl && $filename =~ /^[^_]*-auto.*\.sql$/) {
+ next FILENAME
+ } elsif ($filename =~ /\.sql$/) {
+ $sql .= $self->_run_sql($filename)
+ } elsif ( $filename =~ /\.pl$/ ) {
+ $self->_run_perl($filename, $versions)
+ } else {
+ croak "A file ($filename) got to deploy that wasn't sql or perl!";
+ }
+ }
- return $sql;
+ return $sql;
+ });
}
sub deploy {
requires 'prepare_downgrade';
requires 'downgrade_single_step';
+requires 'txn_do';
+
1;
# vim: ts=2 sw=2 expandtab
that version of the schema and C<$upgrade_sql> is the SQL that was run to
upgrade the database.
+=method txn_do
+
+ $dh->txn_do(sub { ... })
+
+Wrap the passed coderef in a transaction (if transactions are enabled.)
+
=head1 KNOWN IMPLEMENTATIONS
=over