Commit | Line | Data |
5410c047 |
1 | package DBIx::Class::SQLMaker::Role::SQLA2Passthrough; |
2 | |
78227631 |
3 | use strict; |
4 | use warnings; |
5 | use Exporter 'import'; |
6 | |
48389aca |
7 | our @EXPORT = qw(on); |
78227631 |
8 | |
9 | sub 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 |
22 | use Role::Tiny; |
23 | |
24 | around 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 |
51 | sub 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 |
68 | 1; |
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 | |
98 | Or 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 | |
115 | becomes |
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 | ); |