... | ... |
@@ -633,30 +633,17 @@ sub select { |
633 | 633 |
$columns = [$columns] unless ref $columns; |
634 | 634 |
my $selection = $args{selection} || ''; |
635 | 635 |
my $where = $args{where} || {}; |
636 |
- my $relation = $args{relation} || {}; |
|
637 | 636 |
my $append = $args{append}; |
638 | 637 |
my $filter = $args{filter}; |
639 | 638 |
my $left_join = $args{left_join} || []; |
639 |
+ croak qq{"left_join" must be array reference} |
|
640 |
+ unless ref $left_join eq 'ARRAY'; |
|
640 | 641 |
|
641 |
- my @left_join_tables; |
|
642 |
- unshift @left_join_tables, $tables->[-1]; |
|
642 |
+ my @join_tables; |
|
643 |
+ unshift @join_tables, $tables->[-1]; |
|
643 | 644 |
|
644 |
- # Relation |
|
645 |
- if (!$selection && keys %$relation) { |
|
646 |
- foreach my $rcolumn (keys %$relation) { |
|
647 |
- my $table1 = (split (/\./, $rcolumn))[0]; |
|
648 |
- my $table2 = (split (/\./, $relation->{$rcolumn}))[0]; |
|
649 |
- |
|
650 |
- my $table1_exists; |
|
651 |
- my $table2_exists; |
|
652 |
- foreach my $table (@$tables) { |
|
653 |
- $table1_exists = 1 if $table eq $table1; |
|
654 |
- $table2_exists = 1 if $table eq $table2; |
|
655 |
- } |
|
656 |
- unshift @$tables, $table1 unless $table1_exists; |
|
657 |
- unshift @$tables, $table2 unless $table2_exists; |
|
658 |
- } |
|
659 |
- } |
|
645 |
+ # Relation table(DEPRECATED!); |
|
646 |
+ $self->_add_relation_table($args{relation}, $tables); |
|
660 | 647 |
|
661 | 648 |
# SQL stack |
662 | 649 |
my @sql; |
... | ... |
@@ -665,13 +652,13 @@ sub select { |
665 | 652 |
|
666 | 653 |
if ($selection) { |
667 | 654 |
push @sql, $selection; |
668 |
- push @left_join_tables, @{$self->_tables($selection)}; |
|
655 |
+ push @join_tables, @{$self->_tables($selection)}; |
|
669 | 656 |
} |
670 | 657 |
else { |
671 | 658 |
# Column clause |
672 | 659 |
if (@$columns) { |
673 | 660 |
foreach my $column (@$columns) { |
674 |
- push @left_join_tables, @{$self->_tables($column)}; |
|
661 |
+ push @join_tables, @{$self->_tables($column)}; |
|
675 | 662 |
push @sql, ($column, ','); |
676 | 663 |
} |
677 | 664 |
pop @sql if $sql[-1] eq ','; |
... | ... |
@@ -708,7 +695,7 @@ sub select { |
708 | 695 |
my $swhere = "$w"; |
709 | 696 |
|
710 | 697 |
# Table name in Where |
711 |
- unshift @left_join_tables, @{$self->_tables($swhere)}; |
|
698 |
+ unshift @join_tables, @{$self->_tables($swhere)}; |
|
712 | 699 |
|
713 | 700 |
# Left join |
714 | 701 |
if (@$left_join) { |
... | ... |
@@ -722,7 +709,7 @@ sub select { |
722 | 709 |
my $table1_exists; |
723 | 710 |
my $table2_exists; |
724 | 711 |
|
725 |
- foreach my $table (@left_join_tables) { |
|
712 |
+ foreach my $table (@join_tables) { |
|
726 | 713 |
$table1_exists = 1 if $table eq $table1; |
727 | 714 |
$table2_exists = 1 if $table eq $table2; |
728 | 715 |
} |
... | ... |
@@ -736,19 +723,9 @@ sub select { |
736 | 723 |
# Add where |
737 | 724 |
push @sql, $swhere; |
738 | 725 |
|
739 |
- # Relation |
|
740 |
- if (!$selection && keys %$relation) { |
|
741 |
- push @sql, $swhere eq '' ? 'where' : 'and'; |
|
742 |
- foreach my $rcolumn (keys %$relation) { |
|
743 |
- my $table1 = (split (/\./, $rcolumn))[0]; |
|
744 |
- my $table2 = (split (/\./, $relation->{$rcolumn}))[0]; |
|
745 |
- push @$tables, ($table1, $table2); |
|
746 |
- |
|
747 |
- push @sql, ("$rcolumn = " . $relation->{$rcolumn}, 'and'); |
|
748 |
- } |
|
749 |
- } |
|
750 |
- pop @sql if $sql[-1] eq 'and'; |
|
751 |
- |
|
726 |
+ # Relation(DEPRECATED!); |
|
727 |
+ $self->_push_relation(\@sql, $tables, $args{relation}, $swhere eq '' ? 1 : 0); |
|
728 |
+ |
|
752 | 729 |
# Append statement |
753 | 730 |
push @sql, $append if $append; |
754 | 731 |
|
... | ... |
@@ -759,7 +736,7 @@ sub select { |
759 | 736 |
my $query = $self->create_query($sql); |
760 | 737 |
return $query if $args{query}; |
761 | 738 |
|
762 |
- unshift @$tables, @left_join_tables; |
|
739 |
+ unshift @$tables, @join_tables; |
|
763 | 740 |
|
764 | 741 |
# Execute query |
765 | 742 |
my $result = $self->execute( |
... | ... |
@@ -1157,6 +1134,8 @@ sub _tables { |
1157 | 1134 |
return $tables; |
1158 | 1135 |
} |
1159 | 1136 |
|
1137 |
+ |
|
1138 |
+ |
|
1160 | 1139 |
# DEPRECATED! |
1161 | 1140 |
__PACKAGE__->attr( |
1162 | 1141 |
dbi_options => sub { {} }, |
... | ... |
@@ -1213,6 +1192,42 @@ sub register_tag_processor { |
1213 | 1192 |
return shift->query_builder->register_tag_processor(@_); |
1214 | 1193 |
} |
1215 | 1194 |
|
1195 |
+# DEPRECATED! |
|
1196 |
+sub _push_relation { |
|
1197 |
+ my ($self, $sql, $tables, $relation, $need_where) = @_; |
|
1198 |
+ |
|
1199 |
+ if (keys %{$relation || {}}) { |
|
1200 |
+ push @$sql, $need_where ? 'where' : 'and'; |
|
1201 |
+ foreach my $rcolumn (keys %$relation) { |
|
1202 |
+ my $table1 = (split (/\./, $rcolumn))[0]; |
|
1203 |
+ my $table2 = (split (/\./, $relation->{$rcolumn}))[0]; |
|
1204 |
+ push @$tables, ($table1, $table2); |
|
1205 |
+ push @$sql, ("$rcolumn = " . $relation->{$rcolumn}, 'and'); |
|
1206 |
+ } |
|
1207 |
+ } |
|
1208 |
+ pop @$sql if $sql->[-1] eq 'and'; |
|
1209 |
+} |
|
1210 |
+ |
|
1211 |
+# DEPRECATED! |
|
1212 |
+sub _add_relation_table { |
|
1213 |
+ my ($self, $relation, $tables) = @_; |
|
1214 |
+ |
|
1215 |
+ if (keys %{$relation || {}}) { |
|
1216 |
+ foreach my $rcolumn (keys %$relation) { |
|
1217 |
+ my $table1 = (split (/\./, $rcolumn))[0]; |
|
1218 |
+ my $table2 = (split (/\./, $relation->{$rcolumn}))[0]; |
|
1219 |
+ my $table1_exists; |
|
1220 |
+ my $table2_exists; |
|
1221 |
+ foreach my $table (@$tables) { |
|
1222 |
+ $table1_exists = 1 if $table eq $table1; |
|
1223 |
+ $table2_exists = 1 if $table eq $table2; |
|
1224 |
+ } |
|
1225 |
+ unshift @$tables, $table1 unless $table1_exists; |
|
1226 |
+ unshift @$tables, $table2 unless $table2_exists; |
|
1227 |
+ } |
|
1228 |
+ } |
|
1229 |
+} |
|
1230 |
+ |
|
1216 | 1231 |
1; |
1217 | 1232 |
|
1218 | 1233 |
=head1 NAME |
... | ... |
@@ -1733,6 +1748,7 @@ This is same as L<DBI>'s C<rollback>. |
1733 | 1748 |
where => \%where, |
1734 | 1749 |
append => $append, |
1735 | 1750 |
relation => \%relation, |
1751 |
+ left_join => ['book.company_id' => 'company.id'] |
|
1736 | 1752 |
filter => \%filter, |
1737 | 1753 |
query => 1, |
1738 | 1754 |
selection => $selection |
... | ... |
@@ -1757,6 +1773,9 @@ First element is a string. it contains tags, |
1757 | 1773 |
such as "{= title} or {like author}". |
1758 | 1774 |
Second element is paramters. |
1759 | 1775 |
|
1776 |
+C<left_join> is add left outer join clause after from clause. |
|
1777 |
+This is experimental. |
|
1778 |
+ |
|
1760 | 1779 |
=head3 C<(experimental) select_at()> |
1761 | 1780 |
|
1762 | 1781 |
To select row by using primary key, use C<select_at()>. |
... | ... |
@@ -1722,3 +1722,29 @@ is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1); |
1722 | 1722 |
|
1723 | 1723 |
eval { $dbi->insert_param({";" => 1}) }; |
1724 | 1724 |
like($@, qr/not safety/); |
1725 |
+ |
|
1726 |
+ |
|
1727 |
+test 'left_join'; |
|
1728 |
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0}); |
|
1729 |
+$dbi->execute($CREATE_TABLE->{0}); |
|
1730 |
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2}); |
|
1731 |
+$dbi->insert(table => 'table1', param => {key1 => 3, key2 => 4}); |
|
1732 |
+$dbi->execute($CREATE_TABLE->{2}); |
|
1733 |
+$dbi->insert(table => 'table2', param => {key1 => 1, key3 => 5}); |
|
1734 |
+$rows = $dbi->select( |
|
1735 |
+ table => 'table1', |
|
1736 |
+ column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3', |
|
1737 |
+ where => {'table1.key2' => 2}, |
|
1738 |
+ left_join => ['table1.key1' => 'table2.key1'] |
|
1739 |
+)->fetch_hash_all; |
|
1740 |
+is_deeply($rows, [{table1_key1 => 1, table2_key1 => 1, key2 => 2, key3 => 5}]); |
|
1741 |
+ |
|
1742 |
+eval { |
|
1743 |
+ $rows = $dbi->select( |
|
1744 |
+ table => 'table1', |
|
1745 |
+ column => 'table1.key1 as table1_key1, table2.key1 as table2_key1, key2, key3', |
|
1746 |
+ where => {'table1.key2' => 2}, |
|
1747 |
+ left_join => {'table1.key1' => 'table2.key1'} |
|
1748 |
+ ); |
|
1749 |
+}; |
|
1750 |
+like ($@, qr/array/); |