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   1598887 use Mojo::Base 'Mojo::EventEmitter';
  6         78  
  6         56  
3              
4 6     6   10524 use Carp 'croak';
  6         12  
  6         279  
5 6     6   7193 use DBI;
  6         83377  
  6         467  
6 6     6   4504 use DBD::SQLite;
  6         54455  
  6         255  
7 6     6   2769 use DBD::SQLite::Constants qw(:database_connection_configuration_options :dbd_sqlite_string_mode);
  6         4474  
  6         2125  
8 6     6   3056 use File::Spec::Functions 'catfile';
  6         4700  
  6         435  
9 6     6   4580 use File::Temp;
  6         59030  
  6         468  
10 6     6   2985 use Mojo::SQLite::Database;
  6         22  
  6         55  
11 6     6   3123 use Mojo::SQLite::Migrations;
  6         13  
  6         38  
12 6     6   234 use Scalar::Util qw(blessed weaken);
  6         12  
  6         322  
13 6     6   3238 use SQL::Abstract::Pg;
  6         127406  
  6         478  
14 6     6   4100 use URI;
  6         26534  
  6         212  
15 6     6   3008 use URI::db;
  6         65928  
  6         8059  
16              
17             our $VERSION = '3.007';
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 35422 sub new { @_ > 1 ? shift->SUPER::new->from_string(@_) : shift->SUPER::new }
38              
39 118     118 1 127537 sub db { $_[0]->database_class->new(dbh => $_[0]->_prepare, sqlite => $_[0]) }
40              
41 5     5 1 54 sub from_filename { shift->from_string(_url_from_file(shift, shift)) }
42              
43             sub from_string {
44 14     14 1 88 my ($self, $str) = @_;
45 14 50       51 return $self unless $str;
46 14 100 100     275 return $self->parent($str) if blessed $str and $str->isa('Mojo::SQLite');
47              
48 12         42 my $url = URI->new($str);
49              
50             # Options
51 12         2000 my %options = $url->query_form;
52 12         798 $url->query(undef);
53             # don't set default string_mode if sqlite_unicode legacy option is set
54 12 100       212 delete $self->options->{sqlite_string_mode} if exists $options{sqlite_unicode};
55 12         35 @{$self->options}{keys %options} = values %options;
  12         37  
56              
57             # Parse URL based on scheme
58 12 100       73 $url->scheme('file') unless $url->has_recognized_scheme;
59 12 100       477 if ($url->scheme eq 'file') {
    100          
60 5         117 $url = _url_from_file($url->file);
61             } elsif ($url->scheme ne 'db') {
62 2         70 $url = URI::db->new($url);
63             }
64              
65 12 50 66     373 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       625 $url->dbname($self->_tempfile) if $url->dbname eq ':temp:';
71            
72 11         742 return $self->dsn($url->dbi_dsn);
73             }
74              
75             sub _dequeue {
76 118     118   162 my $self = shift;
77              
78             # Fork-safety
79 118 100 66     920 delete @$self{qw(pid queue)} unless ($self->{pid} //= $$) eq $$;
80              
81 118 50       218 while (my $dbh = shift @{$self->{queue} || []}) { return $dbh if $dbh->ping }
  91 100       572  
  118         475  
82            
83 27   33     101 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         20985 $dbh->sqlite_db_config(SQLITE_DBCONFIG_DQS_DDL, 0);
86 27         106 $dbh->sqlite_db_config(SQLITE_DBCONFIG_DQS_DML, 0);
87 27 100 66     93 if ($self->options->{wal_mode} and !$self->options->{no_wal}) {
88 26         420 $dbh->do('pragma journal_mode=WAL');
89 26         81657 $dbh->do('pragma synchronous=NORMAL');
90             }
91              
92             # Cache the last insert rowid on inserts
93 27         880 weaken(my $weakdbh = $dbh);
94             $dbh->sqlite_update_hook(sub {
95 40 100   40   1637 $weakdbh->{private_mojo_last_insert_id} = $_[3] if $_[0] == DBD::SQLite::INSERT;
96 27         315 });
97              
98 27         212 $self->emit(connection => $dbh);
99              
100 27         637 return $dbh;
101             }
102              
103             sub _enqueue {
104 124     124   263 my ($self, $dbh) = @_;
105              
106 124 100       330 if (my $parent = $self->parent) { return $parent->_enqueue($dbh) }
  6         44  
107              
108 118   100     624 my $queue = $self->{queue} ||= [];
109 118 100       1090 push @$queue, $dbh if $dbh->{Active};
110 118         456 shift @$queue while @$queue > $self->max_connections;
111             }
112              
113             sub _prepare {
114 124     124   690 my $self = shift;
115              
116             # Automatic migrations
117             ++$self->{migrated} and $self->migrations->migrate
118 124 100 33     533 if !$self->{migrated} && $self->auto_migrate;
      100        
119              
120 124         702 my $parent = $self->parent;
121 124 100       560 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   7252 my $url = URI::db->new;
128 17         1971 $url->engine('sqlite');
129 17         8067 $url->dbname(shift);
130 17 100       1383 if (my $options = shift) { $url->query_form($options) }
  1         10  
131 17         164 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 and C features are not applicable
315             to SQLite queries.
316              
317             $sql->db->select(['some_table', ['other_table', foo_id => 'id']],
318             ['foo', [bar => 'baz'], \q{datetime('now') as dt}],
319             {foo => 'value'},
320             {order_by => 'foo', limit => 10, offset => 5, group_by => ['foo'], having => {baz => 'value'}});
321              
322             =head2 auto_migrate
323              
324             my $bool = $sql->auto_migrate;
325             $sql = $sql->auto_migrate($bool);
326              
327             Automatically migrate to the latest database schema with L, as
328             soon as L has been called for the first time.
329              
330             =head2 database_class
331              
332             my $class = $sql->database_class;
333             $sql = $sql->database_class('MyApp::Database');
334              
335             Class to be used by L, defaults to L. Note that
336             this class needs to have already been loaded before L is called.
337              
338             =head2 dsn
339              
340             my $dsn = $sql->dsn;
341             $sql = $sql->dsn('dbi:SQLite:uri=file:foo.db');
342              
343             Data source name, defaults to C followed by a path to a
344             temporary file.
345              
346             =head2 max_connections
347              
348             my $max = $sql->max_connections;
349             $sql = $sql->max_connections(3);
350              
351             Maximum number of idle database handles to cache for future use, defaults to
352             C<1>.
353              
354             =head2 migrations
355              
356             my $migrations = $sql->migrations;
357             $sql = $sql->migrations(Mojo::SQLite::Migrations->new);
358              
359             L object you can use to change your database schema
360             more easily.
361              
362             # Load migrations from file and migrate to latest version
363             $sql->migrations->from_file('/home/dbook/migrations.sql')->migrate;
364              
365             =head2 options
366              
367             my $options = $sql->options;
368             $sql = $sql->options({AutoCommit => 1, RaiseError => 1});
369              
370             Options for database handles, defaults to setting C to
371             C, setting C,
372             C and C, and deactivating C.
373             Note that C and C are considered mandatory, so
374             deactivating them would be very dangerous. See
375             L and
376             L for more information on available
377             options.
378              
379             =head2 parent
380              
381             my $parent = $sql->parent;
382             $sql = $sql->parent(Mojo::SQLite->new);
383              
384             Another L object to use for connection management, instead of
385             establishing and caching our own database connections.
386              
387             =head1 METHODS
388              
389             L inherits all methods from L and implements
390             the following new ones.
391              
392             =head2 new
393              
394             my $sql = Mojo::SQLite->new;
395             my $sql = Mojo::SQLite->new('file:test.db);
396             my $sql = Mojo::SQLite->new('sqlite:test.db');
397             my $sql = Mojo::SQLite->new(Mojo::SQLite->new);
398              
399             Construct a new L object and parse connection string with
400             L if necessary.
401              
402             # Customize configuration further
403             my $sql = Mojo::SQLite->new->dsn('dbi:SQLite:dbname=test.db');
404             my $sql = Mojo::SQLite->new->dsn('dbi:SQLite:uri=file:test.db?mode=memory');
405              
406             # Pass filename directly
407             my $sql = Mojo::SQLite->new->from_filename($filename);
408              
409             =head2 db
410              
411             my $db = $sql->db;
412              
413             Get a database object based on L (which is usually
414             L) for a cached or newly established database
415             connection. The L database handle will be automatically cached
416             again when that object is destroyed, so you can handle problems like connection
417             timeouts gracefully by holding on to it only for short amounts of time.
418              
419             # Add up all the money
420             say $sql->db->select('accounts')
421             ->hashes->reduce(sub { $a->{money} + $b->{money} });
422              
423             =head2 from_filename
424              
425             $sql = $sql->from_filename('C:\\Documents and Settings\\foo & bar.db', $options);
426              
427             Parse database filename directly. Unlike L, the filename is
428             parsed as a local filename and not a URL. A hashref of L may be
429             passed as the second argument.
430              
431             # Absolute filename
432             $sql->from_filename('/home/fred/data.db');
433              
434             # Relative to current directory
435             $sql->from_filename('data.db');
436              
437             # Temporary file database (default)
438             $sql->from_filename(':temp:');
439              
440             # In-memory temporary database (single connection only)
441             my $db = $sql->from_filename(':memory:')->db;
442              
443             # Additional options
444             $sql->from_filename($filename, { PrintError => 1 });
445            
446             # Readonly connection without WAL mode
447             $sql->from_filename($filename, { ReadOnly => 1, no_wal => 1 });
448            
449             # Strict unicode strings and WAL mode
450             use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
451             $sql->from_filename($filename, { sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT, wal_mode => 1 });
452              
453             =head2 from_string
454              
455             $sql = $sql->from_string('test.db');
456             $sql = $sql->from_string('file:test.db');
457             $sql = $sql->from_string('file:///C:/foo/bar.db');
458             $sql = $sql->from_string('sqlite:C:%5Cfoo%5Cbar.db');
459             $sql = $sql->from_string(Mojo::SQLite->new);
460              
461             Parse configuration from connection string or use another L
462             object as L. Connection strings are parsed as URLs, so you should
463             construct them using a module like L, L, or L.
464             For portability on non-Unix-like systems, either construct the URL with the
465             C scheme, or use L to construct a URL with the C
466             scheme. A URL with no scheme will be parsed as a C URL, and C URLs
467             are parsed according to the current operating system. If specified, the
468             hostname must be C. If the URL has a query string, it will be parsed
469             and applied to L.
470              
471             # Absolute filename
472             $sql->from_string('sqlite:////home/fred/data.db');
473             $sql->from_string('sqlite://localhost//home/fred/data.db');
474             $sql->from_string('sqlite:/home/fred/data.db');
475             $sql->from_string('file:///home/fred/data.db');
476             $sql->from_string('file://localhost/home/fred/data.db');
477             $sql->from_string('file:/home/fred/data.db');
478             $sql->from_string('///home/fred/data.db');
479             $sql->from_string('//localhost/home/fred/data.db');
480             $sql->from_string('/home/fred/data.db');
481              
482             # Relative to current directory
483             $sql->from_string('sqlite:data.db');
484             $sql->from_string('file:data.db');
485             $sql->from_string('data.db');
486              
487             # Connection string must be a valid URL
488             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path($filename));
489             $sql->from_string(URI::db->new->Mojo::Base::tap(engine => 'sqlite')->Mojo::Base::tap(dbname => $filename));
490             $sql->from_string(URI::file->new($filename));
491              
492             # Temporary file database (default)
493             $sql->from_string(':temp:');
494              
495             # In-memory temporary database (single connection only)
496             my $db = $sql->from_string(':memory:')->db;
497              
498             # Additional options
499             $sql->from_string('data.db?PrintError=1&sqlite_allow_multiple_statements=1');
500             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path($filename)->query(sqlite_see_if_its_a_number => 1));
501             $sql->from_string(URI::file->new($filename)->Mojo::Base::tap(query_form => {PrintError => 1}));
502              
503             # Readonly connection without WAL mode
504             $sql->from_string('data.db?ReadOnly=1&no_wal=1');
505              
506             # String unicode strings and WAL mode
507             use DBD::SQLite::Constants ':dbd_sqlite_string_mode';
508             $sql->from_string(Mojo::URL->new->scheme('sqlite')->path('data.db')
509             ->query(sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT, wal_mode => 1));
510              
511             =head1 DEBUGGING
512              
513             You can set the C environment variable to get some advanced
514             diagnostics information printed by L.
515              
516             DBI_TRACE=1
517             DBI_TRACE=15
518             DBI_TRACE=SQL
519              
520             =head1 REFERENCE
521              
522             This is the class hierarchy of the L distribution.
523              
524             =over 2
525              
526             =item * L
527              
528             =item * L
529              
530             =item * L
531              
532             =item * L
533              
534             =item * L
535              
536             =back
537              
538             =head1 BUGS
539              
540             Report any issues on the public bugtracker.
541              
542             =head1 AUTHOR
543              
544             Dan Book, C
545              
546             =head1 CREDITS
547              
548             Sebastian Riedel, author of L, which this distribution is based on.
549              
550             =head1 COPYRIGHT AND LICENSE
551              
552             Copyright 2015, Dan Book.
553              
554             This library is free software; you may redistribute it and/or modify it under
555             the terms of the Artistic License version 2.0.
556              
557             =head1 SEE ALSO
558              
559             L, L, L