File Coverage

blib/lib/DBIx/Lite/ResultSet.pm
Criterion Covered Total %
statement 227 348 65.2
branch 68 148 45.9
condition 28 77 36.3
subroutine 40 62 64.5
pod 33 33 100.0
total 396 668 59.2


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