use strictures 1;
use SQL::ReservedWords;
-use Data::Query::Constants qw(DQ_IDENTIFIER DQ_OPERATOR DQ_VALUE);
+use Data::Query::Constants qw(
+ DQ_IDENTIFIER DQ_OPERATOR DQ_VALUE DQ_JOIN DQ_ALIAS
+);
sub new {
bless({ %{$_[1]||{}} }, (ref($_[0])||$_[0]))->BUILDALL;
sub _flatten_structure {
my ($self, $struct) = @_;
my @bind;
- [ (join ' ', map {
- my $r = ref;
- if (!$r) { $_ }
- elsif ($r eq 'ARRAY') {
- my ($sql, @b) = @{$self->_flatten_structure($_)};
- push @bind, @b;
- $sql;
- }
- elsif ($r eq 'HASH') { push @bind, $_; () }
- else { die "_flatten_structure can't handle ref type $r for $_" }
- } @$struct), @bind ];
+ [ do {
+ my @p = map {
+ my $r = ref;
+ if (!$r) { $_ }
+ elsif ($r eq 'ARRAY') {
+ my ($sql, @b) = @{$self->_flatten_structure($_)};
+ push @bind, @b;
+ $sql;
+ }
+ elsif ($r eq 'HASH') { push @bind, $_; () }
+ else { die "_flatten_structure can't handle ref type $r for $_" }
+ } @$struct;
+ join '', map {
+ ($p[$_], (($p[$_+1]||',') eq ',') ? () : (' '))
+ } 0 .. $#p;
+ },
+ @bind
+ ];
}
# I present this to permit strange people to easily supply a patch to lc()
sub _format_keyword { $_[1] }
sub _render {
- $_[0]->${\"_render_${\lc($_[1]->{type})}"}($_[1]);
+ $_[0]->${\"_render_${\(lc($_[1]->{type})||'broken')}"}($_[1]);
+}
+
+sub _render_broken {
+ my ($self, $dq) = @_;
+ require Data::Dumper::Concise;
+ die "Broken DQ entry: ".Data::Dumper::Concise::Dumper($dq);
}
sub _render_identifier {
# it is, in fact, completely valid for there to be nothing for us
# to project from since many databases handle 'SELECT 1;' fine
- my @select = map {
- # we should perhaps validate that what we've been handed
- # is an expression and possibly an identifier - at least a
- # debugging mode that does such is almost certainly worthwhile;
- # but for present I'm focusing on making this work.
- my $e = $self->_render($_->{expr});
- $_->{name} ? [ $e, 'AS', $self->_render($_->{name}), ',' ] : [ $e, ',' ]
- } @{$dq->{select}};
+ my @select = map [
+ ($_->{type} eq DQ_ALIAS
+ ? $self->_render_alias($_, 'AS')
+ : $self->_render($_)
+ ),
+ ','
+ ], @{$dq->{select}};
# we put the commas inside the [] for each entry as a hint to the pretty
- # printer downstreamso now we need to eliminate the comma from the last
+ # printer downstream so now we need to eliminate the comma from the last
# entry - we know there always is one due to the die guard at the top
pop @{$select[-1]};
}
sub _render_alias {
- my ($self, $dq) = @_;
+ my ($self, $dq, $as) = @_;
# FROM foo foo -> FROM foo
# FROM foo.bar bar -> FROM foo.bar
if ($dq->{alias}{type} eq DQ_IDENTIFIER) {
}
return [
$self->_render($dq->{alias}),
- ' ',
+ $as || ' ',
$self->_render_identifier({ elements => [ $dq->{as} ] })
];
}
];
}
+sub _render_join {
+ my ($self, $dq) = @_;
+ my ($left, $right) = @{$dq->{join}};
+ die "No support for ON yet" if $dq->{on};
+ die "No support for LEFT/RIGHT yet" if $dq->{outer};
+ [ $self->_render($left), ',', $self->_render($right) ];
+}
+
1;
expr_sql_is { SELECT { $_->foo, 1 } }
# the extra space here is a little icky but Naive's _flatten_structure
# will need rewriting to fix it - commit bits available if you do it first
- [ "SELECT foo , ?", binding(1) ],
+ [ "SELECT foo, ?", binding(1) ],
"Identifier and literal";
expr_sql_is { SELECT { $_->foo => AS("foom"), 1 } }
- [ "SELECT foo AS foom , ?", binding(1) ],
+ [ "SELECT foo AS foom, ?", binding(1) ],
"AS with parens";
expr_sql_is { SELECT { $_->foo => AS "foom", 1 } }
- [ "SELECT foo AS foom , ?", binding(1) ],
+ [ "SELECT foo AS foom, ?", binding(1) ],
"AS without parens";