File Coverage

blib/lib/DBIx/Fast.pm
Criterion Covered Total %
statement 18 197 9.1
branch 0 42 0.0
condition 0 2 0.0
subroutine 6 27 22.2
pod 17 17 100.0
total 41 285 14.3


line stmt bran cond sub pod time code
1             package DBIx::Fast;
2              
3             =head1 NAME
4            
5             DBIx::Fast - DBI fast & easy (another one...)
6              
7             =cut
8              
9             our $VERSION = '0.07';
10              
11 1     1   13425 use strict;
  1         1  
  1         25  
12 1     1   3 use warnings FATAL => 'all';
  1         1  
  1         29  
13            
14             =head1 SYNOPSIS
15            
16             $db = DBIx::Fast->new( db => 'test' , user => 'test' , passwd => 'test');
17            
18             $db = DBIx::Fast->new( db => 'test' , user => 'test' , passwd => 'test', trace => '1' , profile => '!Statement:!MethodName' );
19            
20             $db = DBIx::Fast->new( dsn => 'dbi:mysql:database=test:127.0.0.1' , user => 'test', passwd => 'text');
21              
22             $hash = $db->hash('SELECT * FROM users WHERE id = ?',$id);
23              
24             $arrayref = $db->all('SELECT * FROM users');
25              
26             $db->insert( { user => 'test' } , table => 'users' , time => 'date_add' );
27              
28             $db->delete('test', { id => $db->last_id });
29              
30             Fast.. ?
31             $db->update('test',{ sen => { name => 'update t3st' }, where => { id => 1 } }, time => 'time' );
32              
33             $db->up('test', { name => 'update test' } , { id => 1 } );
34              
35             $db->last_sql
36              
37             $db->results
38              
39             =head1 DESCRIPTION
40              
41             =head1 SUBROUTINES/METHODS
42              
43             =cut
44              
45 1     1   3 use Carp;
  1         3  
  1         46  
46 1     1   508 use Moo;
  1         9534  
  1         4  
47 1     1   1613 use DBIx::Connector;
  1         17731  
  1         26  
48 1     1   421 use DateTime::Format::MySQL;
  1         105789  
  1         1577  
49              
50             has db => ( is => 'rw' );
51             has dbd => ( is => 'rwp');
52              
53             has errors => ( is => 'rwp');
54              
55             has last_sql => ( is => 'rw');
56             has last_id => ( is => 'rw');
57              
58             has sql => ( is => 'rw' );
59              
60             has p => ( is => 'rw' );
61              
62             has results => ( is => 'rw');
63              
64             =head2
65             Add error to the array
66             =cut
67             sub set_error {
68 0     0 1   my $self = shift;
69            
70 0           my $error = {
71             id => shift,
72             error => shift,
73             time => time()
74             };
75              
76 0           my $Errors = $self->errors;
77 0           push @{$Errors} ,$error;
  0            
78              
79 0           $self->_set_errors($Errors);
80             }
81              
82             =head2 BUILD
83             Build Moo
84             =cut
85             sub BUILD {
86 0     0 1   my ($self,$args) = @_;
87            
88             my $dbi_args = {
89             RaiseError => 0 // $args->{Error},
90             PrintError => 0 // $args->{PrintError},
91 0           AutoCommit => 1,
92             };
93              
94 0 0         my $dsn = $args->{dsn} ? $self->_check_dsn($args->{dsn}) : $self->_make_dsn($args);
95              
96             $self->db(DBIx::Connector->new( $dsn,
97             $args->{user}, $args->{passwd},
98 0           $dbi_args ));
99            
100 0           $self->db->mode('ping');
101              
102             $self->db->dbh->{HandleError} = sub {
103 0     0     $self->set_error($DBI::err,$DBI::errstr);
104 0           };
105              
106 0 0         $self->db->dbh->trace($args->{trace},'dbix-fast-trace') if $args->{trace};
107              
108 0 0         $self->profile($args->{profile}) if $args->{profile};
109             }
110              
111             =head2 check_dsn
112             Check DSN string
113             =cut
114             sub _check_dsn {
115 0     0     my $self = shift;
116 0           my $dsn = shift;
117              
118 0           my ($dbi,$server,$db,$host) = split ':', $dsn;
119              
120             #$self->_set_dbd(lc($server));
121            
122 0 0         if ( $server eq 'sqlite' ) {
123 0           $self->_set_dbd('sqlite');
124             } else {
125 0           $self->_set_dbd('mysql');
126             }
127            
128             }
129              
130             =head2 make_dsn
131             Make DSN string
132             =cut
133             sub _make_dsn {
134 0     0     my $self = shift;
135 0           my $args = shift;
136            
137 0 0         if ( $args->{host} =~ 'sqlite' ) {
138 0           $self->_set_dbd('sqlite');
139 0           return 'dbi:SQLite:'.$args->{db};
140             } else {
141 0           $self->_set_dbd('mysql');
142 0 0         $args->{host} = '127.0.0.1' unless $args->{host};
143 0           return 'dbi:mysql:database='.$args->{db}.':'.$args->{host};
144             }
145             }
146              
147             =head2 profile
148             Save profile log : dbix-fast--PID.log
149             =cut
150             sub profile {
151 0     0 1   my $self = shift;
152 0           my $stat = shift."/DBI::ProfileDumper/";
153              
154 0           $stat .= qq{File:dbix-fast-$$.log};
155              
156 0           $self->db->dbh->{Profile} = $stat;
157             }
158              
159             =head2 all
160             Execute a SQL sentence and return all data in arrayref
161             =cut
162             sub all {
163 0     0 1   my $self = shift;
164              
165 0           $self->q(@_);
166              
167             my $res = $self->db->dbh->selectall_arrayref($self->sql,
168 0           { Slice => {} },@{$self->p});
  0            
169              
170 0 0         $self->results($res) unless $DBI::err;
171             }
172              
173             =head2 hash
174             Execute a SQL sentence and return one hash
175             =cut
176             sub hash {
177 0     0 1   my $self = shift;
178              
179 0           $self->q(@_);
180              
181 0           my $sth = $self->db->dbh->prepare($self->sql);
182              
183 0           $sth->execute(@{$self->p});
  0            
184              
185 0           my $res = $sth->fetchrow_hashref;
186              
187 0 0         $self->results($res) unless $DBI::err;
188             }
189              
190             =head2 val
191             Return one value
192             =cut
193             sub val {
194 0     0 1   my $self = shift;
195              
196 0           $self->q(@_);
197              
198 0           return $self->db->dbh->selectrow_array($self->sql, undef, @{$self->p});
  0            
199             }
200              
201             =head2 array
202             Execute a SQL sentence and return array
203             =cut
204             sub array {
205 0     0 1   my $self = shift;
206              
207 0           $self->q(@_);
208              
209 0           my $sth = $self->db->dbh->prepare($self->sql);
210              
211 0           $sth->execute(@{$self->p});
  0            
212              
213 0 0         unless ( $DBI::err ) {
214 0           my @rows = @{ $self->db->dbh->selectcol_arrayref(
215 0           $self->sql, undef, @{ $self->p } ) };
  0            
216              
217 0           $self->results(\@rows);
218             }
219             }
220              
221             =head2 count
222             Return count from a table
223             =cut
224             sub count {
225 0     0 1   my $self = shift;
226 0           my $table = shift;
227 0           my $skeel = shift;
228              
229 0           $self->sql("SELECT COUNT(*) FROM $table");
230              
231 0 0         return $self->db->dbh->selectrow_array($self->sql)
232             unless $skeel;
233            
234 0           $self->_make_where($skeel);
235              
236 0           return $self->db->dbh->selectrow_array($self->sql, undef, @{$self->p});
  0            
237             }
238              
239             =head2 make_where
240              
241             =cut
242             sub _make_where {
243 0     0     my $self = shift;
244 0           my $skeel = shift;
245 0           my @p;
246              
247 0           my $sql = " WHERE ";
248              
249 0           for my $K ( keys %{$skeel} ) {
  0            
250 0           my $key;
251              
252 0 0         if ( ref $skeel->{$K} eq 'HASH' ) {
253 0           $key = (keys %{$skeel->{$K}})[0];
  0            
254 0           push @p,$skeel->{$K}->{$key};
255             } else {
256 0           $key = '=';
257 0           push @p,$skeel->{$K};
258             }
259              
260 0           $sql .= qq{$K $key ? };
261             }
262              
263 0           $sql =~ s/,$//;
264              
265 0           $self->sql($self->sql.$sql);
266 0           $self->p(\@p);
267             }
268              
269             =head2 execute
270             Execute SQL
271             =cut
272             sub execute {
273 0     0 1   my $self = shift;
274 0           my $sql = shift;
275 0           my $extra = shift;
276 0   0       my $type = shift // 'arrayref';
277 0           my $res;
278              
279 0           $self->sql($sql);
280              
281             ## Extra Arguments
282 0 0         $self->make_sen($extra) if $extra;
283              
284 0 0         if ( $type eq 'hash' ) {
285 0           my $sth = $self->db->dbh->prepare($self->sql);
286 0 0         if ( $self->p ) {
287 0           $sth->execute(@{$self->p});
  0            
288             } else {
289 0           $sth->execute;
290             }
291 0           $res = $sth->fetchrow_hashref;
292             } else {
293 0 0         if ($self->p ) {
294             $res = $self->db->dbh->selectall_arrayref($self->sql,
295 0           { Slice => {} },@{$self->p});
  0            
296             } else {
297 0           $res = $self->db->dbh->selectall_arrayref($self->sql,
298             { Slice => {} } );
299             }
300             }
301              
302 0 0         unless ( $DBI::err ) {
303 0           $self->results($res);
304             }
305              
306             }
307              
308             =head2 up
309             Update statment : up( table , data , where )
310             =cut
311             sub up {
312 0     0 1   my ($self,$table,$data,$where,$time) = @_;
313              
314 0           $self->update($table,{ sen => $data , where => $where } );
315             }
316              
317             =head2 update
318             Update statment
319             =cut
320             sub update {
321 0     0 1   my $self = shift;
322 0           my $table = shift;
323 0           my $skeel = shift;
324              
325 0 0         $skeel->{sen} = $self->extra_args($skeel->{sen},@_) if scalar @_ > 0;
326              
327 0           my @p;
328              
329 0           my $sql = "UPDATE $table SET ";
330              
331 0           for ( keys %{$skeel->{sen}} ) {
  0            
332 0           push @p,$skeel->{sen}->{$_};
333 0           $sql .= $_.' = ? ,';
334             }
335              
336 0           $sql =~ s/,$//;
337 0           $sql .= 'WHERE ';
338              
339 0           for my $K ( keys %{$skeel->{where}} ) {
  0            
340 0           push @p,$skeel->{where}->{$K};
341 0           $sql .= $K.' = ? ,';
342             }
343              
344 0           $sql =~ s/,$//;
345              
346 0           $self->sql($sql);
347 0           $self->execute_prepare(@p);
348             }
349              
350             =head2 insert
351             Insert data
352             =cut
353             sub insert {
354 0     0 1   my $self = shift;
355 0           my $table = shift;
356 0           my $skeel = shift;
357              
358 0 0         $skeel = $self->extra_args($skeel,@_) if scalar @_ > 0;
359              
360 0           my @p;
361              
362 0           my $sql= "INSERT INTO $table ( ";
363              
364 0           for ( keys %{$skeel} ) {
  0            
365 0           push @p,$skeel->{$_};
366 0           $sql .= $_.',';
367             }
368              
369 0           $sql =~ s/,$/ )/;
370 0           $sql .= ' VALUES ( '.join(',', ('?') x @p).' )';
371              
372 0           $self->sql($sql);
373 0           $self->execute_prepare(@p);
374              
375 0 0         if ( $self->dbd eq 'mysql' ) {
    0          
376 0           $self->last_id($self->db->dbh->{mysql_insertid});
377             } elsif ( $self->dbd eq 'sqlite' ) {
378 0           $self->last_id($self->db->dbh->sqlite_last_insert_rowid());
379             }
380              
381             }
382              
383             =head2 delete
384             Delete
385             =cut
386             sub delete {
387 0     0 1   my $self = shift;
388 0           my $table = shift;
389 0           my $skeel = shift;
390              
391 0           $self->sql("DELETE FROM $table");
392              
393             #unless ( $skeel ) {
394             # return $self->db->dbh->selectrow_array($self->sql);
395             #}
396              
397 0           $self->_make_where($skeel);
398              
399 0           my $sth = $self->db->dbh->prepare($self->sql);
400 0           $sth->execute(@{$self->p});
  0            
401             }
402              
403             =head2 extra_args
404             time : now time in mysql format
405             =cut
406             sub extra_args {
407 0     0 1   my $self = shift;
408 0           my $skeel = shift;
409 0           my %args = @_;
410              
411             $skeel->{$args{time}} = DateTime::Format::MySQL->format_datetime(DateTime->now)
412 0 0         if $args{time};
413              
414 0           return $skeel;
415             }
416              
417             =head2
418             FIXME : Hacer con execute_prepare
419             =cut
420             sub make_sen {
421 0     0 1   my $self = shift;
422 0           my $skeel = shift;
423 0           my $sql = $self->sql();
424 0           my @p;
425              
426             ## Ha de encontrar resultados por el orden de entrada parsear debidamente
427 0           for ( keys %{$skeel} ) {
  0            
428 0           my $arg = ':'.$_;
429 0           push @p,$skeel->{$_};
430 0           $sql =~ s/$arg/\?/;
431             }
432              
433 0           $sql =~ s/,$//;
434              
435 0           $self->sql($sql);
436 0           $self->p(\@p);
437             }
438              
439             =head2
440             Make query
441             =cut
442             sub q {
443 0     0 1   my $self = shift;
444 0           my $sql = shift;
445 0           my @p;
446              
447 0           map { push @p,$_ } @_;
  0            
448              
449 0           $self->sql($sql);
450 0           $self->p(\@p);
451             }
452              
453             =head2
454             Exute and prepare
455             =cut
456             sub execute_prepare {
457 0     0 1   my $self = shift;
458 0           my @p = @_;
459              
460 0           my $sth = $self->db->dbh->prepare($self->sql);
461              
462 0           $sth->execute(@p);
463              
464 0           $self->last_sql($self->sql);
465             }
466            
467             =head1 AUTHOR
468              
469              
470             =head1 BUGS
471              
472             Please report any bugs or feature requests to C, or through
473             the web interface at L. I will be notified, and then you'll
474             automatically be notified of progress on your bug as I make changes.
475              
476              
477             =head1 SUPPORT
478              
479             You can find documentation for this module with the perldoc command.
480              
481             perldoc DBIx::Fast
482              
483             You can also look for information at:
484              
485             =over 4
486              
487             =item * RT: CPAN's request tracker (report bugs here)
488              
489             L
490              
491             =item * AnnoCPAN: Annotated CPAN documentation
492              
493             L
494              
495             =item * CPAN Ratings
496              
497             L
498              
499             =item * Search CPAN
500              
501             L
502              
503             =back
504              
505              
506             =head1 ACKNOWLEDGEMENTS
507              
508              
509             =head1 LICENSE AND COPYRIGHT
510              
511             This program is free software; you can redistribute it and/or modify it
512             under the terms of the the Artistic License (2.0). You may obtain a
513             copy of the full license at:
514              
515             L
516              
517             Any use, modification, and distribution of the Standard or Modified
518             Versions is governed by this Artistic License. By using, modifying or
519             distributing the Package, you accept this license. Do not use, modify,
520             or distribute the Package, if you do not accept this license.
521              
522             If your Modified Version has been derived from a Modified Version made
523             by someone other than you, you are nevertheless required to ensure that
524             your Modified Version complies with the requirements of this license.
525              
526             This license does not grant you the right to use any trademark, service
527             mark, tradename, or logo of the Copyright Holder.
528              
529             This license includes the non-exclusive, worldwide, free-of-charge
530             patent license to make, have made, use, offer to sell, sell, import and
531             otherwise transfer the Package with respect to any patent claims
532             licensable by the Copyright Holder that are necessarily infringed by the
533             Package. If you institute patent litigation (including a cross-claim or
534             counterclaim) against any party alleging that the Package constitutes
535             direct or contributory patent infringement, then this Artistic License
536             to you shall terminate on the date that such litigation is filed.
537              
538             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
539             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
540             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
541             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
542             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
543             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
544             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
545             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
546              
547              
548             =cut
549              
550             1;