X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FData%2FQuery%2FExprHelpers.pm;h=6020be6c3e74a7cd8cfaa6809e57a03d6afb6cc3;hb=8b2c306b68d5196e693256deebbfe4c32786f8d4;hp=455461e820b1fbadc72b33066a861a79b347a945;hpb=7f462f860c233998b75949973bf2acb785ef2132;p=dbsrgits%2FData-Query.git diff --git a/lib/Data/Query/ExprHelpers.pm b/lib/Data/Query/ExprHelpers.pm index 455461e..6020be6 100644 --- a/lib/Data/Query/ExprHelpers.pm +++ b/lib/Data/Query/ExprHelpers.pm @@ -1,11 +1,11 @@ package Data::Query::ExprHelpers; use strictures 1; -use Data::Query::Constants qw(DQ_VALUE DQ_OPERATOR DQ_IDENTIFIER); +use Data::Query::Constants; use base qw(Exporter); -our @EXPORT_OK = qw(perl_scalar_value perl_operator identifier); +our @EXPORT = qw(perl_scalar_value perl_operator Literal Identifier compose); sub perl_scalar_value { +{ @@ -25,11 +25,95 @@ sub perl_operator { } } -sub identifier { - +{ +my %map = ( + Join => [ qw(left right on outer) ], + Alias => [ qw(to from) ], + Operator => [ qw(operator args) ], + Select => [ qw(select from) ], + Where => [ qw(where from) ], + Order => [ qw(by reverse from) ], + Group => [ qw(by from) ], + Delete => [ qw(where target) ], + Update => [ qw(set where target) ], + Insert => [ qw(names values target returning) ], + Slice => [ qw(offset limit from) ], +); + +sub Literal { + my $subtype = shift; + if (ref($_[0])) { + return +{ + type => DQ_LITERAL, + subtype => $subtype, + parts => $_[0], + }; + } + return +{ + type => DQ_LITERAL, + subtype => $subtype, + literal => $_[0], + ($_[1] ? (values => $_[1]) : ()) + }; +} + +sub Identifier { + return +{ type => DQ_IDENTIFIER, - elements => [ @_ ] + elements => [ @_ ], + }; +} + +foreach my $name (values %Data::Query::Constants::CONST) { + no strict 'refs'; + my $sub = "is_${name}"; + *$sub = sub { + my $dq = $_[0]||$_; + $dq->{type} and $dq->{type} eq $name + }; + push @EXPORT, $sub; + if ($map{$name}) { + my @map = @{$map{$name}}; + *$name = sub { + my $dq = { type => $name }; + foreach (0..$#_) { + $dq->{$map[$_]} = $_[$_] if defined $_[$_]; + } + return $dq; + }; + push @EXPORT, $name; } } +sub is_Having { is_Where($_[0]) and is_Group($_[0]->{from}) } + +push @EXPORT, 'is_Having'; + +sub compose (&@) { + my $code = shift; + require Scalar::Util; + my $type = Scalar::Util::reftype($code); + unless($type and $type eq 'CODE') { + require Carp; + Carp::croak("Not a subroutine reference"); + } + no strict 'refs'; + + return shift unless @_ > 1; + + use vars qw($a $b); + + my $caller = caller; + local(*{$caller."::a"}) = \my $a; + local(*{$caller."::b"}) = \my $b; + + $a = pop; + foreach (reverse @_) { + $b = $_; + $a = &{$code}(); + } + + $a; +} + + 1;