File Coverage

blib/lib/Zonemaster/Backend/DB/SQLite.pm
Criterion Covered Total %
statement 76 107 71.0
branch 15 32 46.8
condition 0 3 0.0
subroutine 15 20 75.0
pod 0 13 0.0
total 106 175 60.5


line stmt bran cond sub pod time code
1             package Zonemaster::Backend::DB::SQLite;
2              
3             our $VERSION = '1.1.0';
4              
5 2     2   35 use Moose;
  2         4  
  2         12  
6 2     2   11291 use 5.14.2;
  2         7  
7              
8 2     2   11 use DBI qw(:utils);
  2         3  
  2         341  
9 2     2   39 use JSON::PP;
  2         5  
  2         119  
10 2     2   11 use Digest::MD5 qw(md5_hex);
  2         7  
  2         71  
11              
12 2     2   11 use Zonemaster::Backend::Config;
  2         4  
  2         2111  
13              
14             with 'Zonemaster::Backend::DB';
15              
16             my $connection_string = Zonemaster::Backend::Config->DB_connection_string( 'sqlite' );
17              
18             has 'dbh' => (
19             is => 'ro',
20             isa => 'DBI::db',
21             default => sub { DBI->connect( $connection_string, { RaiseError => 1, AutoCommit => 1 } ) },
22             );
23              
24             sub DEMOLISH {
25 2     2 0 6 my ( $self ) = @_;
26 2 50       118 $self->dbh->disconnect() if $self->dbh;
27             }
28              
29             sub create_db {
30 1     1 0 519 my ( $self ) = @_;
31              
32             ####################################################################
33             # TEST RESULTS
34             ####################################################################
35 1 50       50 $self->dbh->do( 'DROP TABLE IF EXISTS test_specs' ) or die "SQLite Fatal error: " . $self->dbh->errstr();
36              
37 1 50       483 $self->dbh->do( 'DROP TABLE IF EXISTS test_results' ) or die "SQLite Fatal error: " . $self->dbh->errstr();
38              
39 1 50       84 $self->dbh->do(
40             'CREATE TABLE test_results (
41             id integer PRIMARY KEY AUTOINCREMENT,
42             batch_id integer NULL,
43             creation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
44             test_start_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
45             test_end_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
46             priority integer DEFAULT 10,
47             queue integer DEFAULT 0,
48             progress integer DEFAULT 0,
49             params_deterministic_hash character varying(32),
50             params text NOT NULL,
51             results text DEFAULT NULL
52             )
53             '
54             ) or die "SQLite Fatal error: " . $self->dbh->errstr();
55              
56             ####################################################################
57             # BATCH JOBS
58             ####################################################################
59 1 50       7804 $self->dbh->do( 'DROP TABLE IF EXISTS batch_jobs' ) or die "SQLite Fatal error: " . $self->dbh->errstr();
60              
61 1 50       155 $self->dbh->do(
62             'CREATE TABLE batch_jobs (
63             id integer PRIMARY KEY,
64             username character varying(50) NOT NULL,
65             creation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
66             )
67             '
68             ) or die "SQLite Fatal error: " . $self->dbh->errstr();
69              
70             ####################################################################
71             # USERS
72             ####################################################################
73 1         9527 $self->dbh->do( 'DROP TABLE IF EXISTS users' );
74 1 50       186 $self->dbh->do(
75             'CREATE TABLE users (
76             id integer primary key,
77             user_info json DEFAULT NULL
78             )
79             '
80             ) or die "SQLite Fatal error: " . $self->dbh->errstr();
81              
82 1         10046 return 1;
83             }
84              
85             sub user_exists_in_db {
86 1     1 0 3 my ( $self, $user ) = @_;
87 1         3 my $user_id;
88              
89 1         50 my $href = $self->dbh->selectall_hashref( "SELECT * FROM users", 'id' );
90 1         403 foreach my $id ( keys %$href ) {
91 0         0 my $user_info = decode_josn( $href->{$id}->{user_info} );
92 0 0       0 $user_id = $id if ( $user_info->{username} eq $user );
93             }
94              
95 1         9 return $user_id;
96             }
97              
98             sub add_api_user_to_db {
99 1     1 0 5 my ( $self, $user_name, $api_key ) = @_;
100              
101 1         52 my $dbh = $self->dbh;
102 1         8 my $nb_inserted = $dbh->do( "INSERT INTO users (user_info) VALUES (?)", undef, encode_json( { username => $user_name, api_key => $api_key } ) );
103              
104 1         10499 return $nb_inserted;
105             }
106              
107             sub user_authorized {
108 0     0 0 0 my ( $self, $user, $api_key ) = @_;
109              
110 0         0 my $user_id;
111              
112 0         0 my $href = $self->dbh->selectall_hashref( "SELECT * FROM users", 'id' );
113 0         0 foreach my $id ( keys %$href ) {
114 0         0 my $user_info = decode_josn( $href->{$id}->{user_info} );
115 0 0 0     0 if ( $user_info->{username} eq $user && $user_info->{api_key} eq $api_key ) {
116 0         0 $user_id = $id;
117             }
118             }
119              
120 0         0 return $user_id;
121             }
122              
123             sub create_new_batch_job {
124 0     0 0 0 my ( $self, $username ) = @_;
125              
126 0         0 my ( $batch_id, $creaton_time ) = $self->dbh->selectrow_array( "
127             SELECT
128             batch_id,
129             batch_jobs.creation_time AS batch_creation_time
130             FROM
131             test_results
132             JOIN batch_jobs
133             ON batch_id=batch_jobs.id
134             AND username=" . $self->dbh->quote( $username ) . " WHERE
135             test_results.progress<>100
136             LIMIT 1
137             " );
138              
139 0 0       0 die "You can't create a new batch job, job:[$batch_id] started on:[$creaton_time] still running " if ( $batch_id );
140              
141 0         0 my ( $new_batch_id ) = $self->dbh->selectrow_array(
142             "INSERT INTO batch_jobs (username) VALUES(" . $self->dbh->quote( $username ) . ") RETURNING id" );
143              
144 0         0 return $new_batch_id;
145             }
146              
147             sub create_new_test {
148 2     2 0 11 my ( $self, $domain, $test_params, $minutes_between_tests_with_same_params, $batch_id ) = @_;
149 2         4 my $result;
150              
151 2         3 my $priority = 10;
152 2 50       9 $priority = $test_params->{priority} if (defined $test_params->{priority});
153            
154 2         7 my $queue = 0;
155 2 50       10 $queue = $test_params->{queue} if (defined $test_params->{queue});
156              
157 2         6 $test_params->{domain} = $domain;
158 2         20 my $js = JSON::PP->new;
159 2         68 $js->canonical( 1 );
160 2         26 my $encoded_params = $js->encode( $test_params );
161 2         1329 my $test_params_deterministic_hash = md5_hex( $encoded_params );
162              
163 2         77 my $query =
164             "INSERT INTO test_results (batch_id, priority, queue, params_deterministic_hash, params) SELECT "
165             . $self->dbh->quote( $batch_id ) . ", "
166             . $self->dbh->quote( $priority ) . ", "
167             . $self->dbh->quote( $queue ) . ", "
168             . $self->dbh->quote( $test_params_deterministic_hash ) . ", "
169             . $self->dbh->quote( $encoded_params )
170             . " WHERE NOT EXISTS (SELECT * FROM test_results WHERE params_deterministic_hash='$test_params_deterministic_hash' AND creation_time > datetime('now', '-$minutes_between_tests_with_same_params minute'))";
171              
172 2         83 my $nb_inserted = $self->dbh->do( $query );
173              
174 2         17608 ( $result ) = $self->dbh->selectrow_array(
175             "SELECT MAX(id) AS id FROM test_results WHERE params_deterministic_hash='$test_params_deterministic_hash'" );
176              
177 2         628 return $result;
178             }
179              
180             sub test_progress {
181 124     124 0 763 my ( $self, $test_id, $progress ) = @_;
182              
183 124 100       4478 $self->dbh->do( "UPDATE test_results SET progress=$progress WHERE id=$test_id" ) if ( $progress );
184              
185 124         970998 my ( $result ) = $self->dbh->selectrow_array( "SELECT progress FROM test_results WHERE id=$test_id" );
186              
187 124         27937 return $result;
188             }
189              
190             sub get_test_params {
191 2     2 0 10 my ( $self, $test_id ) = @_;
192              
193 2         7 my $result;
194              
195 2         85 my ( $params_json ) = $self->dbh->selectrow_array( "SELECT params FROM test_results WHERE id=$test_id" );
196 2         230 eval { $result = decode_json( $params_json ); };
  2         19  
197 2 50       7648 die $@ if $@;
198              
199 2         11 return $result;
200             }
201              
202             sub test_results {
203 4     4 0 468475 my ( $self, $test_id, $results ) = @_;
204              
205 4 100       94 $self->dbh->do( "UPDATE test_results SET progress=100, test_end_time=datetime('now'), results = "
206             . $self->dbh->quote( $results )
207             . " WHERE id=$test_id " )
208             if ( $results );
209              
210 4         18202 my $result;
211 4         11 eval {
212 4         170 my ( $hrefs ) = $self->dbh->selectall_hashref( "SELECT * FROM test_results WHERE id=$test_id", 'id' );
213 4         1440 $result = $hrefs->{$test_id};
214 4         30 $result->{params} = decode_json( $result->{params} );
215 4         12620 $result->{results} = decode_json( $result->{results} );
216             };
217 4 50       673764 die $@ if $@;
218              
219 4         362 return $result;
220             }
221              
222             sub get_test_request {
223 0     0 0   my ( $self ) = @_;
224              
225 0           my ( $id ) = $self->dbh->selectrow_array(
226             q[ SELECT id FROM test_results WHERE progress=0 ORDER BY priority ASC, id ASC LIMIT 1 ] );
227 0           $self->dbh->do( q[UPDATE test_results SET progress=1 WHERE id=?], undef, $id );
228              
229 0           return $id;
230             }
231              
232             sub get_test_history {
233 0     0 0   my ( $self, $p ) = @_;
234              
235 0           my @results;
236 0           my $quoted_domain = $self->dbh->quote( $p->{frontend_params}->{domain} );
237 0           $quoted_domain =~ s/'/"/g;
238 0           my $query =
239             "SELECT id, creation_time, params FROM test_results WHERE params like '\%\"domain\":$quoted_domain\%' ORDER BY id DESC LIMIT $p->{limit} OFFSET $p->{offset} ";
240 0           my $sth1 = $self->dbh->prepare( $query );
241 0           $sth1->execute;
242 0           while ( my $h = $sth1->fetchrow_hashref ) {
243             push( @results,
244 0           { id => $h->{id}, creation_time => $h->{creation_time}, advanced_options => $h->{advanced_options} } );
245             }
246 0           $sth1->finish;
247              
248 0           return \@results;
249             }
250              
251             sub add_batch_job {
252 0     0 0   my ( $self, $params ) = @_;
253             }
254              
255 2     2   13 no Moose;
  2         4  
  2         10  
256             __PACKAGE__->meta()->make_immutable();
257              
258             1;