From: Peter Rabbitson Date: Sat, 14 Aug 2010 11:04:14 +0000 (+0200) Subject: Drop-in legacy code for DB2-AS/400 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2149a4e91f82d2f77657c18d4a0b312327987d5d;p=dbsrgits%2FDBIx-Class-Historic.git Drop-in legacy code for DB2-AS/400 --- diff --git a/lib/DBIx/Class/SQLAHacks/LimitDialects.pm b/lib/DBIx/Class/SQLAHacks/LimitDialects.pm index 1cf5cb7..2ca6fd5 100644 --- a/lib/DBIx/Class/SQLAHacks/LimitDialects.pm +++ b/lib/DBIx/Class/SQLAHacks/LimitDialects.pm @@ -7,6 +7,78 @@ use Carp::Clan qw/^DBIx::Class|^SQL::Abstract|^Try::Tiny/; use List::Util 'first'; use namespace::clean; +# FIXME +# This dialect has not been ported to the subquery-realiasing code +# that all other subquerying dialects are using. It is very possible +# that this dialect is entirely unnecessary - it is currently only +# used by ::Storage::DBI::ODBC::DB2_400_SQL which *should* be able to +# just subclass ::Storage::DBI::DB2 and use the already rewritten +# RowNumberOver. However nobody has access to this specific database +# engine, thus keeping legacy code as-is +# IF someone ever manages to test DB2-AS/400 with RNO, all the code +# in this block should go on to meet its maker +{ + sub _FetchFirst { + my ( $self, $sql, $order, $rows, $offset ) = @_; + + my $last = $rows + $offset; + + my ( $order_by_up, $order_by_down ) = $self->_order_directions( $order ); + + $sql = " + SELECT * FROM ( + SELECT * FROM ( + $sql + $order_by_up + FETCH FIRST $last ROWS ONLY + ) foo + $order_by_down + FETCH FIRST $rows ROWS ONLY + ) bar + $order_by_up + "; + + return $sql; + } + + sub _order_directions { + my ( $self, $order ) = @_; + + return unless $order; + + my $ref = ref $order; + + my @order; + + CASE: { + @order = @$order, last CASE if $ref eq 'ARRAY'; + @order = ( $order ), last CASE unless $ref; + @order = ( $$order ), last CASE if $ref eq 'SCALAR'; + croak __PACKAGE__ . ": Unsupported data struct $ref for ORDER BY"; + } + + my ( $order_by_up, $order_by_down ); + + foreach my $spec ( @order ) + { + my @spec = split ' ', $spec; + croak( "bad column order spec: $spec" ) if @spec > 2; + push( @spec, 'ASC' ) unless @spec == 2; + my ( $col, $up ) = @spec; # or maybe down + $up = uc( $up ); + croak( "bad direction: $up" ) unless $up =~ /^(?:ASC|DESC)$/; + $order_by_up .= ", $col $up"; + my $down = $up eq 'ASC' ? 'DESC' : 'ASC'; + $order_by_down .= ", $col $down"; + } + + s/^,/ORDER BY/ for ( $order_by_up, $order_by_down ); + + return $order_by_up, $order_by_down; + } +} +### end-of-FIXME + # PostgreSQL and SQLite sub _LimitOffset { my ( $self, $sql, $order, $rows, $offset ) = @_; diff --git a/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm b/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm index 16be2f8..29e9da9 100644 --- a/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm +++ b/lib/DBIx/Class/Storage/DBI/ODBC/DB2_400_SQL.pm @@ -5,6 +5,21 @@ use warnings; use base qw/DBIx::Class::Storage::DBI::ODBC/; use mro 'c3'; +warn 'Major advances took place in the DBIC codebase since this driver' + .' (::Storage::DBI::ODBC::DB2_400_SQL) was written. However since the' + .' RDBMS in question is so rare it is not possible for us to test any' + .' of the "new hottness". If you are using DB2 on AS-400 please get' + .' in contact with the developer team:' + .' http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class.pm#GETTING_HELP/SUPPORT' + ."\n" +; + +# FIXME +# Most likely all of this code is redundant and unnecessary. We should +# be able to simply use base qw/DBIx::Class::Storage::DBI::DB2/; +# Unfortunately nobody has an RDBMS engine to test with, so keeping +# things as-is for the time being + sub _dbh_last_insert_id { my ($self, $dbh, $source, $col) = @_;