fixup passthrough and add example
[dbsrgits/SQL-Abstract.git] / lib / DBIx / Class / SQLMaker / Role / SQLA2Passthrough.pm
CommitLineData
5410c047 1package DBIx::Class::SQLMaker::Role::SQLA2Passthrough;
2
78227631 3use strict;
4use warnings;
5use Exporter 'import';
6
48389aca 7our @EXPORT = qw(on);
78227631 8
9sub on (&) {
10 my ($on) = @_;
11 sub {
12 my ($args) = @_;
13 $args->{self_resultsource}
14 ->schema->storage->sql_maker
15 ->expand_join_condition(
16 $on->($args),
17 $args
18 );
19 }
20}
21
5410c047 22use Role::Tiny;
23
24around select => sub {
25 my ($orig, $self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
26
27 $fields = \[ $self->render_expr({ -list => [
28 grep defined,
29 map +(ref($_) eq 'HASH'
30 ? do {
31 my %f = %$_;
32 my $as = delete $f{-as};
33 my ($f, $rhs) = %f;
48389aca 34 my $func = +{ ($f =~ /^-/ ? $f : "-${f}") => $rhs };
5410c047 35 ($as
36 ? +{ -op => [ 'as', $func, { -ident => [ $as ] } ] }
37 : $func)
38 }
39 : $_), ref($fields) eq 'ARRAY' ? @$fields : $fields
40 ] }, -ident) ];
41
42 if (my $gb = $rs_attrs->{group_by}) {
43 $rs_attrs = {
44 %$rs_attrs,
45 group_by => \[ $self->render_expr({ -list => $gb }, -ident) ]
46 };
47 }
48 $self->$orig($table, $fields, $where, $rs_attrs, $limit, $offset);
48389aca 49};
5410c047 50
78227631 51sub expand_join_condition {
52 my ($self, $cond, $args) = @_;
53 my $wrap = sub {
54 my ($orig) = @_;
55 sub {
56 my $res = $orig->(@_);
57 my ($name, @rest) = @{$res->{-ident}};
58 if ($name eq 'self' or $name eq 'foreign') {
59 $res->{-ident} = [ $args->{"${name}_alias"}, @rest ];
60 }
61 return $res;
62 };
63 };
64 my $sqla = $self->clone->wrap_op_expander(ident => $wrap);
65 $sqla->expand_expr($cond, -ident);
66}
67
5410c047 681;
78227631 69
70__END__
71
72=head1 SETUP
73
74 (on_connect_call => sub {
75 my ($storage) = @_;
76 $storage->sql_maker
77 ->with::roles('DBIx::Class::SQLMaker::Role::SQLA2Passthrough');
78 })
79
80=head2 expand_join_condition
81
82 __PACKAGE__->has_many(minions => 'Blah::Person' => sub {
83 my ($args) = @_;
84 $args->{self_resultsource}
85 ->schema->storage->sql_maker
86 ->expand_join_condition(
87 $args
88 );
89 });
90
91=head2 on
92
93 __PACKAGE__->has_many(minions => 'Blah::Person' => on {
94 { 'self.group_id' => 'foreign.group_id',
95 'self.rank' => { '>', 'foreign.rank' } }
96 });
97
98Or with ParameterizedJoinHack,
99
100 __PACKAGE__->parameterized_has_many(
101 priority_tasks => 'MySchema::Result::Task',
102 [['min_priority'] => sub {
103 my $args = shift;
104 return +{
105 "$args->{foreign_alias}.owner_id" => {
106 -ident => "$args->{self_alias}.id",
107 },
108 "$args->{foreign_alias}.priority" => {
109 '>=' => $_{min_priority},
110 },
111 };
112 }],
113 );
114
115becomes
116
117 __PACKAGE__->parameterized_has_many(
118 priority_tasks => 'MySchema::Result::Task',
119 [['min_priority'] => on {
120 { 'foreign.owner_id' => 'self.id',
121 'foreign.priority' => { '>=', { -value => $_{min_priority} } } }
122 }]
123 );