From: Rafael Kitover Date: Thu, 4 Jun 2009 12:50:49 +0000 (+0000) Subject: sybase limit count without offset now works X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b75051301e6da537ee0f4a0494f2a3ffad448481;p=dbsrgits%2FDBIx-Class-Historic.git sybase limit count without offset now works --- diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index f7ba454..f3ea456 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -926,6 +926,22 @@ sub _fix_bind_params { } @bind; } +sub _flatten_bind_params { + my ($self, @bind) = @_; + + ### Turn @bind from something like this: + ### ( [ "artist", 1 ], [ "cdid", 1, 3 ] ) + ### to this: + ### ( 1, 1, 3 ) + return + map { + if ( defined( $_ && $_->[1] ) ) { + @{$_}[ 1 .. $#$_ ]; + } + else { undef; } + } @bind; +} + sub _query_start { my ( $self, $sql, @bind ) = @_; @@ -1229,16 +1245,25 @@ sub _select_args { return @args; } -sub count { +sub _trim_attributes_for_count { my ($self, $source, $attrs) = @_; + my %attrs = %$attrs; # take off any column specs, any pagers, record_filter is cdbi, and no point of ordering a count - delete $attrs->{$_} for (qw/columns +columns select +select as +as rows offset page pager order_by record_filter/); + delete $attrs{$_} for (qw/columns +columns select +select as +as rows offset page pager order_by record_filter/); + + return \%attrs; +} + +sub count { + my ($self, $source, $attrs) = @_; + + my $new_attrs = $self->_trim_attributes_for_count($source, $attrs); - $attrs->{select} = { count => '*' }; - $attrs->{as} = [qw/count/]; + $new_attrs->{select} = { count => '*' }; + $new_attrs->{as} = [qw/count/]; - my $tmp_rs = $source->resultset_class->new($source, $attrs); + my $tmp_rs = $source->resultset_class->new($source, $new_attrs); my ($count) = $tmp_rs->cursor->next; return $count; diff --git a/lib/DBIx/Class/Storage/DBI/Sybase.pm b/lib/DBIx/Class/Storage/DBI/Sybase.pm index 5220dac..e5acf8d 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase.pm @@ -59,6 +59,36 @@ sub _dbh_last_insert_id { return ($dbh->selectrow_array($sth))[0]; } +sub count { + my ($self, $source, $attrs) = @_; + + if (exists $attrs->{rows}) { + my $new_attrs = $self->_trim_attributes_for_count($source, $attrs); + + $new_attrs->{select} = '1'; + $new_attrs->{as} = ['dummy']; + +# speed things up at least *a little* + $new_attrs->{result_class} = 'DBIx::Class::ResultClass::HashRefInflator'; + + my $offset = $attrs->{offset} || 0; + my $total = $attrs->{rows} + $offset; + + $self->dbh->do("set rowcount $total"); + + my $tmp_rs = $source->resultset_class->new($source, $new_attrs); + + my $count = 0; + $count++ while $tmp_rs->cursor->next; + + $self->dbh->do("set rowcount 0"); + + return $count; + } + + return $self->next::method(@_); +} + sub datetime_parser_type { "DBIx::Class::Storage::DBI::Sybase::DateTime" } 1; @@ -90,6 +120,9 @@ On connection C is set to C, e.g.: C<2004-08-21T14:36:48.080Z> and C is set to C, e.g.: C<08/13/1979 18:08:55.080>. +This works for both C and C columns, although +C columns only have minute precision. + You will need the L module if you are going to use L. diff --git a/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm b/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm index f458b91..cbde13d 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm @@ -3,6 +3,7 @@ package DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server; use strict; use warnings; +use Class::C3; use base qw/ DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server DBIx::Class::Storage::DBI::NoBindVars @@ -33,9 +34,7 @@ L. =head1 AUTHORS -Brandon L Black - -Justin Hunter +See L. =head1 LICENSE diff --git a/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm b/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm index b5d61a2..1f5dfc4 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm @@ -1,5 +1,6 @@ package DBIx::Class::Storage::DBI::Sybase::NoBindVars; +use Class::C3; use base qw/ DBIx::Class::Storage::DBI::NoBindVars DBIx::Class::Storage::DBI::Sybase diff --git a/t/746sybase.t b/t/746sybase.t index 47064af..3a4ebb9 100644 --- a/t/746sybase.t +++ b/t/746sybase.t @@ -62,16 +62,15 @@ SQL $seen_id{$new->artistid}++; } - my $it = $schema->resultset('Artist')->search( {}, { +## avoid quoting bug with NoBindVars for now +# my $it = $schema->resultset('Artist')->search({artistid => { '>' => 0 }}, { + + my $it = $schema->resultset('Artist')->search({}, { rows => 3, order_by => 'artistid', }); - TODO: { - local $TODO = 'Sybase is very very fucked in the limit department'; - - is( $it->count, 3, "LIMIT count ok" ); - } + is( $it->count, 3, "LIMIT count ok" ); is( $it->next->name, "foo", "iterator->next ok" ); $it->next;