File Coverage

blib/lib/DBIx/DBO/Query.pm
Criterion Covered Total %
statement 468 517 90.5
branch 156 228 68.4
condition 81 136 59.5
subroutine 64 65 98.4
pod 36 38 94.7
total 805 984 81.8


line stmt bran cond sub pod time code
1             package DBIx::DBO::Query;
2              
3 11     11   64 use strict;
  11         1360  
  11         3316  
4 11     11   62 use warnings;
  11         51  
  11         809  
5 11     11   55 use Carp 'croak';
  11         20  
  11         697  
6 11     11   18683 use Devel::Peek 'SvREFCNT';
  11         6729  
  11         66  
7              
8 11     11   1164 use overload '**' => \&column, fallback => 1;
  11         25  
  11         98  
9              
10             BEGIN {
11 11 50   11   1370 if ($] < 5.008_009) {
12 0         0 require XSLoader;
13 0         0 XSLoader::load(__PACKAGE__, $DBIx::DBO::VERSION);
14             } else {
15 11         11413 require Hash::Util;
16 11         134166 *_hv_store = \&Hash::Util::hv_store;
17             }
18             }
19              
20 9     9   163 sub _table_class { $_[0]{DBO}->_table_class }
21 10     10   53 sub _row_class { $_[0]{DBO}->_row_class }
22              
23             *_isa = \&DBIx::DBO::DBD::_isa;
24              
25             =head1 NAME
26              
27             DBIx::DBO::Query - An OO interface to SQL queries and results. Encapsulates an entire query in an object.
28              
29             =head1 SYNOPSIS
30              
31             # Create a Query object by JOINing 2 tables
32             my $query = $dbo->query('my_table', 'my_other_table');
33            
34             # Get the Table objects from the query
35             my($table1, $table2) = $query->tables;
36            
37             # Add a JOIN ON clause
38             $query->join_on($table1 ** 'login', '=', $table2 ** 'username');
39            
40             # Find our ancestors, and order by age (oldest first)
41             $query->where('name', '=', 'Adam');
42             $query->where('name', '=', 'Eve');
43             $query->order_by({ COL => 'age', ORDER => 'DESC' });
44            
45             # New Query using a LEFT JOIN
46             ($query, $table1) = $dbo->query('my_table');
47             $table2 = $query->join_table('another_table', 'LEFT');
48             $query->join_on($table1 ** 'parent_id', '=', $table2 ** 'child_id');
49            
50             # Find those not aged between 20 and 30.
51             $query->where($table1 ** 'age', '<', 20, FORCE => 'OR'); # Force OR so that we get: (age < 20 OR age > 30)
52             $query->where($table1 ** 'age', '>', 30, FORCE => 'OR'); # instead of the default: (age < 20 AND age > 30)
53              
54             =head1 DESCRIPTION
55              
56             A C object represents rows from a database (from one or more tables). This module makes it easy, not only to fetch and use the data in the returned rows, but also to modify the query to return a different result set.
57              
58             =head1 METHODS
59              
60             =head3 C
61              
62             DBIx::DBO::Query->new($dbo, $table1, ...);
63             # or
64             $dbo->query($table1, ...);
65              
66             Create a new C object from the tables specified.
67             In scalar context, just the C object will be returned.
68             In list context, the C object and L objects will be returned for each table specified.
69             Tables can be specified with the same arguments as L or another Query can be used as a subquery.
70              
71             my($query, $table1, $table2) = DBIx::DBO::Query->new($dbo, 'customers', ['history', 'transactions']);
72              
73             You can also pass in a Query instead of a Table to use that query as a subquery.
74              
75             my $subquery = DBIx::DBO::Query->new($dbo, 'history.transactions');
76             my $query = DBIx::DBO::Query->new($dbo, 'customers', $subquery);
77             # SELECT * FROM customers, (SELECT * FROM history.transactions) t1;
78              
79             =cut
80              
81             sub new {
82 13     13 1 78 my $proto = shift;
83 13 50       24 eval { $_[0]->isa('DBIx::DBO') } or croak 'Invalid DBO Object';
  13         106  
84 13   33     82 my $class = ref($proto) || $proto;
85 13         87 $class->_init(@_);
86             }
87              
88             sub _init {
89 13     13   26 my $class = shift;
90 13         81 my $me = { DBO => shift, sql => undef, Columns => [] };
91 13 50       56 croak 'No table specified in new Query' unless @_;
92 13         31 bless $me, $class;
93              
94 13         35 for my $table (@_) {
95 14         65 $me->join_table($table);
96             }
97 12         163 $me->reset;
98 12 100       76 return wantarray ? ($me, $me->tables) : $me;
99             }
100              
101             sub _build_data {
102 318     318   1165 $_[0]->{build_data};
103             }
104              
105             =head3 C
106              
107             $query->reset;
108              
109             Reset the query, start over with a clean slate.
110             Resets the columns to return, removes all the WHERE, DISTINCT, HAVING, LIMIT, GROUP BY & ORDER BY clauses.
111              
112             B: This will not remove the JOINs or JOIN ON clauses.
113              
114             =cut
115              
116             sub reset {
117 14     14 1 28 my $me = shift;
118 14         62 $me->finish;
119 14         66 $me->unwhere;
120 14         63 $me->distinct(0);
121 14         73 $me->show;
122 14         57 $me->group_by;
123 14         62 $me->order_by;
124 14         52 $me->unhaving;
125 14         51 $me->limit;
126             }
127              
128             =head3 C
129              
130             Return a list of L or Query objects that appear in the C clause for this query.
131              
132             =cut
133              
134             sub tables {
135 225     225 1 274 @{$_[0]->{Tables}};
  225         880  
136             }
137              
138             sub _table_idx {
139 26     26   46 my($me, $tbl) = @_;
140 26         44 for my $i (0 .. $#{$me->{Tables}}) {
  26         335  
141 27 100       6197 return $i if $tbl == $me->{Tables}[$i];
142             }
143 12         66 return undef;
144             }
145              
146             sub _table_alias {
147 119     119   159 my($me, $tbl) = @_;
148              
149             # This means it's checking for an aliased column in this Query
150 119 100       396 return undef if $me == $tbl;
151              
152             # Don't use aliases, when there's only 1 table unless its a subquery
153 112 100 66     250 return undef if $me->tables == 1 and _isa($tbl, 'DBIx::DBO::Table');
154              
155 31   100     109 my $_from_alias = $me->{build_data}{_from_alias} ||= {};
156 31   66     210 return $_from_alias->{$tbl} ||= 't'.scalar(keys %$_from_alias);
157             }
158              
159             sub _from {
160 0     0   0 my($me, $parent_build_data) = @_;
161 0         0 $parent_build_data->{_subqueries}{$me} = $me->sql;
162             local(
163 0         0 $me->{build_data}{_from_alias},
164             $me->{build_data}{from},
165             $me->{build_data}{show},
166             $me->{build_data}{where},
167             $me->{build_data}{orderby},
168             $me->{build_data}{groupby},
169             $me->{build_data}{having}
170             ) = ($parent_build_data->{_from_alias});
171 0         0 return '('.$me->{DBO}{dbd_class}->_build_sql_select($me).')';
172             }
173              
174             =head3 C
175              
176             Return a list of column names that will be returned by L.
177              
178             =cut
179              
180             sub columns {
181 18     18 1 37 my($me) = @_;
182              
183 6         22 @{$me->{Columns}} = do {
  18         70  
184 6 100       9 if (@{$me->{build_data}{Showing}}) {
  6         29  
185 2 50       5 map {
186 1         3 _isa($_, 'DBIx::DBO::Table', 'DBIx::DBO::Query') ? ($_->columns) : $me->_build_col_val_name(@$_)
187 1         2 } @{$me->{build_data}{Showing}};
188             } else {
189 5         10 map { $_->columns } @{$me->{Tables}};
  7         27  
  5         18  
190             }
191 18 100       27 } unless @{$me->{Columns}};
192              
193 18         29 @{$me->{Columns}};
  18         84  
194             }
195              
196             sub _build_col_val_name {
197 17     17   83 my($me, $fld, $func, $opt) = @_;
198 17 100       106 return $opt->{AS} if exists $opt->{AS};
199              
200             my @ary = map {
201 9 50       22 if (not ref $_) {
  8 50       37  
    0          
    0          
202 0         0 $me->rdbh->quote($_);
203             } elsif (_isa($_, 'DBIx::DBO::Column')) {
204 8         32 $_->[1];
205             } elsif (ref $_ eq 'SCALAR') {
206 0         0 $$_;
207             } elsif (_isa($_, 'DBIx::DBO::Query')) {
208 0         0 $_->_from($me->{build_data});
209             }
210             } @$fld;
211 9 100       52 return $ary[0] unless defined $func;
212 1         5 $func =~ s/$DBIx::DBO::DBD::placeholder/shift @ary/ego;
  0         0  
213 1         5 return $func;
214             }
215              
216             =head3 C
217              
218             $query->column($alias_or_column_name);
219             $query ** $column_name;
220              
221             Returns a reference to a column for use with other methods.
222             The C<**> method is a shortcut for the C method.
223              
224             =cut
225              
226             sub column {
227 3     3 1 13 my($me, $col) = @_;
228 3         4 my @show;
229 3 50       5 @show = @{$me->{build_data}{Showing}} or @show = @{$me->{Tables}};
  0         0  
  3         18  
230 3         7 for my $fld (@show) {
231             return $me->{Column}{$col} ||= bless [$me, $col], 'DBIx::DBO::Column'
232             if (_isa($fld, 'DBIx::DBO::Table') and exists $fld->{Column_Idx}{$col})
233 6 100 50     18 or (_isa($fld, 'DBIx::DBO::Query') and eval { $fld->column($col) })
  0   66     0  
      33        
      33        
      66        
      100        
      33        
234             or (ref($fld) eq 'ARRAY' and exists $fld->[2]{AS} and $col eq $fld->[2]{AS});
235             }
236 1         16 croak 'No such column: '.$me->{DBO}{dbd_class}->_qi($me, $col);
237             }
238              
239             sub _inner_col {
240 50     50   100 my($me, $col, $_check_aliases) = @_;
241 50 50       104 $_check_aliases = $me->{DBO}{dbd_class}->_alias_preference($me, 'column') unless defined $_check_aliases;
242 50         115 my $column;
243 50 100 100     196 return $column if $_check_aliases == 1 and $column = $me->_check_alias($col);
244 44         139 for my $tbl ($me->tables) {
245 44 100       289 return $tbl->column($col) if exists $tbl->{Column_Idx}{$col};
246             }
247 1 50 33     9 return $column if $_check_aliases == 2 and $column = $me->_check_alias($col);
248 0 0       0 croak 'No such column'.($_check_aliases ? '/alias' : '').': '.$me->{DBO}{dbd_class}->_qi($me, $col);
249             }
250              
251             sub _check_alias {
252 34     34   59 my($me, $col) = @_;
253 34         68 for my $fld (@{$me->{build_data}{Showing}}) {
  34         157  
254 30 100 100     333 return $me->{Column}{$col} ||= bless [$me, $col], 'DBIx::DBO::Column'
      66        
      100        
255             if ref($fld) eq 'ARRAY' and exists $fld->[2]{AS} and $col eq $fld->[2]{AS};
256             }
257             }
258              
259             =head3 C
260              
261             $query->show(@columns);
262             $query->show($table1, { COL => $table2 ** 'name', AS => 'name2' });
263             $query->show($table1 ** 'id', { FUNC => 'UCASE(?)', COL => 'name', AS => 'alias' }, ...
264              
265             List which columns to return when we L.
266             If called without arguments all columns will be shown, C
267             If you use a Table object, all the columns from that table will be shown, C
268             You can also add a subquery by passing that Query as the value with an alias, Eg.
269              
270             $query->show({ VAL => $subquery, AS => 'sq' }, ...);
271             # SELECT ($subquery_sql) AS sq ...
272              
273             =cut
274              
275             # TODO: Keep track of all aliases in use and die if a used alias is removed
276             sub show {
277 26     26 1 713 my $me = shift;
278 26         48 undef $me->{sql};
279 26         52 undef $me->{build_data}{from};
280 26         54 undef $me->{build_data}{show};
281 26         31 undef @{$me->{build_data}{Showing}};
  26         79  
282 26         39 undef @{$me->{Columns}};
  26         60  
283 26         61 for my $fld (@_) {
284 21 100       73 if (_isa($fld, 'DBIx::DBO::Table', 'DBIx::DBO::Query')) {
285 6 100       25 croak 'Invalid table to show' unless defined $me->_table_idx($fld);
286 5         9 push @{$me->{build_data}{Showing}}, $fld;
  5         14  
287 5         10 push @{$me->{Columns}}, $fld->columns;
  5         25  
288 5         17 next;
289             }
290             # If the $fld is just a scalar use it as a column name not a value
291 15         91 my @col = $me->{DBO}{dbd_class}->_parse_col_val($me, $fld, Aliases => 0);
292 15         30 push @{$me->{build_data}{Showing}}, \@col;
  15         49  
293 15         28 push @{$me->{Columns}}, $me->_build_col_val_name(@col);
  15         65  
294             }
295             }
296              
297             =head3 C
298              
299             $query->distinct(1);
300              
301             Takes a boolean argument to add or remove the DISTINCT clause for the returned rows.
302              
303             =cut
304              
305             sub distinct {
306 16     16 1 29 my $me = shift;
307 16         24 undef $me->{sql};
308 16         38 undef $me->{build_data}{show};
309 16         40 my $distinct = $me->{build_data}{Show_Distinct};
310 16 100       82 $me->{build_data}{Show_Distinct} = shift() ? 1 : undef if @_;
    50          
311             }
312              
313             =head3 C
314              
315             $query->join_table($table, $join_type);
316              
317             Join a table onto the query, creating a L object if needed.
318             This will perform a comma (", ") join unless $join_type is specified.
319              
320             Tables can be specified with the same arguments as L or another Query can be used as a subquery.
321              
322             Valid join types are any accepted by the DB. Eg: C<'JOIN'>, C<'LEFT'>, C<'RIGHT'>, C (for comma join), C<'INNER'>, C<'OUTER'>, ...
323              
324             Returns the Table or Query object added.
325              
326             =cut
327              
328             sub join_table {
329 18     18 1 551 my($me, $tbl, $type) = @_;
330 18 100       59 if (_isa($tbl, 'DBIx::DBO::Table')) {
    50          
331 9 100       47 croak 'This table is already in this query' if defined $me->_table_idx($tbl);
332 8 100       161 croak 'This table is from a different DBO connection' if $me->{DBO} != $tbl->{DBO};
333             } elsif (_isa($tbl, 'DBIx::DBO::Query')) {
334             # Subquery
335 0 0       0 croak 'This table is from a different DBO connection' if $me->{DBO} != $tbl->{DBO};
336             } else {
337 9         36 $tbl = $me->_table_class->new($me->{DBO}, $tbl);
338             }
339 16 100       53 if (defined $type) {
340 3         12 $type =~ s/^\s*/ /;
341 3         17 $type =~ s/\s*$/ /;
342 3         9 $type = uc $type;
343 3 100       18 $type .= 'JOIN ' if $type !~ /\bJOIN\b/;
344             } else {
345 13         27 $type = ', ';
346             }
347 16         25 push @{$me->{Tables}}, $tbl;
  16         50  
348 16         31 push @{$me->{build_data}{Join}}, $type;
  16         87  
349 16         32 push @{$me->{build_data}{Join_On}}, undef;
  16         47  
350 16         23 push @{$me->{Join_Bracket_Refs}}, [];
  16         40  
351 16         27 push @{$me->{Join_Brackets}}, [];
  16         55  
352 16         43 undef $me->{sql};
353 16         39 undef $me->{build_data}{from};
354 16         35 undef $me->{build_data}{show};
355 16         24 undef @{$me->{Columns}};
  16         31  
356 16         50 return $tbl;
357             }
358              
359             =head3 C
360              
361             $query->join_on($table_object, $expression1, $operator, $expression2);
362             $query->join_on($table2, $table1 ** 'id', '=', $table2 ** 'id');
363              
364             Join tables on a specific WHERE clause. The first argument is the table object being joined onto.
365             Then a JOIN ON condition follows, which uses the same arguments as L.
366              
367             =cut
368              
369             sub join_on {
370 7     7 1 589 my $me = shift;
371 7         14 my $t2 = shift;
372 7 100       25 my $i = $me->_table_idx($t2) or croak 'Invalid table object to join onto';
373              
374 6         53 my($col1, $col1_func, $col1_opt) = $me->{DBO}{dbd_class}->_parse_col_val($me, shift);
375 6         18 my $op = shift;
376 6         29 my($col2, $col2_func, $col2_opt) = $me->{DBO}{dbd_class}->_parse_col_val($me, shift);
377              
378             # Validate the fields
379 6         31 $me->_validate_where_fields(@$col1, @$col2);
380              
381             # Force a new search
382 6         12 undef $me->{sql};
383 6         12 undef $me->{build_data}{from};
384              
385             # Find the current Join_On reference
386 6   100     37 my $ref = $me->{build_data}{Join_On}[$i] ||= [];
387 6         13 $ref = $ref->[$_] for (@{$me->{Join_Bracket_Refs}[$i]});
  6         22  
388              
389 6 100       29 $me->{build_data}{Join}[$i] = ' JOIN ' if $me->{build_data}{Join}[$i] eq ', ';
390 6         30 $me->_add_where($ref, $op, $col1, $col1_func, $col1_opt, $col2, $col2_func, $col2_opt, @_);
391             }
392              
393             =head3 C, C
394              
395             $query->open_join_on_bracket($table, 'OR');
396             $query->join_on(...
397             $query->close_join_on_bracket($table);
398              
399             Equivalent to L, but for the JOIN ON clause.
400             The first argument is the table being joined onto.
401              
402             =cut
403              
404             sub open_join_on_bracket {
405 3     3 1 1048 my $me = shift;
406 3 100       14 my $tbl = shift or croak 'Invalid table object for join on clause';
407 2 100       5 my $i = $me->_table_idx($tbl) or croak 'No such table object in the join';
408 1   50     8 $me->_open_bracket($me->{Join_Brackets}[$i], $me->{Join_Bracket_Refs}[$i], $me->{build_data}{Join_On}[$i] ||= [], @_);
409             }
410              
411             sub close_join_on_bracket {
412 3     3 1 1042 my $me = shift;
413 3 100       14 my $tbl = shift or croak 'Invalid table object for join on clause';
414 2 100       8 my $i = $me->_table_idx($tbl) or croak 'No such table object in the join';
415 1         7 $me->_close_bracket($me->{Join_Brackets}[$i], $me->{Join_Bracket_Refs}[$i]);
416             }
417              
418             =head3 C
419              
420             Restrict the query with the condition specified (WHERE clause).
421              
422             $query->where($expression1, $operator, $expression2);
423              
424             C<$operator> is one of: C<'=', '', '<', 'E', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'BETWEEN', 'NOT BETWEEN', ...>
425              
426             C<$expression>s can be any of the following:
427              
428             =over 4
429              
430             =item *
431              
432             A scalar value: C<123> or C<'hello'> (or for C<$expression1> a column name: C<'id'>)
433              
434             $query->where('name', '<>', 'John');
435              
436             =item *
437              
438             A scalar reference: C<\"22 * 3"> (These are passed unquoted in the SQL statement!)
439              
440             $query->where(\'CONCAT(id, name)', '=', \'"22John"');
441              
442             =item *
443              
444             An array reference: C<[1, 3, 5]> (Used with C and C etc)
445              
446             $query->where('id', 'NOT IN', [21, 22, 25, 39]);
447              
448             =item *
449              
450             A Column object: C<$table ** 'id'> or C<$table-Ecolumn('id')>
451              
452             $query->where($table1 ** 'id', '=', $table2 ** 'id');
453              
454             =item *
455              
456             A Query object, to be used as a subquery.
457              
458             $query->where('id', '>', $subquery);
459              
460             =item *
461              
462             A hash reference: see L
463              
464             =back
465              
466             Multiple C expressions are combined I using the preferred aggregator C<'AND'> (unless L was used to change this). So that when you add where expressions to the query, they will be Ced together. However some expressions that refer to the same column will automatically be Ced instead where this makes sense, currently: C<'='>, C<'IS NULL'>, C<'E=E'>, C<'IN'> and C<'BETWEEN'>. Similarly, when the preferred aggregator is C<'OR'> the following operators will be Ced together: C<'!='>, C<'IS NOT NULL'>, C<'EE'>, C<'NOT IN'> and C<'NOT BETWEEN'>.
467              
468             $query->where('id', '=', 5);
469             $query->where('name', '=', 'Bob');
470             $query->where('id', '=', 7);
471             $query->where(...
472             # Produces: WHERE ("id" = 5 OR "id" = 7) AND "name" = 'Bob' AND ...
473              
474             =cut
475              
476             sub where {
477 20     20 1 2285 my $me = shift;
478              
479             # If the $fld is just a scalar use it as a column name not a value
480 20         116 my($fld, $fld_func, $fld_opt) = $me->{DBO}{dbd_class}->_parse_col_val($me, shift);
481 20         74 my $op = shift;
482 20         111 my($val, $val_func, $val_opt) = $me->{DBO}{dbd_class}->_parse_val($me, shift, Check => 'Auto');
483              
484             # Validate the fields
485 19         65 $me->_validate_where_fields(@$fld, @$val);
486              
487             # Force a new search
488 19         35 undef $me->{sql};
489 19         30 undef $me->{build_data}{where};
490              
491             # Find the current Where_Data reference
492 19   100     108 my $ref = $me->{build_data}{Where_Data} ||= [];
493 19         26 $ref = $ref->[$_] for (@{$me->{Where_Bracket_Refs}});
  19         60  
494              
495 19         67 $me->_add_where($ref, $op, $fld, $fld_func, $fld_opt, $val, $val_func, $val_opt, @_);
496             }
497              
498             =head3 C
499              
500             $query->unwhere();
501             $query->unwhere($column);
502              
503             Removes all previously added L restrictions for a column.
504             If no column is provided, the I WHERE clause is removed.
505              
506             =cut
507              
508             sub unwhere {
509 16     16 1 29 my $me = shift;
510 16         91 $me->_del_where('Where', @_);
511             }
512              
513             sub _validate_where_fields {
514 28     28   50 my $me = shift;
515 28         49 for my $f (@_) {
516 58 100       134 if (_isa($f, 'DBIx::DBO::Column')) {
    100          
517 32         125 $me->{DBO}{dbd_class}->_valid_col($me, $f);
518             } elsif (my $type = ref $f) {
519 1 50 33     7 croak 'Invalid value type: '.$type if $type ne 'SCALAR' and not _isa($f, 'DBIx::DBO::Query');
520             }
521             }
522             }
523              
524             sub _del_where {
525 32     32   52 my $me = shift;
526 32         51 my $clause = shift;
527              
528 32 100       76 if (@_) {
529 4         1346 require Data::Dumper;
530 4         6648 my($fld, $fld_func, $fld_opt) = $me->{DBO}{dbd_class}->_parse_col_val($me, shift);
531             # TODO: Validate the fields?
532              
533 4 50       21 return unless exists $me->{build_data}{$clause.'_Data'};
534             # Find the current Where_Data reference
535 4         11 my $ref = $me->{build_data}{$clause.'_Data'};
536 4         9 $ref = $ref->[$_] for (@{$me->{$clause.'_Bracket_Refs'}});
  4         19  
537              
538 4         11 local $Data::Dumper::Indent = 0;
539 4         7 local $Data::Dumper::Maxdepth = 2;
540 11         719 my @match = grep {
541 4         15 Data::Dumper::Dumper($fld, $fld_func, $fld_opt) eq Data::Dumper::Dumper(@{$ref->[$_]}[1,2,3])
  11         437  
542             } 0 .. $#$ref;
543              
544 4 100       454 if (@_) {
545 1         3 my $op = shift;
546 1         8 my($val, $val_func, $val_opt) = $me->{DBO}{dbd_class}->_parse_val($me, shift, Check => 'Auto');
547              
548 3         144 @match = grep {
549 1         4 Data::Dumper::Dumper($op, $val, $val_func, $val_opt) eq Data::Dumper::Dumper(@{$ref->[$_]}[0,4,5,6])
  3         100  
550             } @match;
551             }
552 4         73 splice @$ref, $_, 1 for reverse @match;
553             } else {
554 28         128 delete $me->{build_data}{$clause.'_Data'};
555 28         74 $me->{$clause.'_Bracket_Refs'} = [];
556 28         82 $me->{$clause.'_Brackets'} = [];
557             }
558             # This forces a new search
559 32         62 undef $me->{sql};
560 32         150 undef $me->{build_data}{lc $clause};
561             }
562              
563             ##
564             # This will add an arrayref to the $ref given.
565             # The arrayref will contain 8 values:
566             # $op, $fld, $fld_func, $fld_opt, $val, $val_func, $val_opt, $force
567             # $op is the operator (those supported differ by DBD)
568             # $fld_func is undef or a scalar of the form '? AND ?' or 'POSITION(? IN ?)'
569             # $fld is an arrayref of columns/values for use with $fld_func
570             # $val_func is similar to $fld_func
571             # $val is an arrayref of values for use with $val_func
572             # $force is one of undef / 'AND' / 'OR' which if defined, overrides the default aggregator
573             ##
574             sub _add_where {
575 28     28   41 my $me = shift;
576 28         66 my($ref, $op, $fld, $fld_func, $fld_opt, $val, $val_func, $val_opt, %opt) = @_;
577              
578 28 50 66     98 croak 'Invalid option, FORCE must be AND or OR'
      66        
579             if defined $opt{FORCE} and $opt{FORCE} ne 'AND' and $opt{FORCE} ne 'OR';
580              
581             # Deal with NULL values
582 28 100       79 $op = '<>' if $op eq '!='; # Use the valid SQL op
583 28 100 100     193 if (@$val == 1 and !defined $val->[0] and !defined $val_func) {
      66        
584 2 100       9 if ($op eq '=') { $op = 'IS'; $val_func = 'NULL'; delete $val->[0]; }
  1 50       2  
  1         2  
  1         3  
585 1         2 elsif ($op eq '<>') { $op = 'IS NOT'; $val_func = 'NULL'; delete $val->[0]; }
  1         4  
  1         3  
586             }
587              
588             # Deal with array values: BETWEEN & IN
589 28 100       79 unless (defined $val_func) {
590 19 100 100     165 if ($op eq 'BETWEEN' or $op eq 'NOT BETWEEN') {
    100 100        
    100          
591 3 100 66     23 croak 'Invalid value argument, BETWEEN requires 2 values'
592             if ref $val ne 'ARRAY' or @$val != 2;
593 2         16 $val_func = $me->{DBO}{dbd_class}->PLACEHOLDER.' AND '.$me->{DBO}{dbd_class}->PLACEHOLDER;
594             } elsif ($op eq 'IN' or $op eq 'NOT IN') {
595 3 50       8 if (ref $val eq 'ARRAY') {
596 3 50       10 croak 'Invalid value argument, IN requires at least 1 value' if @$val == 0;
597             } else {
598 0         0 $val = [ $val ];
599             }
600             # Add to previous 'IN' and 'NOT IN' Where expressions
601 3         20 my $op_ag = $me->{DBO}{dbd_class}->_op_ag($op);
602 3 50 33     10 unless ($opt{FORCE} and $opt{FORCE} ne $op_ag) {
603 3         27 for my $lim (grep $$_[0] eq $op, @$ref) {
604             # $fld and $$lim[1] are always ARRAY refs
605 1 50       3 next if "@{$$lim[1]}" ne "@$fld";
  1         11  
606 1 50 33     10 last if $$lim[7] and $$lim[7] ne $op_ag;
607 1 50       6 last if $$lim[5] ne '('.join(',', ($me->{DBO}{dbd_class}->PLACEHOLDER) x @{$$lim[4]}).')';
  1         11  
608 1         3 push @{$$lim[4]}, @$val;
  1         5  
609 1         6 $$lim[5] = '('.join(',', ($me->{DBO}{dbd_class}->PLACEHOLDER) x @{$$lim[4]}).')';
  1         5  
610 1         7 return;
611             }
612             }
613 2         24 $val_func = '('.join(',', ($me->{DBO}{dbd_class}->PLACEHOLDER) x @$val).')';
614             } elsif (@$val != 1) {
615             # Check that there is only 1 placeholder
616 1         5 croak 'Wrong number of fields/values, called with '.@$val.' while needing 1';
617             }
618             }
619              
620 25         39 push @{$ref}, [ $op, $fld, $fld_func, $fld_opt, $val, $val_func, $val_opt, $opt{FORCE} ];
  25         148  
621             }
622              
623             =head3 C, C
624              
625             $query->open_bracket('OR');
626             $query->where( ...
627             $query->where( ...
628             $query->close_bracket;
629              
630             Used to group C expressions together in parenthesis using either C<'AND'> or C<'OR'> as the preferred aggregator.
631             All the C calls made between C and C will be inside the parenthesis.
632              
633             Without any parenthesis C<'AND'> is the preferred aggregator.
634              
635             =cut
636              
637             sub open_bracket {
638 2     2 1 3 my $me = shift;
639 2   50     14 $me->_open_bracket($me->{Where_Brackets}, $me->{Where_Bracket_Refs}, $me->{build_data}{Where_Data} ||= [], @_);
640             }
641              
642             sub _open_bracket {
643 3     3   8 my($me, $brackets, $bracket_refs, $ref, $ag) = @_;
644 3 50 33     34 croak 'Invalid argument MUST be AND or OR' if !$ag or $ag !~ /^(AND|OR)$/;
645 3 100       8 my $last = @$brackets ? $brackets->[-1] : 'AND';
646 3 50       15 if ($ag ne $last) {
647             # Find the current data reference
648 3         9 $ref = $ref->[$_] for @$bracket_refs;
649              
650 3         8 push @$ref, [];
651 3         4 push @$bracket_refs, $#$ref;
652             }
653 3         15 push @$brackets, $ag;
654             }
655              
656             sub close_bracket {
657 2     2 1 5 my $me = shift;
658 2         10 $me->_close_bracket($me->{Where_Brackets}, $me->{Where_Bracket_Refs});
659             }
660              
661             sub _close_bracket {
662 3     3   8 my($me, $brackets, $bracket_refs) = @_;
663 3 50       5 my $ag = pop @{$brackets} or croak "Can't close bracket with no open bracket!";
  3         15  
664 3 100       14 my $last = @$brackets ? $brackets->[-1] : 'AND';
665 3 50       13 pop @$bracket_refs if $last ne $ag;
666 3         13 return $ag;
667             }
668              
669             =head3 C
670              
671             $query->group_by('column', ...);
672             $query->group_by($table ** 'column', ...);
673             $query->group_by({ COL => $table ** 'column', ORDER => 'DESC' }, ...);
674              
675             Group the results by the column(s) listed. This will replace the GROUP BY clause.
676             To remove the GROUP BY clause simply call C without any columns.
677              
678             =cut
679              
680             sub group_by {
681 17     17 1 31 my $me = shift;
682 17         34 undef $me->{sql};
683 17         53 undef $me->{build_data}{group};
684 17         26 undef @{$me->{build_data}{GroupBy}};
  17         96  
685 17         47 for my $col (@_) {
686 3         14 my @group = $me->{DBO}{dbd_class}->_parse_col_val($me, $col);
687 3         8 push @{$me->{build_data}{GroupBy}}, \@group;
  3         17  
688             }
689             }
690              
691             =head3 C
692              
693             Restrict the query with the condition specified (HAVING clause). This takes the same arguments as L.
694              
695             $query->having($expression1, $operator, $expression2);
696              
697             =cut
698              
699             sub having {
700 3     3 1 4 my $me = shift;
701              
702             # If the $fld is just a scalar use it as a column name not a value
703 3         13 my($fld, $fld_func, $fld_opt) = $me->{DBO}{dbd_class}->_parse_col_val($me, shift);
704 3         7 my $op = shift;
705 3         13 my($val, $val_func, $val_opt) = $me->{DBO}{dbd_class}->_parse_val($me, shift, Check => 'Auto');
706              
707             # Validate the fields
708 3         10 $me->_validate_where_fields(@$fld, @$val);
709              
710             # Force a new search
711 3         5 undef $me->{sql};
712 3         6 undef $me->{build_data}{having};
713              
714             # Find the current Having_Data reference
715 3   100     12 my $ref = $me->{build_data}{Having_Data} ||= [];
716 3         5 $ref = $ref->[$_] for (@{$me->{Having_Bracket_Refs}});
  3         8  
717              
718 3         10 $me->_add_where($ref, $op, $fld, $fld_func, $fld_opt, $val, $val_func, $val_opt, @_);
719             }
720              
721             =head3 C
722              
723             $query->unhaving();
724             $query->unhaving($column);
725              
726             Removes all previously added L restrictions for a column.
727             If no column is provided, the I HAVING clause is removed.
728              
729             =cut
730              
731             sub unhaving {
732 16     16 1 33 my $me = shift;
733 16         53 $me->_del_where('Having', @_);
734             }
735              
736             =head3 C
737              
738             $query->order_by('column', ...);
739             $query->order_by($table ** 'column', ...);
740             $query->order_by({ COL => $table ** 'column', ORDER => 'DESC' }, ...);
741              
742             Order the results by the column(s) listed. This will replace the ORDER BY clause.
743             To remove the ORDER BY clause simply call C without any columns.
744              
745             =cut
746              
747             sub order_by {
748 24     24 1 55 my $me = shift;
749 24         44 undef $me->{sql};
750 24         55 undef $me->{build_data}{order};
751 24         37 undef @{$me->{build_data}{OrderBy}};
  24         77  
752 24         59 for my $col (@_) {
753 9         51 my @order = $me->{DBO}{dbd_class}->_parse_col_val($me, $col);
754 9         23 push @{$me->{build_data}{OrderBy}}, \@order;
  9         45  
755             }
756             }
757              
758             =head3 C
759              
760             $query->limit;
761             $query->limit($rows);
762             $query->limit($rows, $offset);
763              
764             Limit the maximum number of rows returned to C<$rows>, optionally skipping the first C<$offset> rows.
765             When called without arguments or if C<$rows> is undefined, the limit is removed.
766              
767             NB. Oracle does not support pagging prior to version 12c, so this has been implemented in software,
768             , but if an offset is given, an extra column "_DBO_ROWNUM_" is added to the Query to achieve this.
769             TODO: Implement the new "FIRST n / NEXT n" clause if connected to a 12c database.
770              
771             =cut
772              
773             sub limit {
774 18     18 1 37 my($me, $rows, $offset) = @_;
775 18         32 undef $me->{sql};
776 18         43 undef $me->{build_data}{limit};
777 18 100       114 return undef $me->{build_data}{LimitOffset} unless defined $rows;
778 4   33     37 /^\d+$/ or croak "Invalid argument '$_' in limit" for grep defined, $rows, $offset;
779 4         7 @{$me->{build_data}{LimitOffset}} = ($rows, $offset);
  4         15  
780             }
781              
782             =head3 C
783              
784             $query->arrayref;
785             $query->arrayref(\%attr);
786              
787             Run the query using Lselectall_arrayref|DBI/"selectall_arrayref"> which returns the result as an arrayref.
788             You can specify a slice by including a 'Slice' or 'Columns' attribute in C<%attr> - See Lselectall_arrayref|DBI/"selectall_arrayref">.
789              
790             =cut
791              
792             sub arrayref {
793 3     3 1 6 my($me, $attr) = @_;
794 3         15 $me->{DBO}{dbd_class}->_selectall_arrayref($me, $me->sql, $attr,
795             $me->{DBO}{dbd_class}->_bind_params_select($me));
796             }
797              
798             =head3 C
799              
800             $query->hashref($key_field);
801             $query->hashref($key_field, \%attr);
802              
803             Run the query using Lselectall_hashref|DBI/"selectall_hashref"> which returns the result as an hashref.
804             C<$key_field> defines which column, or columns, are used as keys in the returned hash.
805              
806             =cut
807              
808             sub hashref {
809 1     1 1 4 my($me, $key, $attr) = @_;
810 1         5 $me->{DBO}{dbd_class}->_selectall_hashref($me, $me->sql, $key, $attr,
811             $me->{DBO}{dbd_class}->_bind_params_select($me));
812             }
813              
814             =head3 C
815              
816             $query->col_arrayref;
817             $query->col_arrayref(\%attr);
818              
819             Run the query using Lselectcol_arrayref|DBI/"selectcol_arrayref"> which returns the result as an arrayref of the values of each row in one array. By default it pushes all the columns requested by the L method onto the result array (this differs from the C). Or to specify which columns to include in the result use the 'Columns' attribute in C<%attr> - see Lselectcol_arrayref|DBI/"selectcol_arrayref">.
820              
821             =cut
822              
823             sub col_arrayref {
824 3     3 1 11 my($me, $attr) = @_;
825 3         12 my($sql, @bind) = ($me->sql, $me->{DBO}{dbd_class}->_bind_params_select($me));
826 3         23 $me->{DBO}{dbd_class}->_sql($me, $sql, @bind);
827 3 50       9 my $sth = $me->rdbh->prepare($sql, $attr) or return;
828 3 100       541 unless (defined $attr->{Columns}) {
829             # Some drivers don't provide $sth->{NUM_OF_FIELDS} until after execute is called
830 1 50       14 if ($sth->{NUM_OF_FIELDS}) {
831 1         8 $attr->{Columns} = [1 .. $sth->{NUM_OF_FIELDS}];
832             } else {
833 0 0       0 $sth->execute(@bind) or return;
834 0         0 my @col;
835 0 0       0 if (my $max = $attr->{MaxRows}) {
836 0   0     0 push @col, @$_ while 0 < $max-- and $_ = $sth->fetch;
837             } else {
838 0         0 push @col, @$_ while $_ = $sth->fetch;
839             }
840 0         0 return \@col;
841             }
842             }
843 3         12 return $me->rdbh->selectcol_arrayref($sth, $attr, @bind);
844             }
845              
846             =head3 C
847              
848             my $row = $query->fetch;
849              
850             Fetch the next row from the query. This will run/rerun the query if needed.
851              
852             Returns a L object or undefined if there are no more rows.
853              
854             =cut
855              
856             sub fetch {
857 30     30 1 27824 my $me = $_[0];
858             # Prepare and/or execute the query if needed
859 30 50 66     90 $me->_sth and ($me->{Active} or $me->run)
      33        
860             or croak $me->rdbh->errstr;
861             # Detach the old row if there is still another reference to it
862 30 50 66     290 if (defined $me->{Row} and SvREFCNT(${$me->{Row}}) > 1) {
  23         403  
863 0         0 $me->{Row}->_detach;
864             }
865              
866 30         95 my $row = $me->row;
867 30 50       84 if (exists $me->{cache}) {
868 30 100       56 if ($me->{cache}{idx} < @{$me->{cache}{data}}) {
  30         103  
869 26         36 @{$me->{cache}{array}}[0..$#{$me->{cache}{array}}] = @{$me->{cache}{data}[$me->{cache}{idx}++]};
  26         76  
  26         57  
  26         96  
870 26         77 $$row->{array} = $me->{cache}{array};
871 26         54 $$row->{hash} = $me->{hash};
872 26         154 return $row;
873             }
874 4         13 undef $$row->{array};
875 4         12 $me->{cache}{idx} = 0;
876             } else {
877             # Fetch and store the data then return the Row on success and undef on failure or no more rows
878 0 0       0 if ($$row->{array} = $me->{sth}->fetch) {
879 0         0 $$row->{hash} = $me->{hash};
880 0         0 return $row;
881             }
882 0         0 $me->{Active} = 0;
883             }
884 4         11 $$row->{hash} = {};
885 4         25 return;
886             }
887              
888             =head3 C
889              
890             my $row = $query->row;
891              
892             Returns the L object for the current row from the query or an empty L object if there is no current row.
893              
894             =cut
895              
896             sub row {
897 37     37 1 76 my $me = $_[0];
898 37         121 $me->sql; # Build the SQL and detach the Row if needed
899 37   66     223 $me->{Row} ||= $me->_row_class->new($me->{DBO}, $me);
900             }
901              
902             =head3 C
903              
904             $query->run;
905              
906             Run/rerun the query.
907             This is called automatically before fetching the first row.
908              
909             =cut
910              
911             sub run {
912 15     15 1 7472 my $me = shift;
913 15         51 $me->sql; # Build the SQL and detach the Row if needed
914 15 100       47 if (defined $me->{Row}) {
915 11         21 undef ${$me->{Row}}->{array};
  11         79  
916 11         25 ${$me->{Row}}->{hash} = {};
  11         33  
917             }
918              
919 15 50       66 my $rv = $me->_execute or return undef;
920 15         53 $me->{Active} = 1;
921 15         54 $me->_bind_cols_to_hash;
922 15 50       38 if ($me->config('CacheQuery')) {
923 15         333 $me->{cache}{data} = $me->{sth}->fetchall_arrayref;
924 15         100 $me->{cache}{idx} = 0;
925             } else {
926 0         0 delete $me->{cache};
927             }
928 15         87 return $rv;
929             }
930              
931             sub _execute {
932 15     15   28 my $me = shift;
933 15         92 $me->{DBO}{dbd_class}->_sql($me, $me->sql, $me->{DBO}{dbd_class}->_bind_params_select($me));
934 15 50       47 $me->_sth or return;
935 15         800 $me->{sth}->execute($me->{DBO}{dbd_class}->_bind_params_select($me));
936             }
937              
938             sub _bind_cols_to_hash {
939 15     15   29 my $me = shift;
940 15 100       54 unless ($me->{hash}) {
941             # Bind only to the first column of the same name
942 14         18 @{$me->{Columns}} = @{$me->{sth}{NAME}};
  14         58  
  14         206  
943 14 50       62 if ($me->config('CacheQuery')) {
944 14         32 @{$me->{cache}{array}} = (undef) x @{$me->{Columns}};
  14         59  
  14         44  
945 14         33 $me->{hash} = \my %hash;
946 14         21 my $i = 0;
947 14         32 for (@{$me->{Columns}}) {
  14         38  
948 36 100       166 _hv_store(%hash, $_, $me->{cache}{array}[$i]) unless exists $hash{$_};
949 36         68 $i++;
950             }
951             } else {
952 0         0 my $i;
953 0         0 for (@{$me->{Columns}}) {
  0         0  
954 0         0 $i++;
955 0 0       0 $me->{sth}->bind_col($i, \$me->{hash}{$_}) unless exists $me->{hash}{$_};
956             }
957             }
958             }
959             }
960              
961             =head3 C
962              
963             my $row_count = $query->rows;
964              
965             Count the number of rows returned.
966             Returns undefined if the number is unknown.
967             This uses the DBI C method which is unreliable in some situations (See Lrows|DBI/"rows">).
968              
969             =cut
970              
971             sub rows {
972 1     1 1 3 my $me = shift;
973 1         4 $me->sql; # Ensure the Row_Count is cleared if needed
974 1 50       20 $me->{DBO}{dbd_class}->_rows($me) unless defined $me->{Row_Count};
975 1         8 $me->{Row_Count};
976             }
977              
978             =head3 C
979              
980             my $row_count = $query->count_rows;
981              
982             Count the number of rows that would be returned.
983             Returns undefined if there is an error.
984              
985             =cut
986              
987             sub count_rows {
988 2     2 1 4 my $me = shift;
989 2         12 local $me->{Config}{CalcFoundRows} = 0;
990 2         7 my $old_sb = delete $me->{build_data}{Show_Bind};
991 2         5 $me->{build_data}{show} = '1';
992              
993 2         10 my $sql = 'SELECT COUNT(*) FROM ('.$me->{DBO}{dbd_class}->_build_sql_select($me).') t';
994 2         13 my($count) = $me->{DBO}{dbd_class}->_selectrow_array($me, $sql, undef,
995             $me->{DBO}{dbd_class}->_bind_params_select($me));
996              
997 2 50       1235 $me->{build_data}{Show_Bind} = $old_sb if $old_sb;
998 2         6 undef $me->{build_data}{show};
999 2         11 return $count;
1000             }
1001              
1002             =head3 C
1003              
1004             $query->config(CalcFoundRows => 1); # Only applicable to MySQL
1005             my $total_rows = $query->found_rows;
1006              
1007             Return the number of rows that would have been returned if there was no limit clause. Before runnning the query the C config option can be enabled for improved performance on supported databases.
1008              
1009             Returns undefined if there is an error or is unable to determine the number of found rows.
1010              
1011             =cut
1012              
1013             sub found_rows {
1014 1     1 1 3 my $me = shift;
1015 1 50       16 $me->{DBO}{dbd_class}->_calc_found_rows($me) unless defined $me->{Found_Rows};
1016 1         5 $me->{Found_Rows};
1017             }
1018              
1019             =head3 C
1020              
1021             my $sql = $query->sql;
1022              
1023             Returns the SQL statement string.
1024              
1025             =cut
1026              
1027             sub _search_where_chunk {
1028 157 100       675 map {
1029 163     163   382 ref $_->[0] eq 'ARRAY' ? _search_where_chunk(@$_) : ($_->[1], $_->[4])
1030             } @_
1031             }
1032              
1033             our @_RECURSIVE_SQ;
1034             sub sql {
1035 132     132 1 173 my $me = shift;
1036             # Check for changes to subqueries and recursion
1037 132 50       323 croak 'Recursive subquery found' if grep $me eq $_, @_RECURSIVE_SQ;
1038 132         340 local @_RECURSIVE_SQ = (@_RECURSIVE_SQ, $me);
1039 132         166 for my $fld (@{$me->{build_data}{Showing}}) {
  132         394  
1040 149 50 100     476 if (ref $fld eq 'ARRAY' and @{$fld->[0]} == 1 and _isa($fld->[0][0], 'DBIx::DBO::Query')) {
  118   66     1043  
1041 0         0 my $sq = $fld->[0][0];
1042 0 0 0     0 if ($sq->sql ne ($me->{build_data}{_subqueries}{$sq} ||= '')) {
1043 0         0 undef $me->{sql};
1044 0         0 undef $me->{build_data}{show};
1045             }
1046             }
1047             }
1048 132         210 for my $sq (@{$me->{Tables}}) {
  132         275  
1049 146 50       562 if (_isa($sq, 'DBIx::DBO::Query')) {
1050 0 0 0     0 if ($sq->sql ne ($me->{build_data}{_subqueries}{$sq} ||= '')) {
1051 0         0 undef $me->{sql};
1052 0         0 undef $me->{build_data}{from};
1053             }
1054             }
1055             }
1056 132 100       214 for my $w (map { $_ ? _search_where_chunk(@$_) : () } @{$me->{build_data}{Join_On}}) {
  146         415  
  132         518  
1057 50 50 66     169 if (@$w == 1 and _isa($w->[0], 'DBIx::DBO::Query')) {
1058 0         0 my $sq = $w->[0];
1059 0 0 0     0 if ($sq->sql ne ($me->{build_data}{_subqueries}{$sq} ||= '')) {
1060 0         0 undef $me->{sql};
1061 0         0 undef $me->{build_data}{from};
1062             }
1063             }
1064             }
1065 132         380 for my $w (_search_where_chunk(@{$me->{build_data}{Where_Data}})) {
  132         628  
1066 228 50 66     1642 if (@$w == 1 and _isa($w->[0], 'DBIx::DBO::Query')) {
1067 0         0 my $sq = $w->[0];
1068 0 0 0     0 if ($sq->sql ne ($me->{build_data}{_subqueries}{$sq} ||= '')) {
1069 0         0 undef $me->{sql};
1070 0         0 undef $me->{build_data}{where};
1071             }
1072             }
1073             }
1074 132 100       784 $me->{sql} || $me->_build_sql;
1075             }
1076              
1077             sub _build_sql {
1078 31     31   49 my $me = shift;
1079 31         254 undef $me->{sth};
1080 31         465 undef $me->{hash};
1081 31         62 undef $me->{Row_Count};
1082 31         275 undef $me->{Found_Rows};
1083 31         93 delete $me->{cache};
1084 31         332 $me->{Active} = 0;
1085 31 100       98 if (defined $me->{Row}) {
1086 19 50       31 if (SvREFCNT(${$me->{Row}}) > 1) {
  19         106  
1087 0         0 $me->{Row}->_detach;
1088             } else {
1089 19         31 undef ${$me->{Row}}->{array};
  19         51  
1090 19         37 undef %{$me->{Row}};
  19         89  
1091              
1092 19         124 $me->{sql} = $me->{DBO}{dbd_class}->_build_sql_select($me, $me->{build_data});
1093 19         82 $me->{Row}{from} = $me->{DBO}{dbd_class}->_build_from($me, $me->{build_data});
1094 19         93 $me->{Row}->_copy_build_data;
1095 19         145 return $me->{sql};
1096             }
1097             }
1098 12         16 undef @{$me->{Columns}};
  12         42  
1099              
1100 12         267 $me->{sql} = $me->{DBO}{dbd_class}->_build_sql_select($me);
1101             }
1102              
1103             # Get the DBI statement handle for the query.
1104             # It may not have been executed yet.
1105             sub _sth {
1106 49     49   69 my $me = shift;
1107             # Ensure the sql is rebuilt if needed
1108 49         106 my $sql = $me->sql;
1109 49   66     316 $me->{sth} ||= $me->rdbh->prepare($sql);
1110             }
1111              
1112             =head3 C
1113              
1114             $query->update(department => 'Tech');
1115             $query->update(salary => { FUNC => '? * 1.10', COL => 'salary' }); # 10% raise
1116              
1117             Updates every row in the query with the new values specified.
1118             Returns the number of rows updated or C<'0E0'> for no rows to ensure the value is true,
1119             and returns false if there was an error.
1120              
1121             =cut
1122              
1123             sub update {
1124 2     2 1 766 my $me = shift;
1125 2         20 my @update = $me->{DBO}{dbd_class}->_parse_set($me, @_);
1126 2         16 my $sql = $me->{DBO}{dbd_class}->_build_sql_update($me, @update);
1127 2         18 $me->{DBO}{dbd_class}->_do($me, $sql, undef, $me->{DBO}{dbd_class}->_bind_params_update($me));
1128             }
1129              
1130             =head3 C
1131              
1132             $query->finish;
1133              
1134             Calls Lfinish|DBI/"finish"> on the statement handle, if it's active.
1135             Restarts cached queries from the first row (if created using the C config).
1136             This ensures that the next call to L will return the first row from the query.
1137              
1138             =cut
1139              
1140             sub finish {
1141 18     18 1 45 my $me = shift;
1142 18 100       62 if (defined $me->{Row}) {
1143 6 50       15 if (SvREFCNT(${$me->{Row}}) > 1) {
  6         31  
1144 0         0 $me->{Row}->_detach;
1145             } else {
1146 6         9 undef ${$me->{Row}}{array};
  6         28  
1147 6         14 ${$me->{Row}}{hash} = {};
  6         22  
1148             }
1149             }
1150 18 100       67 if (exists $me->{cache}) {
1151 5         29 $me->{cache}{idx} = 0;
1152             } else {
1153 13 50 33     52 $me->{sth}->finish if $me->{sth} and $me->{sth}{Active};
1154 13         54 $me->{Active} = 0;
1155             }
1156             }
1157              
1158             =head2 Common Methods
1159              
1160             These methods are accessible from all DBIx::DBO* objects.
1161              
1162             =head3 C
1163              
1164             The C object.
1165              
1166             =head3 C
1167              
1168             The I C handle.
1169              
1170             =head3 C
1171              
1172             The I C handle, or if there is no I connection, the I C handle.
1173              
1174             =cut
1175              
1176 5     5 1 35 sub dbo { $_[0]{DBO} }
1177 2     2 1 12 sub dbh { $_[0]{DBO}->dbh }
1178 140     140 1 524 sub rdbh { $_[0]{DBO}->rdbh }
1179              
1180             =head3 C
1181              
1182             $query_setting = $query->config($option);
1183             $query->config($option => $query_setting);
1184              
1185             Get or set this C object's config settings. When setting an option, the previous value is returned. When getting an option's value, if the value is undefined, the L's value is returned.
1186              
1187             See: L.
1188              
1189             =cut
1190              
1191             sub config {
1192 220     220 1 15397 my $me = shift;
1193 220         312 my $opt = shift;
1194 220 100 50     664 return $me->{DBO}{dbd_class}->_set_config($me->{Config} ||= {}, $opt, shift) if @_;
1195 192   100     1231 $me->{DBO}{dbd_class}->_get_config($opt, $me->{Config} ||= {}, $me->{DBO}{Config}, \%DBIx::DBO::Config);
1196             }
1197              
1198             sub STORABLE_freeze {
1199 5     5 0 12464 my($me, $cloning) = @_;
1200 5 100       125 return unless defined $me->{sth};
1201              
1202 2         5 local $me->{sth};
1203 2         5 local $me->{Row};
1204 2 50       7 local $me->{hash} unless exists $me->{cache};
1205 2 50       7 local $me->{Active} = 0 unless exists $me->{cache};
1206 2 50       8 local $me->{cache}{idx} = 0 if exists $me->{cache};
1207 2         5 return Storable::nfreeze($me);
1208             }
1209              
1210             sub STORABLE_thaw {
1211 2     2 0 883 my($me, $cloning, @frozen) = @_;
1212 2         5 %$me = %{ Storable::thaw(@frozen) };
  2         8  
1213             }
1214              
1215             sub DESTROY {
1216 15     15   1551 undef %{$_[0]};
  15         281  
1217             }
1218              
1219             1;
1220              
1221             __END__