order by somewhat working
[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
9f0ad8f6 11our @EXPORT = qw(
12 expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC
13);
aad6ee1b 14
15sub expr (&) {
16 _run_expr($_[0])->{expr};
17}
18
19sub _run_expr {
20 local $_ = Data::Query::ExprBuilder::Identifier->new({
21 expr => Identifier(),
22 });
23 $_[0]->();
24}
25
26sub _value {
4e0c6139 27 if ($_[0]->$_isa('Data::Query::ExprBuilder')) {
28 $_[0]->{expr};
29 } elsif (ref($_[0])) {
30 $_[0]
31 } else {
32 perl_scalar_value($_[0]);
33 }
aad6ee1b 34}
35
36sub AS {
37 my $as = shift;
38 (bless(\$as, 'LIES::AS'), @_);
39}
40
41sub SELECT (&;@) {
42 my @select = map _value($_), _run_expr(shift);
43 my @final;
44 while (@select) {
45 my $e = shift @select;
46 push @final,
47 (ref($select[0]) eq 'LIES::AS'
48 ? Alias(${shift(@select)}, $e)
49 : $e
50 );
51 }
52
53 return Select(\@final, $_[0]);
54}
55
56sub BY (&;@) { @_ }
57
58sub FROM (&;@) {
59 my @from = _run_expr(shift);
60 my $from_dq = do {
61 if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
62 Alias(${$from[1]}, _value($from[0]))
63 } elsif (@from == 1) {
64 _value($from[0]);
65 }
66 };
4e0c6139 67 while (is_Join($_[0])) {
aad6ee1b 68 $from_dq = { %{+shift}, left => $from_dq };
69 }
4e0c6139 70 if (is_Where($_[0])) {
9f0ad8f6 71 my $where = shift->{where};
72 if (is_Select($from_dq)) {
73 $from_dq = Select($from_dq->{select}, Where($where, $from_dq->{from}));
74 } else {
75 $from_dq = Where($where, $from_dq);
76 }
77 }
78 while (is_Order($_[0])) {
79 my $order = shift;
80 $from_dq = Order($order->{by}, $order->{reverse}, $from_dq);
4e0c6139 81 }
aad6ee1b 82 return $from_dq;
aad6ee1b 83}
84
85sub LEFT {
86 my ($join, @rest) = @_;
87 die "LEFT used as modifier on non-join ${join}"
88 unless is_Join($join);
89 return +{ %$join, outer => 'LEFT' }, @rest;
90}
91
92sub JOIN (&;@) {
93 my $join = FROM(\&{+shift});
94 my $on = do {
95 if ($_[0]->$_isa('LIES::ON')) {
96 ${+shift}
97 } else {
98 undef
99 }
100 };
101 Join(undef, $join, $on), @_;
102}
103
104sub ON (&;@) {
105 my $on = _value(_run_expr(shift));
106 return bless(\$on, 'LIES::ON'), @_;
107}
108
109sub WHERE (&;@) {
110 my $w = shift;
111 return Where(_value(_run_expr($w))), @_;
112}
113
9f0ad8f6 114sub DESC { bless({}, 'LIES::DESC'), @_ }
115
116sub ORDER {
117 my @order = map _value($_), _run_expr(shift);
118 my $reverse = do {
119 if ($_[0]->$_isa('LIES::DESC')) {
120 shift; 1;
121 } else {
122 0;
123 }
124 };
125 return compose { Order($b, $reverse, $a) } @order, undef;
126}
127
aad6ee1b 1281;