File Coverage

blib/lib/CellBIS/SQL/Abstract/Test.pm
Criterion Covered Total %
statement 93 121 76.8
branch 13 46 28.2
condition 1 7 14.2
subroutine 13 15 86.6
pod 2 8 25.0
total 122 197 61.9


line stmt bran cond sub pod time code
1             package CellBIS::SQL::Abstract::Test;
2             $CellBIS::SQL::Abstract::Test::VERSION = '1.5';
3 4     4   1217623 use Mojo::Base -base;
  4         38  
  4         33  
4              
5 4     4   770 use Carp 'croak';
  4         8  
  4         166  
6 4     4   1345 use Mojo::Loader 'load_class';
  4         98285  
  4         248  
7 4     4   36 use Mojo::Util qw(dumper);
  4         9  
  4         142  
8 4     4   1893 use Mojo::Home;
  4         2034  
  4         185  
9 4     4   1646 use CellBIS::SQL::Abstract;
  4         12  
  4         38  
10 4     4   2208 use CellBIS::SQL::Abstract::Test::Table;
  4         11  
  4         32  
11              
12             has 'dsn';
13             has 'via';
14             has 'backend';
15             has 'table';
16              
17             # internal purpose
18             has 'abstract';
19             has 'dir';
20             has home => sub {
21             state $home = Mojo::Home->new;
22             };
23             has table_info => sub {
24             state $table = CellBIS::SQL::Abstract::Test::Table->new;
25             };
26              
27             sub create_table {
28 3     3 0 1878 my $self = shift;
29              
30 3         12 my $result = {result => 0, code => 400};
31 3         11 my $dbtype = $self->via;
32 3         19 my $table = $self->table;
33              
34 3         17 my @table_info = $self->table_info->$table->$dbtype;
35 3         172 my $q = $self->abstract->create_table(@table_info);
36 3 50       16 if (my $dbh = $self->backend->db->query($q)) {
37 3         6270 $result->{result} = $dbh->rows;
38 3         39 $result->{code} = 200;
39             }
40 3         14 return $result;
41             }
42              
43             sub create_table_with_fk {
44 1     1 0 485 my $self = shift;
45              
46 1         4 my ($result, $dbtype, $table_users, $table_roles, @table_info, $table, $q);
47 1         4 $result = {result => 0, code => 400};
48 1         4 $dbtype = $self->via;
49 1         6 $table = $self->table;
50 1         5 $table_users = $self->table_info->users;
51 1         8 $table_roles = $self->table_info->roles;
52              
53             # table construction
54 1         9 @table_info = $self->table_info->$table->$dbtype;
55 1         93 push @table_info,
56             {
57             fk => {
58             name => 'users_roles_id',
59             col_name => $table_users->id_roles,
60             table_target => $table_roles->table_name,
61             col_target => $table_roles->id,
62             attr => {onupdate => 'cascade', ondelete => 'cascade'}
63             }
64             };
65 1         19 $q = $self->abstract->create_table(@table_info);
66 1 50       6 if (my $dbh = $self->backend->db->query($q)) {
67 1         713 $result->{result} = $dbh->rows;
68 1         13 $result->{code} = 200;
69             }
70 1         4 return $result;
71             }
72              
73             sub check_table {
74 4     4 0 23169 my $self = shift;
75              
76 4         11 my ($result, $dbtype, $table_info, $table, @pre_q, $q);
77 4         15 $result = {result => 0, code => 400};
78 4         21 $dbtype = $self->via;
79 4         25 $table = $self->table;
80 4         51 $table_info = $self->table_info->$table;
81              
82 4 50       57 @pre_q = (
83             'sqlite_master',
84             ['name'],
85             {
86             where => 'type=\'table\' AND tbl_name=\''
87             . $table_info->table_name . '\''
88             }
89             ) if $dbtype eq 'sqlite';
90 4 50       48 @pre_q = (
91             'information_schema.tables', ['table_name'],
92             {where => 'table_name=\'' . $table_info->table_name . '\''}
93             ) if $dbtype eq 'mariadb';
94 4 50       15 @pre_q = (
95             'information_schema.tables',
96             ['table_name'],
97             {
98             where =>
99             'table_type=\'BASE TABLE\' AND table_schema=\'public\' AND table_name=\''
100             . $table_info->table_name . '\''
101             }
102             ) if $dbtype eq 'pg';
103              
104 4         13 $q = $self->abstract->select(@pre_q);
105 4 50       18 if (my $dbh = $self->backend->db->query($q)) {
106 4         2846 $result->{result} = $dbh->hash;
107 4         115 $result->{code} = 200;
108             }
109 4         43 return $result;
110             }
111              
112             sub empty_table {
113 2     2 0 2262 my $self = shift;
114              
115 2         6 my ($result, $dbtype, $table, $table_info);
116 2         11 $dbtype = $self->via;
117 2         16 $table = $self->table;
118 2         12 $table_info = $self->table_info->$table;
119 2         24 $result = {result => 0, code => 500};
120              
121 2 50       7 if (my $dbh
122             = $self->backend->db->query('DELETE FROM ' . $table_info->table_name))
123             {
124 2         771 $result->{result} = $dbh->rows;
125 2         21 $result->{code} = 200;
126             }
127 2         9 return $result;
128             }
129              
130             sub drop_table {
131 2     2 0 1405 my $self = shift;
132              
133 2         5 my ($result, $dbtype, $table, $table_info);
134 2         9 $dbtype = $self->via;
135 2         12 $table = $self->table;
136 2         9 $table_info = $self->table_info->$table;
137 2         18 $result = {result => 0, code => 500};
138              
139 2 50       138 if (
140             my $dbh = $self->backend->db->query(
141             'DROP TABLE IF EXISTS ' . $table_info->table_name
142             )
143             )
144             {
145 2         856 $result->{result} = $dbh->rows;
146 2         19 $result->{code} = 200;
147             }
148 2         7 return $result;
149             }
150              
151             sub create {
152 0     0 0 0 my $self = shift;
153              
154 0         0 my ($result, $dbtype, $table, $table_info);
155 0         0 $dbtype = $self->via;
156 0         0 $table = $self->table;
157 0         0 $table_info = $self->table_info->$table;
158              
159             # return if table is not exist.
160 0         0 $result = {result => 0, code => 500};
161 0 0       0 return $result unless $self->check_table->{result};
162              
163 0         0 $result = {result => 0, code => 400};
164 0         0 my $q = $self->abstract->insert();
165 0 0       0 if (my $dbh = $self->backend->db->query($q)) {
166 0         0 $result->{result} = $dbh->rows;
167 0         0 $result->{code} = 200;
168             }
169 0         0 return $result;
170             }
171              
172             sub change_dbms {
173 0     0 1 0 my ($self, $dbms) = @_;
174              
175 0   0     0 $dbms //= 'sqlite';
176 0         0 $self->{via} = $dbms;
177 0         0 $self->abstract(CellBIS::SQL::Abstract->new(db_type => $self->via));
178 0 0       0 my $backend = 'Mojo::mysql' if $self->via eq 'mariadb';
179 0 0       0 $backend = 'Mojo::Pg' if $self->via eq 'pg';
180 0 0       0 $backend = 'Mojo::SQLite' if $self->via eq 'sqlite';
181              
182             # dsn attribute alert
183 0 0 0     0 croak 'dsn attribute must be defined'
184             if ($self->via ne 'sqlite' && $self->dsn =~ /^sqlite\:/);
185              
186             # Only for SQLite
187 0 0       0 if ($self->via eq 'sqlite') {
188 0         0 $self->dir($self->home->child(qw(t db)));
189 0         0 $self->dsn('sqlite:' . $self->dir . '/csa_test.db');
190             }
191              
192 0         0 my $load = load_class $backend;
193 0 0       0 croak ref $load ? $load : qq{Backend "$backend" missing} if $load;
    0          
194 0         0 $self->backend($backend->new($self->dsn));
195              
196 0         0 return $self;
197             }
198              
199             sub new {
200 1     1 1 100 my $self = shift->SUPER::new(@_);
201              
202 1         10 my ($backend);
203 1   50     11 $self->{via} //= 'sqlite';
204              
205 1         5 $self->abstract(CellBIS::SQL::Abstract->new(db_type => $self->via));
206 1 50       23 $backend = 'Mojo::mysql' if $self->via eq 'mariadb';
207 1 50       7 $backend = 'Mojo::Pg' if $self->via eq 'pg';
208 1 50       5 $backend = 'Mojo::SQLite' if $self->via eq 'sqlite';
209              
210             # Only for SQLite
211 1 50       7 if ($self->via eq 'sqlite') {
212 1         7 $self->dir($self->home->child(qw(t db)));
213 1         100 $self->dsn('sqlite:' . $self->dir . '/csa_test.db');
214             }
215              
216             # Load Class for backend database type
217 1         21 my $load = load_class $backend;
218 1 0       193502 croak ref $load ? $load : qq{Backend "$backend" missing} if $load;
    50          
219 1         8 $self->backend($backend->new($self->dsn));
220              
221 1         3541 return $self;
222             }
223             1;
224              
225             =encoding utf8
226              
227             =head1 NAME
228              
229             CellBIS::SQL::Abstract::Test - A part of Unit Testing
230              
231             =head1 SYNOPSIS
232              
233             use CellBIS::SQL::Abstract::Test;
234            
235             # Initialization for SQLite
236             my $test = CellBIS::SQL::Abstract::Test->new(table => 'users');
237             unless (-d $test->dir) { mkdir $test->dir }
238            
239             $backend = $test->backend;
240             $db = $backend->db;
241             ok $db->ping, 'connected';
242            
243             # Initialization for MariaDB
244             my $test = CellBIS::SQL::Abstract::Test->new(
245             table => 'users',
246             via => 'mariadb',
247             dsn => 'mariadb://myuser:mypass@localhost:3306/mydbtest'
248             );
249             $backend = $test->backend;
250             $db = $backend->db;
251             ok $db->ping, 'connected';
252            
253             # Initialization for PostgreSQL
254             my $test = CellBIS::SQL::Abstract::Test->new(
255             table => 'users',
256             via => 'pg',
257             dsn => 'posgresql://myuser:mypass@localhost:5432/mydbtest'
258             );
259             $backend = $test->backend;
260             $db = $backend->db;
261             ok $db->ping, 'connected';
262              
263             =head1 DESCRIPTION
264              
265             This module is only a test instrument in SQLite, Mariadb, and PostgreSQL
266              
267             =head1 ATTRIBUTES
268              
269             L implements the following attributes.
270              
271             =head2 table
272              
273             my $test = CellBIS::SQL::Abstract::Test->new(
274             ...
275             table => 'users',
276             ...
277             );
278            
279             $test->table('users'); # to defined table
280             $test->table; # to use get table
281              
282             Information of table form L
283              
284             =head2 via and dsn
285              
286             # initialization for mariadb
287             my $test = CellBIS::SQL::Abstract::Test->new(
288             ...
289             via => 'mariadb',
290             dsn => 'mariadb://myuser:mypass@localhost:3306/mydbtest',
291             ...
292             );
293            
294             # initialization for postgresql
295             my $test = CellBIS::SQL::Abstract::Test->new(
296             ...
297             via => 'pg',
298             dsn => 'posgresql://myuser:mypass@localhost:3306/mydbtest',
299             ...
300             );
301            
302             # switch to mariadb
303             $test->dsn('mariadb://myuser:mypass@localhost:3306/mydbtest');
304            
305             # switch to postgresql
306             $test->dsn('posgresql://myuser:mypass@localhost:5432/mydbtest');
307            
308             C attribute must be defined together with C attribute when
309             initializing mariadb or postgresql. However, when initializing using
310             sqlite, you don't need to use the C and C (Data Source Name)
311             attributes.
312              
313             =head2 backend
314              
315             $test->backend;
316             $test->backend(Mojo::SQLite->new);
317             $test->backend(Mojo::mysq->new);
318             $test->backend(Mojo::Pg->new);
319              
320             C attribute only for initializing L, L,
321             and L.
322              
323             =head1 METHODS
324              
325             L implements the following new ones
326              
327             =head2 change_dbms
328              
329             This method for change dbms from one to the other. For example from
330             sqlite to mariadb or from mariadb to sqlite and vice versa.
331              
332             # switch to mariadb
333             $test->dsn('mariadb://myuser:mypass@localhost:3306/mydbtest');
334             $test->change_dbms('mariadb');
335            
336             # switch to postgresql
337             $test->dsn('postgresql://myuser:mypass@localhost:5432/mydbtest');
338             $test->change_dbms('pg');
339            
340             # switch back to sqlite
341             $test->change_dbms('sqlite');
342             unless (-d $test->dir) { mkdir $test->dir }
343              
344             =head2 methods for tables query
345              
346             The method here is to query tables, such as check, create, empty, and drop tables.
347              
348             $test->check_table;
349             $test->create_table;
350             $test->create_table_with_fk;
351             $test->empty_table;
352             $test->drop_table;
353            
354             # if use key hashref 'result'
355             $test->check_table->{result};
356             $test->create_table->{result};
357             $test->create_table_with_fk->{result};
358             $test->empty_table->{result};
359             $test->drop_table->{result};
360            
361             # if use key hashref 'code'
362             $test->check_table->{code};
363             $test->create_table->{code};
364             $test->create_table_with_fk->{code};
365             $test->empty_table->{code};
366             $test->drop_table->{code};
367              
368             The output of this method is a hashref and contains key C and C.
369              
370             =head1 AUTHOR
371              
372             Achmad Yusri Afandi, C
373              
374             =head1 COPYRIGHT AND LICENSE
375              
376             Copyright (C) 2021 by Achmad Yusri Afandi
377              
378             This program is free software, you can redistribute it and/or modify
379             it under the terms of the Artistic License version 2.0.
380              
381             =cut