line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package SQL::Stash; |
2
|
1
|
|
|
1
|
|
27246
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
29
|
|
3
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
24
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
12
|
use v5.6; |
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
72
|
|
6
|
1
|
|
|
1
|
|
5
|
use Carp qw(croak); |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
51
|
|
7
|
1
|
|
|
1
|
|
1218
|
use version v0.77; |
|
1
|
|
|
|
|
2209
|
|
|
1
|
|
|
|
|
8
|
|
8
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
89
|
use constant CACHE_DEFAULT => 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
478
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = version->declare("v0.2.0"); |
12
|
|
|
|
|
|
|
my %STASH; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub new { |
15
|
2
|
|
|
2
|
1
|
261205
|
my ($class, %args) = @_; |
16
|
2
|
|
|
|
|
6
|
my $self = bless({}, $class); |
17
|
2
|
100
|
|
|
|
56
|
$self->{'dbh'} = $args{'dbh'} or croak("DBI handle missing"); |
18
|
1
|
|
|
|
|
3
|
$self->{'stash'} = {}; |
19
|
1
|
|
|
|
|
9
|
return $self; |
20
|
|
|
|
|
|
|
} |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub stash { |
23
|
0
|
|
|
0
|
1
|
|
my ($class, $name, $sql, $should_cache) = @_; |
24
|
0
|
|
|
|
|
|
my $stash; |
25
|
0
|
|
0
|
|
|
|
$should_cache ||= CACHE_DEFAULT; |
26
|
|
|
|
|
|
|
|
27
|
0
|
0
|
|
|
|
|
if(ref($class)) { |
28
|
0
|
|
|
|
|
|
$stash = $class->{'stash'}; |
29
|
|
|
|
|
|
|
} else { |
30
|
0
|
|
0
|
|
|
|
$STASH{$class} ||= {}; |
31
|
0
|
|
|
|
|
|
$stash = $STASH{$class}; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
0
|
|
0
|
|
|
|
$stash->{$name} = { |
35
|
|
|
|
|
|
|
'sql' => $sql, |
36
|
|
|
|
|
|
|
'should_cache' => $should_cache || 1, |
37
|
|
|
|
|
|
|
}; |
38
|
0
|
|
|
|
|
|
return; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub retrieve { |
42
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
43
|
0
|
|
|
|
|
|
my $name = shift; |
44
|
0
|
|
0
|
|
|
|
my $class = ref($self) || $self; |
45
|
0
|
|
|
|
|
|
my $sth; |
46
|
|
|
|
|
|
|
my $stashed; |
47
|
|
|
|
|
|
|
|
48
|
0
|
0
|
|
|
|
|
if(ref($self)) { |
49
|
0
|
|
|
|
|
|
$stashed = $self->{'stash'}->{$name}; |
50
|
|
|
|
|
|
|
} |
51
|
0
|
0
|
0
|
|
|
|
$stashed ||= $STASH{$class}->{$name} or return; |
52
|
0
|
|
|
|
|
|
my $sql = $self->transform_sql($stashed->{'sql'}, @_); |
53
|
|
|
|
|
|
|
|
54
|
0
|
0
|
|
|
|
|
if($stashed->{'should_cache'}) { |
55
|
0
|
|
|
|
|
|
$sth = $self->{'dbh'}->prepare_cached($sql); |
56
|
|
|
|
|
|
|
} else { |
57
|
0
|
|
|
|
|
|
$sth = $self->{'dbh'}->prepare($sql); |
58
|
|
|
|
|
|
|
} |
59
|
0
|
|
|
|
|
|
return $sth; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub transform_sql { |
63
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
64
|
0
|
|
|
|
|
|
my $sql = shift; |
65
|
0
|
|
|
|
|
|
return sprintf($sql, @_); |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
1; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
__END__ |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=head1 NAME |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
SQL::Stash - A stash for SQL queries |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head1 SYNOPSIS |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
package SQL::Stash::Foo; |
79
|
|
|
|
|
|
|
use base qw(SQL::Stash); |
80
|
|
|
|
|
|
|
__PACKAGE__->stash('select_foo', 'SELECT * FROM Foo'); |
81
|
|
|
|
|
|
|
1; |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
package main; |
84
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:SQLite:dbname=:memory:', '', ''); |
85
|
|
|
|
|
|
|
my $stash = SQL::Stash::Foo->new(); |
86
|
|
|
|
|
|
|
my $sth = $stash->retrieve('select_foo'); |
87
|
|
|
|
|
|
|
$sth->execute(); |
88
|
|
|
|
|
|
|
while(my $row = $sth->fetchrow_arrayref()) { |
89
|
|
|
|
|
|
|
print("$_\n") for @$row; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head1 DESCRIPTION |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
L<SQL::Stash|SQL::Stash> is a simple query library for SQL statements. |
95
|
|
|
|
|
|
|
SQL statements are populated at the class level. SQL::Stash objects |
96
|
|
|
|
|
|
|
prepare these statements as late as possible (i.e. before they are |
97
|
|
|
|
|
|
|
executed). |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
SQL::Stash is in concept very similar to L<Ima::DBI|Ima::DBI>, but |
100
|
|
|
|
|
|
|
differs by having instance-specific database handles and statements, and |
101
|
|
|
|
|
|
|
by supporting externally defined database handles. |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=head1 METHODS |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=head2 new |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
SQL::Stash->new(%args); |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Designated constructor. Instantiates a new L<SQL::Stash|SQL::Stash> |
110
|
|
|
|
|
|
|
object. The C<dbh> argument, a L<DBI|DBI>-like object, must be |
111
|
|
|
|
|
|
|
provided. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
my $dbh = DBI->connect('dbi:SQLite:dbname=:memory:', '', ''); |
114
|
|
|
|
|
|
|
my $stash = SQL::Stash->new('dbh' => $dbh); |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head2 stash |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
SQL::Stash::Foo->stash($name, $statement, $should_cache); |
119
|
|
|
|
|
|
|
$stash->stash($name, $statement, $should_cache); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Stash an SQL C<statement>. The method can be called both on the class |
122
|
|
|
|
|
|
|
and instance. If the class method is called the C<statement> will be |
123
|
|
|
|
|
|
|
added to the global stash. If the instance method is called the |
124
|
|
|
|
|
|
|
C<statement> will only be added to the instance-specific C<stash>. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
The C<name> is used as an identifier in order to later |
127
|
|
|
|
|
|
|
L<retrieve|retrieve> it. The C<should_cache> parameter is optional and |
128
|
|
|
|
|
|
|
specifies whether C<prepare()> or C<prepare_cached()> is used to prepare |
129
|
|
|
|
|
|
|
the C<statement>. It defaults to C<true>. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
SQL::Stash::Foo->stash('select_foo', 'SELECT * FROM Foo'); |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 retrieve |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
$stash->retrieve($name, @_); |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Prepare the statement stored via L<stash|stash>, identified by C<name>, |
138
|
|
|
|
|
|
|
and return a prepared statement handle. The SQL statement may be |
139
|
|
|
|
|
|
|
modified by L<transform_sql|transform_sql> before it is prepared. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 transform_sql |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
$stash->transform_sql($sql, @_) |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
Transform the SQL statement before it is prepared to enable dynamically |
146
|
|
|
|
|
|
|
generated statements. The default implementation is to use |
147
|
|
|
|
|
|
|
L<sprintf|sprintf>, but sub-classes may override this method to perform |
148
|
|
|
|
|
|
|
any transformation. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
$stash->transform_sql("SELECT * FROM %s", "table"); |
151
|
|
|
|
|
|
|
#=> SELECT * FROM table |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=head1 SEE ALSO |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
L<Ima::DBI|Ima::DBI> |
156
|
|
|
|
|
|
|
L<SQL::Bibliosoph|SQL::Bibliosoph> |
157
|
|
|
|
|
|
|
L<SQL::Snippet|SQL::Snippet> |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=head1 AUTHOR |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
Sebastian Nowicki <sebnow@gmail.com> |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=cut |
164
|
|
|
|
|
|
|
|