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];
'!=' => '!=',
);
+ has ast_version => (
+ is => 'ro',
+ isa => Int,
+ required => 1
+ );
+
has name_separator => (
is => 'rw',
isa => NameSeparator,
}
);
- 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) {
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);
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";
}
push @output, '(' . $self->_recurse_where($_) . ')';
}
} else {
- push @output, $self->generate($_);
+ push @output, $self->dispatch($_);
}
}
}
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 ) .
")";
}
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/],
), "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' ] ]
]
);
-is $sqla->generate(
+is $sqla->dispatch(
[ -where => -or =>
[ '>', [-name => qw/me id/], [-value => 500 ] ],
[ '==', [-name => qw/me name/], [-value => '200' ] ],
), "WHERE me.id > ? OR me.name = ?", "where clause";
-is $sqla->generate(
+is $sqla->dispatch(
[ -where => -or =>
[ '>', [-name => qw/me id/], [-value => 500 ] ],
[ -or =>
]
), "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 =>
]
), "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 =>
), "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 =>
eq_or_diff(
[SQL::Abstract->generate(
- [ -where =>
+ [ -ast_version => 1,
+ -where =>
[ -in =>
[-name => qw/me id/],
[-value => '100' ],