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   33 use 5.006;
  2         6  
5 2     2   9 use strict;
  2         5  
  2         41  
6 2     2   10 use warnings;
  2         4  
  2         153  
7              
8             require Exporter;
9              
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw();
12              
13             our $VERSION = '0.012';
14              
15 2     2   15 use Carp;
  2         2  
  2         1337  
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              
47 0 0         if ( $self->{DBH}->isa('Tao::DBI::db') ) {
48 0           $self->{STMT} = $self->{DBH}->{DBH}->prepare($ssql);
49              
50             # FIXME: needs to support optional args
51             # FIXME: knows too much on Tao::DBI::db
52             }
53             else {
54 0           $self->{STMT} = $self->{DBH}->prepare($ssql);
55             }
56 0 0         unless ( $self->{STMT} ) {
57 0           %$self = ();
58 0           return undef;
59             }
60 0           return $self;
61             }
62              
63             # ($ssql, $places, $argns) = strip($sql);
64             sub strip {
65 0     0 0   my $sql = shift;
66 0           my $ssql = '';
67 0           my @places = ();
68 0           my %args = ();
69              
70 0           for ( $_ = $sql ; ; ) {
71 0 0         $ssql .= ':', next
72             if /\G::/gc;
73 0 0         $ssql .= "?", push( @places, $1 ), $args{$1} = 1, next
74             if /\G:(\w+)/gc;
75 0 0         $ssql .= $1, next
76             if /\G(:?[^:]*)/gc;
77 0           last;
78             }
79              
80             # if not at the end of string, invalid use of :[^\w:] -> not yet implemented
81              
82 0           my @argns = keys %args;
83 0           return ( $ssql, \@places, \@argns );
84             }
85              
86             # $stmt->execute($hash_ref)
87             # $stmt->execute($scalar)
88             # $stmt->execute
89             sub execute {
90 0     0 1   my $self = shift;
91 0           my $args = shift;
92              
93 0 0         if ( !$args ) {
    0          
94 0 0         if ( @{ $self->{ARGNS} } ) {
  0            
95 0           croak "execute on SQL::Statement missing arguments";
96             }
97 0           return $self->{STMT}->execute;
98              
99             }
100             elsif ( ref $args ) {
101 0           return $self->{STMT}->execute( @{$args}{ @{ $self->{PLACES} } }, @_ );
  0            
  0            
102             }
103             else {
104 0 0         if ( @{ $self->{ARGNS} } != 1 ) {
  0            
105 0           croak
106             "execute on SQL::Statement with a single non-ref argument only for one-parameter statements";
107             }
108 0           return $self->{STMT}->execute( ($args) x @{ $self->{PLACES} }, @_ );
  0            
109             }
110             }
111              
112             # fetch*
113              
114 2     2   11 use vars qw($AUTOLOAD);
  2         3  
  2         245  
115              
116             # If method wasn't found, delegates to STMT instance variable.
117             # This way, instances of this class behaves like DBI statements.
118             sub AUTOLOAD {
119 0     0     my $self = shift;
120 0           my $meth = $AUTOLOAD;
121 0           $meth =~ s/.*:://;
122 0           return $self->{STMT}->$meth(@_);
123             }
124              
125       0     sub DESTROY { }
126              
127             1;
128              
129             # NOTE.
130             # In SQL statements, ':' has a special meaning as the prefix of a placeholder.
131             # If you need to include ':' within a statement to be literally interpreted,
132             # double it: '::'.
133              
134             __END__