File Coverage

blib/lib/Tao/DBI/st.pm
Criterion Covered Total %
statement 14 63 22.2
branch 0 22 0.0
condition 0 3 0.0
subroutine 5 11 45.4
pod 1 4 25.0
total 20 103 19.4


line stmt bran cond sub pod time code
1              
2             package Tao::DBI::st;
3              
4 2     2   35 use 5.006;
  2         6  
5 2     2   10 use strict;
  2         2  
  2         43  
6 2     2   9 use warnings;
  2         4  
  2         157  
7              
8             require Exporter;
9              
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw();
12              
13             our $VERSION = '0.01';
14              
15 2     2   9 use Carp;
  2         4  
  2         1319  
16              
17             # the instance variables:
18             # DBH
19             # SQL
20             # PLACES, (the mapping between anonymous placholders and named placeholders)
21             # ARGNS (the current argument names)
22             # STMT
23             #
24             # NAME
25              
26             # creates a Tao::DBI::st object (the statement is
27             # prepared during initialization).
28             sub new {
29 0     0 0   my $proto = shift;
30 0   0       my $class = ref($proto) || $proto;
31 0           my $obj = bless {}, $class;
32 0           return $obj->initialize(@_);
33              
34             }
35              
36             # { dbh => , sql => }
37             sub initialize {
38 0     0 0   my ($self, $args) = @_;
39 0 0         croak "argument 'sql' undefined" unless defined $args->{sql};
40 0           my $sql = $self->{SQL} = $args->{sql};
41 0 0         croak "argument 'dbh' is required" unless $args->{dbh};
42 0           $self->{DBH} = $args->{dbh};
43 0           my ($ssql, $places, $argns) = strip($sql);
44 0           $self->{PLACES} = $places;
45 0           $self->{ARGNS} = $argns;
46 0 0         if ($self->{DBH}->isa('Tao::DBI::db')) {
47 0           $self->{STMT} = $self->{DBH}->{DBH}->prepare($ssql);
48             # FIXME: needs to support optional args
49             # FIXME: knows too much on Tao::DBI::db
50             } else {
51 0           $self->{STMT} = $self->{DBH}->prepare($ssql);
52             }
53 0 0         unless ($self->{STMT}) {
54 0           %$self = ();
55 0           return undef;
56             }
57 0           return $self
58             }
59              
60             # ($ssql, $places, $argns) = strip($sql);
61             sub strip {
62 0     0 0   my $sql = shift;
63 0           my $ssql = '';
64 0           my @places = (); my %args = ();
  0            
65              
66 0           for ( $_ = $sql; ; ) {
67 0 0         $ssql .= ':', next
68             if /\G::/gc;
69 0 0         $ssql .= "?", push(@places, $1), $args{$1}=1, next
70             if /\G:(\w+)/gc;
71 0 0         $ssql .= $1, next
72             if /\G(:?[^:]*)/gc;
73 0           last;
74             }
75             # if not at the end of string, invalid use of :[^\w:] -> not yet implemented
76              
77 0           my @argns = keys %args;
78 0           return ($ssql, \@places, \@argns);
79             }
80              
81             # $stmt->execute($hash_ref)
82             # $stmt->execute($scalar)
83             # $stmt->execute
84             sub execute {
85 0     0 1   my $self = shift;
86 0           my $args = shift;
87              
88 0 0         if (!$args) {
    0          
89 0 0         if (@{$self->{ARGNS}}) {
  0            
90 0           croak "execute on SQL::Statement missing arguments";
91             }
92 0           return $self->{STMT}->execute;
93              
94             } elsif (ref $args) {
95 0           return $self->{STMT}->execute(@{$args}{@{$self->{PLACES}}}, @_);
  0            
  0            
96             } else {
97 0 0         if (@{$self->{ARGNS}}!=1) {
  0            
98 0           croak "execute on SQL::Statement with a single non-ref argument only for one-parameter statements";
99             }
100 0           return $self->{STMT}->execute(($args) x @{$self->{PLACES}}, @_);
  0            
101             }
102             }
103              
104             # fetch*
105              
106 2     2   10 use vars qw($AUTOLOAD);
  2         4  
  2         258  
107              
108             # If method wasn't found, delegates to STMT instance variable.
109             # This way, instances of this class behaves like DBI statements.
110             sub AUTOLOAD {
111 0     0     my $self = shift;
112 0           my $meth = $AUTOLOAD;
113 0           $meth =~ s/.*:://;
114 0           return $self->{STMT}->$meth(@_);
115             }
116              
117       0     sub DESTROY {}
118              
119             1;
120              
121             # NOTE.
122             # In SQL statements, ':' has a special meaning as the prefix of a placeholder.
123             # If you need to include ':' within a statement to be literally interpreted,
124             # double it: '::'.
125              
126              
127             __END__