| 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
|
|
|
|
|
|
|
|