Fix multiple savepointing transactions on DBD::SQLite
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / SQLite.pm
1 package DBIx::Class::Storage::DBI::SQLite;
2
3 use strict;
4 use warnings;
5
6 use base qw/DBIx::Class::Storage::DBI/;
7 use mro 'c3';
8
9 use DBIx::Class::_Util qw(modver_gt_or_eq sigwarn_silencer);
10 use DBIx::Class::Carp;
11 use Try::Tiny;
12 use namespace::clean;
13
14 __PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::SQLite');
15 __PACKAGE__->sql_limit_dialect ('LimitOffset');
16 __PACKAGE__->sql_quote_char ('"');
17 __PACKAGE__->datetime_parser_type ('DateTime::Format::SQLite');
18
19 =head1 NAME
20
21 DBIx::Class::Storage::DBI::SQLite - Automatic primary key class for SQLite
22
23 =head1 SYNOPSIS
24
25   # In your table classes
26   use base 'DBIx::Class::Core';
27   __PACKAGE__->set_primary_key('id');
28
29 =head1 DESCRIPTION
30
31 This class implements autoincrements for SQLite.
32
33 =head2 Known Issues
34
35 =over
36
37 =item RT79576
38
39  NOTE - This section applies to you only if ALL of these are true:
40
41   * You are or were using DBD::SQLite with a version lesser than 1.38_01
42
43   * You are or were using DBIx::Class versions between 0.08191 and 0.08209
44     (inclusive) or between 0.08240-TRIAL and 0.08242-TRIAL (also inclusive)
45
46   * You use objects with overloaded stringification and are feeding them
47     to DBIC CRUD methods directly
48
49 An unfortunate chain of events led to DBIx::Class silently hitting the problem
50 described in L<RT#79576|https://rt.cpan.org/Public/Bug/Display.html?id=79576>.
51
52 In order to trigger the bug condition one needs to supply B<more than one>
53 bind value that is an object with overloaded stringification (numification
54 is not relevant, only stringification is). When this is the case the internal
55 DBIx::Class call to C<< $sth->bind_param >> would be executed in a way that
56 triggers the above-mentioned DBD::SQLite bug. As a result all the logs and
57 tracers will contain the expected values, however SQLite will receive B<all>
58 these bind positions being set to the value of the B<last> supplied
59 stringifiable object.
60
61 Even if you upgrade DBIx::Class (which works around the bug starting from
62 version 0.08210) you may still have corrupted/incorrect data in your database.
63 DBIx::Class will currently detect when this condition (more than one
64 stringifiable object in one CRUD call) is encountered and will issue a warning
65 pointing to this section. This warning will be removed 2 years from now,
66 around April 2015, You can disable it after you've audited your data by
67 setting the C<DBIC_RT79576_NOWARN> environment variable. Note - the warning
68 is emitted only once per callsite per process and only when the condition in
69 question is encountered. Thus it is very unlikely that your logsystem will be
70 flooded as a result of this.
71
72 =back
73
74 =head1 METHODS
75
76 =cut
77
78 sub backup {
79
80   require File::Spec;
81   require File::Copy;
82   require POSIX;
83
84   my ($self, $dir) = @_;
85   $dir ||= './';
86
87   ## Where is the db file?
88   my $dsn = $self->_dbi_connect_info()->[0];
89
90   my $dbname = $1 if($dsn =~ /dbname=([^;]+)/);
91   if(!$dbname)
92   {
93     $dbname = $1 if($dsn =~ /^dbi:SQLite:(.+)$/i);
94   }
95   $self->throw_exception("Cannot determine name of SQLite db file")
96     if(!$dbname || !-f $dbname);
97
98 #  print "Found database: $dbname\n";
99 #  my $dbfile = file($dbname);
100   my ($vol, $dbdir, $file) = File::Spec->splitpath($dbname);
101 #  my $file = $dbfile->basename();
102   $file = POSIX::strftime("%Y-%m-%d-%H_%M_%S", localtime()) . $file;
103   $file = "B$file" while(-f $file);
104
105   mkdir($dir) unless -f $dir;
106   my $backupfile = File::Spec->catfile($dir, $file);
107
108   my $res = File::Copy::copy($dbname, $backupfile);
109   $self->throw_exception("Backup failed! ($!)") if(!$res);
110
111   return $backupfile;
112 }
113
114 sub _exec_svp_begin {
115   my ($self, $name) = @_;
116
117   $self->_dbh->do("SAVEPOINT $name");
118 }
119
120 sub _exec_svp_release {
121   my ($self, $name) = @_;
122
123   $self->_dbh->do("RELEASE SAVEPOINT $name");
124 }
125
126 sub _exec_svp_rollback {
127   my ($self, $name) = @_;
128
129   $self->_dbh->do("ROLLBACK TO SAVEPOINT $name");
130 }
131
132 # older SQLite has issues here too - both of these are in fact
133 # completely benign warnings (or at least so say the tests)
134 sub _exec_txn_rollback {
135   local $SIG{__WARN__} = sigwarn_silencer( qr/rollback ineffective/ )
136     unless $DBD::SQLite::__DBIC_TXN_SYNC_SANE__;
137
138   shift->next::method(@_);
139 }
140
141 sub _exec_txn_commit {
142   local $SIG{__WARN__} = sigwarn_silencer( qr/commit ineffective/ )
143     unless $DBD::SQLite::__DBIC_TXN_SYNC_SANE__;
144
145   shift->next::method(@_);
146 }
147
148 sub _ping {
149   my $self = shift;
150
151   # Be extremely careful what we do here. SQLite is notoriously bad at
152   # synchronizing its internal transaction state with {AutoCommit}
153   # https://metacpan.org/source/ADAMK/DBD-SQLite-1.37/lib/DBD/SQLite.pm#L921
154   # There is a function http://www.sqlite.org/c3ref/get_autocommit.html
155   # but DBD::SQLite does not expose it (nor does it seem to properly use it)
156
157   # Therefore only execute a "ping" when we have no other choice *AND*
158   # scrutinize the thrown exceptions to make sure we are where we think we are
159   my $dbh = $self->_dbh or return undef;
160   return undef unless $dbh->FETCH('Active');
161   return undef unless $dbh->ping;
162
163   my $ping_fail;
164
165   # older DBD::SQLite does not properly synchronize commit state between
166   # the libsqlite and the $dbh
167   unless (defined $DBD::SQLite::__DBIC_TXN_SYNC_SANE__) {
168     $DBD::SQLite::__DBIC_TXN_SYNC_SANE__ = modver_gt_or_eq('DBD::SQLite', '1.38_02');
169   }
170
171   # fallback to travesty
172   unless ($DBD::SQLite::__DBIC_TXN_SYNC_SANE__) {
173     # since we do not have access to sqlite3_get_autocommit(), do a trick
174     # to attempt to *safely* determine what state are we *actually* in.
175     # FIXME
176     # also using T::T here leads to bizarre leaks - will figure it out later
177     my $really_not_in_txn = do {
178       local $@;
179
180       # older versions of DBD::SQLite do not properly detect multiline BEGIN/COMMIT
181       # statements to adjust their {AutoCommit} state. Hence use such a statement
182       # pair here as well, in order to escape from poking {AutoCommit} needlessly
183       # https://rt.cpan.org/Public/Bug/Display.html?id=80087
184       eval {
185         # will fail instantly if already in a txn
186         $dbh->do("-- multiline\nBEGIN");
187         $dbh->do("-- multiline\nCOMMIT");
188         1;
189       } or do {
190         ($@ =~ /transaction within a transaction/)
191           ? 0
192           : undef
193         ;
194       };
195     };
196
197     # if we were unable to determine this - we may very well be dead
198     if (not defined $really_not_in_txn) {
199       $ping_fail = 1;
200     }
201     # check the AC sync-state
202     elsif ($really_not_in_txn xor $dbh->{AutoCommit}) {
203       carp_unique (sprintf
204         'Internal transaction state of handle %s (apparently %s a transaction) does not seem to '
205       . 'match its AutoCommit attribute setting of %s - this is an indication of a '
206       . 'potentially serious bug in your transaction handling logic',
207         $dbh,
208         $really_not_in_txn ? 'NOT in' : 'in',
209         $dbh->{AutoCommit} ? 'TRUE' : 'FALSE',
210       );
211
212       # it is too dangerous to execute anything else in this state
213       # assume everything works (safer - worst case scenario next statement throws)
214       return 1;
215     }
216   }
217
218   # do the actual test and return on no failure
219   ( $ping_fail ||= ! try { $dbh->do('SELECT * FROM sqlite_master LIMIT 1'); 1 } )
220     or return 1; # the actual RV of _ping()
221
222   # ping failed (or so it seems) - need to do some cleanup
223   # it is possible to have a proper "connection", and have "ping" return
224   # false anyway (e.g. corrupted file). In such cases DBD::SQLite still
225   # keeps the actual file handle open. We don't really want this to happen,
226   # so force-close the handle via DBI itself
227   #
228   local $@; # so that we do not clobber the real error as set above
229   eval { $dbh->disconnect }; # if it fails - it fails
230   undef; # the actual RV of _ping()
231 }
232
233 sub deployment_statements {
234   my $self = shift;
235   my ($schema, $type, $version, $dir, $sqltargs, @rest) = @_;
236
237   $sqltargs ||= {};
238
239   if (
240     ! exists $sqltargs->{producer_args}{sqlite_version}
241       and
242     my $dver = $self->_server_info->{normalized_dbms_version}
243   ) {
244     $sqltargs->{producer_args}{sqlite_version} = $dver;
245   }
246
247   $sqltargs->{quote_identifiers}
248     = !!$self->sql_maker->_quote_chars
249   if ! exists $sqltargs->{quote_identifiers};
250
251   $self->next::method($schema, $type, $version, $dir, $sqltargs, @rest);
252 }
253
254 sub bind_attribute_by_data_type {
255
256   # According to http://www.sqlite.org/datatype3.html#storageclasses
257   # all numeric types are dynamically allocated up to 8 bytes per
258   # individual value
259   # Thus it should be safe and non-wasteful to bind everything as
260   # SQL_BIGINT and have SQLite deal with storage/comparisons however
261   # it deems correct
262   $_[1] =~ /^ (?: int(?:[1248]|eger)? | (?:tiny|small|medium|big)int ) $/ix
263     ? DBI::SQL_BIGINT()
264     : undef
265   ;
266 }
267
268 # FIXME - what the flying fuck... work around RT#76395
269 # DBD::SQLite warns on binding >32 bit values with 32 bit IVs
270 sub _dbh_execute {
271   if (
272     (
273       DBIx::Class::_ENV_::IV_SIZE < 8
274         or
275       DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
276     )
277       and
278     ! defined $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
279   ) {
280     $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT = (
281       modver_gt_or_eq('DBD::SQLite', '1.37')
282     ) ? 1 : 0;
283   }
284
285   local $SIG{__WARN__} = sigwarn_silencer( qr/
286     \Qdatatype mismatch: bind\E \s (?:
287       param \s+ \( \d+ \) \s+ [-+]? \d+ (?: \. 0*)? \Q as integer\E
288         |
289       \d+ \s type \s @{[ DBI::SQL_BIGINT() ]} \s as \s [-+]? \d+ (?: \. 0*)?
290     )
291   /x ) if (
292     (
293       DBIx::Class::_ENV_::IV_SIZE < 8
294         or
295       DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
296     )
297       and
298     $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
299   );
300
301   shift->next::method(@_);
302 }
303
304 # DBD::SQLite (at least up to version 1.31 has a bug where it will
305 # non-fatally numify a string value bound as an integer, resulting
306 # in insertions of '0' into supposed-to-be-numeric fields
307 # Since this can result in severe data inconsistency, remove the
308 # bind attr if such a situation is detected
309 #
310 # FIXME - when a DBD::SQLite version is released that eventually fixes
311 # this situation (somehow) - no-op this override once a proper DBD
312 # version is detected
313 sub _dbi_attrs_for_bind {
314   my ($self, $ident, $bind) = @_;
315
316   my $bindattrs = $self->next::method($ident, $bind);
317
318   if (! defined $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values) {
319     $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
320       = modver_gt_or_eq('DBD::SQLite', '1.37') ? 1 : 0;
321   }
322
323   # an attempt to detect former effects of RT#79576, bug itself present between
324   # 0.08191 and 0.08209 inclusive (fixed in 0.08210 and higher)
325   my $stringifiable = 0;
326
327   for my $i (0.. $#$bindattrs) {
328
329     $stringifiable++ if ( length ref $bind->[$i][1] and overload::Method($bind->[$i][1], '""') );
330
331     if (
332       defined $bindattrs->[$i]
333         and
334       defined $bind->[$i][1]
335         and
336       grep { $bindattrs->[$i] eq $_ } (
337         DBI::SQL_INTEGER(), DBI::SQL_TINYINT(), DBI::SQL_SMALLINT(), DBI::SQL_BIGINT()
338       )
339     ) {
340       if ( $bind->[$i][1] !~ /^ [\+\-]? [0-9]+ (?: \. 0* )? $/x ) {
341         carp_unique( sprintf (
342           "Non-integer value supplied for column '%s' despite the integer datatype",
343           $bind->[$i][0]{dbic_colname} || "# $i"
344         ) );
345         undef $bindattrs->[$i];
346       }
347       elsif (
348         ! $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
349       ) {
350         # unsigned 32 bit ints have a range of −2,147,483,648 to 2,147,483,647
351         # alternatively expressed as the hexadecimal numbers below
352         # the comparison math will come out right regardless of ivsize, since
353         # we are operating within 31 bits
354         # P.S. 31 because one bit is lost for the sign
355         if ($bind->[$i][1] > 0x7fff_ffff or $bind->[$i][1] < -0x8000_0000) {
356           carp_unique( sprintf (
357             "An integer value occupying more than 32 bits was supplied for column '%s' "
358           . 'which your version of DBD::SQLite (%s) can not bind properly so DBIC '
359           . 'will treat it as a string instead, consider upgrading to at least '
360           . 'DBD::SQLite version 1.37',
361             $bind->[$i][0]{dbic_colname} || "# $i",
362             DBD::SQLite->VERSION,
363           ) );
364           undef $bindattrs->[$i];
365         }
366         else {
367           $bindattrs->[$i] = DBI::SQL_INTEGER()
368         }
369       }
370     }
371   }
372
373   carp_unique(
374     'POSSIBLE *PAST* DATA CORRUPTION detected - see '
375   . 'DBIx::Class::Storage::DBI::SQLite/RT79576 or '
376   . 'http://v.gd/DBIC_SQLite_RT79576 for further details or set '
377   . '$ENV{DBIC_RT79576_NOWARN} to disable this warning. Trigger '
378   . 'condition encountered'
379   ) if (!$ENV{DBIC_RT79576_NOWARN} and $stringifiable > 1);
380
381   return $bindattrs;
382 }
383
384 =head2 connect_call_use_foreign_keys
385
386 Used as:
387
388     on_connect_call => 'use_foreign_keys'
389
390 In L<connect_info|DBIx::Class::Storage::DBI/connect_info> to turn on foreign key
391 (including cascading) support for recent versions of SQLite and L<DBD::SQLite>.
392
393 Executes:
394
395   PRAGMA foreign_keys = ON
396
397 See L<http://www.sqlite.org/foreignkeys.html> for more information.
398
399 =cut
400
401 sub connect_call_use_foreign_keys {
402   my $self = shift;
403
404   $self->_do_query(
405     'PRAGMA foreign_keys = ON'
406   );
407 }
408
409 1;
410
411 =head1 AUTHOR AND CONTRIBUTORS
412
413 See L<AUTHOR|DBIx::Class/AUTHOR> and L<CONTRIBUTORS|DBIx::Class/CONTRIBUTORS> in DBIx::Class
414
415 =head1 LICENSE
416
417 You may distribute this code under the same terms as Perl itself.
418
419 =cut