Consolidate handling of "is this a literal" and "is this a value"
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / SQLite.pm
index a1a84c0..3024e89 100644 (file)
@@ -6,7 +6,7 @@ use warnings;
 use base qw/DBIx::Class::Storage::DBI/;
 use mro 'c3';
 
-use DBIx::Class::_Util qw(modver_gt_or_eq sigwarn_silencer);
+use DBIx::Class::_Util qw(modver_gt_or_eq sigwarn_silencer is_plain_value);
 use DBIx::Class::Carp;
 use Try::Tiny;
 use namespace::clean;
@@ -126,11 +126,23 @@ sub _exec_svp_release {
 sub _exec_svp_rollback {
   my ($self, $name) = @_;
 
-  # For some reason this statement changes the value of $dbh->{AutoCommit}, so
-  # we localize it here to preserve the original value.
-  local $self->_dbh->{AutoCommit} = $self->_dbh->{AutoCommit};
+  $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__;
 
-  $self->_dbh->do("ROLLBACK TRANSACTION TO SAVEPOINT $name");
+  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(@_);
 }
 
 sub _ping {
@@ -257,7 +269,11 @@ sub bind_attribute_by_data_type {
 # DBD::SQLite warns on binding >32 bit values with 32 bit IVs
 sub _dbh_execute {
   if (
-    DBIx::Class::_ENV_::IV_SIZE < 8
+    (
+      DBIx::Class::_ENV_::IV_SIZE < 8
+        or
+      DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
+    )
       and
     ! defined $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
   ) {
@@ -272,7 +288,15 @@ sub _dbh_execute {
         |
       \d+ \s type \s @{[ DBI::SQL_BIGINT() ]} \s as \s [-+]? \d+ (?: \. 0*)?
     )
-  /x ) if DBIx::Class::_ENV_::IV_SIZE < 8 and $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT;
+  /x ) if (
+    (
+      DBIx::Class::_ENV_::IV_SIZE < 8
+        or
+      DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
+    )
+      and
+    $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
+  );
 
   shift->next::method(@_);
 }
@@ -291,13 +315,9 @@ sub _dbi_attrs_for_bind {
 
   my $bindattrs = $self->next::method($ident, $bind);
 
-  # somewhere between 1.33 and 1.37 things went horribly wrong
   if (! defined $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values) {
-    $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values = (
-      modver_gt_or_eq('DBD::SQLite', '1.34')
-        and
-      ! modver_gt_or_eq('DBD::SQLite', '1.37')
-    ) ? 0 : 1;
+    $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
+      = modver_gt_or_eq('DBD::SQLite', '1.37') ? 1 : 0;
   }
 
   # an attempt to detect former effects of RT#79576, bug itself present between
@@ -306,7 +326,7 @@ sub _dbi_attrs_for_bind {
 
   for my $i (0.. $#$bindattrs) {
 
-    $stringifiable++ if ( length ref $bind->[$i][1] and overload::Method($bind->[$i][1], '""') );
+    $stringifiable++ if ( length ref $bind->[$i][1] and is_plain_value($bind->[$i][1]) );
 
     if (
       defined $bindattrs->[$i]
@@ -326,23 +346,26 @@ sub _dbi_attrs_for_bind {
       }
       elsif (
         ! $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
-          and
+      ) {
         # unsigned 32 bit ints have a range of −2,147,483,648 to 2,147,483,647
         # alternatively expressed as the hexadecimal numbers below
         # the comparison math will come out right regardless of ivsize, since
         # we are operating within 31 bits
         # P.S. 31 because one bit is lost for the sign
-        ($bind->[$i][1] > 0x7fff_ffff or $bind->[$i][1] < -0x8000_0000)
-      ) {
-        carp_unique( sprintf (
-          "An integer value occupying more than 32 bits was supplied for column '%s' "
-        . 'which your version of DBD::SQLite (%s) can not bind properly so DBIC '
-        . 'will treat it as a string instead, consider upgrading to at least '
-        . 'DBD::SQLite version 1.37',
-          $bind->[$i][0]{dbic_colname} || "# $i",
-          DBD::SQLite->VERSION,
-        ) );
-        undef $bindattrs->[$i];
+        if ($bind->[$i][1] > 0x7fff_ffff or $bind->[$i][1] < -0x8000_0000) {
+          carp_unique( sprintf (
+            "An integer value occupying more than 32 bits was supplied for column '%s' "
+          . 'which your version of DBD::SQLite (%s) can not bind properly so DBIC '
+          . 'will treat it as a string instead, consider upgrading to at least '
+          . 'DBD::SQLite version 1.37',
+            $bind->[$i][0]{dbic_colname} || "# $i",
+            DBD::SQLite->VERSION,
+          ) );
+          undef $bindattrs->[$i];
+        }
+        else {
+          $bindattrs->[$i] = DBI::SQL_INTEGER()
+        }
       }
     }
   }