File Coverage

blib/lib/Database/Temp.pm
Criterion Covered Total %
statement 62 69 89.8
branch 17 26 65.3
condition n/a
subroutine 15 15 100.0
pod 3 3 100.0
total 97 113 85.8


line stmt bran cond sub pod time code
1             package Database::Temp;
2             ## no critic (ControlStructures::ProhibitPostfixControls)
3              
4 5     5   1074848 use strict;
  5         11  
  5         206  
5 5     5   38 use warnings;
  5         8  
  5         335  
6              
7             # ABSTRACT: Create an ad-hoc database which drops itself automatically
8              
9             our $VERSION = '0.003'; # VERSION: generated by DZP::OurPkgVersion
10              
11 5     5   2299 use Module::Load qw( load );
  5         7090  
  5         32  
12 5     5   349 use Carp qw{ croak };
  5         26  
  5         318  
13              
14 5     5   2413 use UUID::Tiny qw{ create_uuid_as_string UUID_V1 };
  5         131620  
  5         638  
15 5     5   2872 use Data::GUID;
  5         108914  
  5         36  
16 5     5   2302 use Const::Fast;
  5         6133  
  5         45  
17 5     5   2832 use Try::Tiny;
  5         10101  
  5         333  
18              
19 5     5   2364 use Database::Temp::DB ();
  5         25  
  5         5125  
20              
21             const my $SHORT_UUID_LEN => 8;
22             const my $DEFAULT_BASENAME => 'database_temp_';
23             const my $DEFAULT_CLEANUP => 1;
24             const my $DEFAULT_INIT_METHOD => sub { };
25             const my $DEFAULT_DEINIT_METHOD => sub { };
26              
27             sub new {
28 6     6 1 30608 my ( $class, %params ) = @_;
29              
30             # Load driver module
31 6         35 my $driver_module = _driver_module( $params{'driver'} );
32 6         42 load $driver_module;
33              
34 6 50       669 if ( !$driver_module->is_available() ) {
35 0         0 croak "Driver $driver_module not available";
36             }
37              
38             # Create db name
39 6         23 my $basename = $DEFAULT_BASENAME;
40 6 100       29 if ( defined $params{'basename'} ) {
41 0         0 croak "Invalid temp database basename '${ \$params{'basename'} }'"
42 1 50       10 unless $params{'basename'} =~ m/[[:alnum:]_]{1,}/msx;
43 1         3 $basename = $params{'basename'};
44             }
45 6         24 my $name = $basename . random_name();
46 6 100       1294 if ( defined $params{'name'} ) {
47 1         4 $name = $basename . $params{'name'};
48             }
49              
50 6         20 my $cleanup = $DEFAULT_CLEANUP;
51 6 50       24 if ( defined $params{'cleanup'} ) {
52 0         0 croak "Invalid value for parameter cleanup '${ \$params{'cleanup'} }'"
53 0 0       0 unless $params{'cleanup'} =~ m/^[10]$/msx;
54 0         0 $cleanup = $params{'cleanup'};
55             }
56              
57 6         16 my $init = $DEFAULT_INIT_METHOD;
58 6 100       22 if ( defined $params{'init'} ) {
59 2 50       21 croak if ( ref $params{'init'} !~ m/(?: SCALAR|CODE)/msx );
60 2         7 $init = $params{'init'};
61             }
62 6         12 my $deinit = $DEFAULT_DEINIT_METHOD;
63 6 50       20 if ( defined $params{'deinit'} ) {
64 0 0       0 croak if ( ref $params{'deinit'} !~ m/(?: SCALAR|CODE)/msx );
65 0         0 $deinit = $params{'deinit'};
66             }
67              
68 6 100       28 my $args = defined $params{'args'} ? $params{'args'} : {};
69              
70 6         83 return $driver_module->new(
71             name => $name,
72             cleanup => $cleanup,
73             init => $init,
74             deinit => $deinit,
75             args => $args,
76             );
77             }
78              
79             sub is_available {
80 8     8 1 1726943 my ( $class, %params ) = @_;
81              
82 8 100       49 return 0 if ( !$params{'driver'} );
83              
84             # Load driver module
85 6         31 my $driver_module = _driver_module( $params{'driver'} );
86 6         14 my $can_load;
87             try {
88 6     6   444 load $driver_module;
89 5         30993 $can_load = 1;
90 5         24 1;
91             }
92             catch {
93 1     1   714 $can_load = 0;
94 6         87 };
95 6 100       207 return 0 if ( !$can_load );
96              
97 5         47 return $driver_module->is_available();
98             }
99              
100             sub _driver_module {
101 12     12   34 return "${ \__PACKAGE__ }::Driver::$_[0]";
  12         57  
102             }
103              
104             sub random_name {
105 6     6 1 82 return ( substr Data::GUID->new, 0, $SHORT_UUID_LEN );
106             }
107              
108             1;
109              
110             __END__
111              
112             =pod
113              
114             =encoding UTF-8
115              
116             =head1 NAME
117              
118             Database::Temp - Create an ad-hoc database which drops itself automatically
119              
120             =head1 VERSION
121              
122             version 0.003
123              
124             =head1 SYNOPSIS
125              
126             use DBI;
127             my $db = Database::Temp->new(
128             driver => 'SQLite',
129             );
130             my $dbh = DBI->connect( $db->connection_info );
131             my $rows = $dbh->selectall_arrayref(
132             "SELECT 1, 1+2",
133             );
134              
135             =head1 DESCRIPTION
136              
137             With Database::Temp you can quickly create a temporary database
138             and be sure it gets removed automatically when your reference to it
139             is deleted, normally when the scope ends.
140              
141             =head2 new
142              
143             Create a temporary database.
144              
145             =head3 Parameters
146              
147             =over 8
148              
149             =item driver
150              
151             Available drivers: SQLite. No default value.
152              
153             =item basename
154              
155             =item name
156              
157             The full name of a database consists of two parts:
158             basename and name. By default the basename is "database_temp_"
159             and name is a random string of eight letters and numbers.
160             You can change both of these if you need to.
161              
162             =item cleanup
163              
164             Remove database after use. Default: 1.
165              
166             =item init
167              
168             =item deinit
169              
170             Pointer to an initializing subroutine or just a SQL script.
171              
172             =item args
173              
174             Special arguments for the creation of the database.
175             These are mentioned separately in the equivalent driver documentation.
176              
177             =back
178              
179             =head2 is_available
180              
181             Confirm a driver is available and it can
182             create a temporary database.
183              
184             Return boolean
185              
186             =head3 Parameters
187              
188             =over 8
189              
190             =item driver
191              
192             Available drivers: SQLite. No default value.
193              
194             =back
195              
196             =head2 random_name
197              
198             Generate a random name. A string of 8 random letters and characters.
199              
200             =head1 STATUS
201              
202             This module is currently being developed so changes in the API are possible.
203              
204             =head1 AUTHOR
205              
206             Mikko Koivunalho <mikkoi@cpan.org>
207              
208             =head1 COPYRIGHT AND LICENSE
209              
210             This software is copyright (c) 2023 by Mikko Johannes Koivunalho.
211              
212             This is free software; you can redistribute it and/or modify it under
213             the same terms as the Perl 5 programming language system itself.
214              
215             =cut