File Coverage

blib/lib/Fey/Role/SQL/HasWhereClause.pm
Criterion Covered Total %
statement 87 87 100.0
branch 14 14 100.0
condition n/a
subroutine 20 20 100.0
pod 3 4 75.0
total 124 125 99.2


line stmt bran cond sub pod time code
1             package Fey::Role::SQL::HasWhereClause;
2              
3 27     27   16618 use strict;
  27         118  
  27         1023  
4 27     27   124 use warnings;
  27         45  
  27         770  
5 27     27   114 use namespace::autoclean;
  27         37  
  27         179  
6              
7             our $VERSION = '0.42';
8              
9 27     27   2838 use Fey::Exceptions qw( param_error );
  27         47  
  27         1567  
10              
11 27     27   10303 use Fey::SQL::Fragment::Where::Boolean;
  27         83  
  27         1060  
12 27     27   15616 use Fey::SQL::Fragment::Where::Comparison;
  27         129  
  27         1193  
13 27     27   15064 use Fey::SQL::Fragment::Where::SubgroupStart;
  27         316  
  27         1021  
14 27     27   12962 use Fey::SQL::Fragment::Where::SubgroupEnd;
  27         96  
  27         1095  
15 27     27   220 use Fey::Types qw( ArrayRef );
  27         43  
  27         221  
16              
17 27     27   114459 use Moose::Role;
  27         57  
  27         246  
18              
19             has '_where' => (
20             traits => ['Array'],
21             is => 'bare',
22             isa => ArrayRef,
23             default => sub { [] },
24             handles => {
25             _add_where_element => 'push',
26             _has_where_elements => 'count',
27             _last_where_element => [ 'get', -1 ],
28             _where => 'elements',
29             },
30             init_arg => undef,
31             );
32              
33             sub where {
34 88     88 1 6549 my $self = shift;
35              
36 88         248 $self->_condition( 'where', @_ );
37              
38 82         161 return $self;
39             }
40              
41             # Just some sugar
42             sub and {
43 1     1 1 86 my $self = shift;
44              
45 1         3 return $self->where(@_);
46             }
47              
48             {
49             my %dispatch = (
50             'and' => '_and',
51             'or' => '_or',
52             '(' => '_subgroup_start',
53             ')' => '_subgroup_end',
54             );
55              
56             sub _condition {
57 115     115   120 my $self = shift;
58 115         125 my $key = shift;
59              
60 115 100       287 if ( @_ == 1 ) {
61 16 100       54 if ( my $meth = $dispatch{ lc $_[0] } ) {
62 15         40 $self->$meth($key);
63 15         26 return;
64             }
65             else {
66 1         5 param_error
67             qq|Cannot pass one argument to $key() unless it is one of "and", "or", "(", or ")".|;
68             }
69             }
70              
71 99         360 $self->_add_and_if_needed($key);
72              
73 99         190 my $add_method = '_add_' . $key . '_element';
74 99         2669 $self->$add_method(
75             Fey::SQL::Fragment::Where::Comparison->new(
76             $self->auto_placeholders(), @_
77             )
78             );
79             }
80             }
81              
82             sub _add_and_if_needed {
83 104     104   116 my $self = shift;
84 104         104 my $key = shift;
85              
86 104         199 my $has_method = '_has_' . $key . '_elements';
87              
88 104 100       3871 return unless $self->$has_method();
89              
90 18         120 my $last_method = '_last_' . $key . '_element';
91 18         604 my $last = $self->$last_method();
92              
93 18 100       169 return if $last->isa('Fey::SQL::Fragment::Where::Boolean');
94 13 100       64 return if $last->isa('Fey::SQL::Fragment::Where::SubgroupStart');
95              
96 8         27 $self->_and($key);
97             }
98              
99             sub _and {
100 8     8   15 my $self = shift;
101 8         19 my $key = shift;
102              
103 8         20 my $add_method = '_add_' . $key . '_element';
104 8         282 $self->$add_method(
105             Fey::SQL::Fragment::Where::Boolean->new( comparison => 'AND' ) );
106              
107 8         14 return $self;
108             }
109              
110             sub _or {
111 5     5   8 my $self = shift;
112 5         6 my $key = shift;
113              
114 5         15 my $add_method = '_add_' . $key . '_element';
115 5         159 $self->$add_method(
116             Fey::SQL::Fragment::Where::Boolean->new( comparison => 'OR' ) );
117              
118 5         6 return $self;
119             }
120              
121             sub _subgroup_start {
122 5     5   7 my $self = shift;
123 5         6 my $key = shift;
124              
125 5         9 $self->_add_and_if_needed($key);
126              
127 5         11 my $add_method = '_add_' . $key . '_element';
128 5         145 $self->$add_method( Fey::SQL::Fragment::Where::SubgroupStart->new() );
129              
130 5         5 return $self;
131             }
132              
133             sub _subgroup_end {
134 5     5   6 my $self = shift;
135 5         7 my $key = shift;
136              
137 5         9 my $add_method = '_add_' . $key . '_element';
138 5         161 $self->$add_method( Fey::SQL::Fragment::Where::SubgroupEnd->new() );
139              
140 5         7 return $self;
141             }
142              
143             sub where_clause {
144 130     130 1 682 my $self = shift;
145 130         158 my $dbh = shift;
146 130         141 my $skip_where = shift;
147              
148 130 100       4441 return unless $self->_has_where_elements();
149              
150 61         84 my $sql = '';
151 61 100       134 $sql = 'WHERE '
152             unless $skip_where;
153              
154             return (
155 89         534 $sql
156             . (
157             join ' ',
158 61         1887 map { $_->sql($dbh) } $self->_where()
159             )
160             );
161             }
162              
163             sub bind_params {
164 36     36 0 49 my $self = shift;
165              
166             return (
167 27         69 map { $_->bind_params() }
  30         130  
168 36         1207 grep { $_->can('bind_params') } $self->_where()
169             );
170             }
171              
172             1;
173              
174             # ABSTRACT: A role for queries which can include a WHERE clause
175              
176             __END__
177              
178             =pod
179              
180             =head1 NAME
181              
182             Fey::Role::SQL::HasWhereClause - A role for queries which can include a WHERE clause
183              
184             =head1 VERSION
185              
186             version 0.42
187              
188             =head1 SYNOPSIS
189              
190             use Moose 0.90;
191              
192             with 'Fey::Role::SQL::HasWhereClause';
193              
194             =head1 DESCRIPTION
195              
196             Classes which do this role represent a query which can include a
197             C<WHERE> clause.
198              
199             =head1 METHODS
200              
201             This role provides the following methods:
202              
203             =head2 $query->where(...)
204              
205             See the L<Fey::SQL section on WHERE Clauses|Fey::SQL/WHERE Clauses>
206             for more details.
207              
208             =head2 $query->and(...)
209              
210             See the L<Fey::SQL section on WHERE Clauses|Fey::SQL/WHERE Clauses>
211             for more details.
212              
213             =head2 $query->where_clause( $dbh, $skip_where )
214              
215             Returns the C<WHERE> clause portion of the SQL statement as a string. The
216             first argument, a database handle, is required. If the second argument is
217             true, the string returned will not start with "WHERE", it will simply start
218             with the where clause conditions.
219              
220             =head1 BUGS
221              
222             See L<Fey> for details on how to report bugs.
223              
224             =head1 AUTHOR
225              
226             Dave Rolsky <autarch@urth.org>
227              
228             =head1 COPYRIGHT AND LICENSE
229              
230             This software is Copyright (c) 2011 - 2015 by Dave Rolsky.
231              
232             This is free software, licensed under:
233              
234             The Artistic License 2.0 (GPL Compatible)
235              
236             =cut