File Coverage

blib/lib/DBIx/Lite/ResultSet.pm
Criterion Covered Total %
statement 237 359 66.0
branch 75 154 48.7
condition 33 83 39.7
subroutine 40 62 64.5
pod 33 33 100.0
total 418 691 60.4


line stmt bran cond sub pod time code
1             package DBIx::Lite::ResultSet;
2             $DBIx::Lite::ResultSet::VERSION = '0.36';
3 6     6   189415 use strict;
  6         14  
  6         307  
4 6     6   28 use warnings;
  6         11  
  6         348  
5              
6 6     6   50 use Carp qw(croak);
  6         10  
  6         420  
7 6     6   2890 use Clone qw(clone);
  6         3273  
  6         444  
8 6     6   4186 use Data::Page;
  6         40259  
  6         38  
9 6     6   3944 use List::MoreUtils qw(uniq firstval);
  6         107816  
  6         65  
10 6     6   9332 use vars qw($AUTOLOAD);
  6         14  
  6         2044  
11             $Carp::Internal{$_}++ for __PACKAGE__;
12              
13             sub _new {
14 74     74   152 my $class = shift;
15 74         341 my (%params) = @_;
16            
17 74         389 my $self = {
18             table_alias => 'me',
19             joins => [],
20             where => [],
21             select => undef,
22             rows_per_page => 10,
23             };
24            
25             # required arguments
26 74         270 for (qw(dbix_lite table)) {
27 148 50       613 $self->{$_} = delete $params{$_} or croak "$_ argument needed";
28             }
29            
30             # optional arguments
31 74         590 for (grep exists($params{$_}), qw(joins where select group_by having order_by
32             limit offset for rows_per_page page cur_table with from distinct table_alias)) {
33 272         3434 $self->{$_} = delete $params{$_};
34             }
35 74   66     311 $self->{cur_table} //= $self->{table};
36            
37 74 50       175 !%params
38             or croak "Unknown options: " . join(', ', keys %params);
39            
40 74         191 bless $self, $class;
41 74         385 $self;
42             }
43              
44             # create setters
45             for my $methname (qw(group_by having order_by limit offset rows_per_page page from distinct table_alias)) {
46 6     6   64 no strict 'refs';
  6         12  
  6         35933  
47             *$methname = sub {
48 12     12   24 my $self = shift;
49            
50             # we always return a new object for easy chaining
51 12         34 my $new_self = $self->_clone;
52            
53             # set new values
54 12 100       112 $new_self->{$methname} = $methname =~ /^(group_by|order_by|from|distinct)$/ ? [@_] : $_[0];
55 12 0 33     44 $new_self->{pager}->current_page($_[0]) if $methname eq 'page' && $new_self->{pager};
56            
57             # return object
58 12         37 $new_self;
59             };
60             }
61              
62             sub for_update {
63 0     0 1 0 my ($self) = @_;
64            
65 0         0 return $self->for('UPDATE');
66             }
67              
68             sub for {
69 0     0 1 0 my ($self, $for) = @_;
70            
71 0         0 my $new_self = $self->_clone;
72 0         0 $new_self->{for} = $for;
73 0         0 $new_self;
74             }
75              
76             # return a clone of this object
77             sub _clone {
78 45     45   74 my $self = shift;
79             (ref $self)->_new(
80             # clone all members except for some which we copy by reference
81 45 100       520 map { $_ => /^(?:dbix_lite|table|cur_table)$/ ? $self->{$_} : clone($self->{$_}) }
  362         2770  
82             grep !/^(?:sth|pager)$/, keys %$self,
83             );
84             }
85              
86             sub select {
87 15     15 1 28 my $self = shift;
88              
89 15         37 my $new_self = $self->_clone;
90 15 50       82 $new_self->{select} = @_ ? [@_] : undef;
91            
92 15         71 $new_self;
93             }
94              
95             sub select_also {
96 1     1 1 3 my $self = shift;
97 1   50     2 return $self->select(@{$self->{select} // []}, @_);
  1         8  
98             }
99              
100             sub with {
101 0     0 1 0 my $self = shift;
102 0         0 my %with = @_;
103            
104             croak "with() requires a hash of scalarrefs or refs to arrayrefs"
105 0 0       0 if grep { !ref($_) eq 'SCALAR' } values %with;
  0         0  
106            
107 0         0 my $new_self = $self->_clone;
108 0 0       0 $new_self->{with} = %with ? {%with} : undef;
109            
110 0         0 $new_self;
111             }
112              
113             sub with_also {
114 0     0 1 0 my $self = shift;
115 0         0 return $self->with(%{$self->{with}}, @_);
  0         0  
116             }
117              
118             sub pager {
119 0     0 1 0 my $self = shift;
120 0 0       0 if (!$self->{pager}) {
121 0   0     0 $self->{pager} ||= Data::Page->new;
122 0         0 $self->{pager}->total_entries($self->page(undef)->count);
123 0   0     0 $self->{pager}->entries_per_page($self->{rows_per_page} // $self->{pager}->total_entries);
124 0         0 $self->{pager}->current_page($self->{page});
125             }
126 0         0 return $self->{pager};
127             }
128              
129             sub search {
130 13     13 1 24 my $self = shift;
131 13         31 my ($where) = @_;
132            
133 13         94 my $new_self = $self->_clone;
134 13 50       64 push @{$new_self->{where}}, $where if defined $where;
  13         40  
135 13         54 $new_self;
136             }
137              
138             sub clear_search {
139 0     0 1 0 my $self = shift;
140            
141 0         0 my $new_self = $self->_clone;
142 0         0 @{$new_self->{where}} = ();
  0         0  
143 0         0 $new_self;
144             }
145              
146             sub find {
147 4     4 1 10 my $self = shift;
148 4         10 my ($where) = @_;
149            
150             # if user did not supply a search hashref, we assume the supplied
151             # value(s) are the key(s) of the primary key column(s) defined for
152             # this table
153 4 50 33     22 if (!ref $where && (my @pk = $self->{table}->pk)) {
154             # prepend table alias to all pk columns
155 0         0 my $table_alias = $self->{table_alias};
156 0         0 $_ =~ s/^[^.]+$/$table_alias\.$&/ for @pk;
157            
158 0         0 $where = { map +(shift(@pk) => $_), @_ };
159             }
160 4         18 return $self->search($where)->single;
161             }
162              
163             sub where_sql {
164 0     0 1 0 my $self = shift;
165            
166 0         0 my ($sql, @bind) = $self->{dbix_lite}->{abstract}->where({ -and => $self->{where} });
167 0         0 return ($sql, @bind);
168             }
169              
170             sub select_sql {
171 23     23 1 49 my $self = shift;
172            
173             # prepare names of columns to be selected
174 23         46 my @cols = ();
175 23         108 my $cur_table_prefix = $self->_table_alias($self->{cur_table}{name}, 'select');
176 23   100     123 my $select = $self->{select} // [$self->{table_alias} . '.*'];
177 23         77 foreach my $col (grep defined $_, @$select) {
178             # check whether user specified an alias
179 24 50       91 my ($expr, $as) = ref $col eq 'ARRAY' ? @$col : ($col, undef);
180            
181             # prepend table alias if column name doesn't contain one already
182 24 50 66     215 $expr =~ s/^[^.]+$/$cur_table_prefix\.$&/ if !ref($expr) && !$self->{from};
183            
184             # explode the expression if it's a scalar ref
185 24 100       185 if (ref $expr eq 'SCALAR') {
186 7         18 $expr = $$expr;
187             }
188            
189             # build the column definition according to the SQL::Abstract::More syntax
190 24 50       100 push @cols, $expr . ($as ? "|$as" : "");
191             }
192            
193             # joins
194 23         44 my @joins = ();
195 23         33 foreach my $join (@{$self->{joins}}) {
  23         65  
196             # get table name and alias if any
197 4         10 my ($table_name, $table_alias) = @{$join->{table}};
  4         14  
198 4         15 my $left_table_prefix = $self->_table_alias($join->{cur_table}{name}, 'select');
199            
200             # prepare join conditions
201 4         10 my %cond = ();
202 4         7 while (my ($col1, $col2) = each %{$join->{condition}}) {
  9         41  
203             # in case they have no explicit table alias,
204             # $col1 is supposed to belong to the current table, and
205             # $col2 is supposed to belong to the joined table
206            
207             # prepend table alias to the column of the first table
208 5         39 $col1 =~ s/^[^.]+$/$left_table_prefix.$&/;
209            
210             # in case user supplied the table name as table alias, replace it
211             # with the proper one (such as "me.")
212 5         72 $col1 =~ s/^$join->{cur_table}{name}\./$left_table_prefix./;
213            
214             # prepend table alias to the column of the second table
215 5 100 33     51 $col2 = ($table_alias || $self->{dbix_lite}->_quote($table_name)) . ".$col2"
      66        
216             unless ref $col2 || $col2 =~ /\./;
217            
218             # in case the second item is a scalar reference (literal SQL)
219             # or a hashref (search condition), pass it unchanged
220 5 100       134 $cond{$col1} = ref($col2) ? $col2 : \ "= $col2";
221             }
222            
223             # store the join definition according to the SQL::Abstract::More syntax
224             push @joins, {
225 4 100       25 operator => $join->{join_type} eq 'inner' ? '<=>' : '=>',
226             condition => \%cond,
227             };
228 4 50       37 push @joins, $table_name . ($table_alias ? "|$table_alias" : "");
229             }
230            
231             # from
232 23         45 my @from = ();
233 23 50       81 if ($self->{from}) {
234 0         0 @from = @{$self->{from}};
  0         0  
235             } else {
236 23         96 @from = (-join => $self->{table}{name} . "|" . $self->{table_alias}, @joins);
237             }
238            
239             # paging overrides limit and offset if any
240 23 50 33     69 if ($self->{page} && defined $self->{rows_per_page}) {
241 0         0 $self->{limit} = $self->{rows_per_page};
242 0         0 $self->{offset} = $self->pager->skipped;
243             }
244            
245             # ordering
246 23 100       136 if ($self->{order_by}) {
247             $self->{order_by} = [$self->{order_by}]
248 8 50       30 unless ref $self->{order_by} eq 'ARRAY';
249             }
250            
251             my ($sql, @bind) = $self->{dbix_lite}->{abstract}->select(
252             -columns => [ uniq @cols ],
253             -from => [ @from ],
254             -where => { -and => $self->{where} },
255             $self->{group_by} ? (-group_by => $self->{group_by}) : (),
256             $self->{having} ? (-having => $self->{having}) : (),
257             $self->{order_by} ? (-order_by => $self->{order_by}) : (),
258             $self->{limit} ? (-limit => $self->{limit}) : (),
259             $self->{offset} ? (-offset => $self->{offset}) : (),
260 23 50       388 $self->{for} ? (-for => $self->{for}) : (),
    50          
    100          
    50          
    50          
    50          
261             );
262              
263 23 100       22341 if ($self->{distinct}) {
264 3         5 my $distinct_sql;
265 3 100       4 if (@{$self->{distinct}} > 0) {
  3         7  
266 2 100       3 my @cols = map { ref($_) ? $$_ : $self->{dbix_lite}->_quote($_) } @{$self->{distinct}};
  2         8  
  2         3  
267 2         15 $distinct_sql = sprintf "DISTINCT ON (%s)", join ', ', @cols;
268             } else {
269 1         2 $distinct_sql = "DISTINCT";
270             }
271 3         16 $sql =~ s/^SELECT /SELECT $distinct_sql /i;
272             }
273            
274 23 50       71 if ($self->{with}) {
275 0         0 my @with_sql = ();
276 0         0 foreach my $alias (keys %{$self->{with}}) {
  0         0  
277 0         0 my $def = $self->{with}{$alias};
278            
279 0 0       0 if (ref $$def eq 'ARRAY') {
280 0         0 my ($wsql, @wbind) = @$$def;
281 0         0 push @with_sql, sprintf "%s AS (%s)", $alias, $wsql;
282 0         0 unshift @bind, @wbind;
283             } else {
284 0         0 push @with_sql, sprintf "%s AS (%s)", $alias, $$def;
285             }
286             }
287 0         0 $sql = sprintf 'WITH %s %s', join(', ', @with_sql), $sql;
288             }
289            
290 23         122 return ($sql, @bind);
291             }
292              
293             sub select_sth {
294 16     16 1 32 my $self = shift;
295            
296 16         59 my ($sql, @bind) = $self->select_sql;
297 16   50     109 return $self->{dbix_lite}->dbh->prepare($sql) || undef, @bind;
298             }
299              
300             sub _select_sth_for_object {
301 7     7   14 my $self = shift;
302            
303             # check whether any of the selected columns is a scalar ref
304 7         32 my $cur_table_prefix = $self->_table_alias($self->{cur_table}{name}, 'select');
305 7         15 my $have_scalar_ref = 0;
306 7         13 my $have_star = 0;
307 7   100     47 my $select = $self->{select} // [$self->{table_alias} . '.*'];
308 7         28 foreach my $col (grep defined $_, @$select) {
309 7 50       24 my $expr = ref($col) eq 'ARRAY' ? $col->[0] : $col;
310 7 50       36 if (ref($expr) eq 'SCALAR') {
    100          
311 0         0 $have_scalar_ref = 1;
312             } elsif ($expr eq "$cur_table_prefix.*") {
313 6         34 $have_star = 1;
314             }
315             }
316            
317             # always retrieve our primary key if provided and no col name is a scalar ref
318             # also skip this if we are retrieving all columns (me.*)
319 7 100 66     48 if (!$have_scalar_ref && !$have_star && (my @pk = $self->{cur_table}->pk)) {
      66        
320             # prepend table alias to all pk columns
321 1         35 $_ =~ s/^[^.]+$/$cur_table_prefix\.$&/ for @pk;
322            
323             # append instead of prepend, otherwise get_column() on a non-PK column
324             # would return the wrong values
325 1         8 $self = $self->select_also(@pk);
326             }
327            
328 7         28 return $self->select_sth;
329             }
330              
331             sub insert_sql {
332 5     5 1 12 my $self = shift;
333 5         10 my $insert_cols = shift;
334 5 50       21 ref $insert_cols eq 'HASH' or croak "insert_sql() requires a hashref";
335            
336 5 50       10 if (@{$self->{joins}}) {
  5         19  
337 0         0 warn "Attempt to call ->insert() after joining other tables\n";
338             }
339            
340 5 50 33     22 if (!%$insert_cols && $self->{dbix_lite}->driver_name eq 'Pg') {
341             # Postgres doesn't support the VALUES () syntax
342             return sprintf "INSERT INTO %s DEFAULT VALUES",
343 0         0 $self->{dbix_lite}->_quote($self->{table}{name});
344             }
345            
346             return $self->{dbix_lite}->{abstract}->insert(
347 5         74 $self->{table}{name}, $insert_cols,
348             );
349             }
350              
351             sub insert_sth {
352 5     5 1 11 my $self = shift;
353 5         13 my $insert_cols = shift;
354 5 50       34 ref $insert_cols eq 'HASH' or croak "insert_sth() requires a hashref";
355            
356 5         28 my ($sql, @bind) = $self->insert_sql($insert_cols);
357 5   50     3444 return $self->{dbix_lite}->dbh->prepare($sql) || undef, @bind;
358             }
359              
360             sub insert {
361 5     5 1 12 my $self = shift;
362 5         9 my $insert_cols = shift;
363 5 50       22 ref $insert_cols eq 'HASH' or croak "insert() requires a hashref";
364            
365             # perform operation
366 5         12 my $res;
367             $self->{dbix_lite}->dbh_do(sub {
368 5     5   466 my ($sth, @bind) = $self->insert_sth($insert_cols);
369 5         92346 $res = $sth->execute(@bind);
370 5         58 });
371 5 50       74 return undef if !$res;
372            
373             # populate the autopk field if any
374 5 50       54 if (my $pk = $self->{table}->autopk) {
375 0         0 $insert_cols = clone $insert_cols;
376             $insert_cols->{$pk} = $self->{dbix_lite}->_autopk($self->{table}{name})
377 0 0       0 if !exists $insert_cols->{$pk};
378             }
379            
380             # return a DBIx::Lite::Row object with the inserted values
381 5         33 return $self->_inflate_row($insert_cols);
382             }
383              
384             sub update_sql {
385 1     1 1 2 my $self = shift;
386 1         2 my $update_cols = shift;
387 1 50       4 ref $update_cols eq 'HASH' or croak "update_sql() requires a hashref";
388            
389 1         46 my $update_where = { -and => $self->{where} };
390            
391 1 50       7 if ($self->{cur_table}{name} ne $self->{table}{name}) {
392             my @pk = $self->{cur_table}->pk
393 0 0       0 or croak "No primary key defined for " . $self->{cur_table}{name} . "; cannot update using relationships";
394 0 0       0 @pk == 1
395             or croak "Update across relationships is not allowed with multi-column primary keys";
396            
397 0         0 my $fq_pk = $self->_table_alias($self->{cur_table}{name}, 'update') . "." . $pk[0];
398 0         0 $update_where = {
399             $fq_pk => {
400             -in => \[ $self->select($pk[0])->select_sql ],
401             },
402             };
403             }
404            
405             return $self->{dbix_lite}->{abstract}->update(
406 1         7 -table => $self->_table_alias_expr($self->{cur_table}{name}, 'update'),
407             -set => $update_cols,
408             -where => $update_where,
409             );
410             }
411              
412             sub update_sth {
413 1     1 1 2 my $self = shift;
414 1         2 my $update_cols = shift;
415 1 50       5 ref $update_cols eq 'HASH' or croak "update_sth() requires a hashref";
416            
417 1         4 my ($sql, @bind) = $self->update_sql($update_cols);
418 1   50     957 return $self->{dbix_lite}->dbh->prepare($sql) || undef, @bind;
419             }
420              
421             sub update {
422 1     1 1 2 my $self = shift;
423 1         3 my $update_cols = shift;
424 1 50       6 ref $update_cols eq 'HASH' or croak "update() requires a hashref";
425            
426 1         2 my $affected_rows;
427             $self->{dbix_lite}->dbh_do(sub {
428 1     1   62 my ($sth, @bind) = $self->update_sth($update_cols);
429 1         17439 $affected_rows = $sth->execute(@bind);
430 1         13 });
431 1         19 return $affected_rows;
432             }
433              
434             sub find_or_insert {
435 0     0 1 0 my $self = shift;
436 0         0 my $cols = shift;
437 0 0       0 ref $cols eq 'HASH' or croak "find_or_insert() requires a hashref";
438            
439 0         0 my $object;
440             $self->{dbix_lite}->txn(sub {
441 0 0   0   0 if (!($object = $self->find($cols))) {
442 0         0 $object = $self->insert($cols);
443             }
444 0         0 });
445 0         0 return $object;
446             }
447              
448             sub delete_sql {
449 0     0 1 0 my $self = shift;
450            
451 0         0 my $delete_where = { -and => $self->{where} };
452            
453 0 0       0 if ($self->{cur_table}{name} ne $self->{table}{name}) {
454             my @pk = $self->{cur_table}->pk
455 0 0       0 or croak "No primary key defined for " . $self->{cur_table}{name} . "; cannot delete using relationships";
456 0 0       0 @pk == 1
457             or croak "Delete across relationships is not allowed with multi-column primary keys";
458            
459 0         0 my $fq_pk = $self->_table_alias($self->{cur_table}{name}, 'delete') . "." . $pk[0];
460 0         0 $delete_where = {
461             $fq_pk => {
462             -in => \[ $self->select($pk[0])->select_sql ],
463             },
464             };
465             }
466            
467             return $self->{dbix_lite}->{abstract}->delete(
468 0         0 $self->_table_alias_expr($self->{cur_table}{name}, 'delete'),
469             $delete_where,
470             );
471             }
472              
473             sub delete_sth {
474 0     0 1 0 my $self = shift;
475            
476 0         0 my ($sql, @bind) = $self->delete_sql;
477 0   0     0 return $self->{dbix_lite}->dbh->prepare($sql) || undef, @bind;
478             }
479              
480             sub delete {
481 0     0 1 0 my $self = shift;
482            
483 0         0 my $affected_rows;
484             $self->{dbix_lite}->dbh_do(sub {
485 0     0   0 my ($sth, @bind) = $self->delete_sth;
486 0         0 $affected_rows = $sth->execute(@bind);
487 0         0 });
488 0         0 return $affected_rows;
489             }
490              
491             sub single {
492 7     7 1 898 my $self = shift;
493            
494 7         12 my $row;
495             $self->{dbix_lite}->dbh_do(sub {
496 7     7   434 my ($sth, @bind) = $self->_select_sth_for_object;
497 7         1375 $sth->execute(@bind);
498 7         437 $row = $sth->fetchrow_hashref;
499 7         68 });
500 7 50       177 return $row ? $self->_inflate_row($row) : undef;
501             }
502              
503             sub single_value {
504 0     0 1 0 my $self = shift;
505            
506 0         0 my $value;
507             $self->{dbix_lite}->dbh_do(sub {
508 0     0   0 my ($sth, @bind) = $self->select_sth;
509 0         0 $sth->execute(@bind);
510 0         0 ($value) = $sth->fetchrow_array;
511 0         0 });
512 0         0 return $value;
513             }
514              
515             sub all {
516 0     0 1 0 my $self = shift;
517            
518 0         0 my $rows;
519             $self->{dbix_lite}->dbh_do(sub {
520 0     0   0 my ($sth, @bind) = $self->_select_sth_for_object;
521 0         0 $sth->execute(@bind);
522 0         0 $rows = $sth->fetchall_arrayref({});
523 0         0 });
524 0         0 return map $self->_inflate_row($_), @$rows;
525             }
526              
527             sub next {
528 0     0 1 0 my $self = shift;
529            
530             $self->{dbix_lite}->dbh_do(sub {
531 0     0   0 ($self->{sth}, my @bind) = $self->_select_sth_for_object;
532 0         0 $self->{sth}->execute(@bind);
533 0 0       0 }) if !$self->{sth};
534            
535 0 0       0 my $row = $self->{sth}->fetchrow_hashref or return undef;
536 0         0 return $self->_inflate_row($row);
537             }
538              
539             sub count {
540 7     7 1 90 my $self = shift;
541            
542 7         12 my $count;
543             $self->{dbix_lite}->dbh_do(sub {
544             # Postgres throws an error when using ORDER BY clauses with COUNT(*)
545 7     7   455 my $count_rs = $self->select(\ "COUNT(*)")->order_by(undef);
546 7         69 my ($sth, @bind) = $count_rs->select_sth;
547 7         1846 $sth->execute(@bind);
548 7         410 $count = +($sth->fetchrow_array)[0];
549 7         71 });
550 7         83 return $count;
551             }
552              
553             sub column_names {
554 2     2 1 5 my $self = shift;
555              
556             $self->{dbix_lite}->dbh_do(sub {
557 2     2   115 ($self->{sth}, my @bind) = $self->select_sth;
558 2         311 $self->{sth}->execute(@bind);
559 2 50       21 }) if !$self->{sth};
560              
561 2         40 my $c = $self->{sth}->{NAME};
562 2 100       19 return wantarray ? @$c : $c;
563             }
564              
565             sub get_column {
566 1     1 1 3 my $self = shift;
567 1 50       5 my $column_name = shift or croak "get_column() requires a column name";
568            
569 1         3 my @values = ();
570             $self->{dbix_lite}->dbh_do(sub {
571 1     1   78 my $rs = ($self->_clone)->select($column_name);
572 1         10 my ($sql, @bind) = $rs->select_sql;
573            
574 1         2 @values = @{$self->{dbix_lite}->dbh->selectcol_arrayref($sql, {}, @bind)};
  1         8  
575 1         13 });
576 1         434 return @values;
577             }
578              
579             sub inner_join {
580 1     1 1 4 my $self = shift;
581 1         5 return $self->_join('inner', @_);
582             }
583              
584             sub left_join {
585 3     3 1 7 my $self = shift;
586 3         14 return $self->_join('left', @_);
587             }
588              
589             sub _join {
590 4     4   8 my $self = shift;
591 4         14 my ($type, $table_name, $condition, $options) = @_;
592 4   50     24 $options ||= {};
593 4 50       16 $table_name = [ $table_name, undef ] if ref $table_name ne 'ARRAY';
594            
595 4         13 my $new_self = $self->_clone;
596            
597             # if user asked for duplicate join removal, check whether no joins
598             # with the same table alias exist
599 4 50       22 if ($options->{prevent_duplicates}) {
600 0         0 foreach my $join (@{$self->{joins}}) {
  0         0  
601 0 0 0     0 if ((defined($table_name->[1]) && defined $join->{table}[1] && $table_name->[1] eq $join->{table}[1])
      0        
      0        
      0        
602             || (!defined($table_name->[1]) && $table_name->[0] eq $join->{table}[0])) {
603 0         0 return $new_self;
604             }
605             }
606             }
607            
608 4         25 push @{$new_self->{joins}}, {
609             join_type => $type,
610             cur_table => $self->{cur_table},
611 4         8 table => $table_name,
612             condition => $condition,
613             };
614            
615 4         25 $new_self;
616             }
617              
618             sub clear_joins {
619 0     0 1 0 my $self = shift;
620            
621 0         0 my $new_self = $self->_clone;
622 0         0 @{$new_self->{joins}} = ();
  0         0  
623 0         0 $new_self;
624             }
625              
626             sub _table_alias {
627 35     35   55 my $self = shift;
628 35         114 my ($table_name, $op) = @_;
629            
630 35         136 my $driver_name = $self->{dbix_lite}->driver_name;
631            
632 35 50       349 if ($table_name eq $self->{table}{name}) {
633 35 50 33     108 if ($op eq 'select'
      66        
      33        
      33        
634             || ($op eq 'update' && $driver_name =~ /^(?:MySQL|Pg)$/i)
635             || ($op eq 'delete' && $driver_name =~ /^Pg$/i)) {
636 34         126 return $self->{table_alias};
637             }
638             }
639            
640 1         2 return $table_name;
641             }
642              
643             sub _table_alias_expr {
644 1     1   2 my $self = shift;
645 1         4 my ($table_name, $op) = @_;
646            
647 1         4 my $table_alias = $self->_table_alias($table_name, $op);
648 1 50       6 if ($table_name eq $table_alias) {
649             # foo
650 1         8 return $table_name;
651             } else {
652             # foo AS my_foo
653 0         0 return $self->{dbix_lite}->{abstract}->table_alias($table_name, $table_alias);
654             }
655             }
656              
657             sub _inflate_row {
658 12     12   29 my $self = shift;
659 12         36 my ($hashref) = @_;
660            
661             # get the row package
662 12   100     98 my $package = $self->{cur_table}{class} || 'DBIx::Lite::Row';
663            
664             # get the constructor, if any
665 12         31 my $constructor = $self->{cur_table}{class_constructor};
666 12 50 66     164 if (!defined $constructor && $package->can('new')) {
667 0         0 $constructor = 'new';
668             }
669            
670             # create the object
671 12         23 my $object;
672 12 100       103 if (defined $constructor) {
673 1 50       5 if (ref($constructor) eq 'CODE') {
674 0         0 $object = $constructor->($hashref);
675             } else {
676 1         9 $object = $package->$constructor;
677             }
678             } else {
679 11         26 $object = {};
680 11         51 bless $object, $package;
681             }
682            
683             # get the hashref where we are going to store our data
684 12         1766 my $storage;
685 12 100       42 if (my $method = $self->{cur_table}{class_storage}) {
686 1 50       8 croak "No ${package}::${method} method exists"
687             if !$package->can($method);
688 1         41 $storage = $object->$method;
689 1 50       7 croak "${package}::${method}() did not return a hashref"
690             if ref($storage) ne 'HASH';
691             } else {
692 11         21 $storage = $object;
693             }
694            
695             # store our data
696 12         46 $storage->{dbix_lite} = $self->{dbix_lite};
697 12         32 $storage->{table} = $self->{cur_table};
698 12         33 $storage->{data} = $hashref;
699            
700 12         167 return $object;
701             }
702              
703             sub AUTOLOAD {
704 0 0   0     my $self = shift or return undef;
705            
706             # Get the called method name and trim off the namespace
707 0           (my $method = $AUTOLOAD) =~ s/.*:://;
708            
709 0 0         if (my $rel = $self->{cur_table}{has_many}{$method}) {
710 0           my $new_self = $self->inner_join($rel->[0], $rel->[1])->select("$method.*");
711 0           $new_self->{cur_table} = $self->{dbix_lite}->schema->table($rel->[0]);
712 0   0       bless $new_self, $new_self->{cur_table}->resultset_class || __PACKAGE__;
713 0           return $new_self;
714             }
715            
716 0           croak "No $method method is provided by this " . ref($self) . " object";
717             }
718              
719       0     sub DESTROY {}
720              
721             1;
722              
723             __END__