ORDER BY, HAVING, GROUP BY and WHERE clauses on select
[dbsrgits/SQL-Abstract-2.0-ish.git] / lib / SQL / Abstract / AST / v1.pm
index 0ce6e9f..ae2e05c 100644 (file)
@@ -54,14 +54,24 @@ class SQL::Abstract::AST::v1 extends SQL::Abstract {
     push @output, FROM => $self->dispatch($ast->{tablespec})
       if exists $ast->{tablespec};
 
-    for (qw//) {
+    if (exists $ast->{where}) {
+      my $sub_ast = $ast->{where};
+
+      confess "$_ option is not an AST: " . dump($sub_ast)
+        unless is_AST($sub_ast);
+
+      push @output, "WHERE", $self->_expr($sub_ast);
+    }
+
+    for (qw/group_by having order_by/) {
       if (exists $ast->{$_}) {
         my $sub_ast = $ast->{$_};
-        $sub_ast->{-type} = "$_" if is_HashRef($sub_ast);
-        confess "$_ option is not an AST"
-          unless is_AST($sub_ast);
 
-        push @output, $self->dispatch($sub_ast);
+        confess "$_ option is not an AST or an ArrayRef: " . dump($sub_ast)
+          unless is_AST($sub_ast) || is_ArrayRef($sub_ast);;
+
+        my $meth = "__$_";
+        push @output, $self->$meth($sub_ast);
       }
     }
 
@@ -69,44 +79,39 @@ class SQL::Abstract::AST::v1 extends SQL::Abstract {
   }
 
   method _join(HashRef $ast) {
-    confess "'args' option to join should be an array ref, not " . dump($ast->{args})
-      unless is_ArrayRef($ast->{args});
-
-    my ($from, $to) = @{ $ast->{args} };
 
     # TODO: Validate join type
     my $type = $ast->{join_type} || "";
   
-    my @output = $self->dispatch($from);
+    my @output = $self->dispatch($ast->{lhs});
 
     push @output, uc $type if $type;
-    push @output, "JOIN", $self->dispatch($to);
+    push @output, "JOIN", $self->dispatch($ast->{rhs});
 
     push @output, 
         exists $ast->{on}
       ? ('ON', '(' . $self->_expr( $ast->{on} ) . ')' )
-      : ('USING', '(' .$self->dispatch($ast->{using} || croak "No 'on' or 'join' clause passed to -join").
+      : ('USING', '(' .$self->dispatch($ast->{using} 
+                        || croak "No 'on' or 'uinsg' clause passed to join cluase: " .
+                                 dump($ast) 
+                        ) .
                   ')' );
 
     return join(" ", @output);
       
   }
 
-  method _order_by(AST $ast) {
-    my @clauses = @{$ast->{order_by}};
-  
-    my @output;
-   
-    for (@clauses) {
-      if (is_ArrayRef($_) && $_->[0] =~ /^-(asc|desc)$/) {
-        my $o = $1;
-        push @output, $self->dispatch($_->[1]) . " " . uc($o);
-        next;
-      }
-      push @output, $self->dispatch($_);
-    }
+  method _ordering(AST $ast) {
+    my $output = $self->_expr($ast->{expr});
+
+    $output .= " " . uc $1
+      if $ast->{direction} && 
+         ( $ast->{direction} =~ /^(asc|desc)$/i 
+           || confess "Unknown ordering direction " . dump($ast)
+         );
 
-    return "ORDER BY " . join(", ", @output);
+    return $output;
   }
 
   method _name(HashAST $ast) {
@@ -136,7 +141,9 @@ class SQL::Abstract::AST::v1 extends SQL::Abstract {
 
 
   method _list(AST $ast) {
-    my @items = @{$ast->{args}};
+    my @items = is_ArrayRef($ast->{args})
+              ? @{$ast->{args}}
+              : $ast->{args};
 
     return join(
       $self->list_separator,
@@ -157,6 +164,20 @@ class SQL::Abstract::AST::v1 extends SQL::Abstract {
     return "?";
   }
 
+  # Not dispatchable to.
+  method __having($args) {
+    return "HAVING " . $self->_list({-type => 'list', args => $args});
+  }
+
+  method __group_by($args) {
+    return "GROUP BY " . $self->_list({-type => 'list', args => $args});
+  }
+
+  method __order_by($args) {
+    return "ORDER BY " . $self->_list({-type => 'list', args => $args});
+  }
+
+
   # Perhaps badly named. handles 'and' and 'or' clauses
   method _recurse_where(HashAST $ast) {