X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSQLMaker.pm;h=705c569deec137e826169288ca10c0a4d5f0a914;hb=be64931c710bcde7abe7334349b4c8a123645332;hp=ba932a7183b2689824e9b7e66f1e82c6bc030911;hpb=fcb7fcbb6bde5f9a211c62011b3110f07828caec;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/SQLMaker.pm b/lib/DBIx/Class/SQLMaker.pm index ba932a7..705c569 100644 --- a/lib/DBIx/Class/SQLMaker.pm +++ b/lib/DBIx/Class/SQLMaker.pm @@ -27,9 +27,9 @@ Currently the enhancements to L are: =item * Support of C<...FOR UPDATE> type of select statement modifiers -=item * The -ident operator +=item * The L operator -=item * The -value operator +=item * The L operator =back @@ -93,6 +93,14 @@ BEGIN { # as the value to abuse with MSSQL ordered subqueries) sub __max_int () { 0x7FFFFFFF }; +# poor man's de-qualifier +sub _quote { + $_[0]->next::method( ( $_[0]{_dequalify_idents} and ! ref $_[1] ) + ? $_[1] =~ / ([^\.]+) $ /x + : $_[1] + ); +} + sub new { my $self = shift->next::method(@_); @@ -197,7 +205,12 @@ sub select { } ; - $sql = $self->$limiter ($sql, $rs_attrs, $limit, $offset); + $sql = $self->$limiter ( + $sql, + { %{$rs_attrs||{}}, _selector_sql => $fields }, + $limit, + $offset + ); } else { ($sql, @bind) = $self->next::method ($table, $fields, $where, $rs_attrs); @@ -216,7 +229,7 @@ sub select { sub _assemble_binds { my $self = shift; - return map { @{ (delete $self->{"${_}_bind"}) || [] } } (qw/select from where group having order limit/); + return map { @{ (delete $self->{"${_}_bind"}) || [] } } (qw/pre_select select from where group having order limit/); } my $for_syntax = { @@ -428,15 +441,18 @@ sub _gen_from_blocks { sub _from_chunk_to_sql { my ($self, $fromspec) = @_; - return join (' ', $self->_SWITCH_refkind($fromspec, { - SCALARREF => sub { + return join (' ', do { + if (! ref $fromspec) { + $self->_quote($fromspec); + } + elsif (ref $fromspec eq 'SCALAR') { $$fromspec; - }, - ARRAYREFREF => sub { + } + elsif (ref $fromspec eq 'REF' and ref $$fromspec eq 'ARRAY') { push @{$self->{from_bind}}, @{$$fromspec}[1..$#$$fromspec]; $$fromspec->[0]; - }, - HASHREF => sub { + } + elsif (ref $fromspec eq 'HASH') { my ($as, $table, $toomuch) = ( map { $_ => $fromspec->{$_} } ( grep { $_ !~ /^\-/ } keys %$fromspec ) @@ -446,11 +462,11 @@ sub _from_chunk_to_sql { if defined $toomuch; ($self->_from_chunk_to_sql($table), $self->_quote($as) ); - }, - SCALAR => sub { - $self->_quote($fromspec); - }, - })); + } + else { + $self->throw_exception('Unsupported from refkind: ' . ref $fromspec ); + } + }); } sub _join_condition { @@ -488,6 +504,41 @@ sub _join_condition { 1; +=head1 OPERATORS + +=head2 -ident + +Used to explicitly specify an SQL identifier. Takes a plain string as value +which is then invariably treated as a column name (and is being properly +quoted if quoting has been requested). Most useful for comparison of two +columns: + + my %where = ( + priority => { '<', 2 }, + requestor => { -ident => 'submitter' } + ); + +which results in: + + $stmt = 'WHERE "priority" < ? AND "requestor" = "submitter"'; + @bind = ('2'); + +=head2 -value + +The -value operator signals that the argument to the right is a raw bind value. +It will be passed straight to DBI, without invoking any of the SQL::Abstract +condition-parsing logic. This allows you to, for example, pass an array as a +column value for databases that support array datatypes, e.g.: + + my %where = ( + array => { -value => [1, 2, 3] } + ); + +which results in: + + $stmt = 'WHERE array = ?'; + @bind = ([1, 2, 3]); + =head1 AUTHORS See L.