Really fix SQLite savepoints unlike the shortsighted 398215b1
Peter Rabbitson [Wed, 30 Mar 2016 18:24:49 +0000 (20:24 +0200)]
( cherry-pick of 66c817df1 )

Changes
lib/DBIx/Class/Storage/DBI/SQLite.pm
t/752sqlite.t
t/storage/savepoints.t

diff --git a/Changes b/Changes
index 062797e..272bccd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -17,6 +17,8 @@ Revision history for DBIx::Class
         - Work around unreliable $sth->finish() on INSERT ... RETURNING within
           DBD::Firebird on some compiler/driver combinations (RT#110979)
         - Fix leaktest failures with upcoming version of Sub::Quote
+        - Really fix savepoint rollbacks on older DBD::SQLite (fix in 0.082800
+          was not sufficient to cover up RT#67843)
 
 0.082821 2016-02-11 17:58 (UTC)
     * Fixes
index 4311bdf..5acf261 100644 (file)
@@ -123,22 +123,17 @@ sub _exec_svp_rollback {
   my ($self, $name) = @_;
 
   $self->_dbh->do("ROLLBACK TO SAVEPOINT $name");
-}
-
-# older SQLite has issues here too - both of these are in fact
-# completely benign warnings (or at least so say the tests)
-sub _exec_txn_rollback {
-  local $SIG{__WARN__} = sigwarn_silencer( qr/rollback ineffective/ )
-    unless $DBD::SQLite::__DBIC_TXN_SYNC_SANE__;
-
-  shift->next::method(@_);
-}
-
-sub _exec_txn_commit {
-  local $SIG{__WARN__} = sigwarn_silencer( qr/commit ineffective/ )
-    unless $DBD::SQLite::__DBIC_TXN_SYNC_SANE__;
 
-  shift->next::method(@_);
+  # resync state for older DBD::SQLite (RT#67843)
+  # https://github.com/DBD-SQLite/DBD-SQLite/commit/9b3cdbf
+  if (
+    ! modver_gt_or_eq('DBD::SQLite', '1.33')
+      and
+    $self->_dbh->FETCH('AutoCommit')
+  ) {
+    $self->_dbh->STORE('AutoCommit', 0);
+    $self->_dbh->STORE('BegunWork', 1);
+  }
 }
 
 sub _ping {
index d162270..f12cc42 100644 (file)
@@ -94,6 +94,11 @@ DDL
 }
 
 # test blank begin/svp/commit/begin cycle
+#
+# need to prime this for exotic testing scenarios
+# before testing for lack of warnings
+modver_gt_or_eq('DBD::SQLite', '1.33');
+
 warnings_are {
   my $schema = DBICTest->init_schema( no_populate => 1 );
   my $rs = $schema->resultset('Artist');
index 0c56afc..b42ceca 100644 (file)
@@ -228,6 +228,9 @@ for ('', keys %$env2optdep) { SKIP: {
     undef,
     'rollback from inner transaction';
 
+  # make sure a fresh txn will work after above
+  $schema->storage->txn_do(sub { ok "noop" } );
+
 ### cleanupz
   $schema->storage->dbh->do ("DROP TABLE artist");
 }}
@@ -235,6 +238,6 @@ for ('', keys %$env2optdep) { SKIP: {
 done_testing;
 
 END {
-  eval { $schema->storage->dbh->do ("DROP TABLE artist") } if defined $schema;
+  eval { $schema->storage->dbh_do(sub { $_[1]->do("DROP TABLE artist") }) } if defined $schema;
   undef $schema;
 }