From: Ash Berlin Date: Tue, 3 Mar 2009 22:37:05 +0000 (+0000) Subject: Require -ast_version to generate (and un-dual life it. Now is class method only) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c314b35ded929f7b6f7f284e90cc9a1afe91e0ee;p=dbsrgits%2FSQL-Abstract-2.0-ish.git Require -ast_version to generate (and un-dual life it. Now is class method only) --- diff --git a/Makefile.PL b/Makefile.PL index 3937cd5..1630685 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -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'; diff --git a/lib/SQL/Abstract.pm b/lib/SQL/Abstract.pm index 5026129..dafa646 100644 --- a/lib/SQL/Abstract.pm +++ b/lib/SQL/Abstract.pm @@ -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 ) . ")"; } diff --git a/t/001_basic.t b/t/001_basic.t index bd6220f..a482a6d 100644 --- a/t/001_basic.t +++ b/t/001_basic.t @@ -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' ],