with_deferred_fk_checks for Informix
Rafael Kitover [Fri, 26 Mar 2010 14:08:16 +0000 (14:08 +0000)]
lib/DBIx/Class/Storage/DBI/Informix.pm
t/748informix.t

index 314f4c1..8f23077 100644 (file)
@@ -3,9 +3,11 @@ use strict;
 use warnings;
 
 use base qw/DBIx::Class::Storage::DBI/;
-
 use mro 'c3';
 
+use Scope::Guard ();
+use Context::Preserve ();
+
 __PACKAGE__->mk_group_accessors('simple' => '__last_insert_id');
 
 =head1 NAME
@@ -59,6 +61,21 @@ sub _svp_rollback {
     $self->_get_dbh->do("ROLLBACK TO SAVEPOINT $name")
 }
 
+sub with_deferred_fk_checks {
+  my ($self, $sub) = @_;
+
+  my $txn_scope_guard = $self->txn_scope_guard;
+
+  $self->_do_query('SET CONSTRAINTS ALL DEFERRED');
+
+  my $sg = Scope::Guard->new(sub {
+    $self->_do_query('SET CONSTRAINTS ALL IMMEDIATE');
+  });
+
+  return Context::Preserve::preserve_context(sub { $sub->() },
+    after => sub { $txn_scope_guard->commit });
+}
+
 =head2 connect_call_datetime_setup
 
 Used as:
index a9ad66b..02ee6bb 100644 (file)
@@ -20,8 +20,30 @@ my $schema = DBICTest::Schema->connect($dsn, $user, $pass, {
 my $dbh = $schema->storage->dbh;
 
 eval { $dbh->do("DROP TABLE artist") };
-
 $dbh->do("CREATE TABLE artist (artistid SERIAL, name VARCHAR(255), charfield CHAR(10), rank INTEGER DEFAULT 13);");
+eval { $dbh->do("DROP TABLE cd") };
+$dbh->do(<<EOS);
+CREATE TABLE cd (
+  cdid int PRIMARY KEY,
+  artist int,
+  title varchar(255),
+  year varchar(4),
+  genreid int,
+  single_track int
+)
+EOS
+eval { $dbh->do("DROP TABLE track") };
+$dbh->do(<<EOS);
+CREATE TABLE track (
+  trackid int,
+  cd int REFERENCES cd(cdid),
+  position int,
+  title varchar(255),
+  last_updated_on date,
+  last_updated_at date,
+  small_dt date
+)
+EOS
 
 my $ars = $schema->resultset('Artist');
 is ( $ars->count, 0, 'No rows at first' );
@@ -96,6 +118,27 @@ like $@, qr/rolling back outer txn/,
 ok ((not $ars->search({ name => 'in_outer_txn' })->first),
   'outer txn rolled back');
 
+######## test with_deferred_fk_checks
+lives_ok {
+  $schema->storage->with_deferred_fk_checks(sub {
+    $schema->resultset('Track')->create({
+      trackid => 999, cd => 999, position => 1, title => 'deferred FK track'
+    });
+    $schema->resultset('CD')->create({
+      artist => 1, cdid => 999, year => '2003', title => 'deferred FK cd'
+    });
+  });
+} 'with_deferred_fk_checks code survived';
+
+is eval { $schema->resultset('Track')->find(999)->title }, 'deferred FK track',
+ 'code in with_deferred_fk_checks worked'; 
+
+throws_ok {
+  $schema->resultset('Track')->create({
+    trackid => 1, cd => 9999, position => 1, title => 'Track1'
+  });
+} qr/constraint/i, 'with_deferred_fk_checks is off';
+
 done_testing;
 
 # clean up our mess