add compose routine and refactor FetchFirst to functional style
[dbsrgits/Data-Query.git] / lib / Data / Query / Renderer / SQL / Slice / FetchFirst.pm
index 930c382..7a3234d 100644 (file)
@@ -86,40 +86,51 @@ sub _render_slice {
     push @order_nodes, $order;
     $order = $order->{from};
   }
-  my $inside_order = $order;
-  $inside_order = Order($_->{by}, $_->{reverse}, $inside_order)
-    for reverse @order_nodes;
-  my $inside_select = Select(\@inside_select_list, $inside_order);
+  $default_inside_alias ||= 'me';
   my $limit_plus_offset = +{
     %{$dq->{limit}}, value => $dq->{limit}{value} + $dq->{offset}{value}
   };
-  $default_inside_alias ||= 'me';
-  my $bridge_from = Alias(
-    $default_inside_alias,
-    Slice(undef, $limit_plus_offset, $inside_select)
-  );
-  my $outside_order = $bridge_from;
-  $outside_order = Order($order_map{$_->{by}}, !$_->{reverse}, $outside_order)
-    for reverse @order_nodes;
-  my $outside_select = Select(
-    (
+  my $inner_body = $order;
+  return $self->_render(
+    map {
       $dq->{preserve_order}
-        ? [
+        ? Select(
+          \@outside_select_list,
+          compose {
+            Order($order_map{$b->{by}}, $b->{reverse}, $a)
+          } @order_nodes, Alias($default_inside_alias, $_)
+        )
+        : $_
+    } Slice(
+        undef, $dq->{limit},
+        Select(
+          [
             @outside_select_list,
-            grep @{$_->{elements}} == 1, @order_map{map $_->{by}, @order_nodes}
-          ]
-        : \@outside_select_list,
-    ),
-    $outside_order,
+            $dq->{preserve_order}
+              ? (grep @{$_->{elements}} == 1,
+                  @order_map{map $_->{by}, @order_nodes})
+              : (),
+          ],
+          compose {
+            Order($order_map{$b->{by}}, !$b->{reverse}, $a)
+          } (
+            @order_nodes,
+            Alias(
+              $default_inside_alias,
+              Slice(
+                undef, $limit_plus_offset,
+                Select(
+                  \@inside_select_list,
+                  compose {
+                    Order($b->{by}, $b->{reverse}, $a)
+                  } @order_nodes, $inner_body
+                )
+              )
+            )
+          )
+        )
+      )
   );
-  my $final = Slice(undef, $dq->{limit}, $outside_select);
-  if ($dq->{preserve_order}) {
-    $final = Alias($default_inside_alias, $final);
-    $final = Order($order_map{$_->{by}}, $_->{reverse}, $final)
-      for reverse @order_nodes;
-    $final = Select(\@outside_select_list, $final);
-  }
-  return $self->_render($final);
 }
 
 1;