Require -ast_version to generate (and un-dual life it. Now is class method only)
Ash Berlin [Tue, 3 Mar 2009 22:37:05 +0000 (22:37 +0000)]
Makefile.PL
lib/SQL/Abstract.pm
t/001_basic.t

index 3937cd5..1630685 100644 (file)
@@ -6,7 +6,7 @@ use inc::Module::Install 0.79;
 name 'SQL-Abstract';
 requires 'Moose' => '0.71';
 requires 'MooseX::Method::Signatures' => '0.10';
-requires 'MooseX::Declare' => '0.07';
+requires 'MooseX::Declare' => '0.09';
 
 test_requires 'Test::More';
 test_requires 'Test::Differences';
index 5026129..dafa646 100644 (file)
@@ -9,10 +9,10 @@ class SQL::Abstract {
 
   use Moose::Util::TypeConstraints;
   use MooseX::Types -declare => [qw/NameSeparator/];
-  use MooseX::Types::Moose qw/ArrayRef Str/;
+  use MooseX::Types::Moose qw/ArrayRef Str Int/;
   use MooseX::AttributeHelpers;
 
-  use namespace::clean -except => ['meta'];
+  clean;
 
   subtype NameSeparator,
     as ArrayRef[Str];
@@ -38,6 +38,12 @@ class SQL::Abstract {
     '!=' => '!=',
   );
 
+  has ast_version => (
+    is => 'ro',
+    isa => Int,
+    required => 1
+  );
+
   has name_separator => ( 
     is => 'rw', 
     isa => NameSeparator,
@@ -64,16 +70,29 @@ class SQL::Abstract {
     }
   );
 
-  method generate (Object|ClassName $self: ArrayRef $ast) {
-    my $class_meth = !blessed($self);
-    $self = $self->new if $class_meth;
+  method BUILD( $ast ) {
+    croak "AST version @{[$self->ast_version]} is greater than supported version of $AST_VERSION"
+      if $self->ast_version > $AST_VERSION;
+  }
+
+  # Main entry point
+  method generate(ClassName $class: ArrayRef $ast) {
+    croak "SQL::Abstract AST version not specified"
+      unless ($ast->[0] eq '-ast_version');
+
+    my (undef, $ver) = splice(@$ast, 0, 2);
+
+    my $self = $class->new(ast_version => $ver);
+
+    return ($self->dispatch($ast), $self->binds);
+  }
+
+  method dispatch (ArrayRef $ast) {
 
     local $_ = $ast->[0];
     s/^-/_/g or croak "Unknown type tag '$_'";
     my $meth = $self->can($_) || \&_generic_func;
-    return $class_meth
-         ? ($meth->($self, $ast), $self->binds)
-         : $meth->($self, $ast);
+    return $meth->($self, $ast);
   }
 
   method _select(ArrayRef $ast) {
@@ -94,10 +113,10 @@ class SQL::Abstract {
     for (@clauses) {
       if ($_->[0] =~ /^-(asc|desc)$/) {
         my $o = $1;
-        push @output, $self->generate($_->[1]) . " " . uc($o);
+        push @output, $self->dispatch($_->[1]) . " " . uc($o);
         next;
       }
-      push @output, $self->generate($_);
+      push @output, $self->dispatch($_);
     }
 
     return "ORDER BY " . join(", ", @output);
@@ -116,18 +135,22 @@ class SQL::Abstract {
     return join($sep->[0], @names);
   }
 
+  method _join(ArrayRef $ast) {
+    
+  }
+
   method _list(ArrayRef $ast) {
     my (undef, @items) = @$ast;
 
     return join(
       $self->list_separator,
-      map { $self->generate($_) } @items);
+      map { $self->dispatch($_) } @items);
   }
 
   method _alias(ArrayRef $ast) {
     my (undef, $alias, $as) = @$ast;
 
-    return $self->generate($alias) . " AS $as";
+    return $self->dispatch($alias) . " AS $as";
 
   }
 
@@ -169,7 +192,7 @@ class SQL::Abstract {
           push @output, '(' . $self->_recurse_where($_) . ')';
         }
       } else {
-        push @output, $self->generate($_);
+        push @output, $self->dispatch($_);
       }
     }
 
@@ -177,18 +200,18 @@ class SQL::Abstract {
   }
 
   method _binop($op, $lhs, $rhs) {
-    join (' ', $self->generate($lhs), 
+    join (' ', $self->dispatch($lhs), 
                $OP_MAP{$op} || croak("Unknown binary operator $op"),
-               $self->generate($rhs)
+               $self->dispatch($rhs)
     );
   }
 
   method _in($ast) {
     my (undef, $field, @values) = @$ast;
 
-    return $self->generate($field) .
+    return $self->dispatch($field) .
            " IN (" .
-           join(", ", map { $self->generate($_) } @values ) .
+           join(", ", map { $self->dispatch($_) } @values ) .
            ")";
   }
 
index bd6220f..a482a6d 100644 (file)
@@ -6,11 +6,11 @@ use Test::Differences;
 
 use_ok('SQL::Abstract') or BAIL_OUT( "$@" );
 
-my $sqla = SQL::Abstract->new;
-is $sqla->generate( [ -name => qw/me id/]), "me.id",
+my $sqla = SQL::Abstract->new(ast_version => 1);
+is $sqla->dispatch( [ -name => qw/me id/]), "me.id",
   "Simple name generator";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -list => 
     [ -name => qw/me id/],
     [ -name => qw/me foo bar/],
@@ -19,35 +19,36 @@ is $sqla->generate(
 ), "me.id, me.foo.bar, bar",
   "List generator";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -alias => [ -name => qw/me id/], "foobar", ] 
 ), "me.id AS foobar",
   "Alias generator";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -order_by => [ -name => qw/me date/ ] ]
 ), "ORDER BY me.date";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -order_by => 
     [ -name => qw/me date/ ],
     [ -name => qw/me foobar/ ],
   ]
 ), "ORDER BY me.date, me.foobar";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -order_by => [ -desc => [ -name => qw/me date/ ] ] ]
 ), "ORDER BY me.date DESC";
 
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>
       [ '>', [-name => qw/me id/], [-value => 500 ] ]
   ]
 ), "WHERE me.id > ?", "where clause";
 
 eq_or_diff( [ SQL::Abstract->generate(
-    [ -where =>
+    [ -ast_version => 1,
+      -where =>
         [ '>', [-name => qw/me id/], [-value => 500 ] ],
         [ '==', [-name => qw/me name/], [-value => '200' ] ]
     ]
@@ -61,7 +62,7 @@ eq_or_diff( [ SQL::Abstract->generate(
 );
 
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>  -or =>
       [ '>', [-name => qw/me id/], [-value => 500 ] ],
       [ '==', [-name => qw/me name/], [-value => '200' ] ],
@@ -69,7 +70,7 @@ is $sqla->generate(
 ), "WHERE me.id > ? OR me.name = ?", "where clause";
 
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>  -or =>
       [ '>', [-name => qw/me id/], [-value => 500 ] ],
       [ -or => 
@@ -79,7 +80,7 @@ is $sqla->generate(
   ]
 ), "WHERE me.id > ? OR me.name = ? OR me.name = ?", "where clause";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>  -or =>
       [ '==', [-name => qw/me id/], [-value => 500 ] ],
       [ -and => 
@@ -89,7 +90,7 @@ is $sqla->generate(
   ]
 ), "WHERE me.id = ? OR me.name > ? AND me.name < ?", "where clause";
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>  -and =>
       [ '==', [-name => qw/me id/], [-value => 500 ] ],
       [ -and => 
@@ -100,7 +101,7 @@ is $sqla->generate(
 ), "WHERE me.id = ? AND me.name > ? AND me.name < ?", "where clause";
 
 
-is $sqla->generate(
+is $sqla->dispatch(
   [ -where =>  -and =>
       [ '==', [-name => qw/me id/], [-value => 500 ] ],
       [ -or => 
@@ -112,7 +113,8 @@ is $sqla->generate(
 
 eq_or_diff(
   [SQL::Abstract->generate(
-    [ -where => 
+    [ -ast_version => 1,
+      -where =>
       [ -in => 
         [-name => qw/me id/],
         [-value => '100' ],