diff --git a/AUTHORS b/AUTHORS index 44667b0f2..ae2aca7e0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ abraxxa: Alexander Hartmaier acca: Alexander Kuznetsov acme: Leon Brocard +agregory: Andrew Gregory aherzog: Adam Herzog Alexander Keusch alexrj: Alessandro Ranellucci diff --git a/lib/DBIx/Class/Storage/DBI/MSSQL.pm b/lib/DBIx/Class/Storage/DBI/MSSQL.pm index e54ab69b1..f2db24210 100644 --- a/lib/DBIx/Class/Storage/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Storage/DBI/MSSQL.pm @@ -9,6 +9,8 @@ use base qw/ /; use mro 'c3'; +use Context::Preserve 'preserve_context'; +use Scope::Guard (); use Try::Tiny; use namespace::clean; @@ -185,6 +187,32 @@ sub _ping { }; } +sub with_deferred_fk_checks { + my ( $self, $sub ) = @_; + + my $txn_scope_guard = $self->txn_scope_guard; + + $self->_do_query( + 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT ALL"'); + + my $sg = Scope::Guard->new( + sub { + $self->_do_query( + 'EXEC sp_msforeachtable "ALTER TABLE ? CHECK CONSTRAINT ALL"' + ); + } ); + + return preserve_context { $sub->() } after => sub { + # explicitly check constraints because MSSQL does not check when + # re-enabling them + $self->_do_query( + 'EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL"' + ); + $txn_scope_guard->commit; + $sg->dismiss; + }; +} + package # hide from PAUSE DBIx::Class::Storage::DBI::MSSQL::DateTime::Format; diff --git a/lib/DBIx/Class/Storage/DBI/SQLite.pm b/lib/DBIx/Class/Storage/DBI/SQLite.pm index 72e627693..3fcbe0a2c 100644 --- a/lib/DBIx/Class/Storage/DBI/SQLite.pm +++ b/lib/DBIx/Class/Storage/DBI/SQLite.pm @@ -6,6 +6,7 @@ use warnings; use base qw/DBIx::Class::Storage::DBI/; use mro 'c3'; +use Context::Preserve 'preserve_context'; use SQL::Abstract::Util 'is_plain_value'; use DBIx::Class::_Util qw(modver_gt_or_eq sigwarn_silencer); use DBIx::Class::Carp; @@ -360,6 +361,16 @@ sub _dbi_attrs_for_bind { return $bindattrs; } +sub with_deferred_fk_checks { + my ($self, $sub) = @_; + + my $txn_scope_guard = $self->txn_scope_guard; + + $self->_do_query('PRAGMA defer_foreign_keys = ON'); + + return preserve_context { $sub->() } after => sub { $txn_scope_guard->commit }; +} + =head2 connect_call_use_foreign_keys Used as: