name 'SQL-Abstract';
requires 'Moose' => '0.71';
-requires 'MooseX::Method::Signatures' => '0.10';
+requires 'MooseX::Method::Signatures' => '0.13_804d1448';
requires 'MooseX::Declare' => '0.09';
test_requires 'Test::More';
use MooseX::Types -declare => [qw/NameSeparator/];
use MooseX::Types::Moose qw/ArrayRef Str Int HashRef CodeRef/;
use MooseX::AttributeHelpers;
- use SQL::Abstract::Types qw/NameSeparator AST ArrayAST/;
+ use SQL::Abstract::Types qw/NameSeparator QuoteChars AST ArrayAST/;
clean;
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',
}
method _select(HashAST $ast) {
-
+ # Default to requiring columns and from
+ # Once TCs give better errors, make this a SelectAST type
+ for (qw/columns from/) {
+ confess "$_ key is required (and must be an AST) to select"
+ unless is_ArrayAST($ast->{$_});
+ }
+
+ # Check that columns is a -list
+ confess "columns key should be a -list AST, not " . $ast->{columns}[0]
+ unless $ast->{columns}[0] eq '-list';
+
+ my @output = (
+ "SELECT",
+ $self->dispatch($ast->{columns}),
+ "FROM",
+ $self->dispatch($ast->{from})
+ );
+
+ for (qw/join/) {
+ if (exists $ast->{$_}) {
+ my $sub_ast = $ast->{$_};
+ $sub_ast->{-type} = "$_" if is_HashRef($sub_ast);
+ confess "$_ option is not an AST"
+ unless is_AST($sub_ast);
+
+ push @output, $self->dispatch($sub_ast);
+ }
+ }
+
+ return join(' ', @output);
}
method _where(ArrayAST $ast) {
my (undef, @names) = @$ast;
my $sep = $self->name_separator;
+ my $quote = $self->is_quoting
+ ? $self->quote_chars
+ : [ '' ];
+
+ my $join = $quote->[-1] . $sep . $quote->[0];
- return $sep->[0] .
- join( $sep->[1] . $sep->[0], @names ) .
- $sep->[1]
- if (@$sep > 1);
+ # We dont want to quote * in [qw/me */]: `me`.* is the desired output there
+ # This means you can't have a field called `*`. I am willing to accept this
+ # situation, cos thats a really stupid thing to want.
+ my $post;
+ $post = pop @names if $names[-1] eq '*';
- return join($sep->[0], @names);
+ my $ret =
+ $quote->[0] .
+ join( $join, @names ) .
+ $quote->[-1];
+
+ $ret .= $sep . $post if defined $post;
+ return $ret;
}
- method _join(HashAST $ast) {
+ method _join(HashRef $ast) {
my $output = 'JOIN ' . $self->dispatch($ast->{tablespec});
method _alias(ArrayAST $ast) {
my (undef, $alias, $as) = @$ast;
+ confess "Not enough paremeters to -alias"
+ unless defined $as;
+
+ # TODO: Maybe we want qq{ AS "$as"} here
return $self->dispatch($alias) . " AS $as";
}
use MooseX::Declare;
class SQL::Abstract::Types {
use Moose::Util::TypeConstraints;
- use MooseX::Types -declare => [qw/NameSeparator AST ArrayAST HashAST/];
+ use MooseX::Types -declare => [qw/NameSeparator QuoteChars AST ArrayAST HashAST/];
use MooseX::Types::Moose qw/ArrayRef Str Int Ref HashRef/;
subtype ArrayAST, as ArrayRef,
subtype AST, as ArrayAST|HashAST;
subtype NameSeparator,
+ as Str,
+ where { length($_) == 1 };
+
+
+ subtype QuoteChars,
as ArrayRef[Str];
- #where { @$_ == 1 ||| @$_ == 2 },
- #message { "Name separator must be one or two elements" };
+ where { @$_ == 1 || @$_ == 2 },
+ message { "Quote characters must be one or two elements" };
- coerce NameSeparator, from Str, via { [ $_ ] };
+ coerce QuoteChars, from Str, via { [ split //, $_ ] };
}
use strict;
use warnings;
-use Test::More tests => 9;
+use Test::More tests => 11;
use Test::Differences;
use_ok('SQL::Abstract') or BAIL_OUT( "$@" );
is $sqla->dispatch( [ -name => qw/me id/]), "me.id",
"Simple name generator";
+is $sqla->dispatch( [ -name => qw/me */]),
+ "me.*",
+ "Simple name generator";
+
+$sqla->quote_chars(['`']);
+
+is $sqla->dispatch( [ -name => qw/me */]),
+ "`me`.*",
+ "Simple name generator";
+
+$sqla->disable_quoting;
+
is $sqla->dispatch(
[ '-false' ]
), "0 = 1", "false value";
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More tests => 3;
+use Test::Differences;
+
+use_ok('SQL::Abstract') or BAIL_OUT( "$@" );
+
+my $sqla = SQL::Abstract->create(1);
+
+is $sqla->dispatch(
+ { -type => 'select',
+ from => [-alias => [-name => 'foo'] => 'me' ],
+ columns => [ -list =>
+ [ -name => qw/me id/ ],
+ [ -alias => [ -name => qw/me foo_id/ ], 'foo' ],
+ ]
+ }
+), "SELECT me.id, me.foo_id AS foo FROM foo AS me",
+ "simple select clause";
+
+is $sqla->dispatch(
+ { -type => 'select',
+ from => [-alias => [-name => 'foo'] => 'me' ],
+ columns => [ -list =>
+ [ -name => qw/me id/ ],
+ [ -alias => [ -name => qw/me foo_id/ ], 'foo' ],
+ [ -name => qw/bar name/ ],
+ ],
+ join => {
+ tablespec => [-name => qw/bar/],
+ on => [ '==', [-name => qw/bar id/], [ -name => qw/me bar_id/ ] ],
+ }
+ }
+), "SELECT me.id, me.foo_id AS foo, bar.name FROM foo AS me JOIN bar ON (bar.id = me.bar_id)",
+ "select with join clause";
+
+