Port more of the back-compat tests
[dbsrgits/SQL-Abstract-2.0-ish.git] / lib / SQL / Abstract / AST / Compat.pm
index 97e2fd3..4093bc2 100644 (file)
@@ -16,8 +16,35 @@ class SQL::Abstract::AST::Compat {
     default => 'AND'
   );
 
-  method generate(WhereType $ast) returns (AST) {
-    return $self->recurse_where($ast);
+  sub mk_name {
+    shift;
+    return { -type => 'name', args => [ @_ ] };
+  }
+
+  method select(Str|ArrayRef|ScalarRef $from, ArrayRef|Str $fields,
+                WhereType $where?,
+                WhereType $order?)
+  {
+    my $ast = {
+      -type => 'select',
+      columns => [ 
+        map {
+          $self->mk_name($_)
+        } ( is_Str($fields) ? $fields : @$fields )
+      ],
+      tablespec => $self->tablespec($from)
+    };
+
+
+    $ast->{where} = $self->recurse_where($where)
+      if defined $where;
+
+    return $ast;
+  }
+
+  method tablespec(Str|ArrayRef|ScalarRef $from) {
+    return $self->mk_name($from)
+      if is_Str($from);
   }
 
   method recurse_where(WhereType $ast, LogicEnum $logic?) returns (AST) {
@@ -95,13 +122,59 @@ class SQL::Abstract::AST::Compat {
       ],
     };
 
-    if (is_Str($value)) {
-      push @{$ret->{args}}, { -type => 'value', value => $value };
+    if (is_HashRef($value)) {
+      my ($op, @rest) = keys %$value;
+      confess "Don't know how to handle " . dump($value) . " (too many keys)"
+        if @rest;
+
+      # TODO: Validate the op?
+      if ($op =~ /^-([a-z_]+)$/i) {
+        $ret->{op} = lc $1;
+
+        if (is_ArrayRef($value->{$op})) {
+          push @{$ret->{args}}, $self->value($_)
+            for @{$value->{$op}};
+          return $ret;
+        }
+      }
+      else {
+        $ret->{op} = $op;
+      }
+
+      push @{$ret->{args}}, $self->value($value->{$op});
+
+    }
+    elsif (is_ArrayRef($value)) {
+      # Return an or clause, sort of.
+      return {
+        -type => 'expr',
+        op => 'or',
+        args => [ map {
+          {
+            -type => 'expr',
+            op => '==',
+            args => [
+              { -type => 'name', args => [$key] },
+              $self->value($_)
+            ],
+          }
+        } @$value ]
+      };
+    }
+    else {
+      push @{$ret->{args}}, $self->value($value);
     }
 
     return $ret;
   }
 
+  method value($value) returns (AST) {
+    return { -type => 'value', value => $value }
+      if is_Str($value);
+
+    confess "Don't know how to handle terminal value " . dump($value);
+  }
+
 
 };