File Coverage

blib/lib/Database/Temp/DB.pm
Criterion Covered Total %
statement 40 41 97.5
branch 5 10 50.0
condition n/a
subroutine 11 11 100.0
pod 1 3 33.3
total 57 65 87.6


line stmt bran cond sub pod time code
1             package Database::Temp::DB;
2             ## no critic (ControlStructures::ProhibitPostfixControls)
3              
4 5     5   180002 use strict;
  5         12  
  5         196  
5 5     5   31 use warnings;
  5         10  
  5         426  
6              
7             # ABSTRACT: This class represents the created database to user
8              
9             our $VERSION = '0.003'; # VERSION: generated by DZP::OurPkgVersion
10              
11 5     5   9205 use DBI;
  5         130210  
  5         585  
12 5     5   77 use Carp qw( shortmess );
  5         13  
  5         360  
13              
14 5     5   5895 use Moo;
  5         46124  
  5         58  
15 5     5   12890 use Types::Standard qw( Str Int Bool HashRef CodeRef Maybe );
  5         754495  
  5         146  
16 5     5   22934 use Log::Any;
  5         50740  
  5         64  
17              
18             my $ENV_VAR_FOR_KEEPING_DB = 'DATABASE_TEMP_KEEP';
19              
20             has driver => (
21             is => 'ro',
22             isa => Str,
23             required => 1,
24             );
25              
26             has name => (
27             is => 'ro',
28             isa => Str,
29             required => 1,
30             );
31              
32             has cleanup => (
33             is => 'rw',
34             isa => Bool,
35             required => 1,
36             );
37              
38             has init => (
39             is => 'ro',
40             isa => CodeRef,
41             required => 1,
42             );
43              
44             has deinit => (
45             is => 'rw',
46             isa => CodeRef,
47             required => 1,
48             );
49              
50             # Connection info
51             has dsn => (
52             is => 'ro',
53             isa => Str,
54             required => 1,
55             );
56             has username => (
57             is => 'ro',
58             isa => Maybe [Str],
59             required => 1,
60             );
61             has password => (
62             is => 'ro',
63             isa => Maybe [Str],
64             required => 1,
65             );
66             has attr => (
67             is => 'ro',
68             isa => HashRef,
69             required => 1,
70             );
71              
72             has info => (
73             is => 'ro',
74             isa => HashRef,
75             required => 1,
76             );
77              
78             sub BUILD {
79 8     8 0 59563 my ($self) = @_;
80 8         56 $self->_execute( $self->_start );
81 8         54 $self->_execute( $self->init );
82 8         162 return;
83             }
84              
85             sub DEMOLISH {
86 8     8 0 84384 my ( $self, $in_global_destruction ) = @_;
87 8         96 my $_log = Log::Any->get_logger( category => 'Database::Temp' );
88              
89 8         2973 $self->_execute( $self->deinit );
90 8 50       387 if ( defined $ENV{$ENV_VAR_FOR_KEEPING_DB} ) {
    100          
91 0 0       0 $_log->infof( 'Env var %s set. Keeping temp db', $ENV_VAR_FOR_KEEPING_DB ) if ( !$in_global_destruction );
92             }
93             elsif ( $self->cleanup ) {
94 6 50       99 $_log->debugf('Cleanup set. Deleting temp db') if ( !$in_global_destruction );
95 6         67 $self->_execute( $self->_cleanup );
96             }
97             else {
98 2 50       67 $_log->debugf('Cleanup not set. Keeping temp db') if ( !$in_global_destruction );
99             }
100 8         296 return;
101             }
102              
103             sub _execute {
104 30     30   144 my ( $self, $sub ) = @_;
105 30         84 my $dbh = DBI->connect( $self->connection_info );
106 30         27476 $sub->( $dbh, $self->name, $self->info, $self->driver );
107 30         38026 $dbh->disconnect();
108 30         1191 return $self;
109             }
110              
111             has _start => (
112             is => 'ro',
113             isa => CodeRef,
114             required => 1,
115             );
116             has _cleanup => (
117             is => 'ro',
118             isa => CodeRef,
119             required => 1,
120             );
121              
122             sub connection_info {
123 37     37 1 154552 my ($self) = @_;
124 37         396 return ( $self->dsn, $self->username, $self->password, $self->attr );
125             }
126              
127             1;
128              
129             __END__
130              
131             =pod
132              
133             =encoding UTF-8
134              
135             =head1 NAME
136              
137             Database::Temp::DB - This class represents the created database to user
138              
139             =head1 VERSION
140              
141             version 0.003
142              
143             =head1 SYNOPSIS
144              
145             my $db = Database::Temp->new(
146             driver => 'SQLite',
147             );
148             my $dbh = $db->dbh;
149             my $rows = $dbh->selectall_arrayref(
150             "SELECT 1, 1+2",
151             );
152              
153             =head1 DESCRIPTION
154              
155             The end user should never create this class directly.
156             Database::Temp uses this class to create an object
157             which represents the database just created
158             by Database::Temp.
159              
160             This class, when instantiated into an object,
161             contains everything user needs
162             to access the created temporary database,
163             regardless of it database engine.
164              
165             =for Pod::Coverage ^(BUILD|DEMOLISH)$
166              
167             =head1 METHODS
168              
169             =head2 driver
170              
171             The short name of the L<Database::Temp> driver,
172             for example, in the case of L<Database::Temp::Driver::SQLite>
173             the value would be B<SQLite>. Read-only.
174              
175             =head2 name
176              
177             Name of the database. Read-only.
178              
179             =head2 cleanup
180              
181             A boolean variable. Do we do cleanup?
182             Depends on the DB driver what cleanup would be,
183             e.g. in the case of SQLite, cleanup means erasing the database file.
184             In the case of Postgres, cleanup would be dropping the database.
185              
186             User can change this value.
187             Value 1 means cleanup will be done, value 0 means
188             no cleanup.
189              
190             Default value is true: database will be erased when this
191             object drops out of the scope.
192              
193             =head2 init
194              
195             Reference to the subroutine which is executed
196             immediately after database creation. Therefore,
197             this action has already been executed
198             by the time user gets hold of this object.
199             Read-only.
200              
201             =head2 deinit
202              
203             Reference to the subroutine which is executed
204             immediately before database is demolished.
205             User can change this value.
206             Default value is pointer to an empty subroutine.
207              
208             =head2 dsn
209              
210             =head2 username
211              
212             =head2 password
213              
214             =head2 attr
215              
216             These four fields are required to make a connection
217             to a database. Read-only.
218              
219             B<dsn>, B<username> and B<password> are strings.
220             B<attr> is a hashref.
221              
222             Most likely user would not use these directly,
223             but instead use the method C<connection_info>.
224             See below.
225              
226             =head2 info
227              
228             This field can contain other related information which
229             is not required for establishing connection and creating
230             a database handle, but which can be useful to the user or
231             required by the driver when doing cleanup. Read-only.
232              
233             =head2 connection_info
234              
235             This method returns a list of connection information details
236             which can be fed directly into C<DBI->connect()> method.
237              
238             my $dbh = DBI->connect( $temp_db->connection_info );
239              
240             =head1 AUTHOR
241              
242             Mikko Koivunalho <mikkoi@cpan.org>
243              
244             =head1 COPYRIGHT AND LICENSE
245              
246             This software is copyright (c) 2023 by Mikko Johannes Koivunalho.
247              
248             This is free software; you can redistribute it and/or modify it under
249             the same terms as the Perl 5 programming language system itself.
250              
251             =cut