X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FSQLAHacks.pm;h=4da469e14432e7771586b73ccc3408b6c8f464ac;hb=1415f198da91a23911972ad06b6dafaf6f4c0e8f;hp=02c336c86ef430559eb6f58c5438ddb073fb0bf7;hpb=84ddb3da1f8d9e733d4aef1f3ce47653b6431111;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/SQLAHacks.pm b/lib/DBIx/Class/SQLAHacks.pm index 02c336c..4da469e 100644 --- a/lib/DBIx/Class/SQLAHacks.pm +++ b/lib/DBIx/Class/SQLAHacks.pm @@ -51,19 +51,27 @@ sub new { sub _RowNumberOver { my ($self, $sql, $order, $rows, $offset ) = @_; + # get the select to make the final amount of columns equal the original one + my ($select) = $sql =~ /^ \s* SELECT \s+ (.+?) \s+ FROM/ix + or croak "Unrecognizable SELECT: $sql"; + # get the order_by only (or make up an order if none exists) my $order_by = $self->_order_by( (delete $order->{order_by}) || $self->_rno_default_order ); - # whatever is left + # whatever is left of the order_by my $group_having = $self->_order_by($order); - $sql = sprintf (<<'EOS', $order_by, $sql, $group_having, $offset + 1, $offset + $rows, ); + my $qalias = $self->_quote ($self->{_dbic_rs_attrs}{alias}); -SELECT * FROM ( - SELECT orig_query.*, ROW_NUMBER() OVER(%s ) AS rno__row__index FROM (%s%s) orig_query -) rno_subq WHERE rno__row__index BETWEEN %d AND %d + $sql = sprintf (<_order_by ($order), + ); +} + +# Firebird specific limit, reverse of _SkipFirst for Informix +sub _FirstSkip { + my ($self, $sql, $order, $rows, $offset) = @_; + + $sql =~ s/^ \s* SELECT \s+ //ix + or croak "Unrecognizable SELECT: $sql"; + + return sprintf ('SELECT %s%s%s%s', + sprintf ('FIRST %d ', $rows), + $offset + ? sprintf ('SKIP %d ', $offset) + : '' + , + $sql, + $self->_order_by ($order), + ); +} + # Crappy Top based Limit/Offset support. Legacy from MSSQL. sub _Top { my ( $self, $sql, $order, $rows, $offset ) = @_; @@ -316,7 +360,13 @@ sub insert { # which is sadly understood only by MySQL. Change default behavior here, # until SQLA2 comes with proper dialect support if (! $_[0] or (ref $_[0] eq 'HASH' and !keys %{$_[0]} ) ) { - return "INSERT INTO ${table} DEFAULT VALUES" + my $sql = "INSERT INTO ${table} DEFAULT VALUES"; + + if (my $ret = ($_[1]||{})->{returning} ) { + $sql .= $self->_insert_returning ($ret); + } + + return $sql; } $self->SUPER::insert($table, @_); @@ -381,7 +431,7 @@ sub _recurse_fields { $self->_sqlcase($func), $self->_recurse_fields($args), $as - ? sprintf (' %s %s', $self->_sqlcase('as'), $as) + ? sprintf (' %s %s', $self->_sqlcase('as'), $self->_quote ($as) ) : '' ); @@ -459,6 +509,14 @@ sub _table { } } +sub _generate_join_clause { + my ($self, $join_type) = @_; + + return sprintf ('%s JOIN ', + $join_type ? ' ' . uc($join_type) : '' + ); +} + sub _recurse_from { my ($self, $from, @join) = @_; my @sqlf; @@ -477,10 +535,7 @@ sub _recurse_from { $join_type = $self->{_default_jointype} if not defined $join_type; - my $join_clause = sprintf ('%s JOIN ', - $join_type ? ' ' . uc($join_type) : '' - ); - push @sqlf, $join_clause; + push @sqlf, $self->_generate_join_clause( $join_type ); if (ref $to eq 'ARRAY') { push(@sqlf, '(', $self->_recurse_from(@$to), ')');