don't negate undef in Slice/FetchFirst
[dbsrgits/Data-Query.git] / lib / Data / Query / ExprHelpers.pm
CommitLineData
12e6eab8 1package Data::Query::ExprHelpers;
2
3use strictures 1;
6b45ffe4 4use Data::Query::Constants;
12e6eab8 5
6use base qw(Exporter);
7
bb5b7a0d 8our @EXPORT = qw(
9 perl_scalar_value perl_operator Literal Identifier compose intersperse
10);
11
12sub intersperse { my $i = shift; my @i = map +($_, $i), @_; pop @i; @i }
12e6eab8 13
14sub perl_scalar_value {
15 +{
9c8fc055 16 type => DQ_VALUE,
17 subtype => { Perl => 'Scalar' },
7f462f86 18 value => $_[0],
19 $_[1] ? (value_meta => $_[1]) : ()
12e6eab8 20 }
21}
22
23sub perl_operator {
24 my ($op, @args) = @_;
25 +{
26 type => DQ_OPERATOR,
27 operator => { Perl => $op },
28 args => \@args
29 }
30}
31
6b45ffe4 32my %map = (
33 Join => [ qw(left right on outer) ],
34 Alias => [ qw(to from) ],
35 Operator => [ qw(operator args) ],
36 Select => [ qw(select from) ],
37 Where => [ qw(where from) ],
e3335558 38 Order => [ qw(by reverse nulls from) ],
6b45ffe4 39 Group => [ qw(by from) ],
40 Delete => [ qw(where target) ],
41 Update => [ qw(set where target) ],
42 Insert => [ qw(names values target returning) ],
43 Slice => [ qw(offset limit from) ],
44);
45
46sub Literal {
af2d4155 47 my $subtype = shift;
6b45ffe4 48 if (ref($_[0])) {
49 return +{
50 type => DQ_LITERAL,
af2d4155 51 subtype => $subtype,
cc5ec83c 52 parts => $_[0],
6b45ffe4 53 };
54 }
55 return +{
56 type => DQ_LITERAL,
af2d4155 57 subtype => $subtype,
6b45ffe4 58 literal => $_[0],
59 ($_[1] ? (values => $_[1]) : ())
60 };
61}
62
63sub Identifier {
64 return +{
9c8fc055 65 type => DQ_IDENTIFIER,
6b45ffe4 66 elements => [ @_ ],
67 };
68}
69
70foreach my $name (values %Data::Query::Constants::CONST) {
71 no strict 'refs';
72 my $sub = "is_${name}";
73 *$sub = sub {
74 my $dq = $_[0]||$_;
5a058623 75 $dq->{type} and $dq->{type} eq $name
6b45ffe4 76 };
77 push @EXPORT, $sub;
78 if ($map{$name}) {
79 my @map = @{$map{$name}};
80 *$name = sub {
81 my $dq = { type => $name };
82 foreach (0..$#_) {
83 $dq->{$map[$_]} = $_[$_] if defined $_[$_];
84 }
85 return $dq;
86 };
87 push @EXPORT, $name;
9c8fc055 88 }
89}
90
5a058623 91sub is_Having { is_Where($_[0]) and is_Group($_[0]->{from}) }
92
93push @EXPORT, 'is_Having';
94
9fcc2256 95sub compose (&@) {
96 my $code = shift;
97 require Scalar::Util;
98 my $type = Scalar::Util::reftype($code);
99 unless($type and $type eq 'CODE') {
100 require Carp;
101 Carp::croak("Not a subroutine reference");
102 }
103 no strict 'refs';
104
105 return shift unless @_ > 1;
106
107 use vars qw($a $b);
108
109 my $caller = caller;
110 local(*{$caller."::a"}) = \my $a;
111 local(*{$caller."::b"}) = \my $b;
112
113 $a = pop;
114 foreach (reverse @_) {
115 $b = $_;
116 $a = &{$code}();
117 }
118
119 $a;
120}
121
122
12e6eab8 1231;