use Moose::Util::TypeConstraints;
use MooseX::Types -declare => [qw/NameSeparator/];
- use MooseX::Types::Moose qw/ArrayRef Str Int/;
+ use MooseX::Types::Moose qw/ArrayRef Str Int HashRef CodeRef/;
use MooseX::AttributeHelpers;
+ use SQL::Abstract::Types qw/NameSeparator QuoteChars AST ArrayAST/;
clean;
- subtype NameSeparator,
- as ArrayRef[Str];
- #where { @$_ == 1 ||| @$_ == 2 },
- #message { "Name separator must be one or two elements" };
-
- coerce NameSeparator, from Str, via { [ $_ ] };
-
our $VERSION = '2.000000';
our $AST_VERSION = '1';
or => 50
);
- our %OP_MAP = (
+ our %BINOP_MAP = (
'>' => '>',
'<' => '<',
'==' => '=',
'!=' => '!=',
+ # LIKE is always "field LIKE <value>"
+ '-like' => 'LIKE',
+ '-not_like' => 'NOT LIKE',
+ );
+
+ has where_dispatch_table => (
+ is => 'ro',
+ lazy => 1,
+ builder => '_build_where_dispatch_table',
+ isa => HashRef[CodeRef],
+ metaclass => 'Collection::ImmutableHash',
+ provides => {
+ get => 'lookup_where_dispatch'
+ }
+ );
+
+ has binop_map => (
+ is => 'ro',
+ lazy => 1,
+ builder => '_build_binops',
+ isa => HashRef,
+ metaclass => 'Collection::ImmutableHash',
+ provides => {
+ exists => 'is_valid_binop',
+ get => 'binop_mapping',
+ keys => 'binary_operators'
+ }
);
+ # List of default binary operators (for in where clauses)
+ sub _build_binops { return {%BINOP_MAP} };
+
+ method _build_where_dispatch_table {
+ my $binop = $self->can('_binop') or croak "InternalError: $self can't do _binop!";
+ return {
+ map { $_ => $binop } $self->binary_operators
+ }
+ }
+
has ast_version => (
is => 'ro',
isa => Int,
has name_separator => (
is => 'rw',
isa => NameSeparator,
- default => sub { ['.'] },
+ default => '.',
coerece => 1,
required => 1,
);
required => 1,
);
+ has quote_chars => (
+ is => 'rw',
+ isa => QuoteChars,
+ coerece => 1,
+ predicate => 'is_quoting',
+ clearer => 'disable_quoting',
+ );
+
has binds => (
isa => ArrayRef,
is => 'ro',
+ clearer => '_clear_binds',
+ lazy => 1,
default => sub { [ ] },
metaclass => 'Collection::Array',
provides => {
push => 'add_bind',
- clear => '_clear_binds',
}
);
}
# Main entry point
- method generate(ClassName $class: ArrayRef $ast) {
+ method generate(ClassName $class: AST $ast) {
croak "SQL::Abstract AST version not specified"
unless ($ast->[0] eq '-ast_version');
return ($self->dispatch($ast), $self->binds);
}
+ method reset() {
+ $self->_clear_binds();
+ }
+
+ method dispatch (AST $ast) {
+ # I want multi methods!
+ my $tag;
+ if (is_ArrayAST($ast)) {
+ ($tag = $ast->[0]) =~ s/^-/_/;
+ } else {
+ $tag = "_" . $ast->{-type};
+ }
+
+ my $meth = $self->can($tag) || croak "Unknown tag '$tag'";
+ return $meth->($self, $ast);
+ }
};