X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FAbstract%2FExtraClauses.pm;h=c0e753dd75a03fe1a1b1cd99a66c2ab0e266ff6c;hb=ec49a2e10ad2cca513719dc04f410fb9cae85978;hp=e0b253292119d34b557e00f5d56e6fe2dbd2a94a;hpb=3001f09746dcc5164c040fcbb5d87d454f61c726;p=scpubgit%2FQ-Branch.git diff --git a/lib/SQL/Abstract/ExtraClauses.pm b/lib/SQL/Abstract/ExtraClauses.pm index e0b2532..c0e753d 100644 --- a/lib/SQL/Abstract/ExtraClauses.pm +++ b/lib/SQL/Abstract/ExtraClauses.pm @@ -17,9 +17,25 @@ sub cb { }; } +sub register { + my ($self, $method, @pairs) = @_; + my $sqla = $self->sqla; + while (my ($car, $cdr) = splice(@pairs, 0, 2)) { + my $cb = $self->cb($cdr); + $sqla->$method($car, $cb); + } + return $self; +} + sub apply_to { my ($self, $sqla) = @_; $self = $self->new unless ref($self); + local $self->{sqla} = $sqla; + $self->register_extensions($sqla); +} + +sub register_extensions { + my ($self, $sqla) = @_; my @clauses = $sqla->clauses_of('select'); my @before_setop; CLAUSE: foreach my $idx (0..$#clauses) { @@ -31,11 +47,12 @@ sub apply_to { } die "Huh?" unless @before_setop; $sqla->clauses_of(select => 'with', @clauses); - $sqla->clause_expanders( - 'select.group_by', $self->cb(sub { - $_[0]->expand_maybe_list_expr($_[2], -ident) - }), - 'select.having', $self->cb(sub { $_[0]->expand_expr($_[2]) }), + $self->register( + clause_expanders => + 'select.group_by' + => sub { $_[0]->expand_maybe_list_expr($_[2], -ident) }, + 'select.having' + => sub { $_[0]->expand_expr($_[2]) }, ); foreach my $thing (qw(join from_list)) { $sqla->expander($thing => $self->cb("_expand_${thing}")) @@ -338,6 +355,8 @@ sub _expand_clause_setop { 1; +__END__ + =head1 NAME SQL::Abstract::ExtraClauses - new/experimental additions to L @@ -362,4 +381,74 @@ For plugin authors, creates a callback to call a method on the plugin. Available only during plugin callback executions, contains the currently active L object. +=head1 NODE TYPES + +=head2 alias + +Represents a table alias. Expands name and column names with ident as default. + + # expr + { -alias => [ 't', 'x', 'y', 'z' ] } + + # aqt + { -alias => [ + { -ident => [ 't' ] }, { -ident => [ 'x' ] }, + { -ident => [ 'y' ] }, { -ident => [ 'z' ] }, + ] } + + # query + t(x, y, z) + [] + +=head2 as + +Represents an sql AS. LHS is expanded with ident as default, RHS is treated +as a list of arguments for the alias node. + + # expr + { foo => { -as => 'bar' } } + + # aqt + { -as => + [ + { -ident => [ 'foo' ] }, + { -alias => [ { -ident => [ 'bar' ] } ] }, + ] + } + + # query + foo AS bar + [] + + # expr + { -as => [ { -select => { _ => 'blah' } }, 't', 'blah' ] } + + # aqt + { -as => [ + { -select => + { select => { -op => [ ',', { -ident => [ 'blah' ] } ] } } + }, + { -alias => [ { -ident => [ 't' ] }, { -ident => [ 'blah' ] } ] }, + ] } + + # query + (SELECT blah) AS t(blah) + [] + +=head2 cast + + # expr + { -cast => [ { -ident => 'birthday' }, 'date' ] } + + # aqt + { -func => [ + 'cast', { + -as => [ { -ident => [ 'birthday' ] }, { -ident => [ 'date' ] } ] + }, + ] } + + # query + CAST(birthday AS date) + [] + =cut