(travis) Only consider the runmode a 'Smoker' when we CI ourselves
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Storage / DBI / SQLite.pm
CommitLineData
843f8ecd 1package DBIx::Class::Storage::DBI::SQLite;
2
3use strict;
4use warnings;
2ad62d97 5
6use base qw/DBIx::Class::Storage::DBI/;
7use mro 'c3';
8
b5ce6748 9use SQL::Abstract 'is_plain_value';
10use DBIx::Class::_Util qw(modver_gt_or_eq sigwarn_silencer);
632d1e0f 11use DBIx::Class::Carp;
8d1fb3e2 12use Try::Tiny;
632d1e0f 13use namespace::clean;
14
d5dedbd6 15__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::SQLite');
6a247f33 16__PACKAGE__->sql_limit_dialect ('LimitOffset');
2b8cc2f2 17__PACKAGE__->sql_quote_char ('"');
6f7a118e 18__PACKAGE__->datetime_parser_type ('DateTime::Format::SQLite');
09cedb88 19
2fa97c7d 20=head1 NAME
21
22DBIx::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
32This class implements autoincrements for SQLite.
33
75a1d824 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
50An unfortunate chain of events led to DBIx::Class silently hitting the problem
51described in L<RT#79576|https://rt.cpan.org/Public/Bug/Display.html?id=79576>.
52
53In order to trigger the bug condition one needs to supply B<more than one>
4a0eed52 54bind value that is an object with overloaded stringification (numification
75a1d824 55is not relevant, only stringification is). When this is the case the internal
56DBIx::Class call to C<< $sth->bind_param >> would be executed in a way that
57triggers the above-mentioned DBD::SQLite bug. As a result all the logs and
58tracers will contain the expected values, however SQLite will receive B<all>
59these bind positions being set to the value of the B<last> supplied
60stringifiable object.
61
62Even if you upgrade DBIx::Class (which works around the bug starting from
63version 0.08210) you may still have corrupted/incorrect data in your database.
64DBIx::Class will currently detect when this condition (more than one
65stringifiable object in one CRUD call) is encountered and will issue a warning
66pointing to this section. This warning will be removed 2 years from now,
67around April 2015, You can disable it after you've audited your data by
68setting the C<DBIC_RT79576_NOWARN> environment variable. Note - the warning
4a0eed52 69is emitted only once per callsite per process and only when the condition in
70question is encountered. Thus it is very unlikely that your logsystem will be
75a1d824 71flooded as a result of this.
72
73=back
74
2fa97c7d 75=head1 METHODS
76
77=cut
78
357eb92c 79sub backup {
80
81 require File::Spec;
82 require File::Copy;
83 require POSIX;
84
8795fefb 85 my ($self, $dir) = @_;
86 $dir ||= './';
c9d2e0a2 87
88 ## Where is the db file?
12c9beea 89 my $dsn = $self->_dbi_connect_info()->[0];
c9d2e0a2 90
91 my $dbname = $1 if($dsn =~ /dbname=([^;]+)/);
92 if(!$dbname)
93 {
94 $dbname = $1 if($dsn =~ /^dbi:SQLite:(.+)$/i);
95 }
357eb92c 96 $self->throw_exception("Cannot determine name of SQLite db file")
c9d2e0a2 97 if(!$dbname || !-f $dbname);
98
99# print "Found database: $dbname\n";
79923569 100# my $dbfile = file($dbname);
8795fefb 101 my ($vol, $dbdir, $file) = File::Spec->splitpath($dbname);
79923569 102# my $file = $dbfile->basename();
357eb92c 103 $file = POSIX::strftime("%Y-%m-%d-%H_%M_%S", localtime()) . $file;
c9d2e0a2 104 $file = "B$file" while(-f $file);
8795fefb 105
106 mkdir($dir) unless -f $dir;
107 my $backupfile = File::Spec->catfile($dir, $file);
108
357eb92c 109 my $res = File::Copy::copy($dbname, $backupfile);
c9d2e0a2 110 $self->throw_exception("Backup failed! ($!)") if(!$res);
111
8795fefb 112 return $backupfile;
c9d2e0a2 113}
114
86a51471 115sub _exec_svp_begin {
116 my ($self, $name) = @_;
117
118 $self->_dbh->do("SAVEPOINT $name");
119}
120
121sub _exec_svp_release {
122 my ($self, $name) = @_;
123
124 $self->_dbh->do("RELEASE SAVEPOINT $name");
125}
126
127sub _exec_svp_rollback {
128 my ($self, $name) = @_;
129
398215b1 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)
135sub _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
142sub _exec_txn_commit {
143 local $SIG{__WARN__} = sigwarn_silencer( qr/commit ineffective/ )
144 unless $DBD::SQLite::__DBIC_TXN_SYNC_SANE__;
86a51471 145
398215b1 146 shift->next::method(@_);
86a51471 147}
148
8d1fb3e2 149sub _ping {
150 my $self = shift;
2aeb3c7f 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
ab0b0a09 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__) {
b1dbf716 169 $DBD::SQLite::__DBIC_TXN_SYNC_SANE__ = modver_gt_or_eq('DBD::SQLite', '1.38_02');
ab0b0a09 170 }
2aeb3c7f 171
ab0b0a09 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 };
2aeb3c7f 196 };
2aeb3c7f 197
ab0b0a09 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 }
2aeb3c7f 217 }
218
ab0b0a09 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 #
4a0eed52 229 local $@; # so that we do not clobber the real error as set above
ab0b0a09 230 eval { $dbh->disconnect }; # if it fails - it fails
231 undef; # the actual RV of _ping()
8d1fb3e2 232}
233
2361982d 234sub deployment_statements {
96736321 235 my $self = shift;
2361982d 236 my ($schema, $type, $version, $dir, $sqltargs, @rest) = @_;
237
238 $sqltargs ||= {};
239
96736321 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;
6d766626 246 }
2361982d 247
248 $self->next::method($schema, $type, $version, $dir, $sqltargs, @rest);
249}
250
0e773352 251sub bind_attribute_by_data_type {
04ab4eb1 252
253 # According to http://www.sqlite.org/datatype3.html#storageclasses
254 # all numeric types are dynamically allocated up to 8 bytes per
255 # individual value
256 # Thus it should be safe and non-wasteful to bind everything as
257 # SQL_BIGINT and have SQLite deal with storage/comparisons however
258 # it deems correct
259 $_[1] =~ /^ (?: int(?:[1248]|eger)? | (?:tiny|small|medium|big)int ) $/ix
260 ? DBI::SQL_BIGINT()
0e773352 261 : undef
262 ;
263}
264
04ab4eb1 265# FIXME - what the flying fuck... work around RT#76395
266# DBD::SQLite warns on binding >32 bit values with 32 bit IVs
267sub _dbh_execute {
1363f0f5 268 if (
00882d2c 269 (
270 DBIx::Class::_ENV_::IV_SIZE < 8
271 or
272 DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
273 )
1363f0f5 274 and
275 ! defined $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
276 ) {
277 $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT = (
278 modver_gt_or_eq('DBD::SQLite', '1.37')
279 ) ? 1 : 0;
04ab4eb1 280 }
281
1363f0f5 282 local $SIG{__WARN__} = sigwarn_silencer( qr/
283 \Qdatatype mismatch: bind\E \s (?:
284 param \s+ \( \d+ \) \s+ [-+]? \d+ (?: \. 0*)? \Q as integer\E
285 |
286 \d+ \s type \s @{[ DBI::SQL_BIGINT() ]} \s as \s [-+]? \d+ (?: \. 0*)?
287 )
00882d2c 288 /x ) if (
289 (
290 DBIx::Class::_ENV_::IV_SIZE < 8
291 or
292 DBIx::Class::_ENV_::OS_NAME eq 'MSWin32'
293 )
294 and
295 $DBD::SQLite::__DBIC_CHECK_dbd_mishandles_bound_BIGINT
296 );
1363f0f5 297
04ab4eb1 298 shift->next::method(@_);
299}
300
632d1e0f 301# DBD::SQLite (at least up to version 1.31 has a bug where it will
4a0eed52 302# non-fatally numify a string value bound as an integer, resulting
632d1e0f 303# in insertions of '0' into supposed-to-be-numeric fields
304# Since this can result in severe data inconsistency, remove the
4a0eed52 305# bind attr if such a situation is detected
632d1e0f 306#
307# FIXME - when a DBD::SQLite version is released that eventually fixes
4a0eed52 308# this situation (somehow) - no-op this override once a proper DBD
632d1e0f 309# version is detected
310sub _dbi_attrs_for_bind {
311 my ($self, $ident, $bind) = @_;
75a1d824 312
632d1e0f 313 my $bindattrs = $self->next::method($ident, $bind);
314
04ab4eb1 315 if (! defined $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values) {
215102b9 316 $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
317 = modver_gt_or_eq('DBD::SQLite', '1.37') ? 1 : 0;
04ab4eb1 318 }
319
75a1d824 320 # an attempt to detect former effects of RT#79576, bug itself present between
321 # 0.08191 and 0.08209 inclusive (fixed in 0.08210 and higher)
322 my $stringifiable = 0;
323
49f7b6c7 324 for my $i (0.. $#$bindattrs) {
75a1d824 325
3705e3b2 326 $stringifiable++ if ( length ref $bind->[$i][1] and is_plain_value($bind->[$i][1]) );
75a1d824 327
632d1e0f 328 if (
49f7b6c7 329 defined $bindattrs->[$i]
632d1e0f 330 and
49f7b6c7 331 defined $bind->[$i][1]
632d1e0f 332 and
d830d9f4 333 grep { $bindattrs->[$i] eq $_ } (
334 DBI::SQL_INTEGER(), DBI::SQL_TINYINT(), DBI::SQL_SMALLINT(), DBI::SQL_BIGINT()
335 )
632d1e0f 336 ) {
04ab4eb1 337 if ( $bind->[$i][1] !~ /^ [\+\-]? [0-9]+ (?: \. 0* )? $/x ) {
338 carp_unique( sprintf (
339 "Non-integer value supplied for column '%s' despite the integer datatype",
340 $bind->[$i][0]{dbic_colname} || "# $i"
341 ) );
342 undef $bindattrs->[$i];
343 }
344 elsif (
345 ! $DBD::SQLite::__DBIC_CHECK_dbd_can_bind_bigint_values
215102b9 346 ) {
04ab4eb1 347 # unsigned 32 bit ints have a range of −2,147,483,648 to 2,147,483,647
348 # alternatively expressed as the hexadecimal numbers below
349 # the comparison math will come out right regardless of ivsize, since
350 # we are operating within 31 bits
351 # P.S. 31 because one bit is lost for the sign
215102b9 352 if ($bind->[$i][1] > 0x7fff_ffff or $bind->[$i][1] < -0x8000_0000) {
353 carp_unique( sprintf (
354 "An integer value occupying more than 32 bits was supplied for column '%s' "
355 . 'which your version of DBD::SQLite (%s) can not bind properly so DBIC '
356 . 'will treat it as a string instead, consider upgrading to at least '
357 . 'DBD::SQLite version 1.37',
358 $bind->[$i][0]{dbic_colname} || "# $i",
359 DBD::SQLite->VERSION,
360 ) );
361 undef $bindattrs->[$i];
362 }
363 else {
364 $bindattrs->[$i] = DBI::SQL_INTEGER()
365 }
04ab4eb1 366 }
632d1e0f 367 }
368 }
369
75a1d824 370 carp_unique(
371 'POSSIBLE *PAST* DATA CORRUPTION detected - see '
372 . 'DBIx::Class::Storage::DBI::SQLite/RT79576 or '
373 . 'http://v.gd/DBIC_SQLite_RT79576 for further details or set '
374 . '$ENV{DBIC_RT79576_NOWARN} to disable this warning. Trigger '
375 . 'condition encountered'
376 ) if (!$ENV{DBIC_RT79576_NOWARN} and $stringifiable > 1);
377
632d1e0f 378 return $bindattrs;
379}
380
732e4282 381=head2 connect_call_use_foreign_keys
382
383Used as:
384
385 on_connect_call => 'use_foreign_keys'
386
8384a713 387In L<connect_info|DBIx::Class::Storage::DBI/connect_info> to turn on foreign key
388(including cascading) support for recent versions of SQLite and L<DBD::SQLite>.
732e4282 389
390Executes:
391
8273e845 392 PRAGMA foreign_keys = ON
732e4282 393
394See L<http://www.sqlite.org/foreignkeys.html> for more information.
395
396=cut
397
398sub connect_call_use_foreign_keys {
399 my $self = shift;
400
401 $self->_do_query(
402 'PRAGMA foreign_keys = ON'
403 );
404}
405
a2bd3796 406=head1 FURTHER QUESTIONS?
843f8ecd 407
a2bd3796 408Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
843f8ecd 409
a2bd3796 410=head1 COPYRIGHT AND LICENSE
843f8ecd 411
a2bd3796 412This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
413by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
414redistribute it and/or modify it under the same terms as the
415L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
843f8ecd 416
417=cut
a2bd3796 418
4191;