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 WHERE ORDER GROUP);
+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 {
: $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 (&;@) { @_ }
$from_dq = { %{+shift}, left => $from_dq };
}
if (is_Where($_[0])) {
- $from_dq = Where(shift->{where}, $from_dq);
+ 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;
+ return ($from_dq, @_);
}
sub LEFT {
}
sub JOIN (&;@) {
- my $join = FROM(\&{+shift});
+ my ($join) = FROM(\&{+shift});
my $on = do {
if ($_[0]->$_isa('LIES::ON')) {
${+shift}
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;