X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FData%2FQuery%2FExprDeclare.pm;h=b6896bdd284d5b4282ea469fc9c09999b991563a;hb=HEAD;hp=0a1bcaa763cb8a8e0a879517cd299fb4a1de080c;hpb=aad6ee1b9034ca9f7cb54cb7d29984c76e9906f0;p=dbsrgits%2FData-Query.git diff --git a/lib/Data/Query/ExprDeclare.pm b/lib/Data/Query/ExprDeclare.pm index 0a1bcaa..b6896bd 100644 --- a/lib/Data/Query/ExprDeclare.pm +++ b/lib/Data/Query/ExprDeclare.pm @@ -5,13 +5,21 @@ use Data::Query::ExprBuilder::Identifier; use Data::Query::ExprHelpers; use Data::Query::Constants; use Safe::Isa; +use Exporter (); -use base qw(Exporter); +sub import { + warnings->unimport('precedence'); + goto &Exporter::import; +} + +our @EXPORT = qw(expr); -our @EXPORT = qw(expr SELECT AS FROM BY JOIN ON LEFT); +our @EXPORT_OK = qw( + SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC LIMIT OFFSET NULLS FIRST LAST +); sub expr (&) { - _run_expr($_[0])->{expr}; + _run_expr($_[0]); } sub _run_expr { @@ -22,7 +30,13 @@ sub _run_expr { } sub _value { - ref($_[0]) ? $_[0]->{expr} : perl_scalar_value($_[0]) + if ($_[0]->$_isa('Data::Query::ExprBuilder')) { + $_[0]->{expr}; + } elsif (ref($_[0])) { + $_[0] + } else { + perl_scalar_value($_[0]); + } } sub AS { @@ -41,8 +55,15 @@ sub SELECT (&;@) { : $e ); } - - return Select(\@final, $_[0]); + + my $final = Select(\@final, shift); + + if (is_Slice($_[0])) { + my ($limit, $offset) = @{+shift}{qw(limit offset)}; + $final = Slice($offset, $limit, $final); + } + + return $final; } sub BY (&;@) { @_ } @@ -56,11 +77,22 @@ sub FROM (&;@) { _value($from[0]); } }; - while ($_[0] and is_Join($_[0])) { + while (is_Join($_[0])) { $from_dq = { %{+shift}, left => $from_dq }; } - return $from_dq; - die "Huh?" + if (is_Where($_[0])) { + my $where = shift->{where}; + if (is_Select($from_dq)) { + $from_dq = Select($from_dq->{select}, Where($where, $from_dq->{from})); + } else { + $from_dq = Where($where, $from_dq); + } + } + while (is_Order($_[0])) { + my $order = shift; + $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq); + } + return ($from_dq, @_); } sub LEFT { @@ -71,7 +103,7 @@ sub LEFT { } sub JOIN (&;@) { - my $join = FROM(\&{+shift}); + my ($join) = FROM(\&{+shift}); my $on = do { if ($_[0]->$_isa('LIES::ON')) { ${+shift} @@ -92,4 +124,37 @@ sub WHERE (&;@) { return Where(_value(_run_expr($w))), @_; } +sub DESC { bless({}, 'LIES::DESC'), @_ } +sub NULLS { bless(\shift, 'LIES::NULLS'), @_ } +sub FIRST { 1, @_ } +sub LAST { -1, @_ } + +sub ORDER { + my @order = map _value($_), _run_expr(shift); + my $reverse = do { + if ($_[0]->$_isa('LIES::DESC')) { + shift; 1; + } else { + 0; + } + }; + my $nulls = $_[0]->$_isa('LIES::NULLS') ? ${+shift} : undef; + + return ((compose { Order($b, $reverse, $nulls, $a) } @order, undef), @_); +} + +sub LIMIT (&;@) { + my ($limit) = map _value($_), _run_expr(shift); + if (is_Slice($_[0])) { + my $slice = shift; + return +{ %{$slice}, limit => $limit }, @_; + } + return Slice(undef, $limit), @_; +} + +sub OFFSET (&;@) { + my ($offset) = map _value($_), _run_expr(shift); + return Slice($offset, undef), @_; +} + 1;