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