File Coverage

blib/lib/DBIx/Query.pm
Criterion Covered Total %
statement 277 392 70.6
branch 49 118 41.5
condition 20 41 48.7
subroutine 72 94 76.6
pod 2 2 100.0
total 420 647 64.9


line stmt bran cond sub pod time code
1             package DBIx::Query;
2             # ABSTRACT: Simplified abstracted chained DBI subclass
3              
4 3     3   846557 use 5.010;
  3         14  
5 3     3   21 use strict;
  3         7  
  3         95  
6 3     3   19 use warnings;
  3         7  
  3         328  
7              
8             our $VERSION = '1.17'; # VERSION
9              
10 3     3   9936 use DBI 1.40;
  3         75966  
  3         274  
11 3     3   1037 use parent 'DBI';
  3         647  
  3         20  
12              
13             {
14 3     3   220 no warnings 'once';
  3         5  
  3         964  
15             *errstr = \*DBI::errstr;
16             }
17              
18             sub _connect {
19 4     4   18 my ( $self, $dsn, $user, $pass, $attr, $connect ) = @_;
20              
21 4 100       20 $attr = ($attr) ? \%$attr : {};
22 4 50       43 $attr->{PrintError} = 0 unless ( exists $attr->{PrintError} );
23 4 100       20 $attr->{RaiseError} = 1 unless ( exists $attr->{RaiseError} );
24              
25 4 50       62 return $self->SUPER::connect( $dsn, $user, $pass, {
26             %$attr,
27             dbi_connect_method => ( $DBI::connect_via eq 'Apache::DBI::connect' )
28             ? 'Apache::DBI::connect' : $connect,
29             } );
30             }
31              
32             sub connect {
33 3     3 1 213934 my ( $self, $dsn, $user, $pass, $attr ) = @_;
34 3         16 return $self->_connect( $dsn, $user, $pass, $attr, 'connect_cached' );
35             }
36              
37             sub connect_uncached {
38 1     1 1 279538 my ( $self, $dsn, $user, $pass, $attr ) = @_;
39 1         7 return $self->_connect( $dsn, $user, $pass, $attr, 'connect' );
40             }
41              
42             #-----------------------------------------------------------------------------
43              
44             {
45             package DBIx::Query::_Common;
46 3     3   22 use strict;
  3         25  
  3         124  
47 3     3   19 use warnings;
  3         23  
  3         171  
48 3     3   17 use Carp 'croak';
  3         6  
  3         1023  
49              
50             sub _param {
51 213     213   1910 my $self = shift;
52 213         371 my $name = shift;
53              
54 213 50       472 return unless ($name);
55 213 100       1053 $self->{'private_dq_stash'}{$name} = shift if (@_);
56 213         1928 return $self->{'private_dq_stash'}{$name};
57             }
58              
59             sub _try {
60 40     40   116 my ( $self, $cb ) = @_;
61              
62 40         117 local $@;
63 40         125 eval { $cb->() };
  40         77  
64 40 50       3679 if ($@) {
65 0         0 ( my $error = $@ ) =~ s/\s*at.+?line \d+\.\s*//;
66 0         0 croak $error;
67             }
68             }
69             }
70              
71             #-----------------------------------------------------------------------------
72              
73             {
74             package DBIx::Query::db;
75 3     3   22 use strict;
  3         5  
  3         83  
76 3     3   16 use warnings;
  3         4  
  3         151  
77 3     3   2971 use SQL::Parser;
  3         140348  
  3         265  
78 3     3   3497 use SQL::Abstract::Complete;
  3         95350  
  3         195  
79 3     3   48 use Carp 'carp';
  3         21  
  3         194  
80              
81 3     3   19 use vars '@ISA';
  3         6  
  3         5106  
82             @ISA = qw( DBI::db DBIx::Query::_Common );
83              
84             sub connected {
85 4     4   39672 my $self = shift;
86              
87 4         13 my $connection = {};
88 4         28 @{$connection}{qw( dsn user pass attr )} = @_;
  4         27  
89              
90 4         32 $self->_param( 'connection' => $connection );
91 4         60 $self->_param( 'sql_abstract' => SQL::Abstract::Complete->new );
92              
93             my $dialect = ( ref $connection eq 'HASH' and ref $connection->{attr} eq 'HASH' )
94             ? $connection->{attr}{dq_dialect}
95 4 50 33     55 : undef;
96              
97 4   100     60 my $sql_parser = SQL::Parser->new(
98             ( $dialect || 'ANSI' ),
99             { 'RaiseError' => 0, 'PrintError' => 0 },
100             );
101              
102 4 100       118487 unless ($dialect) {
103             $sql_parser->feature( 'reserved_words', $_, 0 )
104 3         7 for ( keys %{ $sql_parser->{opts}{reserved_words} } );
  3         170  
105             }
106              
107 4         5210 $self->_param( 'sql_parser' => $sql_parser );
108 4         16 $self->_param( '_dq_parser_cache' => {} );
109              
110 4         21 return;
111             }
112              
113             sub connection {
114 7     7   10064 my $self = shift;
115              
116             return
117 2         27 ( @_ == 0 and wantarray ) ? @{ $self->_param('connection') }{ qw( dsn user pass attr ) } :
118             ( @_ == 0 and not wantarray ) ? $self->_param('connection') :
119 1         5 ( @_ > 1 and wantarray ) ? @{ $self->_param('connection') }{@_} :
120 1         30 ( @_ > 1 and not wantarray ) ? [ @{ $self->_param('connection') }{@_} ] :
121 7 100 100     78 @{ $self->_param('connection') }{@_};
  1 100 66     5  
    100 100        
    100 66        
122             }
123              
124             sub _sth_setup {
125 22     22   50 my ( $self, $sql, $attr, $cache_type, $variables ) = @_;
126              
127 22         39 my $sth;
128             $self->_try( sub {
129 22 100 66 22   254 $sth = ( defined $cache_type and $cache_type == -1 )
130             ? $self->SUPER::prepare( $sql, $attr )
131             : $self->SUPER::prepare_cached( $sql, $attr, $cache_type );
132 22         168 } );
133              
134 22         131 return $sth;
135             }
136              
137             sub _query {
138 22     22   65 my ( $self, $sql, $attr, $cache_type, $variables ) = @_;
139 22   100     114 $cache_type //= 3;
140              
141 22         60 my $sth = $self->_sth_setup( $sql, $attr, $cache_type, $variables );
142              
143 22         653 $sql =~ s/(\r?\n|\s+)/ /g;
144 22         265 $sql =~ s/^\s+|\s+$//g;
145              
146 22         86 $sth->_param( 'sql' => $sql );
147 22         75 $sth->_param( 'dq' => $self );
148 22         96 $sth->_param( 'variables' => $variables );
149              
150 22         67 return $sth;
151             }
152              
153             sub sql {
154 7     7   9995 my ( $self, $sql, $attr, $cache_type, $variables ) = @_;
155 7 50       29 $self->_croak('SQL input missing in sql() call') unless ( length $sql );
156 7         22 return $self->_query( $sql, $attr, $cache_type, $variables );
157             }
158              
159             sub get {
160 15     15   716 my ( $self, $tables, $columns, $where, $meta, $attr, $cache_type ) = @_;
161 15         45 my ( $sql, @variables ) = $self->_param('sql_abstract')->select( $tables, $columns, $where, $meta );
162 15         13144 my $sth = $self->_query( $sql, $attr, $cache_type, \@variables );
163              
164 15         137 $sth->_param( 'query' => {
165             'tables' => $tables,
166             'columns' => $columns,
167             'where' => $where,
168             'meta' => $meta,
169             'attr' => $attr,
170             'cache_type' => $cache_type,
171             'sql' => $sql,
172             'variables' => \@variables,
173             } );
174              
175 15         68 return $sth;
176             }
177              
178             sub sql_uncached {
179 1     1   5 my ( $self, $sql, $attr, $cache_type, $variables ) = @_;
180 1         2 $cache_type = -1;
181 1         4 return $self->sql( $sql, $attr, $cache_type, $variables );
182             }
183              
184             sub get_uncached {
185 1     1   4 my ( $self, $tables, $columns, $where, $meta, $attr, $cache_type ) = @_;
186 1         2 $cache_type = -1;
187 1         4 return $self->get( $tables, $columns, $where, $meta, $attr, $cache_type );
188             }
189              
190             sub sql_fast {
191 0     0   0 my $self = shift;
192 0         0 carp('sql_fast() is deprecated in favor of sql()');
193 0         0 return $self->sql(@_);
194             }
195              
196             sub get_fast {
197 0     0   0 my $self = shift;
198 0         0 carp('get_fast() is deprecated in favor of get()');
199 0         0 return $self->get(@_);
200             }
201              
202             sub add {
203 1     1   4 my ( $self, $table_name, $params, $attr, $cache_type ) = @_;
204 1         4 my ( $sql, @variables ) = $self->_param('sql_abstract')->insert( $table_name, $params );
205              
206             $self->_try( sub {
207 1     1   5 my $sth = $self->sql( $sql, $attr, $cache_type, \@variables );
208 1 50       4 $sth->execute( @{ $sth->_param('variables') || [] } );
  1         3  
209 1         2435 } );
210              
211 1         5 my $pk;
212 1         3 eval {
213             $pk = $self->last_insert_id(
214             undef,
215             undef,
216 1   33     19 delete $attr->{'last_insert_table'} || $table_name,
217             undef,
218             $attr,
219             );
220             };
221              
222 1         3 $self->_param( 'table' => $table_name );
223              
224 1         4 return $pk;
225             }
226              
227             sub rm {
228 1     1   5 my ( $self, $table_name, $params, $attr, $cache_type ) = @_;
229              
230 1         4 my ( $sql, @variables ) = $self->_param('sql_abstract')->delete( $table_name, $params );
231 1         1301 my $sth = $self->sql( $sql, $attr, $cache_type, \@variables );
232              
233 1         5 $sth->run;
234 1         30 return $self;
235             }
236              
237             sub update {
238 1     1   4 my ( $self, $table_name, $params, $where, $attr, $cache_type ) = @_;
239              
240 1         4 my ( $sql, @variables ) = $self->_param('sql_abstract')->update( $table_name, $params, $where );
241 1         2134 my $sth = $self->sql( $sql, $attr, $cache_type, \@variables );
242              
243 1         6 $sth->run;
244 1         5 return $self;
245             }
246              
247             sub abstract {
248 1     1   5 return $_[0]->_param('sql_abstract');
249             }
250              
251             sub get_run {
252 5     5   12 my $self = shift;
253 5         20 my $sth = $self->get(@_);
254              
255             $self->_try( sub {
256 5 50   5   8 $sth->execute( @{ $sth->_param('variables') || [] } );
  5         12  
257 5         36 } );
258              
259 5         40 return $sth;
260             }
261              
262             sub fetch_value {
263 1     1   3 my $self = shift;
264 1         3 my $sth = $self->get_run(@_);
265 1         3 my $value;
266              
267             $self->_try( sub {
268 1     1   15 $value = ( $sth->fetchrow_array )[0];
269 1         25 $sth->finish;
270 1         8 } );
271              
272 1         5 return $value;
273             }
274              
275             sub fetchall_arrayref {
276 2     2   589 my $self = shift;
277 2         7 my $sth = $self->get_run(@_);
278 2         5 my $value;
279              
280             $self->_try( sub {
281 2     2   40 $value = $sth->fetchall_arrayref;
282 2         339 $sth->finish;
283 2         44 } );
284              
285 2         14 return $value;
286             }
287              
288             sub fetchall_hashref {
289 1     1   580 my $self = shift;
290 1         4 my $sth = $self->get_run(@_);
291 1         2 my $value;
292              
293             $self->_try( sub {
294 1     1   6 $value = $sth->fetchall_arrayref({});
295 1         280 $sth->finish;
296 1         8 } );
297              
298 1         13 return $value;
299             }
300              
301             sub fetch_column_arrayref {
302 1     1   632 my $self = shift;
303 1         3 return [ map { $_->[0] } @{ $self->fetchall_arrayref(@_) } ];
  11         29  
  1         5  
304             }
305              
306             sub fetchrow_hashref {
307 0     0   0 my ( $self, $sql ) = ( shift, shift );
308 0 0       0 $self->_croak('SQL input missing in sql() call') unless ( length $sql );
309              
310 0         0 my ( $variables, $attr, $cache_type );
311 0 0 0     0 if ( not defined $_[0] or ref $_[0] eq 'HASH' ) {
312 0         0 ( $variables, $attr, $cache_type ) = @_;
313             }
314             else {
315 0         0 $variables = \@_;
316             }
317 0   0     0 $cache_type //= 3;
318              
319 0         0 my $row;
320             $self->_try( sub {
321 0     0   0 my $sth = $self->_sth_setup( $sql, $attr, $cache_type, $variables );
322 0         0 $sth->execute(@$variables);
323 0         0 $row = $sth->fetchrow_hashref;
324 0         0 $sth->finish;
325 0         0 } );
326              
327 0         0 return $row;
328             }
329             }
330              
331             #-----------------------------------------------------------------------------
332              
333             {
334             package DBIx::Query::st;
335 3     3   40 use strict;
  3         14  
  3         65  
336 3     3   12 use warnings;
  3         3  
  3         263  
337 3     3   16 use Carp qw( croak carp );
  3         8  
  3         152  
338              
339 3     3   14 use vars '@ISA';
  3         3  
  3         1340  
340             @ISA = qw( DBI::st DBIx::Query::_Common );
341              
342             sub where {
343 0     0   0 my $self = shift;
344              
345 0 0       0 croak('Unable to call where() because upstream query not originated with get()')
346             unless ( $self->_param('query') );
347              
348 0 0 0     0 croak('where() requires a hashref or an even number of items in a list')
349             if ( ref( $_[0] ) ne 'HASH' and @_ % 2 );
350              
351 0         0 my $query = $self->_param('query');
352 0 0       0 $query->{'where'} = { %{ $query->{'where'} || {} }, ( ref( $_[0] ) eq 'HASH' ) ? %{ $_[0] } : @_ };
  0 0       0  
  0         0  
353              
354 0         0 return $self->up->get( @{$query}{ qw( tables columns where meta attr cache_type ) } );
  0         0  
355             }
356              
357             sub run {
358 6     6   14 my $self = shift;
359 6         13 my @input = @_;
360              
361             $self->_try( sub {
362 6 50   6   16 $self->execute( (@input) ? @input : @{ $self->_param('variables') || [] } );
  6 50       14  
363 6         43 } );
364              
365 6         42 return DBIx::Query::_Dq::RowSet->new($self);
366             }
367              
368             sub sql {
369 3     3   31 my ( $self, $sql ) = @_;
370 3 50       13 return ($sql) ? $self->_param('dq')->sql($sql) : $self->_param('sql');
371             }
372              
373             sub structure {
374 8     8   491 my $self = shift;
375              
376 8         23 my $saved_structure = $self->_param('structure');
377 8 100       31 return $saved_structure if ($saved_structure);
378 7 50       17 return if ( $self->_param('no_structure') );
379              
380 7         23 my $sql = $self->_param('sql');
381 7         20 my $dq_parser_cache = $self->_param('dq')->_param('_dq_parser_cache');
382              
383 7 100       48 unless ( $dq_parser_cache->{$sql} ) {
384 4         13 $self->_param('dq')->_param('sql_parser')->parse($sql);
385 4         6157 my $parsed_structure = $self->_param('dq')->_param('sql_parser')->structure;
386 4         59 $dq_parser_cache->{$sql} = $parsed_structure;
387 4 100       328 carp $parsed_structure->{'errstr'} if ( $parsed_structure->{errstr} );
388             }
389              
390 7         36 $self->_param( 'wildcard_column' => 0 );
391              
392 7 50       27 if ( $dq_parser_cache->{$sql} ) {
393 7         15 my $structure = $dq_parser_cache->{$sql};
394 7         14 my $column_index = 0;
395 7         15 my %aliases;
396              
397             {
398 3     3   20 no warnings;
  3         6  
  3         1229  
  7         14  
399             $structure->{'column_lookup'} = {
400             map {
401 11         20 my $index = $column_index++;
402 11 50       32 $aliases{ $_->{'alias'} } = $index if ( $_->{'alias'} );
403 11 100       35 $self->_param( 'wildcard_column' => 1 ) if ( $_->{'value'} eq '*' );
404 11         50 $_->{'value'} => $index;
405 7         14 } @{ $structure->{'column_defs'} }
  7         20  
406             };
407             };
408              
409             $structure->{'column_invert_lookup'} = {
410 7         17 map { $structure->{'column_lookup'}->{$_} => $_ } keys %{ $structure->{'column_lookup'} }
  11         49  
  7         25  
411             };
412 7         28 foreach ( keys %aliases ) {
413 0         0 $structure->{'column_lookup'}{$_} = $aliases{$_};
414 0         0 $structure->{'column_invert_lookup'}{ $aliases{$_} } = $_;
415             }
416              
417 7         36 $self->_param( 'structure' => $structure );
418 7         84 return $structure;
419             }
420             else {
421 0         0 $self->_param( 'no_structure' => 1 );
422 0         0 return;
423             }
424             }
425              
426             sub table {
427 1     1   4 return shift->structure->{'table_names'}[0];
428             }
429              
430             sub _wildcard_column {
431 2     2   4 my $self = shift;
432              
433 2         7 my $wildcard_column = $self->_param('wildcard_column');
434 2 50       9 return $wildcard_column if ( defined $wildcard_column );
435              
436 2         8 $self->structure;
437 2         5 return $self->_param('wildcard_column');
438             }
439              
440             sub up {
441 1     1   54 return shift->_param('dq');
442             }
443             }
444              
445             #-----------------------------------------------------------------------------
446              
447             {
448             package DBIx::Query::_Dq::RowSet;
449 3     3   29 use strict;
  3         4  
  3         67  
450 3     3   12 use warnings;
  3         5  
  3         126  
451 3     3   14 use Carp 'croak';
  3         4  
  3         2125  
452              
453             sub new {
454 6     6   42 my ( $self, $sth ) = @_;
455 6         35 return bless( { 'sth' => $sth }, $self );
456             }
457              
458             sub next {
459 2     2   24 my ( $self, $skip ) = @_;
460 2   50     14 $skip ||= 0;
461              
462 2 50       21 my $method = ( $self->{'sth'}->_wildcard_column ) ? 'fetchrow_hashref' : 'fetchrow_arrayref';
463              
464 2         5 my $value;
465             DBIx::Query::_Common::_try( $self, sub {
466 2     2   7 $self->{'sth'}->fetchrow_arrayref while ( $skip-- );
467              
468 2 50       17 if ( my $row = $self->{'sth'}->$method ) {
469 2         48 $value = DBIx::Query::_Dq::Row->new( $row, $self );
470             }
471 2         13 } );
472              
473 2 50       23 return $value if ($value);
474             }
475              
476             sub all {
477 0     0   0 my $self = shift;
478 0         0 my @input = @_;
479              
480 0         0 my $value;
481             DBIx::Query::_Common::_try( $self, sub {
482 0     0   0 $value = $self->{'sth'}->fetchall_arrayref(@input);
483 0         0 $self->{'sth'}->finish;
484 0         0 } );
485              
486 0         0 return $value;
487             }
488              
489             sub each {
490 0     0   0 my ( $self, $code ) = @_;
491 0 0       0 my $method = ( $self->{'sth'}->_wildcard_column ) ? 'fetchrow_hashref' : 'fetchrow_arrayref';
492              
493             DBIx::Query::_Common::_try( $self, sub {
494 0     0   0 $code->( DBIx::Query::_Dq::Row->new( $_, $self ) ) while ( $_ = $self->{'sth'}->$method );
495 0         0 $self->{'sth'}->finish;
496 0         0 } );
497              
498 0         0 return $self;
499             }
500              
501             sub value {
502 0     0   0 my $self = shift;
503              
504 0         0 my @value;
505             DBIx::Query::_Common::_try( $self, sub {
506 0     0   0 @value = $self->{'sth'}->fetchrow_array;
507 0         0 $self->{'sth'}->finish;
508 0         0 } );
509              
510 0         0 my $wantarray = wantarray;
511 0 0       0 if ( not defined $wantarray ) {
    0          
512 0         0 croak('value() must not be called in void context');
513             }
514             elsif ( not wantarray ) {
515 0 0       0 if ( @value < 2 ) {
516 0         0 return $value[0];
517             }
518             else {
519 0         0 croak('value() called in scalar context but multiple values fetched');
520             }
521             }
522             else {
523 0         0 return @value;
524             }
525             }
526              
527             sub first {
528 0     0   0 my ( $self, $type ) = @_;
529 0 0       0 my $method = ( ref $type eq 'HASH' ) ? 'fetchrow_hashref' : 'fetchrow_arrayref';
530              
531 0         0 my $value;
532             DBIx::Query::_Common::_try( $self, sub {
533 0     0   0 $value = $self->{'sth'}->$method;
534 0         0 $self->{'sth'}->finish;
535 0         0 } );
536              
537 0         0 return $value;
538             }
539              
540             sub column {
541 0     0   0 my $self = shift;
542 0         0 my @values = map { $_->[0] } @{ ( $self->all )[0] };
  0         0  
  0         0  
543              
544 0 0       0 return (wantarray) ? @values : \@values;
545             }
546              
547             sub up {
548 2     2   14 return shift->{'sth'};
549             }
550             }
551              
552             #-----------------------------------------------------------------------------
553              
554             {
555             package DBIx::Query::_Dq::Row;
556 3     3   21 use strict;
  3         6  
  3         79  
557 3     3   12 use warnings;
  3         4  
  3         133  
558 3     3   13 use Carp 'croak';
  3         5  
  3         2796  
559              
560             sub new {
561 2     2   5 my ( $self, $row, $set ) = @_;
562 2         12 return bless(
563             {
564             'row' => $row,
565             'set' => $set,
566             },
567             $self,
568             );
569             }
570              
571             sub cell {
572 1     1   4 my ( $self, $index, $new_value ) = @_;
573 1         5 my ( $name, $structure, $value ) = ( $index, $self->up->up->structure, undef );
574              
575 1 50       6 croak('Query used earlier in chain failed to parse, so cell() cannot be called')
576             unless ( ref($structure) eq 'HASH' );
577              
578 1 50       5 if ( ref( $self->{'row'} ) eq 'ARRAY' ) {
579 1 50       5 unless ( $index =~ /^\d+$/ ) {
580 1         2 $name = $index;
581 1         4 $index = $structure->{'column_lookup'}{$index};
582             }
583 1 50 33     29 return undef unless ( defined $index and $index < @{ $self->{'row'} } );
  1         6  
584 1         4 $value = $self->{'row'}[$index];
585             }
586             else {
587 0 0       0 croak('cell() called with integer index but query does not support integer indexing')
588             if ( $index =~ /^\d+$/ );
589              
590 0 0       0 return undef unless ( exists $self->{'row'}{$index} );
591 0         0 $value = $self->{'row'}{$index};
592             }
593              
594 1 50       4 if ( defined $new_value ) {
595 0 0       0 if ( ref( $self->{'row'} ) eq 'ARRAY' ) {
596 0         0 $self->{'row'}[$index] = $new_value;
597             }
598             else {
599 0         0 $self->{'row'}{$name} = $new_value;
600             }
601 0         0 $value = $new_value;
602             }
603              
604 1         10 return DBIx::Query::_Dq::Cell->new( $name, $value, $index, $self );
605             }
606              
607             sub each {
608 0     0   0 my ( $self, $code ) = @_;
609              
610             croak('each() called on a row object that does not have columns defined')
611 0 0       0 if ( ref( $self->{'row'} ) ne 'ARRAY' );
612              
613 0         0 for ( my $i = 0 ; $i < @{ $self->{'row'} } ; $i++ ) {
  0         0  
614             $code->(
615             DBIx::Query::_Dq::Cell->new(
616             $self->up->up->structure->{'column_lookup'}{$i},
617 0         0 $self->{'row'}[$i],
618             $i, $self,
619             )
620             );
621             }
622              
623 0         0 return $self;
624             }
625              
626             sub data {
627 0     0   0 my ($self) = @_;
628              
629 0 0       0 if ( ref( $self->{'row'} ) eq 'ARRAY' ) {
630 0         0 my $structure = $self->up->up->structure;
631 0 0 0     0 if ( ref($structure) eq 'HASH' and $structure->{'column_invert_lookup'} ) {
632             return {
633             map {
634 0         0 $structure->{'column_invert_lookup'}->{$_} => $self->{'row'}[$_]
635 0         0 } ( 0 .. scalar( @{ $self->{'row'} } ) - 1 )
  0         0  
636             };
637             }
638             else {
639 0         0 croak('Unable to parse SQL, therefore data() unavailable; use row() instead');
640             }
641             }
642             else {
643 0         0 return $self->{'row'};
644             }
645             }
646              
647             sub row {
648 0     0   0 my ($self) = @_;
649             croak('For this particular query, use data() instead')
650 0 0       0 unless ( ref( $self->{'row'} ) eq 'ARRAY' );
651 0         0 return $self->{'row'};
652             }
653              
654             sub save {
655 0     0   0 my ( $self, $key, $params, $cache_type ) = @_;
656              
657 0 0       0 croak('save() called without a key or set of keys') unless ($key);
658              
659 0         0 my $data = $self->data;
660 0 0       0 if ( ref($params) eq 'HASH' ) {
661 0         0 $data->{$_} = $params->{$_} foreach ( keys %{$params} );
  0         0  
662             }
663              
664 0         0 my $dq = $self->up->up->up;
665              
666             my ( $sql, @variables ) = $dq->_param('sql_abstract')->update(
667             $self->up->up->table,
668             $data,
669 0 0       0 { map { $_ => delete $data->{$_} } ( ref($key) ? @{$key} : $key ) },
  0         0  
  0         0  
670             );
671 0         0 my $sth = $dq->sql( $sql, undef, $cache_type, \@variables );
672              
673 0         0 $sth->run;
674 0         0 return $self;
675             }
676              
677             sub up {
678 2     2   9 return shift->{'set'};
679             }
680             }
681              
682             #-----------------------------------------------------------------------------
683              
684             {
685             package DBIx::Query::_Dq::Cell;
686 3     3   22 use strict;
  3         4  
  3         61  
687 3     3   35 use warnings;
  3         73  
  3         813  
688              
689             sub new {
690 1     1   5 my ( $self, $name, $value, $index, $row ) = @_;
691 1         10 return bless(
692             {
693             'name' => $name,
694             'value' => $value,
695             'index' => $index,
696             'row' => $row,
697             },
698             $self,
699             );
700             }
701              
702             sub name {
703 0     0   0 return shift->{'name'};
704             }
705              
706             sub value {
707 0     0   0 my ( $self, $new_value ) = @_;
708 0 0       0 return ( defined $new_value ) ? $self->up->cell( $self->name, $new_value ) : $self->{'value'};
709             }
710              
711             sub index {
712 0     0   0 return shift->{'index'};
713             }
714              
715             sub save {
716 0     0   0 return shift->up->save(@_);
717             }
718              
719             sub up {
720 1     1   10 return shift->{'row'};
721             }
722             }
723              
724             1;
725              
726             __END__