File Coverage

blib/lib/DBIx/Squirrel/db.pm
Criterion Covered Total %
statement 95 172 55.2
branch 33 90 36.6
condition 1 3 33.3
subroutine 20 26 76.9
pod 0 6 0.0
total 149 297 50.1


line stmt bran cond sub pod time code
1 9     9   58 use strict;
  9         19  
  9         363  
2 9     9   40 no strict 'subs'; ## no critic
  9         19  
  9         310  
3 9     9   37 use warnings;
  9         17  
  9         467  
4 9     9   160 use 5.010_001;
  9         27  
5              
6             package # hide from PAUSE
7             DBIx::Squirrel::db;
8              
9 9     9   64 use DBI;
  9         15  
  9         448  
10 9     9   42 use Sub::Name 'subname';
  9         13  
  9         558  
11 9         702 use Try::Tiny qw(
12             try
13             catch
14             finally
15 9     9   4520 );
  9         13892  
16 9     9   4208 use DBIx::Squirrel::st 'statement_study';
  9         78  
  9         861  
17 9         650 use DBIx::Squirrel::util qw(
18             carpf
19             confessf
20             get_file_contents
21 9     9   125 );
  9         148  
22 9     9   55 use namespace::clean;
  9         17  
  9         45  
23              
24 9     9   3000 use constant E_EXP_REF => 'Expected a reference to a HASH or ARRAY';
  9         21  
  9         567  
25 9     9   53 use constant E_EXP_STATEMENT => 'Expected a statement';
  9         17  
  9         860  
26              
27             BEGIN {
28             require DBIx::Squirrel
29 9 50   9   51 unless keys %DBIx::Squirrel::;
30 9         78 *DBIx::Squirrel::db::VERSION = *DBIx::Squirrel::VERSION;
31 9         11939 @DBIx::Squirrel::db::ISA = 'DBI::db';
32             }
33              
34             sub _root_class {
35 16   33 16   53 my $root_class = ref $_[0] || $_[0];
36 16         150 $root_class =~ s/::\w+$//;
37 16 50       90 return wantarray ? ( RootClass => $root_class ) : $root_class;
38             }
39              
40             sub _private_state {
41 8     8   385 my $self = shift;
42 8 100       43 $self->{private_ekorn} = {} unless defined $self->{private_ekorn};
43 8 100       17 unless (@_) {
44 5 100       31 return $self->{private_ekorn}, $self if wantarray;
45 2         15 return $self->{private_ekorn};
46             }
47 3 100       4 unless ( defined $_[0] ) {
48 1         18 delete $self->{private_ekorn};
49 1         2 shift;
50             }
51 3 100       5 if (@_) {
52 2 50       6 $self->{private_ekorn} = {} unless defined $self->{private_ekorn};
53 2 100       46 if ( UNIVERSAL::isa( $_[0], 'HASH' ) ) {
54 1         2 $self->{private_ekorn} = { %{ $self->{private_ekorn} }, %{ $_[0] } };
  1         5  
  1         12  
55             }
56             else {
57 1         1 $self->{private_ekorn} = { %{ $self->{private_ekorn} }, @_ };
  1         8  
58             }
59             }
60 3         16 return $self;
61             }
62              
63             sub prepare {
64 16     16 0 40 my $self = shift;
65 16         25 my $statement = shift;
66 16 100       96 if ( UNIVERSAL::isa( $statement, 'CODE' ) ) {
67 3         11 $statement = $statement->();
68             }
69 16 100       70 if ( UNIVERSAL::isa( $statement, 'ARRAY' ) ) {
70 4         8 $statement = join ' ', @{$statement};
  4         15  
71             }
72             my(
73 16         81 $placeholders,
74             $normalised_statement,
75             $original_statement,
76             $digest,
77             ) = statement_study($statement);
78 16 50       39 confessf E_EXP_STATEMENT
79             unless defined $normalised_statement;
80 16 50       134 my $sth = DBI::db::prepare( $self, $normalised_statement, @_ )
81             or confessf $DBI::errstr;
82 16         1823 $sth = bless $sth, $self->_root_class . '::st';
83 16         165 $sth->_private_state( {
84             Placeholders => $placeholders,
85             NormalisedStatement => $normalised_statement,
86             OriginalStatement => $original_statement,
87             Hash => $digest,
88             } );
89 16         61 return $sth;
90             }
91              
92             sub prepare_cached {
93 0     0 0 0 my $self = shift;
94 0         0 my $statement = shift;
95 0 0       0 if ( UNIVERSAL::isa( $statement, 'CODE' ) ) {
96 0         0 $statement = $statement->();
97             }
98 0 0       0 if ( UNIVERSAL::isa( $statement, 'ARRAY' ) ) {
99 0         0 $statement = join ' ', @{$statement};
  0         0  
100             }
101             my(
102 0         0 $placeholders,
103             $normalised_statement,
104             $original_statement,
105             $digest,
106             ) = statement_study($statement);
107 0 0       0 confessf E_EXP_STATEMENT
108             unless defined $normalised_statement;
109 0 0       0 my $sth = DBI::db::prepare_cached( $self, $normalised_statement, @_ )
110             or confessf $DBI::errstr;
111 0         0 $sth = bless $sth, $self->_root_class . '::st';
112 0         0 $sth->_private_state( {
113             Placeholders => $placeholders,
114             NormalisedStatement => $normalised_statement,
115             OriginalStatement => $original_statement,
116             Hash => $digest,
117             CacheKey => join( '#', ( caller 0 )[ 1, 2 ] ),
118             } );
119 0         0 return $sth;
120             }
121              
122             sub do {
123 0     0 0 0 my $self = shift;
124 0         0 my $statement = shift;
125 0         0 my $sth = do {
126 0 0       0 if (@_) {
127 0 0       0 if ( ref $_[0] ) {
128 0 0       0 if ( UNIVERSAL::isa( $_[0], 'HASH' ) ) {
    0          
129 0         0 my $statement_attributes = shift;
130 0         0 $self->prepare( $statement, $statement_attributes );
131             }
132             elsif ( UNIVERSAL::isa( $_[0], 'ARRAY' ) ) {
133 0         0 $self->prepare($statement);
134             }
135             else {
136 0         0 confessf E_EXP_REF;
137             }
138             }
139             else {
140 0 0       0 if ( defined $_[0] ) {
141 0         0 $self->prepare($statement);
142             }
143             else {
144 0         0 shift;
145 0         0 $self->prepare( $statement, undef );
146             }
147             }
148             }
149             else {
150 0         0 $self->prepare($statement);
151             }
152             };
153 0 0       0 return wantarray ? ( $sth->execute(@_), $sth ) : $sth->execute(@_);
154             }
155              
156             sub iterate {
157 2     2 0 3 my $self = shift;
158 2         3 my $statement = shift;
159 2         3 my $sth = do {
160 2 100       5 if (@_) {
161 1 50       2 if ( ref $_[0] ) {
162 1 50       7 if ( UNIVERSAL::isa( $_[0], 'HASH' ) ) {
    50          
    50          
163 0         0 my $statement_attributes = shift;
164 0         0 $self->prepare( $statement, $statement_attributes );
165             }
166             elsif ( UNIVERSAL::isa( $_[0], 'ARRAY' ) ) {
167 0         0 $self->prepare($statement);
168             }
169             elsif ( UNIVERSAL::isa( $_[0], 'CODE' ) ) {
170 1         59 $self->prepare($statement);
171             }
172             else {
173 0         0 confessf E_EXP_REF;
174             }
175             }
176             else {
177 0 0       0 if ( defined $_[0] ) {
178 0         0 $self->prepare($statement);
179             }
180             else {
181 0         0 shift;
182 0         0 $self->prepare( $statement, undef );
183             }
184             }
185             }
186             else {
187 1         3 $self->prepare($statement);
188             }
189             };
190 2         7 return $sth->iterate(@_);
191             }
192              
193             BEGIN {
194 9     9   168 *iterator = subname( iterator => \&iterate );
195 9         71 *itor = subname( itor => \&iterate );
196 9         2746 *it = subname( it => \&iterate );
197             }
198              
199             sub results {
200 2     2 0 5 my $self = shift;
201 2         3 my $statement = shift;
202 2         3 my $sth = do {
203 2 100       5 if (@_) {
204 1 50       3 if ( ref $_[0] ) {
205 1 50       9 if ( UNIVERSAL::isa( $_[0], 'HASH' ) ) {
    50          
    50          
206 0         0 my $statement_attributes = shift;
207 0         0 $self->prepare( $statement, $statement_attributes );
208             }
209             elsif ( UNIVERSAL::isa( $_[0], 'ARRAY' ) ) {
210 0         0 $self->prepare($statement);
211             }
212             elsif ( UNIVERSAL::isa( $_[0], 'CODE' ) ) {
213 1         4 $self->prepare($statement);
214             }
215             else {
216 0         0 confessf E_EXP_REF;
217             }
218             }
219             else {
220 0 0       0 if ( defined $_[0] ) {
221 0         0 $self->prepare($statement);
222             }
223             else {
224 0         0 shift;
225 0         0 $self->prepare( $statement, undef );
226             }
227             }
228             }
229             else {
230 1         5 $self->prepare($statement);
231             }
232             };
233 2         28 return $sth->results(@_);
234             }
235              
236             BEGIN {
237 9     9   110 *resultset = subname( resultset => \&results );
238 9         71 *rset = subname( rset => \&results );
239 9         5051 *rs = subname( rs => \&results );
240             }
241              
242             sub load_tuples {
243 0     0 0   my $self = shift;
244 0           my $filename = shift;
245 0 0         my $tuples = get_file_contents($filename) or die "No data!";
246 0 0         return $tuples unless @_;
247 0           my $func = shift;
248             my $opts = {
249             disconnect => !!0,
250             progress => !!1,
251 0 0         %{ shift || {} },
  0            
252             };
253             try {
254 0     0     my( $before, $percent, $count, $length );
255 0 0         if ( $opts->{progress} ) {
256 0           $before = $percent = $count = 0;
257 0           $length = scalar @{$tuples};
  0            
258 0           printf STDERR 'Progress %3d%% ', $percent;
259             }
260 0           for my $tuple ( @{$tuples} ) {
  0            
261 0           $func->( @{$tuple} );
  0            
262 0 0         if ( $opts->{progress} ) {
263 0           $count += 1;
264 0           $percent = int( $count / $length * 100 );
265 0 0         if ( $percent > $before ) {
266 0           $before = $percent;
267 0           print STDERR "\b\b\b\b\b";
268 0           printf STDERR '%3d%% ', $percent;
269             }
270             }
271             }
272 0 0         $self->commit() unless $self->{AutoCommit};
273             }
274             catch {
275 0     0     carpf("$_\n");
276 0 0         unless ( $self->{AutoCommit} ) {
277 0           $self->rollback();
278 0           print STDERR "Database transaction was rolled back";
279             }
280             }
281             finally {
282 0 0   0     $self->disconnect() if $opts->{disconnect};
283 0 0         print STDERR "\n" if $opts->{progress};
284             }
285 0           }
286              
287             1;