default => 'AND'
);
- method generate(WhereType $ast) returns (AST) {
- return $self->recurse_where($ast);
+ sub mk_name {
+ shift;
+ return { -type => 'name', args => [ @_ ] };
+ }
+
+ method select(Str|ArrayRef|ScalarRef $from, ArrayRef|Str $fields,
+ WhereType $where?,
+ WhereType $order?)
+ {
+ my $ast = {
+ -type => 'select',
+ columns => [
+ map {
+ $self->mk_name($_)
+ } ( is_Str($fields) ? $fields : @$fields )
+ ],
+ tablespec => $self->tablespec($from)
+ };
+
+
+ $ast->{where} = $self->recurse_where($where)
+ if defined $where;
+
+ return $ast;
+ }
+
+ method tablespec(Str|ArrayRef|ScalarRef $from) {
+ return $self->mk_name($from)
+ if is_Str($from);
}
method recurse_where(WhereType $ast, LogicEnum $logic?) returns (AST) {
],
};
- if (is_Str($value)) {
- push @{$ret->{args}}, { -type => 'value', value => $value };
+ if (is_HashRef($value)) {
+ my ($op, @rest) = keys %$value;
+ confess "Don't know how to handle " . dump($value) . " (too many keys)"
+ if @rest;
+
+ # TODO: Validate the op?
+ if ($op =~ /^-([a-z_]+)$/i) {
+ $ret->{op} = lc $1;
+
+ if (is_ArrayRef($value->{$op})) {
+ push @{$ret->{args}}, $self->value($_)
+ for @{$value->{$op}};
+ return $ret;
+ }
+ }
+ else {
+ $ret->{op} = $op;
+ }
+
+ push @{$ret->{args}}, $self->value($value->{$op});
+
+ }
+ elsif (is_ArrayRef($value)) {
+ # Return an or clause, sort of.
+ return {
+ -type => 'expr',
+ op => 'or',
+ args => [ map {
+ {
+ -type => 'expr',
+ op => '==',
+ args => [
+ { -type => 'name', args => [$key] },
+ $self->value($_)
+ ],
+ }
+ } @$value ]
+ };
+ }
+ else {
+ push @{$ret->{args}}, $self->value($value);
}
return $ret;
}
+ method value($value) returns (AST) {
+ return { -type => 'value', value => $value }
+ if is_Str($value);
+
+ confess "Don't know how to handle terminal value " . dump($value);
+ }
+
};