File Coverage

blib/lib/SQL/Stash.pm
Criterion Covered Total %
statement 23 47 48.9
branch 2 10 20.0
condition 0 12 0.0
subroutine 7 10 70.0
pod 4 4 100.0
total 36 83 43.3


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