File Coverage

blib/lib/Mojo/SQLite.pm
Criterion Covered Total %
statement 91 92 98.9
branch 34 38 89.4
condition 19 29 65.5
subroutine 23 23 100.0
pod 4 4 100.0
total 171 186 91.9


line stmt bran cond sub pod time code
1             package Mojo::SQLite;
2 6     6   1717654 use Mojo::Base 'Mojo::EventEmitter';
  6         75  
  6         53  
3              
4 6     6   11056 use Carp 'croak';
  6         17  
  6         351  
5 6     6   7924 use DBI;
  6         92247  
  6         342  
6 6     6   4188 use DBD::SQLite;
  6         55594  
  6         243  
7 6     6   2693 use DBD::SQLite::Constants qw(:database_connection_configuration_options :dbd_sqlite_string_mode);
  6         5008  
  6         1669  
8 6     6   2542 use File::Spec::Functions 'catfile';
  6         4687  
  6         408  
9 6     6   3857 use File::Temp;
  6         61942  
  6         563  
10 6     6   3047 use Mojo::SQLite::Database;
  6         23  
  6         64  
11 6     6   3176 use Mojo::SQLite::Migrations;
  6         23  
  6         47  
12 6     6   244 use Scalar::Util qw(blessed weaken);
  6         11  
  6         321  
13 6     6   3140 use SQL::Abstract::Pg;
  6         144760  
  6         397  
14 6     6   3808 use URI;
  6         30637  
  6         203  
15 6     6   2972 use URI::db;
  6         70618  
  6         9477  
16              
17             our $VERSION = '3.008';
18              
19             has abstract => sub { SQL::Abstract::Pg->new(name_sep => '.', quote_char => '"') };
20             has 'auto_migrate';
21             has database_class => 'Mojo::SQLite::Database';
22             has dsn => sub { _url_from_file(shift->_tempfile)->dbi_dsn };
23             has max_connections => 1;
24             has migrations => sub { Mojo::SQLite::Migrations->new(sqlite => shift) };
25             has options => sub {
26             {
27             AutoCommit => 1,
28             AutoInactiveDestroy => 1,
29             PrintError => 0,
30             RaiseError => 1,
31             sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_FALLBACK,
32             wal_mode => 1,
33             };
34             };
35             has 'parent';
36              
37 21 100   21 1 36582 sub new { @_ > 1 ? shift->SUPER::new->from_string(@_) : shift->SUPER::new }
38              
39 118     118 1 138090 sub db { $_[0]->database_class->new(dbh => $_[0]->_prepare, sqlite => $_[0]) }
40              
41 5     5 1 52 sub from_filename { shift->from_string(_url_from_file(shift, shift)) }
42              
43             sub from_string {
44 14     14 1 87 my ($self, $str) = @_;
45 14 50       47 return $self unless $str;
46 14 100 100     298 return $self->parent($str) if blessed $str and $str->isa('Mojo::SQLite');
47              
48 12         44 my $url = URI->new($str);
49              
50             # Options
51 12         2826 my %options = $url->query_form;
52 12         573 $url->query(undef);
53             # don't set default string_mode if sqlite_unicode legacy option is set
54 12 100       214 delete $self->options->{sqlite_string_mode} if exists $options{sqlite_unicode};
55 12         29 @{$self->options}{keys %options} = values %options;
  12         37  
56              
57             # Parse URL based on scheme
58 12 100       71 $url->scheme('file') unless $url->has_recognized_scheme;
59 12 100       483 if ($url->scheme eq 'file') {
    100          
60 5         116 $url = _url_from_file($url->file);
61             } elsif ($url->scheme ne 'db') {
62 2         72 $url = URI::db->new($url);
63             }
64              
65 12 50 66     436 croak qq{Invalid SQLite connection string "$str"}
      33        
      66        
66             unless $url->has_recognized_engine and $url->canonical_engine eq 'sqlite'
67             and (($url->host // '') eq '' or $url->host eq 'localhost');
68            
69             # Temp database file
70 11 50       608 $url->dbname($self->_tempfile) if $url->dbname eq ':temp:';
71            
72 11         758 return $self->dsn($url->dbi_dsn);
73             }
74              
75             sub _dequeue {
76 118     118   177 my $self = shift;
77              
78             # Fork-safety
79 118 100 66     833 delete @$self{qw(pid queue)} unless ($self->{pid} //= $$) eq $$;
80              
81 118 50       199 while (my $dbh = shift @{$self->{queue} || []}) { return $dbh if $dbh->ping }
  91 100       457  
  118         441  
82            
83 27   33     91 my $dbh = DBI->connect($self->dsn, undef, undef, $self->options)
84 0         0 // croak "DBI connection to @{[$self->dsn]} failed: $DBI::errstr"; # RaiseError disabled
85 27         22289 $dbh->sqlite_db_config(SQLITE_DBCONFIG_DQS_DDL, 0);
86 27         116 $dbh->sqlite_db_config(SQLITE_DBCONFIG_DQS_DML, 0);
87 27 100 66     102 if ($self->options->{wal_mode} and !$self->options->{no_wal}) {
88 26         415 $dbh->do('pragma journal_mode=WAL');
89 26         93074 $dbh->do('pragma synchronous=NORMAL');
90             }
91              
92             # Cache the last insert rowid on inserts
93 27         921 weaken(my $weakdbh = $dbh);
94             $dbh->sqlite_update_hook(sub {
95 40 100   40   1979 $weakdbh->{private_mojo_last_insert_id} = $_[3] if $_[0] == DBD::SQLite::INSERT;
96 27         267 });
97              
98 27         187 $self->emit(connection => $dbh);
99              
100 27         540 return $dbh;
101             }
102              
103             sub _enqueue {
104 124     124   277 my ($self, $dbh) = @_;
105              
106 124 100       274 if (my $parent = $self->parent) { return $parent->_enqueue($dbh) }
  6         48  
107              
108 118   100     686 my $queue = $self->{queue} ||= [];
109 118 100       1120 push @$queue, $dbh if $dbh->{Active};
110 118         449 shift @$queue while @$queue > $self->max_connections;
111             }
112              
113             sub _prepare {
114 124     124   685 my $self = shift;
115              
116             # Automatic migrations
117             ++$self->{migrated} and $self->migrations->migrate
118 124 100 33     485 if !$self->{migrated} && $self->auto_migrate;
      100        
119              
120 124         742 my $parent = $self->parent;
121 124 100       595 return $parent ? $parent->_prepare : $self->_dequeue;
122             }
123              
124 7     7   69 sub _tempfile { catfile(shift->{tempdir} = File::Temp->newdir, 'sqlite.db') }
125              
126             sub _url_from_file {
127 17     17   7406 my $url = URI::db->new;
128 17         2100 $url->engine('sqlite');
129 17         8172 $url->dbname(shift);
130 17 100       1491 if (my $options = shift) { $url->query_form($options) }
  1         10  
131 17         170 return $url;
132             }
133              
134             1;
135              
136             =head1 NAME
137              
138             Mojo::SQLite - A tiny Mojolicious wrapper for SQLite
139              
140             =head1 SYNOPSIS
141              
142             use Mojo::SQLite;
143              
144             # Select the library version
145             my $sql = Mojo::SQLite->new('sqlite:test.db');
146             say $sql->db->query('select sqlite_version() as version')->hash->{version};
147              
148             # Use migrations to create a table
149             $sql->migrations->name('my_names_app')->from_string(<migrate;
150             -- 1 up
151             create table names (id integer primary key autoincrement, name text);
152             -- 1 down
153             drop table names;
154             EOF
155              
156             # Use migrations to drop and recreate the table
157             $sql->migrations->migrate(0)->migrate;
158              
159             # Get a database handle from the cache for multiple queries
160             my $db = $sql->db;
161              
162             # Use SQL::Abstract to generate simple CRUD queries for you
163             $db->insert('names', {name => 'Isabel'});
164             my $id = $db->select('names', ['id'], {name => 'Isabel'})->hash->{id};
165             $db->update('names', {name => 'Bel'}, {id => $id});
166             $db->delete('names', {name => 'Bel'});
167              
168             # Insert a few rows in a transaction with SQL and placeholders
169             eval {
170             my $tx = $db->begin;
171             $db->query('insert into names (name) values (?)', 'Sara');
172             $db->query('insert into names (name) values (?)', 'Stefan');
173             $tx->commit;
174             };
175             say $@ if $@;
176              
177             # Insert another row with SQL::Abstract and return the generated id
178             say $db->insert('names', {name => 'Daniel'})->last_insert_id;
179            
180             # JSON roundtrip
181             say $db->query('select ? as foo', {json => {bar => 'baz'}})
182             ->expand(json => 'foo')->hash->{foo}{bar};
183              
184             # Select one row at a time
185             my $results = $db->query('select * from names');
186             while (my $next = $results->hash) {
187             say $next->{name};
188             }
189              
190             # Select all rows with SQL::Abstract
191             say $_->{name} for $db->select('names')->hashes->each;
192              
193             =head1 DESCRIPTION
194              
195             L is a tiny wrapper around L that makes
196             L a lot of fun to use with the
197             L real-time web framework. Use all
198             L SQLite has to offer, generate CRUD
199             queries from data structures, and manage your database schema with migrations.
200              
201             =head1 BASICS
202              
203             Database and statement handles are cached automatically, so they can be reused
204             transparently to increase performance. And you can handle connection timeouts
205             gracefully by holding on to them only for short amounts of time.
206              
207             use Mojolicious::Lite;
208             use Mojo::SQLite;
209              
210             helper sqlite => sub { state $sql = Mojo::SQLite->new('sqlite:test.db') };
211              
212             get '/' => sub ($c) {
213             my $db = $c->sqlite->db;
214             $c->render(json => $db->query(q{select datetime('now','localtime') as now})->hash);
215             };
216              
217             app->start;
218              
219             In this example application, we create a C helper to store a
220             L object. Our action calls that helper and uses the method
221             L to dequeue a L object from the
222             connection pool. Then we use the method L to
223             execute an L
224             statement, which returns a L object. And finally we call
225             the method L to retrieve the first row as a hash
226             reference.
227              
228             All I/O and queries are performed synchronously, and SQLite's default journal
229             mode only supports concurrent reads from multiple processes while the database
230             is not being written. The "Write-Ahead Log" journal mode allows multiple
231             processes to read and write concurrently to the same database file (but only
232             one can write at a time). WAL mode is enabled by the C option,
233             currently enabled by default, and persists when opening that same database in
234             the future.
235              
236             # Performed concurrently (concurrent with writing only with WAL journaling mode)
237             my $pid = fork || die $!;
238             say $sql->db->query(q{select datetime('now','localtime') as time})->hash->{time};
239             exit unless $pid;
240              
241             The C option prevents WAL mode from being enabled in new databases but
242             doesn't affect databases where it has already been enabled. C may not
243             be set by default in a future release. See L and
244             L for more information.
245              
246             The L
247             |https://sqlite.org/quirks.html#double_quoted_string_literals_are_accepted> is
248             disabled for all connections since Mojo::SQLite 3.003; use single quotes for
249             string literals and double quotes for identifiers, as is normally recommended.
250              
251             All cached database handles will be reset automatically if a new process has
252             been forked, this allows multiple processes to share the same L
253             object safely.
254              
255             Any database errors will throw an exception as C is automatically
256             enabled, so use C or L to catch them. This makes transactions
257             with L easy.
258              
259             While passing a file path of C<:memory:> (or a custom L with
260             C) will create a temporary database, in-memory databases cannot be
261             shared between connections, so subsequent calls to L may return
262             connections to completely different databases. For a temporary database that
263             can be shared between connections and processes, pass a file path of C<:temp:>
264             to store the database in a temporary directory (this is the default), or
265             consider constructing a temporary directory yourself with L if you
266             need to reuse the filename. A temporary directory allows SQLite to create
267             L safely.
268              
269             use File::Spec::Functions 'catfile';
270             use File::Temp;
271             use Mojo::SQLite;
272             my $tempdir = File::Temp->newdir; # Deleted when object goes out of scope
273             my $tempfile = catfile $tempdir, 'test.db';
274             my $sql = Mojo::SQLite->new->from_filename($tempfile);
275              
276             =head1 EXAMPLES
277              
278             This distribution also contains a well-structured example
279             L
280             you can use for inspiration. This application shows how to apply the MVC design
281             pattern in practice.
282              
283             =head1 EVENTS
284              
285             L inherits all events from L and can emit the
286             following new ones.
287              
288             =head2 connection
289              
290             $sql->on(connection => sub ($sql, $dbh) {
291             $dbh->do('pragma journal_size_limit=1000000');
292             });
293              
294             Emitted when a new database connection has been established.
295              
296             =head1 ATTRIBUTES
297              
298             L implements the following attributes.
299              
300             =head2 abstract
301              
302             my $abstract = $sql->abstract;
303             $sql = $sql->abstract(SQL::Abstract->new);
304              
305             L object used to generate CRUD queries for
306             L, defaults to a L object with
307             C set to C<.> and C set to C<">.
308              
309             # Generate WHERE clause and bind values
310             my($stmt, @bind) = $sql->abstract->where({foo => 'bar', baz => 'yada'});
311              
312             L provides additional features to the L
313             query methods in L such as C<-json> and
314             C/C. The C feature is not applicable to SQLite queries.
315              
316             $sql->db->select(['some_table', ['other_table', foo_id => 'id']],
317             ['foo', [bar => 'baz'], \q{datetime('now') as dt}],
318             {foo => 'value'},
319             {order_by => 'foo', limit => 10, offset => 5, group_by => ['foo'], having => {baz => 'value'}});
320              
321             # Upsert supported since SQLite 3.24.0
322             $sql->db->insert('some_table', {name => $name, value => $value},
323             {on_conflict => [name => {value => \'"excluded"."value"'}]});
324              
325             =head2 auto_migrate
326              
327             my $bool = $sql->auto_migrate;
328             $sql = $sql->auto_migrate($bool);
329              
330             Automatically migrate to the latest database schema with L, as
331             soon as L has been called for the first time.
332              
333             =head2 database_class
334              
335             my $class = $sql->database_class;
336             $sql = $sql->database_class('MyApp::Database');
337              
338             Class to be used by L, defaults to L. Note that
339             this class needs to have already been loaded before L is called.
340              
341             =head2 dsn
342              
343             my $dsn = $sql->dsn;
344             $sql = $sql->dsn('dbi:SQLite:uri=file:foo.db');
345              
346             Data source name, defaults to C followed by a path to a
347             temporary file.
348              
349             =head2 max_connections
350              
351             my $max = $sql->max_connections;
352             $sql = $sql->max_connections(3);
353              
354             Maximum number of idle database handles to cache for future use, defaults to
355             C<1>.
356              
357             =head2 migrations
358              
359             my $migrations = $sql->migrations;
360             $sql = $sql->migrations(Mojo::SQLite::Migrations->new);
361              
362             L object you can use to change your database schema
363             more easily.
364              
365             # Load migrations from file and migrate to latest version
366             $sql->migrations->from_file('/home/dbook/migrations.sql')->migrate;
367              
368             =head2 options
369              
370             my $options = $sql->options;
371             $sql = $sql->options({AutoCommit => 1, RaiseError => 1});
372              
373             Options for database handles, defaults to setting C to
374             C, setting C,
375             C and C, and deactivating C.
376             Note that C and C are considered mandatory, so
377             deactivating them would be very dangerous. See
378             L and
379             L for more information on available
380             options.
381              
382             =head2 parent
383              
384             my $parent = $sql->parent;
385             $sql = $sql->parent(Mojo::SQLite->new);
386              
387             Another L object to use for connection management, instead of
388             establishing and caching our own database connections.
389              
390             =head1 METHODS
391              
392             L inherits all methods from L and implements
393             the following new ones.
394              
395             =head2 new
396              
397             my $sql = Mojo::SQLite->new;
398             my $sql = Mojo::SQLite->new('file:test.db);
399             my $sql = Mojo::SQLite->new('sqlite:test.db');
400             my $sql = Mojo::SQLite->new(Mojo::SQLite->new);
401              
402             Construct a new L object and parse connection string with
403             L if necessary.
404              
405             # Customize configuration further
406             my $sql = Mojo::SQLite->new->dsn('dbi:SQLite:dbname=test.db');
407             my $sql = Mojo::SQLite->new->dsn('dbi:SQLite:uri=file:test.db?mode=memory');
408              
409             # Pass filename directly
410             my $sql = Mojo::SQLite->new->from_filename($filename);
411              
412             =head2 db
413              
414             my $db = $sql->db;
415              
416             Get a database object based on L (which is usually
417             L) for a cached or newly established database
418             connection. The L database handle will be automatically cached
419             again when that object is destroyed, so you can handle problems like connection
420             timeouts gracefully by holding on to it only for short amounts of time.
421              
422             # Add up all the money
423             say $sql->db->select('accounts')
424             ->hashes->reduce(sub { $a->{money} + $b->{money} });
425              
426             =head2 from_filename
427              
428             $sql = $sql->from_filename('C:\\Documents and Settings\\foo & bar.db', $options);
429              
430             Parse database filename directly. Unlike L, the filename is
431             parsed as a local filename and not a URL. A hashref of L may be
432             passed as the second argument.
433              
434             # Absolute filename
435             $sql->from_filename('/home/fred/data.db');
436              
437             # Relative to current directory
438             $sql->from_filename('data.db');
439              
440             # Temporary file database (default)
441             $sql->from_filename(':temp:');
442              
443             # In-memory temporary database (single connection only)
444             my $db = $sql->from_filename(':memory:')->db;
445              
446             # Additional options
447             $sql->from_filename($filename, { PrintError => 1 });
448            
449             # Readonly connection without WAL mode
450             $sql->from_filename($filename, { ReadOnly => 1, no_wal => 1 });
451            
452             # Strict unicode strings and WAL mode
453             use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
454             $sql->from_filename($filename, { sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT, wal_mode => 1 });
455              
456             =head2 from_string
457              
458             $sql = $sql->from_string('test.db');
459             $sql = $sql->from_string('file:test.db');
460             $sql = $sql->from_string('file:///C:/foo/bar.db');
461             $sql = $sql->from_string('sqlite:C:%5Cfoo%5Cbar.db');
462             $sql = $sql->from_string(Mojo::SQLite->new);
463              
464             Parse configuration from connection string or use another L
465             object as L. Connection strings are parsed as URLs, so you should
466             construct them using a module like L, L, or L.
467             For portability on non-Unix-like systems, either construct the URL with the
468             C scheme, or use L to construct a URL with the C
469             scheme. A URL with no scheme will be parsed as a C URL, and C URLs
470             are parsed according to the current operating system. If specified, the
471             hostname must be C. If the URL has a query string, it will be parsed
472             and applied to L.
473              
474             # Absolute filename
475             $sql->from_string('sqlite:////home/fred/data.db');
476             $sql->from_string('sqlite://localhost//home/fred/data.db');
477             $sql->from_string('sqlite:/home/fred/data.db');
478             $sql->from_string('file:///home/fred/data.db');
479             $sql->from_string('file://localhost/home/fred/data.db');
480             $sql->from_string('file:/home/fred/data.db');
481             $sql->from_string('///home/fred/data.db');
482             $sql->from_string('//localhost/home/fred/data.db');
483             $sql->from_string('/home/fred/data.db');
484              
485             # Relative to current directory
486             $sql->from_string('sqlite:data.db');
487             $sql->from_string('file:data.db');
488             $sql->from_string('data.db');
489              
490             # Connection string must be a valid URL
491             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path($filename));
492             $sql->from_string(URI::db->new->Mojo::Base::tap(engine => 'sqlite')->Mojo::Base::tap(dbname => $filename));
493             $sql->from_string(URI::file->new($filename));
494              
495             # Temporary file database (default)
496             $sql->from_string(':temp:');
497              
498             # In-memory temporary database (single connection only)
499             my $db = $sql->from_string(':memory:')->db;
500              
501             # Additional options
502             $sql->from_string('data.db?PrintError=1&sqlite_allow_multiple_statements=1');
503             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path($filename)->query(sqlite_see_if_its_a_number => 1));
504             $sql->from_string(URI::file->new($filename)->Mojo::Base::tap(query_form => {PrintError => 1}));
505              
506             # Readonly connection without WAL mode
507             $sql->from_string('data.db?ReadOnly=1&no_wal=1');
508              
509             # String unicode strings and WAL mode
510             use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
511             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path('data.db')
512             ->query(sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT, wal_mode => 1));
513              
514             =head1 DEBUGGING
515              
516             You can set the C environment variable to get some advanced
517             diagnostics information printed by L.
518              
519             DBI_TRACE=1
520             DBI_TRACE=15
521             DBI_TRACE=SQL
522              
523             =head1 REFERENCE
524              
525             This is the class hierarchy of the L distribution.
526              
527             =over 2
528              
529             =item * L
530              
531             =item * L
532              
533             =item * L
534              
535             =item * L
536              
537             =item * L
538              
539             =back
540              
541             =head1 BUGS
542              
543             Report any issues on the public bugtracker.
544              
545             =head1 AUTHOR
546              
547             Dan Book, C
548              
549             =head1 CREDITS
550              
551             Sebastian Riedel, author of L, which this distribution is based on.
552              
553             =head1 COPYRIGHT AND LICENSE
554              
555             Copyright 2015, Dan Book.
556              
557             This library is free software; you may redistribute it and/or modify it under
558             the terms of the Artistic License version 2.0.
559              
560             =head1 SEE ALSO
561              
562             L, L, L