File Coverage

blib/lib/Hailo/Storage/SQLite.pm
Criterion Covered Total %
statement 37 37 100.0
branch 11 12 91.6
condition 4 6 66.6
subroutine 9 9 100.0
pod 0 2 0.0
total 61 66 92.4


line stmt bran cond sub pod time code
1             package Hailo::Storage::SQLite;
2             our $AUTHORITY = 'cpan:AVAR';
3             $Hailo::Storage::SQLite::VERSION = '0.75';
4 28     28   50213 use v5.10.0;
  28         104  
5 28     28   153 use Moose;
  28         59  
  28         231  
6 28     28   199898 use MooseX::StrictConstructor;
  28         64  
  28         237  
7 28     28   92395 use namespace::clean -except => 'meta';
  28         69  
  28         289  
8              
9             extends 'Hailo::Storage';
10             with qw(Hailo::Role::Arguments Hailo::Role::Storage);
11              
12 249     249   5456 sub _build_dbd { return 'SQLite' };
13              
14             override _build_dbd_options => sub {
15             return {
16             %{ super() },
17             sqlite_unicode => 1,
18             };
19             };
20              
21             around _build_dbi_options => sub {
22             my $orig = shift;
23             my $self = shift;
24              
25             my $return;
26             if ($self->_backup_memory_to_disk) {
27             my $file = $self->brain;
28             $self->brain(':memory:');
29             $return = $self->$orig(@_);
30             $self->brain($file);
31             }
32             else {
33             $return = $self->$orig(@_);
34             }
35              
36             return $return;
37             };
38              
39             # Are we running in a mixed mode where we run in memory but
40             # restore/backup to disk?
41             sub _backup_memory_to_disk {
42 552     552   1037 my ($self) = @_;
43              
44             return (defined $self->brain
45             and $self->brain ne ':memory:'
46 552   66     15861 and $self->arguments->{in_memory});
47             }
48              
49             before _engage => sub {
50             my ($self) = @_;
51              
52             # Set any user-defined pragmas
53             $self->_set_pragmas;
54              
55             if ($self->_backup_memory_to_disk) {
56             $self->dbh->sqlite_backup_from_file($self->brain);
57             }
58              
59             return;
60             };
61              
62             before start_training => sub {
63             my $dbh = shift->dbh;
64             $dbh->do('PRAGMA synchronous=OFF;');
65             $dbh->do('PRAGMA journal_mode=OFF;');
66             return;
67             };
68              
69             after stop_training => sub {
70             my $dbh = shift->dbh;
71             $dbh->do('PRAGMA journal_mode=DELETE;');
72             $dbh->do('PRAGMA synchronous=ON;');
73             return;
74             };
75              
76             override initialized => sub {
77             my ($self) = @_;
78              
79             my $brain = $self->brain;
80             return unless defined $brain;
81             return if $brain eq ':memory:';
82             return -e $brain && super();
83             };
84              
85             sub ready {
86 20     20 0 55 my ($self) = @_;
87 20         525 my $brain = $self->brain;
88 20 100       482 return unless defined $self->brain;
89 16 100       428 return 1 if $self->brain eq ':memory:';
90 2         16 return 1;
91             }
92              
93             sub _set_pragmas {
94 251     251   427 my ($self) = @_;
95              
96 251         383 my %pragmas;
97              
98             # speedy defaults when DB is not kept in memory
99 251 50       735 if (!$self->{in_memory}) {
100 251         536 $pragmas{synchronous} = 'OFF';
101 251         530 $pragmas{journal_mode} = 'OFF';
102             }
103              
104 251         417 while (my ($k, $v) = each %{ $self->arguments }) {
  270         7388  
105 19 100       100 if (my ($pragma) = $k =~ /^pragma_(.*)/) {
106 5         13 $pragmas{$pragma} = $v;
107             }
108             }
109              
110 251         953 while (my ($k, $v) = each %pragmas) {
111 505         88225 $self->dbh->do(qq[PRAGMA $k="$v";])
112             }
113              
114 251         23332 return;
115             }
116              
117             sub save {
118 254     254 0 628 my ($self, $filename) = @_;
119 254   66     7047 my $file = $filename // $self->brain;
120              
121 254 100       6141 return unless $self->_engaged;
122 49 100       252 if ($self->_backup_memory_to_disk) {
123 1         26 $self->dbh->sqlite_backup_to_file($file);
124             }
125 49         161 return;
126             };
127              
128             __PACKAGE__->meta->make_immutable;
129              
130             =encoding utf8
131              
132             =head1 NAME
133              
134             Hailo::Storage::SQLite - A storage backend for L<Hailo|Hailo> using L<DBD::SQLite>
135              
136             =head1 SYNOPSIS
137              
138             As a module:
139              
140             my $hailo = Hailo->new(
141             storage_class => 'SQLite',
142             );
143             $hailo->train("hailo.trn");
144              
145             From the command line:
146              
147             hailo --train hailo.trn --storage SQLite
148              
149             See L<Hailo's documentation|Hailo> for other non-MySQL specific options.
150              
151             =head1 DESCRIPTION
152              
153             This backend maintains information in an SQLite database. It is the default
154             storage backend.
155              
156             =head1 ATTRIBUTES
157              
158             =head2 C<storage_args>
159              
160             This is a hash reference which can have the following keys:
161              
162             =head3 C<pragma_*>
163              
164             Any option starting with B<'pragma_'> will be considered to be an L<SQLite
165             pragma|http://www.sqlite.org/pragma.html> which will be set after we connect
166             to the database. An example of this would be
167              
168             storage_args => {
169             pragma_cache_size => 10000,
170             pragma_synchronous => 'OFF',
171             }
172              
173             Setting B<'pragma_cache_size'> in particular can be beneficial. It's the
174             size of the page cache used by SQLite. See L<SQLite's
175             documentation|http://www.sqlite.org/pragma.html#pragma_cache_size> for
176             more information.
177              
178             Increasing it might speed up Hailo, especially when disk IO is slow on
179             your machine. Obviously, you shouldn't bother with this option if
180             L<B<'in_memory'>|/in_memory> is enabled.
181              
182             Setting B<'pragma_synchronous'> to B<'OFF'> or B<'pragma_journal_mode'>
183             to B<'OFF'> will speed up operations at the expense of safety. Since Hailo
184             is most likely not running as a mission-critical component this trade-off
185             should be acceptable in most cases. If the database becomes corrupt
186             it's easy to rebuild it by retraining from the input it was trained on
187             to begin with. For performance reasons, these two are set to B<'OFF'>
188             by default unless L<B<'in_memory'>|/in_memory> is enabled.
189              
190             =head3 C<in_memory>
191              
192             When set to a true value, Hailo behaves much like MegaHAL. The entire
193             database will be kept in memory, and only written out to disk when the
194             L<C<save>|Hailo/save> method is called and/or when the Hailo object gets
195             destroyed (unless you disabled
196             L<C<save_on_exit>|Hailo/save_on_exit>). This is disabled by default.
197              
198             =head1 AUTHOR
199              
200             E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
201              
202             Hinrik E<Ouml>rn SigurE<eth>sson, hinrik.sig@gmail.com
203              
204             =head1 LICENSE AND COPYRIGHT
205              
206             Copyright 2010 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason and
207             Hinrik E<Ouml>rn SigurE<eth>sson
208              
209             This program is free software, you can redistribute it and/or modify
210             it under the same terms as Perl itself.
211              
212             =cut