more tweaks
[dbsrgits/SQL-Abstract.git] / e.pl
CommitLineData
abd9923d 1use strict;
2use warnings;
3
4{
5 package E;
6
7 use overload
8 '==' => '_op_num_eq',
9 '>' => '_op_num_gt',
10 ;
11
12 sub new {
13 my ($self, $data) = @_;
14 my $class = ref($self) || $self;
15 return bless(\$data, $class);
16 };
17
18 sub _op_num_eq { shift->_binop('==', @_) };
19 sub _op_num_gt { shift->_binop('>', @_) };
20
21 sub _binop {
22 my ($self, $op, $rhs) = @_;
23 $self->new([
24 $op,
25 ${$self},
26 (ref $rhs ? ${$rhs} : [ -value, $rhs ]),
27 ]);
28 };
29
30 package I;
31
32 sub AUTOLOAD {
33 our $AUTOLOAD =~ s/.*:://;
34 return I::E->new([ -name, $AUTOLOAD ]);
35 }
36
37 sub DESTROY { }
38
39 package I::E;
40
41 our @ISA = qw(I E);
42
43 1;
44}
45
46use Data::Dump qw(dump);
47use Scalar::Util qw(blessed);
48
49sub _une {
50 my $un = shift;
51 blessed($un) && $un->isa('E')
52 ? ${$un}
53 : ref($un) eq 'ARRAY'
54 ? [ map { _une($_) } @$un ]
55 : $un;
56}
57
58sub _run_e {
59 local $_ = bless(\do { my $x }, 'I');
60 map { _une($_) } $_[0]->();
61}
62
29c7d026 63sub _aliasify {
64 map { ref($_) eq 'ARRAY' ? [ -alias, $_->[1], $_->[0] ] : $_ } @_
65}
66
abd9923d 67sub expr (&) { _run_e(@_) }
68sub _do {
18ca8b57 69 return [ @_ ] unless @_ > 2; # FOO { ... }<nothing or ,>
70 my $name = shift;
71 my $code = shift;
72 my $ret = [ $name, _run_e($code), shift ];
73 return $ret unless @_;
74 die "WHUT";
abd9923d 75}
76sub _dolist {
77 my ($name, $code, @in) = @_;
29c7d026 78 _do($name,
79 sub { [ -list,
80 map { _une($_) }
81 _aliasify $code->()
82 ] },
83 @in);
abd9923d 84}
85sub ORDER_BY (&;@) { _do(-order_by, @_) }
86sub SELECT (&;@) { _dolist('-select', @_); }
af31cae2 87sub JOIN (&;@) { _do('-join', shift, [ -list => _aliasify @{+shift} ], @_) }
abd9923d 88sub WHERE (&;@) { _do(-where, @_) }
89sub GROUP_BY (&;@) { _dolist(-group_by, @_); }
90sub sum { E->new([ -sum, _une(shift) ]); }
91
92#warn dump(expr { $_->one == $_->two });
93warn dump(
94 ORDER_BY { $_->aggregates->total }
95 SELECT { $_->users->name, $_->aggregates->total }
96 JOIN { $_->users->id == $_->aggregates->recipient_id }
af31cae2 97 [
98 [ users => expr { $_->users } ],
99 [ aggregates =>
100 expr {
101 SELECT { $_->recipient_id, [ total => sum($_->commission) ] }
102 WHERE { sum($_->commission) > 500 }
103 GROUP_BY { $_->recipient_id }
104 WHERE { $_->entry_date > '2007-01-01' }
105 expr { $_->commissions }
abd9923d 106 }
af31cae2 107 ]
abd9923d 108 ]
109);
252475d8 110
111warn dump(
112 ORDER_BY { $_->aggregates->total }
113 SELECT { $_->users->name, $_->aggregates->total }
114 JOIN { $_->users->id == $_->aggregates->recipient_id }
af31cae2 115 [
116 [ users => expr { $_->users } ],
117 [ aggregates =>
118 expr {
119 SELECT { $_->recipient_id, [ total => sum($_->commission) ] }
120 WHERE { sum($_->commission) > 500 }
121 GROUP_BY { $_->recipient_id }
122 WHERE { $_->entry_date > '2007-01-01' }
123 expr { $_->commissions }
124 }
125 ]
252475d8 126 ]
127);
128
129warn dump(
130 ORDER_BY { $_->aggregates->total }
131 SELECT { $_->users->name, $_->aggregates->total }
132 WHERE { $_->aggregates->total > 500 }
133 JOIN { $_->users->id == $_->aggregates->recipient_id }
af31cae2 134 [
135 [ users => expr { $_->users } ],
136 [ aggregates =>
137 expr {
138 SELECT { $_->recipient_id, [ total => sum($_->commission) ] }
139 GROUP_BY { $_->recipient_id }
140 WHERE { $_->entry_date > '2007-01-01' }
141 expr { $_->commissions }
142 }
143 ]
252475d8 144 ]
145);