select+join+where
[dbsrgits/Data-Query.git] / lib / Data / Query / ExprDeclare.pm
CommitLineData
aad6ee1b 1package Data::Query::ExprDeclare;
2
3use strictures;
4use Data::Query::ExprBuilder::Identifier;
5use Data::Query::ExprHelpers;
6use Data::Query::Constants;
7use Safe::Isa;
8
9use base qw(Exporter);
10
4e0c6139 11our @EXPORT = qw(expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP);
aad6ee1b 12
13sub expr (&) {
14 _run_expr($_[0])->{expr};
15}
16
17sub _run_expr {
18 local $_ = Data::Query::ExprBuilder::Identifier->new({
19 expr => Identifier(),
20 });
21 $_[0]->();
22}
23
24sub _value {
4e0c6139 25 if ($_[0]->$_isa('Data::Query::ExprBuilder')) {
26 $_[0]->{expr};
27 } elsif (ref($_[0])) {
28 $_[0]
29 } else {
30 perl_scalar_value($_[0]);
31 }
aad6ee1b 32}
33
34sub AS {
35 my $as = shift;
36 (bless(\$as, 'LIES::AS'), @_);
37}
38
39sub SELECT (&;@) {
40 my @select = map _value($_), _run_expr(shift);
41 my @final;
42 while (@select) {
43 my $e = shift @select;
44 push @final,
45 (ref($select[0]) eq 'LIES::AS'
46 ? Alias(${shift(@select)}, $e)
47 : $e
48 );
49 }
50
51 return Select(\@final, $_[0]);
52}
53
54sub BY (&;@) { @_ }
55
56sub FROM (&;@) {
57 my @from = _run_expr(shift);
58 my $from_dq = do {
59 if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
60 Alias(${$from[1]}, _value($from[0]))
61 } elsif (@from == 1) {
62 _value($from[0]);
63 }
64 };
4e0c6139 65 while (is_Join($_[0])) {
aad6ee1b 66 $from_dq = { %{+shift}, left => $from_dq };
67 }
4e0c6139 68 if (is_Where($_[0])) {
69 $from_dq = Where(shift->{where}, $from_dq);
70 }
aad6ee1b 71 return $from_dq;
aad6ee1b 72}
73
74sub LEFT {
75 my ($join, @rest) = @_;
76 die "LEFT used as modifier on non-join ${join}"
77 unless is_Join($join);
78 return +{ %$join, outer => 'LEFT' }, @rest;
79}
80
81sub JOIN (&;@) {
82 my $join = FROM(\&{+shift});
83 my $on = do {
84 if ($_[0]->$_isa('LIES::ON')) {
85 ${+shift}
86 } else {
87 undef
88 }
89 };
90 Join(undef, $join, $on), @_;
91}
92
93sub ON (&;@) {
94 my $on = _value(_run_expr(shift));
95 return bless(\$on, 'LIES::ON'), @_;
96}
97
98sub WHERE (&;@) {
99 my $w = shift;
100 return Where(_value(_run_expr($w))), @_;
101}
102
1031;