X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSQLAHacks.pm;h=68566f368c273eda2c6cd835b92c2b62a11b1035;hb=v0.08123;hp=db67bcfb114ffaf1b5486fe68f14b0797bd09da7;hpb=6298a324307439b76419d0f5db453b0d10f10517;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/SQLAHacks.pm b/lib/DBIx/Class/SQLAHacks.pm index db67bcf..68566f3 100644 --- a/lib/DBIx/Class/SQLAHacks.pm +++ b/lib/DBIx/Class/SQLAHacks.pm @@ -8,10 +8,10 @@ package # Hide from PAUSE use base qw/SQL::Abstract::Limit/; use strict; use warnings; -use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/; use List::Util 'first'; use Sub::Name 'subname'; use namespace::clean; +use Carp::Clan qw/^DBIx::Class|^SQL::Abstract|^Try::Tiny/; BEGIN { # reinstall the carp()/croak() functions imported into SQL::Abstract @@ -33,6 +33,11 @@ BEGIN { } } +# the "oh noes offset/top without limit" constant +# limited to 32 bits for sanity (and since it is fed +# to sprintf %u) +sub __max_int { 0xFFFFFFFF }; + # Tries to determine limit dialect. # @@ -118,7 +123,7 @@ sub _subqueried_limit_attrs { my (@in_sel, @out_sel, %renamed); for my $node (@sel) { if (first { $_ =~ / (?{as}, $node->{unquoted_sql}) ) { - $node->{as} =~ s/ $re_sep /__/xg; + $node->{as} = $self->_unqualify_colname($node->{as}); my $quoted_as = $self->_quote($node->{as}); push @in_sel, sprintf '%s AS %s', $node->{sql}, $quoted_as; push @out_sel, $quoted_as; @@ -154,6 +159,13 @@ sub _subqueried_limit_attrs { ); } +sub _unqualify_colname { + my ($self, $fqcn) = @_; + my $re_sep = quotemeta($self->name_sep || '.'); + $fqcn =~ s/ $re_sep /__/xg; + return $fqcn; +} + # ANSI standard Limit/Offset implementation. DB2 and MSSQL >= 2005 use this sub _RowNumberOver { my ($self, $sql, $rs_attrs, $rows, $offset ) = @_; @@ -392,6 +404,21 @@ sub _Top { return $sql; } +# This for Sybase ASE, to use SET ROWCOUNT when there is no offset, and +# GenericSubQ otherwise. +sub _RowCountOrGenericSubQ { + my $self = shift; + my ($sql, $rs_attrs, $rows, $offset) = @_; + + return $self->_GenericSubQ(@_) if $offset; + + return sprintf <<"EOF", $rows, $sql; +SET ROWCOUNT %d +%s +SET ROWCOUNT 0 +EOF +} + # This is the most evil limit "dialect" (more of a hack) for *really* # stupid databases. It works by ordering the set by some unique column, # and calculating amount of rows that have a less-er value (thus @@ -512,8 +539,6 @@ sub _find_syntax { sub select { my ($self, $table, $fields, $where, $rs_attrs, @rest) = @_; - $self->{"${_}_bind"} = [] for (qw/having from order/); - if (not ref($table) or ref($table) eq 'SCALAR') { $table = $self->_quote($table); } @@ -522,10 +547,20 @@ sub select { croak "LIMIT 0 Does Not Compute" if $rest[0] == 0; # and anyway, SQL::Abstract::Limit will cause a barf if we don't first - my ($sql, @where_bind) = $self->SUPER::select( + my ($sql, @bind) = $self->SUPER::select( $table, $self->_recurse_fields($fields), $where, $rs_attrs, @rest ); - return wantarray ? ($sql, @{$self->{from_bind}}, @where_bind, @{$self->{having_bind}}, @{$self->{order_bind}} ) : $sql; + push @{$self->{where_bind}}, @bind; + +# this *must* be called, otherwise extra binds will remain in the sql-maker + my @all_bind = $self->_assemble_binds; + + return wantarray ? ($sql, @all_bind) : $sql; +} + +sub _assemble_binds { + my $self = shift; + return map { @{ (delete $self->{"${_}_bind"}) || [] } } (qw/from where having order/); } # Quotes table names, and handles default inserts @@ -787,7 +822,7 @@ sub _join_condition { } elsif (ref $cond eq 'ARRAY') { return join(' OR ', map { $self->_join_condition($_) } @$cond); } else { - die "Can't handle this yet!"; + croak "Can't handle this yet!"; } }