File Coverage

blib/lib/DBIx/InterpolationBinding.pm
Criterion Covered Total %
statement 54 63 85.7
branch 15 20 75.0
condition 12 21 57.1
subroutine 11 11 100.0
pod 0 1 0.0
total 92 116 79.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             package DBIx::InterpolationBinding;
4              
5 2     2   40737 use 5.005;
  2         8  
  2         64  
6 2     2   9 use strict;
  2         5  
  2         66  
7 2     2   9 use vars qw($VERSION $DEBUG);
  2         7  
  2         149  
8              
9 2         37 use overload '""' => \&_convert_object_to_string,
10             '.' => \&_append_item_to_object,
11 2     2   3124 'fallback' => 1;
  2         3738  
12             require DBI;
13              
14             $VERSION = '1.01';
15              
16             $DEBUG = 0;
17              
18             sub import {
19 2     2   28 overload::constant 'q' => \&_prepare_object_from_string;
20              
21             # Bind the execute method into the DBI namespace
22             # We do it twice to avoid a tedious warning
23             # We would use the warnings pragma, but this is 5.005 :-)
24 2         201 *DBI::db::execute = \&dbi_exec;
25 2         220 *DBI::db::execute = \&dbi_exec;
26             }
27              
28             sub unimport {
29 1     1   10 overload::remove_constant 'q';
30             }
31              
32             sub dbi_exec {
33 9     9 0 406 my ($dbi, $sql) = @_;
34              
35 9 100 66     273 return $dbi->set_err(1,
36             '\$dbh->execute can only be used with a magic string.')
37             unless (ref $sql and $sql->isa(__PACKAGE__));
38 8         19 ($sql, my @params) = _create_sql_and_params($sql);
39              
40 8 50       20 print STDERR "DBI::prepare($sql)\nDBI::execute(", join(", ",
41             @params) , ")\n" if $DEBUG;
42 8 50       44 my $sth = $dbi->prepare($sql) or return;
43 8 50       1879 $sth->execute(@params) or return;
44 8         7293 return $sth;
45             }
46              
47             sub _create_sql_and_params {
48 11     11   148 my ($sql, @params) = @_;
49              
50 11 100 66     56 if (ref $sql and $sql->isa(__PACKAGE__)) {
51             # We have a DBOx::InterpolationBinding string
52 9         10 unshift @params, @{ $sql->{bind_params} };
  9         22  
53 9         18 $sql = $sql->{sql_string}
54             }
55              
56 11         42 return ($sql, @params);
57             }
58              
59             sub _prepare_object_from_string {
60 45     45   138 my (undef, $string, $mode) = @_;
61              
62             # We only want to affect double-quoted strings
63 45 100       2463 return $string unless ($mode eq "qq");
64              
65             # Make an object out of the string
66 25         71 my $self = {
67             string => $string,
68             sql_string => $string,
69             bind_params => [ ]
70             };
71 25         2582 return bless $self => __PACKAGE__;
72             }
73              
74             sub _convert_object_to_string {
75 11     11   4535 my ($self) = @_;
76              
77             # We need a string for this (eg. to print or use outside DBI)
78 11         350 return $self->{string};
79             }
80              
81             sub _append_item_to_object {
82 39     39   105728 my ($self, $string, $flipped) = @_;
83              
84             # $new_hash will become the object we return, so the old one
85             # isn't mashed.
86 39         198 my $new_hash = { %$self };
87 39         73 $new_hash->{bind_params} = [ @{ $self->{bind_params} } ];
  39         105  
88              
89             # At this point, the thing that isn't $self is either an object of
90             # this class, or it's a boring string. Also, we either need to append
91             # the other thingy before this one, or after, depending on $flipped.
92 39   66     182 my $string_is_this_class = ref($string) && $string->isa(__PACKAGE__);
93              
94 39 100 66     138 if ($string_is_this_class and not $flipped) {
95 16         43 $new_hash->{sql_string} .= $string->{sql_string};
96 16         36 $new_hash->{string} .= $string->{string};
97 16         21 push @{ $new_hash->{bind_params} }, @{ $string->{bind_params} };
  16         27  
  16         34  
98             }
99 39 50 66     131 if ($string_is_this_class and $flipped) {
100 0         0 $new_hash->{sql_string} = $string->{sql_string} .
101             $new_hash->{sql_string};
102 0         0 $new_hash->{string} = $string->{string} . $new_hash->{string};
103 0         0 unshift @{ $new_hash->{bind_params} }, @{ $string->{bind_params} };
  0         0  
  0         0  
104             }
105              
106 39 50 33     113 if ($flipped and not $string_is_this_class) {
107 0         0 $new_hash->{sql_string} = "?" . $new_hash->{sql_string};
108 0         0 $new_hash->{string} = $string . $new_hash->{string};
109 0         0 unshift @{ $new_hash->{bind_params} }, $string;
  0         0  
110             }
111 39 100 33     144 if (not($flipped) and not $string_is_this_class) {
112 23         45 $new_hash->{sql_string} .= "?";
113 23         44 $new_hash->{string} .= $string;
114 23         24 push @{ $new_hash->{bind_params} }, $string;
  23         48  
115             }
116              
117             # Make the new thing an object
118 39         190 return bless $new_hash => ref($self);
119             }
120              
121             1;
122             __END__