3 class SQL::Abstract::Compat {
5 use Moose::Util::TypeConstraints;
6 use MooseX::Types::Moose qw/Str ScalarRef ArrayRef HashRef/;
7 use SQL::Abstract::Types::Compat ':all';
8 use SQL::Abstract::Types qw/AST/;
9 use SQL::Abstract::AST::v1;
10 use Data::Dump qw/pp/;
11 use Devel::PartialDump qw/dump/;
14 class_type 'SQL::Abstract';
27 isa => 'SQL::Abstract',
28 clearer => 'clear_visitor',
30 builder => '_build_visitor',
47 predicate => 'has_field_convertor'
50 method select(Str|ArrayRef|ScalarRef $from, ArrayRef|Str $fields,
59 } ( is_Str($fields) ? $fields : @$fields )
61 tablespec => $self->tablespec($from)
65 $ast->{where} = $self->recurse_where($where)
68 return ($self->visitor->dispatch($ast), $self->visitor->binds);
71 method where(WhereType $where,
77 my $ast = $self->recurse_where($where);
78 $ret .= "WHERE " . $self->visitor->_expr($ast);
84 method _build_visitor() {
85 return SQL::Abstract->create(1);
89 my ($self, $use_convert) = (shift,shift);
90 my $ast = { -type => 'name', args => [ @_ ] };
93 unless $use_convert && $self->has_field_convertor;
95 return $self->apply_convert($ast);
98 method tablespec(Str|ArrayRef|ScalarRef $from) {
99 return $self->mk_name(0, $from)
103 method recurse_where(WhereType $ast, LogicEnum $logic?) returns (AST) {
104 return $self->recurse_where_hash($logic || 'AND', $ast) if is_HashRef($ast);
105 return $self->recurse_where_array($logic || 'OR', $ast) if is_ArrayRef($ast);
106 croak "Unknown where clause type " . dump($ast);
109 method recurse_where_hash(LogicEnum $logic, HashRef $ast) returns (AST) {
117 while (my ($key,$value) = each %$ast) {
118 if ($key =~ /^-(or|and)$/) {
119 my $val = $self->recurse_where($value, uc $1);
120 if ($val->{op} eq $ret->{op}) {
121 push @args, @{$val->{args}};
129 push @args, $self->field($key, $value);
132 return $args[0] if @args == 1;
137 method recurse_where_array(LogicEnum $logic, ArrayRef $ast) returns (AST) {
146 while (my $key = shift @nodes) {
147 if ($key =~ /^-(or|and)$/) {
148 my $value = shift @nodes
149 or confess "missing value after $key at " . dump($ast);
151 my $val = $self->recurse_where($value, uc $1);
152 if ($val->{op} eq $ret->{op}) {
153 push @args, @{$val->{args}};
161 push @args, $self->recurse_where($key);
164 return $args[0] if @args == 1;
169 method field(Str $key, $value) returns (AST) {
170 my $op = $CMP_MAP{$self->cmp} || $self->cmp;
175 $self->mk_name(1, $key)
179 if (is_HashRef($value)) {
180 my ($op, @rest) = keys %$value;
181 confess "Don't know how to handle " . dump($value) . " (too many keys)"
184 # TODO: Validate the op?
185 if ($op =~ /^-([a-z_]+)$/i) {
188 if (is_ArrayRef($value->{$op})) {
189 push @{$ret->{args}}, $self->value($_)
190 for @{$value->{$op}};
198 push @{$ret->{args}}, $self->value($value->{$op});
201 elsif (is_ArrayRef($value)) {
202 # Return an or clause, sort of.
211 { -type => 'name', args => [$key] },
219 push @{$ret->{args}}, $self->value($value);
225 method value($value) returns (AST) {
226 return $self->apply_convert( { -type => 'value', value => $value })
229 confess "Don't know how to handle terminal value " . dump($value);
232 method apply_convert(AST $ast) {
233 return $ast unless $self->has_field_convertor;
237 op => $self->convert,
247 SQL::Abstract::Compant - compatibility layer for SQL::Abstrct v 1.xx
251 This class attempts to maintain the original behaviour of version 1 of
252 SQL::Abstract. It does this by internally converting to an AST and then using
253 the standard AST visitor.
255 If so desired, you can get hold of this transformed AST somehow. This is aimed
256 at libraries such as L<DBIx::Class> that use SQL::Abstract-style arrays or
257 hashes as part of their public interface.
261 Ash Berlin C<< <ash@cpan.org> >>