File Coverage

blib/lib/ActiveRecord/Simple/Find.pm
Criterion Covered Total %
statement 306 382 80.1
branch 98 160 61.2
condition 40 70 57.1
subroutine 32 38 84.2
pod 19 23 82.6
total 495 673 73.5


line stmt bran cond sub pod time code
1             package ActiveRecord::Simple::Find;
2              
3 11     11   202 use 5.010;
  11         37  
4 11     11   58 use strict;
  11         20  
  11         220  
5 11     11   49 use warnings;
  11         20  
  11         309  
6 11     11   1210 use vars qw/$AUTOLOAD/;
  11         23  
  11         427  
7              
8 11     11   55 use Carp;
  11         26  
  11         569  
9 11     11   65 use Storable qw/freeze/;
  11         23  
  11         429  
10 11     11   60 use Module::Load;
  11         28  
  11         56  
11              
12 11     11   1880 use parent 'ActiveRecord::Simple';
  11         1460  
  11         94  
13              
14              
15             our $MAXIMUM_LIMIT = 100_000_000_000;
16              
17              
18             sub new {
19 83     83 1 201 my ($self_class, $class, @param) = @_;
20              
21             #my $self = $class->new();
22 83         213 my $self = bless { class => $class } => $self_class;
23              
24 83 50       776 my $table_name = ($self->{class}->can('_get_table_name')) ? $self->{class}->_get_table_name : undef;
25 83 100       344 my $pkey = ($self->{class}->can('_get_primary_key')) ? $self->{class}->_get_primary_key : undef;
26              
27 83   50     403 $self->{prep_select_fields} //= [];
28 83   50     305 $self->{prep_select_from} //= [];
29 83   50     296 $self->{prep_select_where} //= [];
30              
31 83         136 my ($fields, $from, $where);
32              
33 83 100 100     486 if (!ref $param[0] && scalar @param == 1) {
    100 100        
    100 100        
    100 66        
34 15         44 $fields = qq/"$table_name".*/;
35 15         29 $from = qq/"$table_name"/;
36 15         35 $where = qq/"$table_name"."$pkey" = ?/;
37              
38             $self->{BIND} = \@param
39 15         60 }
40             elsif (!ref $param[0] && scalar @param == 0) {
41 32         70 $fields = qq/"$table_name".*/;
42 32         57 $from = qq/"$table_name"/;
43              
44 32         53 $self->{BIND} = undef;
45             }
46             elsif (ref $param[0] && ref $param[0] eq 'HASH') {
47             # find many by params
48 26         74 my ($bind, $condition_pairs) = $self->parse_hash($param[0]);
49              
50 26         92 my $where_str = join q/ AND /, @$condition_pairs;
51              
52 26         58 $fields = qq/"$table_name".*/;
53 26         51 $from = qq/"$table_name"/;
54 26         37 $where = $where_str;
55              
56 26         60 $self->{BIND} = $bind;
57             }
58             elsif (ref $param[0] && ref $param[0] eq 'ARRAY') {
59             # find many by primary keys
60 3         6 my $whereinstr = join ', ', @{ $param[0] };
  3         11  
61              
62 3         8 $fields = qq/"$table_name".*/;
63 3         11 $from = qq/"$table_name"/;
64 3         9 $where = qq/"$table_name"."$pkey" IN ($whereinstr)/;
65              
66 3         6 $self->{BIND} = undef;
67             }
68             else {
69             # find many by condition
70 7         17 my $wherestr = shift @param;
71              
72 7         19 $fields = qq/"$table_name".*/;
73 7         16 $from = qq/"$table_name"/;
74 7         10 $where = $wherestr;
75              
76 7         16 $self->{BIND} = \@param;
77             }
78              
79 83 50       179 push @{ $self->{prep_select_fields} }, $fields if $fields;
  83         193  
80 83 50       165 push @{ $self->{prep_select_from} }, $from if $from;
  83         143  
81 83 100       149 push @{ $self->{prep_select_where} }, $where if $where;
  51         94  
82              
83 83         308 return $self;
84             }
85              
86             sub count {
87 7     7 1 15 my $inv = shift;
88 7 50       24 my $self = ref $inv ? $inv : $inv->new(@_);
89 7         21 $self->{prep_select_fields} = [ 'COUNT(*)' ];
90 7 100       15 if (@{ $self->{prep_group_by} || [] }) {
  7 100       46  
91 2         6 my $table_name = $self->{class}->_get_table_name;
92 2         4 push @{ $self->{prep_select_fields} }, map qq/"$table_name".$_/, @{ $self->{prep_group_by} };
  2         5  
  2         9  
93 2         4 my @group_by = @{ $self->{prep_group_by} };
  2         6  
94 2         13 s/"//g foreach @group_by;
95 2         4 my @results;
96 2         7 foreach my $item ($self->fetch) {
97 7         14 push my @line, (count => $item->{'COUNT(*)'}), map {$_ => $item->$_} @group_by;
  7         15  
98 7         22 push @results, { @line };
99             }
100 2         21 return @results;
101             }
102             else {
103 5         21 return $self->fetch->{'COUNT(*)'};
104             }
105             }
106              
107             sub parse_hash {
108 26     26 0 58 my ($self, $param_hash) = @_;
109 26         44 my $class = $self->{class};
110 26 50       154 my $table_name = ($self->{class}->can('_get_table_name')) ? $self->{class}->_get_table_name : undef;
111 26         60 my ($bind, $condition_pairs) = ([],[]);
112 26         44 for my $param_name (keys %{ $param_hash }) {
  26         92  
113 28 50 33     109 if (ref $param_hash->{$param_name} eq 'ARRAY' and !ref $param_hash->{$param_name}[0]) {
    100          
114 0         0 my $instr = join q/, /, map { '?' } @{ $param_hash->{$param_name} };
  0         0  
  0         0  
115 0         0 push @$condition_pairs, qq/"$table_name"."$param_name" IN ($instr)/;
116 0         0 push @$bind, @{ $param_hash->{$param_name} };
  0         0  
117             }
118             elsif (ref $param_hash->{$param_name}) {
119 2 50       11 next if !$class->can('_get_relations');
120 2 50       7 my $relation = $class->_get_relations->{$param_name} or next;
121              
122 2 50       6 next if $relation->{type} ne 'one';
123 2         5 my $fk = $relation->{params}{fk};
124 2         5 my $pk = $relation->{params}{pk};
125              
126 2 50       6 if (ref $param_hash->{$param_name} eq __PACKAGE__) {
127 0         0 my $object = $param_hash->{$param_name};
128              
129 0         0 my $tmp_table = qq/tmp_table_/ . sprintf("%x", $object);
130 0         0 my $request_table = $object->{class}->_get_table_name;
131              
132 0         0 $object->{prep_select_fields} = [qq/"$request_table"."$pk"/];
133 0         0 $object->_finish_sql_stmt;
134              
135 0         0 push @$condition_pairs, qq/"$table_name"."$fk" IN (SELECT "$tmp_table"."$pk" from ($object->{SQL}) as $tmp_table)/;
136 0 0       0 push @$bind, @{ $object->{BIND} } if ref $object->{BIND} eq 'ARRAY';
  0         0  
137             }
138             else {
139 2         4 my $object = $param_hash->{$param_name};
140              
141 2 50       5 if (ref $object eq 'ARRAY') {
142 0         0 push @$bind, map $_->$pk, @$object;
143 0         0 push @$condition_pairs, qq/"$table_name"."$fk" IN (@{[ join ', ', map "?", @$object ]})/;
  0         0  
144             }
145             else {
146 2         9 push @$condition_pairs, qq/"$table_name"."$fk" = ?/;
147 2         7 push @$bind, $object->$pk;
148             }
149             }
150             }
151             else {
152 26 50       62 if (defined $param_hash->{$param_name}) {
153 26         88 push @$condition_pairs, qq/"$table_name"."$param_name" = ?/;
154 26         58 push @$bind, $param_hash->{$param_name};
155             }
156             else {
157             # is NULL
158 0         0 push @$condition_pairs, qq/"$table_name"."$param_name" IS NULL/;
159             }
160             }
161             }
162 26         77 return ($bind, $condition_pairs);
163             }
164              
165             sub first {
166 6     6 1 14 my ($self, $limit) = @_;
167              
168 6   100     25 $limit //= 1;
169              
170 6 50       23 $self->{class}->can('_get_primary_key') or croak 'Can\'t use "first" without primary key';
171 6         17 my $primary_key = $self->{class}->_get_primary_key;
172              
173 6         17 return $self->order_by($primary_key)->limit($limit)->fetch;
174             }
175              
176             sub last {
177 3     3 1 8 my ($self, $limit) = @_;
178              
179 3 50       13 $self->{class}->can('_get_primary_key') or croak 'Can\'t use "first" without primary key';
180 3         9 my $primary_key = $self->{class}->_get_primary_key;
181 3   50     14 $limit //= 1;
182              
183 3         8 return $self->order_by($primary_key)->desc->limit($limit)->fetch;
184             }
185              
186             sub only {
187 8     8 1 19 my ($self, @fields) = @_;
188              
189 8 50       19 scalar @fields > 0 or croak 'Not defined fields for method "only"';
190 8 50       20 ref $self or croak 'Create an object abstraction before using the modifiers. Use methods like `find`, `first`, `last` at the beginning';
191              
192 8 50       31 if ($self->{class}->can('_get_primary_key')) {
193 8         21 my $pk = $self->{class}->_get_primary_key;
194 8 100       17 push @fields, $pk if ! grep { $_ eq $pk } @fields;
  10         34  
195             }
196              
197 8         21 my $table_name = $self->{class}->_get_table_name;
198 8 100       54 my $mixins = $self->{class}->can('_get_mixins') ? $self->{class}->_get_mixins : undef;
199              
200             my @filtered_prep_select_fields =
201 8         16 grep { $_ ne qq/"$table_name".*/ } @{ $self->{prep_select_fields} };
  8         27  
  8         15  
202 8         16 for my $fld (@fields) {
203 11 100 100     33 if ($mixins && grep { $_ eq $fld } keys %$mixins) {
  9         29  
204 1         3 my $mixin = $mixins->{$fld}->();
205 1 50       7 $mixin .= qq/ AS $fld/ unless $mixin =~ /as\s+\w+$/i;
206 1         3 push @filtered_prep_select_fields, $mixin;
207             }
208             else {
209 10         30 push @filtered_prep_select_fields, qq/"$table_name"."$fld"/;
210             }
211             }
212              
213 8         19 $self->{prep_select_fields} = \@filtered_prep_select_fields;
214              
215 8         27 return $self;
216             }
217              
218             # alias to only:
219 1     1 1 3 sub fields { shift->only(@_) }
220              
221             sub order_by {
222 23     23 1 44 my ($self, @param) = @_;
223              
224             #return if not defined $self->{SQL}; ### TODO: die
225 23   100     90 $self->{prep_order_by} ||= [];
226 23         27 push @{$self->{prep_order_by}}, map qq/"$_"/, @param;
  23         89  
227 23         35 delete $self->{prep_asc_desc};
228              
229 23         61 return $self;
230             }
231              
232             sub desc {
233 11     11 1 23 return shift->order_by_direction('DESC');
234             }
235              
236             sub asc {
237 2     2 1 28 return shift->order_by_direction('ASC');
238             }
239              
240             sub order_by_direction {
241 13     13 0 23 my ($self, $direction) = @_;
242              
243             # There are no fields for order yet
244 13 50 33     35 return unless ref $self->{prep_order_by} eq 'ARRAY' and scalar @{ $self->{prep_order_by} } > 0;
  13         39  
245              
246             # asc/desc is called before: ->asc->desc
247 13 50       24 return if defined $self->{prep_asc_desc};
248              
249             # $direction should be ASC/DESC
250 13 50       66 return unless $direction =~ /^(ASC|DESC)$/i;
251              
252             # Add $direction to the latest field
253 13         21 @{$self->{prep_order_by}}[-1] .= " $direction";
  13         31  
254 13         23 $self->{prep_asc_desc} = 1;
255              
256 13         34 return $self;
257             }
258              
259             sub group_by {
260 3     3 1 7 my ($self, @param) = @_;
261              
262 3   50     12 $self->{prep_group_by} ||= [];
263 3         5 push @{$self->{prep_group_by}}, map qq/"$_"/, @param;
  3         11  
264 3         10 return $self;
265             }
266              
267             sub limit {
268 14     14 1 27 my ($self, $limit) = @_;
269              
270             #return if not defined $self->{SQL};
271 14 50       29 return $self if exists $self->{prep_limit};
272              
273 14         28 $self->{prep_limit} = $limit; ### TODO: move $limit to $self->{BIND}
274              
275 14         34 return $self;
276             }
277              
278             sub offset {
279 5     5 1 10 my ($self, $offset) = @_;
280              
281             #return if not defined $self->{SQL};
282 5 50       12 return $self if exists $self->{prep_offset};
283              
284 5         8 $self->{prep_offset} = $offset; ### TODO: move $offset to $self->{BIND}
285              
286 5         13 return $self;
287             }
288              
289             sub abstract {
290 7     7 0 13 my ($self, $opts) = @_;
291              
292 7 100 66     23 return $self if ! ref $opts && ref $opts ne 'HASH';
293              
294 5         18 while (my ($method, $param) = each %$opts) {
295 9 100       13 if ($method eq 'order_by') {
296 4         6 $self->order_by(@{ $param->{columns} });
  4         9  
297 4 50       8 my $order_direction = (defined $param->{direction}) ? $param->{direction} : undef;
298 4 50       11 $self->$order_direction if $order_direction;
299             }
300             else {
301 5 100       12 my @p = (ref $param) ? @$param : ($param);
302 5         12 $self->$method(@p);
303             }
304             }
305              
306 5         8 return $self;
307             }
308              
309             sub select {
310 6     6 1 16 my ($self_class, $class, @params) = @_;
311              
312 6         8 my @find_params;
313             my $abstract_params_hashref;
314              
315 6         11 my $first_param = shift @params;
316 6 100       15 push @find_params, $first_param if defined $first_param;
317              
318 6         12 for my $param (@params) {
319             #push @find_params, $param if ref $param ne 'HASH';
320 5 100       13 if (ref $param eq 'HASH') {
321 4         6 $abstract_params_hashref = $param;
322 4         8 last;
323             }
324             else {
325 1         2 push @find_params, $param;
326             }
327             }
328              
329 6         14 my $finder = $self_class->new($class, @find_params);
330 6         14 $finder->abstract($abstract_params_hashref);
331              
332 6         12 return $finder->fetch;
333             }
334              
335              
336             sub _finish_sql_stmt {
337 82     82   133 my ($self) = @_;
338              
339 82 50       185 ref $self->{prep_select_fields} or croak 'Invalid prepare SQL statement';
340 82 50       159 ref $self->{prep_select_from} or croak 'Invalid prepare SQL statement';
341              
342 82         208 my $table_name = $self->{class}->_get_table_name;
343 82 100       139 my @add = grep { $_ !~~ $self->{prep_select_fields} } map qq/"$table_name".$_/, @{ $self->{prep_group_by}||[] };
  4         58  
  82         307  
344 82         129 push @{ $self->{prep_select_fields} }, @add;
  82         160  
345              
346 82         119 $self->{SQL} = "SELECT " . (join q/, /, @{ $self->{prep_select_fields} }) . "\n";
  82         295  
347 82         168 $self->{SQL} .= "FROM " . (join q/, /, @{ $self->{prep_select_from} }) . "\n";
  82         223  
348              
349 82 100       220 if (defined $self->{prep_left_joins}) {
350 7         14 $self->{SQL} .= "$_\n" for @{ $self->{prep_left_joins} };
  7         36  
351 7         25 $self->{has_joined_table} = 1;
352             }
353              
354 82 50       134 if (@{ $self->{prep_select_where}||[] }) {
  82 100       232  
355 52         99 $self->{SQL} .= "WHERE\n";
356 52         82 $self->{SQL} .= join " AND ", @{ $self->{prep_select_where} };
  52         128  
357             }
358              
359 82 100       123 if (@{ $self->{prep_group_by}||[] }) {
  82 100       292  
360 3         7 $self->{SQL} .= ' GROUP BY ';
361 3         5 $self->{SQL} .= join q/, /, @{ $self->{prep_group_by} };
  3         7  
362             }
363              
364 82 100       112 if (@{ $self->{prep_order_by}||[] }) {
  82 100       265  
365 24         41 $self->{SQL} .= ' ORDER BY ';
366 24         32 $self->{SQL} .= join q/, /, @{ $self->{prep_order_by} };
  24         42  
367             }
368              
369 82   66     327 $self->{SQL} .= ' LIMIT ' . ($self->{prep_limit} // $MAXIMUM_LIMIT);
370 82   100     267 $self->{SQL} .= ' OFFSET '. ($self->{prep_offset} // 0);
371              
372 82         167 return $self;
373             }
374              
375             sub _finish_object_representation {
376 130     130   243 my ($self, $obj, $object_data, $read_only) = @_;
377              
378 130 100       272 if ($self->{has_joined_table}) {
379             RELATION:
380 14         23 for my $rel_name (@{ $self->{with} }) {
  14         33  
381 0 0       0 my $relation = $self->{class}->_get_relations->{$rel_name} or next RELATION;
382 0         0 my %pairs = map { $_, $object_data->{$_} } grep { $_ =~ /^JOINED\_$rel_name\_/ } keys %$object_data;
  0         0  
  0         0  
383 0 0       0 next RELATION unless %pairs;
384              
385 0         0 for my $key (keys %pairs) {
386 0         0 my $val = delete $pairs{$key};
387 0         0 $key =~ s/^JOINED\_$rel_name\_//;
388 0         0 $pairs{$key} = $val;
389             }
390 0         0 $obj->{"relation_instance_$rel_name"} = $relation->{class}->new(\%pairs);
391             #bless \%pairs, $relation->{class};
392              
393 0         0 $obj->_delete_keys(qr/^JOINED\_$rel_name/);
394             }
395              
396             }
397              
398 130 50       244 $obj->{read_only} = 1 if defined $read_only;
399 130 100 66     464 $obj->{snapshoot} = freeze($object_data) if $obj->can('_smart_saving_used') && $obj->_smart_saving_used;
400 130         345 $obj->{isin_database} = 1;
401              
402 130         188 return $obj;
403             }
404              
405             sub fetch {
406 76     76 1 163 my ($self, $param) = @_;
407              
408 76         115 my ($read_only, $limit);
409 76 50       191 if (ref $param eq 'HASH') {
410 0         0 $limit = $param->{limit};
411 0         0 $read_only = $param->{read_only};
412             }
413             else {
414 76         111 $limit = $param;
415             }
416              
417 76 50       155 return $self->_get_slice($limit) if $self->{_objects};
418              
419 76         196 $self->_finish_sql_stmt();
420 76         208 $self->_quote_sql_stmt();
421              
422 76         121 my $class = $self->{class};
423 76 50       176 my $sth = $self->dbh->prepare($self->{SQL}) or croak $self->dbh->errstr;
424 76 50       5018 $sth->execute(@{ $self->{BIND} }) or croak $self->dbh->errstr;
  76         1845  
425 76 100       241 if (wantarray) {
426 29         47 my @objects;
427 29         47 my $i = 0;
428 29         628 while (my $object_data = $sth->fetchrow_hashref()) {
429 83         191 $i++;
430 83         246 my $obj = $class->new($object_data);
431 83         201 $self->_finish_object_representation($obj, $object_data, $read_only);
432 83         129 push @objects, $obj;
433              
434 83 50 33     1321 last if $limit && $i == $limit;
435             }
436 29         81 delete $self->{has_joined_table};
437              
438 29         410 return @objects;
439             }
440             else {
441 47 50       678 my $object_data = $sth->fetchrow_hashref() or return;
442 47         234 my $obj = $class->new($object_data);
443 47         143 $self->_finish_object_representation($obj, $object_data, $read_only);
444 47         73 delete $self->{has_joined_table};
445              
446 47         648 return $obj;
447             }
448             }
449              
450             sub upload {
451 1     1 1 6 my ($self, $param) = @_;
452              
453 1         13 my $o = $self->fetch($param);
454 1         3 $_[0] = $o;
455              
456 1         6 return $_[0];
457             }
458              
459             sub next {
460 7     7 0 1979 my ($self, $n) = @_;
461              
462 7   100     26 $n ||= 1;
463              
464 7         10 $self->{prep_limit} = $n;
465 7 100       16 $self->{prep_offset} = 0 unless defined $self->{prep_offset};
466 7         14 my @result = $self->fetch;
467              
468 7         15 $self->{prep_offset} += $n;
469              
470 7 100       25 return wantarray ? @result : $result[0];
471             }
472              
473             sub with {
474 0     0 1 0 my ($self, @rels) = @_;
475              
476 0 0       0 return $self if exists $self->{prep_left_joins};
477 0 0       0 return $self unless @rels;
478              
479 0 0       0 $self->{class}->can('_get_relations')
480             or die "Class doesn't have any relations";
481              
482 0         0 my $table_name = $self->{class}->_get_table_name;
483              
484 0         0 $self->{prep_left_joins} = [];
485 0         0 $self->{with} = \@rels;
486             RELATION:
487 0         0 for my $rel_name (@rels) {
488 0 0       0 my $relation = $self->{class}->_get_relations->{$rel_name}
489             or next RELATION;
490              
491 0 0       0 next RELATION unless grep { $_ eq $relation->{type} } qw/one only/;
  0         0  
492 0         0 my $rel_table_name = $relation->{class}->_get_table_name;
493              
494 0         0 my $rel_columns = $relation->{class}->_get_columns;
495              
496             #push @{ $self->{prep_select_fields} }, qq/"$rel_table_name".*/;
497 0         0 push @{ $self->{prep_select_fields} },
498 0         0 map { qq/"$rel_table_name"."$_" AS "JOINED_$rel_name\_$_"/ }
499 0         0 @{ $relation->{class}->_get_columns };
  0         0  
500              
501 0 0       0 if ($relation->{type} eq 'one') {
502 0         0 my $join_sql = qq/LEFT JOIN "$rel_table_name" ON /;
503 0         0 $join_sql .= qq/"$rel_table_name"."$relation->{params}{pk}"/;
504 0         0 $join_sql .= qq/ = "$table_name"."$relation->{params}{fk}"/;
505              
506 0         0 push @{ $self->{prep_left_joins} }, $join_sql;
  0         0  
507             }
508             }
509              
510 0         0 return $self;
511             }
512              
513 0     0 1 0 sub left_join { shift->with(@_) }
514              
515             sub to_sql {
516 0     0 1 0 my ($self) = @_;
517              
518 0         0 $self->_finish_sql_stmt();
519 0         0 $self->_quote_sql_stmt();
520              
521 0 0       0 return wantarray ? ($self->{SQL}, $self->{BIND}) : $self->{SQL};
522             }
523              
524             sub exists {
525 6     6 1 13 my ($self) = @_;
526              
527 6         18 $self->{prep_select_fields} = ['1'];
528 6         22 $self->_finish_sql_stmt;
529 6         59 $self->_quote_sql_stmt;
530              
531 6         46 my $sth = $self->dbh->prepare($self->{SQL});
532 6         531 $sth->execute(@{ $self->{BIND} });
  6         128  
533              
534 6         123 return $sth->fetchrow_arrayref();
535             }
536              
537              
538             ### Private
539              
540             sub _find_many_to_many {
541 7     7   18 my ($self_class, $class, $param) = @_;
542              
543 7 50 33     23 return unless $self_class->dbh && $class && $param;
      33        
544              
545 7         13 my $mc_fkey;
546 7         13 my $class_opts = {};
547 7         14 my $root_class_opts = {};
548              
549 7         14 eval { load $param->{m_class} };
  7         26  
550              
551 7         1511 for my $opts ( values %{ $param->{m_class}->_get_relations } ) {
  7         37  
552 14 100       52 if ($opts->{class} eq $param->{root_class}) {
    50          
553 7         13 $root_class_opts = $opts;
554             }
555             elsif ($opts->{class} eq $class) {
556 7         17 $class_opts = $opts;
557             }
558             }
559              
560 7         15 my $self = $self_class->new($class, @{ $param->{where_statement} });
  7         30  
561              
562 7         21 my $connected_table_name = $class->_get_table_name;
563 7         26 $self->{prep_select_from} = [ $param->{m_class}->_get_table_name ];
564              
565 7         41 push @{ $self->{prep_left_joins} },
566             'JOIN ' . $connected_table_name . ' ON ' . $connected_table_name . '.' . $class->_get_primary_key . ' = '
567 7         15 . $param->{m_class}->_get_table_name . '.' . $class_opts->{params}{fk};
568              
569 7         36 push @{ $self->{prep_select_where} },
570 7         13 $root_class_opts->{params}{fk} . ' = ' . $param->{self}->{ $param->{root_class}->_get_primary_key };
571              
572 7         55 return $self;
573             }
574              
575             sub _get_slice {
576 0     0   0 my ($self, $time) = @_;
577              
578             return unless $self->{_objects}
579             && ref $self->{_objects} eq 'ARRAY'
580 0 0 0     0 && scalar @{ $self->{_objects} } > 0;
  0   0     0  
581              
582 0 0       0 if (wantarray) {
583 0   0     0 $time ||= scalar @{ $self->{_objects} };
  0         0  
584 0         0 return splice @{ $self->{_objects} }, 0, $time;
  0         0  
585             }
586             else {
587 0         0 return shift @{ $self->{_objects} };
  0         0  
588             }
589             }
590              
591             sub _quote_sql_stmt {
592 82     82   136 my ($self) = @_;
593              
594 82 50 33     301 return unless $self->{SQL} && $self->dbh;
595              
596 82         235 my $driver_name = $self->dbh->{Driver}{Name};
597 82   50     289 $driver_name //= 'Pg';
598 82         245 my $quotes_map = {
599             Pg => q/"/,
600             mysql => q/`/,
601             SQLite => q/`/,
602             };
603 82         151 my $quote = $quotes_map->{$driver_name};
604              
605 82         467 $self->{SQL} =~ s/"/$quote/g;
606              
607 82         232 return $self;
608             }
609              
610       0     sub DESTROY { }
611              
612             sub AUTOLOAD {
613 0     0     my $call = $AUTOLOAD;
614 0           my $self = shift;
615 0           my $class = ref $self;
616              
617 0           $call =~ s/.*:://;
618 0           my $error = "Can't call method `$call` on class $class.\nPerhaps you have forgotten to fetch your object?";
619              
620 0           croak $error;
621             }
622              
623             1;
624              
625