File Coverage

blib/lib/Mojo/Hakkefuin/Backend/sqlite.pm
Criterion Covered Total %
statement 149 149 100.0
branch 30 58 51.7
condition 9 25 36.0
subroutine 19 19 100.0
pod 15 15 100.0
total 222 266 83.4


line stmt bran cond sub pod time code
1             package Mojo::Hakkefuin::Backend::sqlite;
2 6     6   8793 use Mojo::Base 'Mojo::Hakkefuin::Backend';
  6         14  
  6         51  
3              
4 6     6   5224 use Mojo::SQLite;
  6         797716  
  6         73  
5 6     6   2645 use CellBIS::SQL::Abstract;
  6         32828  
  6         47  
6              
7             has 'sqlite';
8             has 'file_db';
9             has 'file_migration';
10             has abstract =>
11             sub { state $abstract = CellBIS::SQL::Abstract->new(db_type => 'sqlite') };
12              
13             sub new {
14 6     6 1 99 my $self = shift->SUPER::new(@_);
15              
16 6         91 $self->file_migration($self->dir . '/mhf_sqlite.sql');
17 6         130 $self->file_db('sqlite:' . $self->dir . '/mhf_sqlite.db');
18              
19 6         86 $self->sqlite(Mojo::SQLite->new($self->file_db));
20 6         15546 return $self;
21             }
22              
23             sub check_table {
24 11     11 1 14573 my $self = shift;
25              
26 11         57 my $result = {result => 0, code => 400};
27 11         68 my $q = $self->abstract->select('sqlite_master', ['name'],
28             {where => 'type=\'table\' AND tbl_name=\'' . $self->table_name . '\''});
29              
30 11 50       1063 if (my $dbh = $self->sqlite->db->query($q)) {
31 11         70071 $result = {result => $dbh->hash, code => 200};
32 11         507 eval { $self->_ensure_indexes };
  11         49  
33             }
34 11         5874 return $result;
35             }
36              
37             sub create_table {
38 6     6 1 517 my $self = shift;
39 6         23 my $table_query = $self->table_query;
40              
41 6         11518 my $result = {result => 0, code => 400};
42              
43 6 50       30 if (my $dbh = $self->sqlite->db->query($table_query)) {
44 6         32718 $result->{result} = $dbh->rows;
45 6         106 $result->{code} = 200;
46 6         17 eval { $self->_ensure_indexes };
  6         29  
47             }
48 6         4253 return $result;
49             }
50              
51             sub _ensure_indexes {
52 17     17   36 my $self = shift;
53              
54 17         65 my $table = $self->table_name;
55 17         198 my @idx_sql = (
56             'CREATE INDEX IF NOT EXISTS idx_'
57             . $table
58             . '_identify ON '
59             . $table . ' ('
60             . $self->identify . ')',
61             'CREATE INDEX IF NOT EXISTS idx_'
62             . $table
63             . '_cookie ON '
64             . $table . ' ('
65             . $self->cookie . ')',
66             'CREATE INDEX IF NOT EXISTS idx_'
67             . $table
68             . '_expire_date ON '
69             . $table . ' ('
70             . $self->expire_date . ')',
71             );
72              
73 17         324 for my $sql (@idx_sql) {
74 51         36715 eval { $self->sqlite->db->query($sql) };
  51         227  
75             }
76             }
77              
78             sub table_query {
79 6     6 1 16 my $self = shift;
80              
81 6         29 $self->abstract->create_table(
82             $self->table_name,
83             [
84             $self->id, $self->identify, $self->cookie,
85             $self->csrf, $self->create_date, $self->expire_date,
86             $self->cookie_lock, $self->lock
87             ],
88             {
89             $self->id =>
90             {type => {name => 'integer'}, is_primarykey => 1, is_autoincre => 1},
91             $self->identify => {type => {name => 'text'}},
92             $self->cookie => {type => {name => 'text'}},
93             $self->csrf => {type => {name => 'text'}},
94             $self->create_date => {type => {name => 'datetime'}},
95             $self->expire_date => {type => {name => 'datetime'}},
96             $self->cookie_lock =>
97             {type => {name => 'text'}, default => '\'no-lock\'', is_null => 1},
98             $self->lock => {type => {name => 'integer'}},
99             }
100             );
101             }
102              
103             sub create {
104 7     7 1 39 my ($self, $identify, $cookie, $csrf, $expires) = @_;
105              
106 7 100       83 return {result => 0, code => 500, data => $cookie} unless $self->_table_ok;
107              
108 6         35 my $result = {result => 0, code => 400, data => $cookie};
109              
110 6         42 my $mhf_utils = $self->mhf_util->new;
111 6         94 my $now_time = $mhf_utils->sql_datetime(0);
112 6         19 my $expire_time = $mhf_utils->sql_datetime($expires);
113              
114 6         22 my @q = (
115             $self->table_name,
116             {
117             $self->identify => $identify,
118             $self->cookie => $cookie,
119             $self->csrf => $csrf,
120             $self->create_date => $now_time,
121             $self->expire_date => $expire_time,
122             $self->cookie_lock => 'no_lock',
123             $self->lock => 0
124             },
125             {on_conflict => undef}
126             );
127              
128 6 50       207 if (my $dbh = $self->sqlite->db->insert(@q)) {
129 6         21397 $result->{result} = $dbh->rows;
130 6         67 $result->{code} = 200;
131             }
132 6         29 return $result;
133             }
134              
135             sub read {
136 11     11 1 12323 my ($self, $identify, $cookie) = @_;
137              
138 11   50     35 $identify //= 'null';
139 11   50     25 $cookie //= 'null';
140              
141 11 50       41 return {result => 0, code => 500, data => $cookie} unless $self->_table_ok;
142              
143 11         104 my $result = {result => 0, code => 400, data => $cookie};
144 11         31 my @q = (
145             $self->table_name, '*',
146             {$self->identify => $identify, $self->cookie => $cookie}
147             );
148 11 50       134 if (my $dbh = $self->sqlite->db->select(@q)) {
149 11         23033 $result->{result} = 1;
150 11         22 $result->{code} = 200;
151 11         37 $result->{data} = $dbh->hash;
152             }
153 11         536 return $result;
154             }
155              
156             sub update {
157 3     3 1 31 my ($self, $id, $cookie, $csrf) = @_;
158              
159 3         36 my $mhf_utils = $self->mhf_util->new;
160 3         41 my $now_time = $mhf_utils->sql_datetime(0);
161              
162 3 50       16 return {result => 0, code => 500, csrf => $csrf, cookie => $cookie}
163             unless $self->_table_ok;
164              
165 3         37 my $result = {result => 0, code => 400, csrf => $csrf, cookie => $cookie};
166 3 50 33     23 return $result unless $id && $csrf;
167              
168 3         38 my @q = (
169             $self->table_name,
170             {$self->cookie, => $cookie, $self->csrf => $csrf},
171             {$self->id => $id, $self->expire_date => {'>=', $now_time}}
172             );
173 3 50       97 if (my $dbh = $self->sqlite->db->update(@q)) {
174 3         10671 $result->{result} = $dbh->rows;
175 3         41 $result->{code} = 200;
176             }
177 3         19 return $result;
178             }
179              
180             sub update_csrf {
181 3     3 1 32 my ($self, $id, $csrf) = @_;
182              
183 3         14 my $mhf_utils = $self->mhf_util->new;
184 3         41 my $now_time = $mhf_utils->sql_datetime(0);
185              
186 3 50       16 return {result => 0, code => 500, data => $csrf} unless $self->_table_ok;
187              
188 3         33 my $result = {result => 0, code => 400, data => $csrf};
189 3 50 33     24 return $result unless $id && $csrf;
190              
191 3         12 my @q = (
192             $self->table_name,
193             {$self->csrf => $csrf},
194             {$self->id => $id, $self->expire_date => {'>=', $now_time}}
195             );
196 3 50       56 if (my $dbh = $self->sqlite->db->update(@q)) {
197 3         7604 $result->{result} = $dbh->rows;
198 3         36 $result->{code} = 200;
199             }
200 3         14 return $result;
201             }
202              
203             sub update_cookie {
204 1     1 1 14 my ($self, $id, $cookie) = @_;
205              
206 1         4 my $mhf_utils = $self->mhf_util->new;
207 1         11 my $now_time = $mhf_utils->sql_datetime(0);
208              
209 1 50       3 return {result => 0, code => 500, data => $cookie} unless $self->_table_ok;
210              
211 1         10 my $result = {result => 0, code => 400, data => $cookie};
212 1 50 33     7 return $result unless $id && $cookie;
213              
214 1         4 my @q = (
215             $self->table_name,
216             {$self->cookie => $cookie},
217             {$self->id => $id, $self->expire_date => {'>=', $now_time}}
218             );
219 1 50       14 if (my $dbh = $self->sqlite->db->update(@q)) {
220 1         2013 $result->{result} = $dbh->rows;
221 1         8 $result->{code} = 200;
222             }
223 1         4 return $result;
224             }
225              
226             sub upd_coolock {
227 8     8 1 1358 my ($self, $id, $cookie_lock) = @_;
228              
229 8         34 my $mhf_utils = $self->mhf_util->new;
230 8         153 my $now_time = $mhf_utils->sql_datetime(0);
231              
232 8 50       35 return {result => 0, code => 500, data => $cookie_lock}
233             unless $self->_table_ok;
234              
235 8         90 my $result = {result => 0, code => 400, data => $cookie_lock};
236 8 50 33     60 return $result unless $id && defined $cookie_lock;
237              
238 8         29 my @q = (
239             $self->table_name,
240             {$self->cookie_lock => $cookie_lock},
241             {$self->id => $id, $self->expire_date => {'>=', $now_time}}
242             );
243 8 50       148 if (my $dbh = $self->sqlite->db->update(@q)) {
244 8         21977 $result->{result} = $dbh->rows;
245 8         93 $result->{code} = 200;
246             }
247 8         39 return $result;
248             }
249              
250             sub upd_lckstate {
251 8     8 1 1089 my ($self, $id, $state) = @_;
252              
253 8         30 my $mhf_utils = $self->mhf_util->new;
254 8         97 my $now_time = $mhf_utils->sql_datetime(0);
255              
256 8 50       67 return {result => 0, code => 500, data => $state} unless $self->_table_ok;
257              
258 8         110 my $result = {result => 0, code => 400, data => $state};
259 8 50 33     52 return $result unless $id && defined $state;
260              
261 8         25 my @q = (
262             $self->table_name,
263             {$self->lock => $state},
264             {$self->id => $id, $self->expire_date => {'>=', $now_time}}
265             );
266 8 50       164 if (my $dbh = $self->sqlite->db->update(@q)) {
267 8         21102 $result->{result} = $dbh->rows;
268 8         88 $result->{code} = 200;
269             }
270 8         37 return $result;
271             }
272              
273             sub delete {
274 5     5 1 1646 my ($self, $identify, $cookie) = @_;
275              
276 5 50       19 return {result => 0, code => 500, data => $cookie} unless $self->_table_ok;
277              
278 5         56 my $result = {result => 0, code => 400, data => $cookie};
279 5 50 33     32 return $result unless $identify && $cookie;
280              
281 5         16 my @q = (
282             $self->table_name, {$self->identify => $identify, $self->cookie => $cookie}
283             );
284 5 50       64 if (my $dbh = $self->sqlite->db->delete(@q)) {
285 5         10857 $result->{result} = $dbh->rows;
286 5         55 $result->{code} = 200;
287             }
288 5         22 return $result;
289             }
290              
291             sub check {
292 26     26 1 255 my ($self, $identify, $cookie) = @_;
293              
294 26 50       118 return {result => 0, code => 500, data => $cookie} unless $self->_table_ok;
295              
296 26         277 my $result = {result => 0, code => 400, data => $cookie};
297 26 50 33     128 return $result unless $identify && $cookie;
298              
299 26         93 my @q = (
300             $self->table_name,
301             '*',
302             {
303             -or => {$self->identify => $identify, $self->cookie => $cookie},
304             $self->expire_date => {'>', "'datetime('now', 'localtime')"}
305             }
306             );
307 26 50       544 if (my $rv = $self->sqlite->db->select(@q)) {
308 26         73765 my $r_data = $rv->hash;
309             $result = {
310             result => 1,
311             code => 200,
312             data => {
313             cookie => $cookie,
314             id => $r_data->{$self->id},
315             csrf => $r_data->{$self->csrf},
316             identify => $r_data->{$self->identify},
317             cookie_lock => $r_data->{$self->cookie_lock},
318 26         1786 lock => $r_data->{$self->lock}
319             }
320             };
321             }
322 26         837 return $result;
323             }
324              
325             sub empty_table {
326 2     2 1 1762 my $self = shift;
327 2         10 my $result = {result => 0, code => 500, data => 'can\'t delete table'};
328              
329 2 50       8 if (my $dbh = $self->sqlite->db->query('DELETE FROM ' . $self->table_name)) {
330 2         1188 $result->{result} = $dbh->rows;
331 2         41 $result->{code} = 200;
332 2         7 $result->{data} = '';
333             }
334 2         9 return $result;
335             }
336              
337             sub drop_table {
338 5     5 1 1158 my $self = shift;
339 5         27 my $result = {result => 0, code => 500, data => 'can\'t drop table'};
340              
341 5 50       22 if (my $dbh
342             = $self->sqlite->db->query('DROP TABLE IF EXISTS ' . $self->table_name))
343             {
344 5         5649 $result->{result} = $dbh->rows;
345 5         60 $result->{code} = 200;
346 5         14 $result->{data} = '';
347 5         29 $self->table_ready(0);
348             }
349 5         51 return $result;
350             }
351              
352             1;
353              
354             =encoding utf8
355              
356             =head1 NAME
357              
358             Mojo::Hakkefuin::Backend::sqlite - SQLite Backend.
359              
360             =head1 SYNOPSIS
361              
362             use Mojo::Hakkefuin::Backend::sqlite;
363              
364             my $sqlite = Mojo::Hakkefuin:Backend:sqlite->new(
365             dir => 'path/your/dir/migrations'
366             );
367              
368             =head1 DESCRIPTION
369              
370             L is a backend for L
371             based on L. All necessary tables will be created automatically.
372              
373             =head1 ATTRIBUTES
374              
375             L inherits all attributes from L
376             and implements the following new ones.
377              
378             =head2 dir
379              
380             # Example use as a config
381             my $backend = Mojo::Hakkefuin::Backend::sqlite->new(
382             ...
383             dir => '/path/of/dir/location/file/database/',
384             ...
385             );
386            
387             # use as a method
388             my $backend = $backend->dir;
389             $backend->dir('/path/of/dir/location/file/database/');
390              
391             This attribute for specify path (directory address) of directory
392             SQLite database file or migrations configuration file.
393              
394             =head1 METHODS
395              
396             L inherits all methods
397             from L and implements the following new ones.
398             In this module contains 2 section methods that is B and B.
399              
400             =head2 Table Interaction
401              
402             A section for all activities related to interaction data in a database table.
403              
404             =head3 table_query
405              
406             my $table_query = $backend->table_query;
407             $backend->table_query;
408              
409             This method used by the C method to generate
410             a query that will be used to create a database table.
411              
412             =head3 check_table
413              
414             $backend->check_table();
415             my $check_table = $backend->check_table;
416            
417             This method is used to check whether a table in the DBMS exists or not
418              
419             =head3 create_table
420              
421             $backend->create_table();
422             my $create_table = $backend->create_table;
423              
424             This method is used to create database table.
425              
426             =head3 empty_table
427              
428             $backend->empty_table;
429             my $empty_table = $backend->empty_table;
430            
431             This method is used to delete all database table
432             (It means to delete all data in a table).
433              
434             =head3 drop_table
435              
436             $backend->drop_table;
437             my $drop_table = $backend->drop_table;
438              
439             This method is used to drop database table
440             (It means to delete all data in a table and its contents).
441              
442             =head2 Data Interaction
443              
444             A section for all activities related to data interaction in a database table.
445             These options are currently available:
446              
447             =over 2
448              
449             =item $id
450              
451             A variable containing a unique id that is generated when inserting data
452             into a table.
453              
454             =item $identify
455              
456             The variables that contain important information for data login
457             but not crucial information.
458              
459             =item $cookie
460              
461             The variable that contains the cookie hash, which hash is used
462             in the HTTP header.
463              
464             =item $csrf
465              
466             The variable that contains the csrf token hash, which hash is used
467             in the HTTP header.
468              
469             =item $expires
470              
471             The variable that contains timestamp format. e.g. C<2023-03-23 12:01:53>.
472             For more information see L.
473              
474             =back
475              
476             =head3 create($identify, $cookie, $csrf, $expires)
477              
478             $backend->create($identify, $cookie, $csrf, $expires)
479            
480             Method for insert data login.
481              
482             =head3 read($identify, $cookie)
483              
484             $backend->read($identify, $cookie);
485              
486             Method for read data login.
487              
488             =head3 update()
489              
490             $backend->update($id, $cookie, $csrf);
491              
492             Method for update data login.
493              
494             =head3 update_csrf()
495              
496             $backend->update_csrf($id, $csrf);
497              
498             Method for update CSRF token login.
499              
500             =head3 update_cookie()
501              
502             $backend->update_cookie($id, $cookie);
503              
504             Method for update cookie login.
505              
506             =head3 upd_coolock()
507              
508             $backend->upd_coolock();
509              
510             Method for update cookie lock session.
511              
512             =head3 upd_lckstate()
513              
514             $backend->upd_lckstate();
515              
516             Method for update lock state condition.
517              
518             =head3 delete($identify, $cookie)
519              
520             $backend->delete($identify, $cookie);
521              
522             Method for delete data login.
523              
524             =head3 check($identify, $cookie)
525              
526             $backend->check($identify, $cookie);
527            
528             Method for check data login.
529              
530             =head2 new()
531              
532             use Mojo::Hakkefuin::Backend::sqlite;
533            
534             my $backend = Mojo::Hakkefuin::Backend::sqlite->new(
535             dir => 'path/your/dir/file/database'
536             );
537              
538             Construct a new L object.
539              
540             =head1 SEE ALSO
541              
542             =over 2
543              
544             =item * L
545              
546             =item * L
547              
548             =item * L
549              
550             =item * L
551              
552             =back
553              
554             =cut