make keyword-like subs optional exports from ExprDeclare
[dbsrgits/Data-Query.git] / lib / Data / Query / ExprDeclare.pm
index b2f38a6..f0285fb 100644 (file)
@@ -8,12 +8,14 @@ use Safe::Isa;
 
 use base qw(Exporter);
 
-our @EXPORT = qw(
-  expr SELECT AS FROM BY JOIN ON LEFT WHERE ORDER GROUP DESC
+our @EXPORT = qw(expr);
+
+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 {
@@ -50,7 +52,14 @@ sub SELECT (&;@) {
      );
   }
       
-  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 (&;@) { @_ }
@@ -77,9 +86,9 @@ sub FROM (&;@) {
   }
   while (is_Order($_[0])) {
     my $order = shift;
-    $from_dq = Order($order->{by}, $order->{reverse}, $from_dq);
+    $from_dq = Order($order->{by}, $order->{reverse}, $order->{nulls}, $from_dq);
   }
-  return $from_dq;
+  return ($from_dq, @_);
 }
 
 sub LEFT {
@@ -90,7 +99,7 @@ sub LEFT {
 }
 
 sub JOIN (&;@) {
-  my $join = FROM(\&{+shift});
+  my ($join) = FROM(\&{+shift});
   my $on = do {
     if ($_[0]->$_isa('LIES::ON')) {
       ${+shift}
@@ -112,6 +121,9 @@ sub WHERE (&;@) {
 }
 
 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);
@@ -122,7 +134,23 @@ sub ORDER {
       0;
     }
   };
-  return compose { Order($b, $reverse, $a) } @order, undef;
+  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;