Add IN generator
[dbsrgits/SQL-Abstract-2.0-ish.git] / lib / SQL / Abstract.pm
index 3c84192..5026129 100644 (file)
@@ -55,27 +55,54 @@ class SQL::Abstract {
 
   has binds => (
     isa => ArrayRef,
+    is => 'ro',
     default => sub { [ ] },
     metaclass => 'Collection::Array',
     provides => {
       push => 'add_bind',
-      get => 'binds'
+      clear => '_clear_binds',
     }
   );
 
   method generate (Object|ClassName $self: ArrayRef $ast) {
-    $self = $self->new unless blessed($self);
+    my $class_meth = !blessed($self);
+    $self = $self->new if $class_meth;
 
     local $_ = $ast->[0];
-    s/^-/_/ or croak "Unknown type tag '$_'";
+    s/^-/_/g or croak "Unknown type tag '$_'";
     my $meth = $self->can($_) || \&_generic_func;
-    return $meth->($self, $ast);
+    return $class_meth
+         ? ($meth->($self, $ast), $self->binds)
+         : $meth->($self, $ast);
   }
 
   method _select(ArrayRef $ast) {
     
   }
 
+  method _where(ArrayRef $ast) {
+    my (undef, @clauses) = @$ast;
+  
+    return 'WHERE ' . $self->_recurse_where(\@clauses);
+  }
+
+  method _order_by(ArrayRef $ast) {
+    my (undef, @clauses) = @$ast;
+
+    my @output;
+   
+    for (@clauses) {
+      if ($_->[0] =~ /^-(asc|desc)$/) {
+        my $o = $1;
+        push @output, $self->generate($_->[1]) . " " . uc($o);
+        next;
+      }
+      push @output, $self->generate($_);
+    }
+
+    return "ORDER BY " . join(", ", @output);
+  }
+
   method _name(ArrayRef $ast) {
     my (undef, @names) = @$ast;
 
@@ -111,12 +138,6 @@ class SQL::Abstract {
     return "?";
   }
 
-  method _where(ArrayRef $ast) {
-    my (undef, @clauses) = @$ast;
-  
-    return 'WHERE ' . $self->_recurse_where(\@clauses);
-  }
-
   method _recurse_where($clauses) {
 
     my $OP = 'AND';
@@ -142,7 +163,7 @@ class SQL::Abstract {
       } elsif ($op =~ /^-(and|or)$/) {
         my $sub_prio = $PRIO{$1}; 
 
-        if ($sub_prio >= $prio) {
+        if ($sub_prio <= $prio) {
           push @output, $self->_recurse_where($_);
         } else {
           push @output, '(' . $self->_recurse_where($_) . ')';
@@ -152,7 +173,7 @@ class SQL::Abstract {
       }
     }
 
-    return wantarray ? @output : join(" $OP ", @output);
+    return join(" $OP ", @output);
   }
 
   method _binop($op, $lhs, $rhs) {
@@ -162,6 +183,15 @@ class SQL::Abstract {
     );
   }
 
+  method _in($ast) {
+    my (undef, $field, @values) = @$ast;
+
+    return $self->generate($field) .
+           " IN (" .
+           join(", ", map { $self->generate($_) } @values ) .
+           ")";
+  }
+
   method _generic_func(ArrayRef $ast) {
   }