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;
return "?";
}
- method _where(ArrayRef $ast) {
- my (undef, @clauses) = @$ast;
-
- return 'WHERE ' . $self->_recurse_where(\@clauses);
- }
-
method _recurse_where($clauses) {
my $OP = 'AND';
} 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($_) . ')';
}
}
- return wantarray ? @output : join(" $OP ", @output);
+ return join(" $OP ", @output);
}
method _binop($op, $lhs, $rhs) {
);
}
+ method _in($ast) {
+ my (undef, $field, @values) = @$ast;
+
+ return $self->generate($field) .
+ " IN (" .
+ join(", ", map { $self->generate($_) } @values ) .
+ ")";
+ }
+
method _generic_func(ArrayRef $ast) {
}