From: Rafael Kitover Date: Wed, 3 Jun 2009 23:51:39 +0000 (+0000) Subject: fix Sybase DT stuff and storage bases X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6b1f5ef74ba9728a8587863b5034a43d7fbe705e;p=dbsrgits%2FDBIx-Class-Historic.git fix Sybase DT stuff and storage bases --- diff --git a/lib/DBIx/Class/Storage/DBI/Sybase.pm b/lib/DBIx/Class/Storage/DBI/Sybase.pm index 28b4059..3fb9045 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase.pm @@ -5,6 +5,8 @@ use warnings; use base qw/DBIx::Class::Storage::DBI/; +use Carp::Clan qw/^DBIx::Class/; + sub _rebless { my $self = shift; @@ -20,26 +22,38 @@ sub _rebless { if (!$exception && $dbtype && $self->load_optional_class($subclass)) { bless $self, $subclass; $self->_rebless; - } else { # probably real Sybase - if (not $self->dbh->{syb_dynamic_supported}) { - bless $self, 'DBIx::Class::Storage:DBI::Sybase::NoBindVars'; - $self->_rebless; - } - - $self->dbh->syb_date_fmt('ISO_strict'); - $self->dbh->do('set dateformat mdy'); + } elsif (not $self->dbh->{syb_dynamic_supported}) { +# probably real Sybase + bless $self, 'DBIx::Class::Storage:DBI::Sybase::NoBindVars'; + $self->_rebless; } } } -sub _dbh_last_insert_id { - my ($self, $dbh, $source, $col) = @_; +{ + my $old_dbd_warned = 0; + + sub _populate_dbh { + my $self = shift; + $self->next::method(@_); + my $dbh = $self->_dbh; + + if ($dbh->can('syb_date_fmt')) { + $dbh->syb_date_fmt('ISO_strict'); + } elsif (not $old_dbd_warned) { + carp "Your DBD::Sybase is too old to support ". + "DBIx::Class::InflateColumn::DateTime, please upgrade!"; + $old_dbd_warned = 1; + } + + $dbh->do('set dateformat mdy'); - if (not $self->dbh->{syb_dynamic_supported}) { - # @@identity works only if not using placeholders - # Should this query be cached? - return ($dbh->selectrow_array('select @@identity'))[0]; + 1; } +} + +sub _dbh_last_insert_id { + my ($self, $dbh, $source, $col) = @_; # sorry, there's no other way! my $sth = $dbh->prepare_cached("select max($col) from ".$source->from); 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 35171e2..f7d3fd1 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase/Microsoft_SQL_Server.pm @@ -5,8 +5,7 @@ use warnings; use base qw/ DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server - DBIx::Class::Storage::DBI::Sybase - DBIx::Class::Storage::DBI::NoBindVars + DBIx::Class::Storage::DBI::Sybase::NoBindVars /; 1; diff --git a/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm b/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm index 72a7372..373d934 100644 --- a/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm +++ b/lib/DBIx/Class/Storage/DBI/Sybase/NoBindVars.pm @@ -1,9 +1,16 @@ -package # hide from PAUSE - DBIx::Class::Storage::DBI::Sybase::NoBindVars; +package DBIx::Class::Storage::DBI::Sybase::NoBindVars; use base qw/ DBIx::Class::Storage::DBI::NoBindVars DBIx::Class::Storage::DBI::Sybase /; +sub _dbh_last_insert_id { + my ($self, $dbh, $source, $col) = @_; + + # @@identity works only if not using placeholders + # Should this query be cached? + return ($dbh->selectrow_array('select @@identity'))[0]; +} + 1; diff --git a/t/746sybase.t b/t/746sybase.t index 035091f..7ee6ec3 100644 --- a/t/746sybase.t +++ b/t/746sybase.t @@ -11,18 +11,31 @@ my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_SYBASE_${_}" } qw/DSN USER PASS/} plan skip_all => 'Set $ENV{DBICTEST_SYBASE_DSN}, _USER and _PASS to run this test' unless ($dsn && $user); -plan tests => 15; +plan tests => 16*2; -my $schema = DBICTest::Schema->connect($dsn, $user, $pass, {AutoCommit => 1}); +my @storage_types = ( + 'DBI::Sybase', + 'DBI::Sybase::NoBindVars', +); +my $schema; + +for my $storage_type (@storage_types) { + $schema = DBICTest::Schema->clone; + + unless ($storage_type eq 'DBI::Sybase') { # autodetect + $schema->storage_type("::$storage_type"); + } + $schema->connection($dsn, $user, $pass, {AutoCommit => 1}); -$schema->storage->ensure_connected; -isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::Sybase' ); + $schema->storage->ensure_connected; -$schema->storage->dbh_do (sub { - my ($storage, $dbh) = @_; - eval { $dbh->do("DROP TABLE artist") }; - eval { $dbh->do("DROP TABLE track") }; - $dbh->do(<<'SQL'); + isa_ok( $schema->storage, "DBIx::Class::Storage::$storage_type" ); + + $schema->storage->dbh_do (sub { + my ($storage, $dbh) = @_; + eval { $dbh->do("DROP TABLE artist") }; + eval { $dbh->do("DROP TABLE track") }; + $dbh->do(<<'SQL'); CREATE TABLE artist ( artistid INT IDENTITY PRIMARY KEY, name VARCHAR(100), @@ -32,7 +45,7 @@ CREATE TABLE artist ( SQL # we only need the DT - $dbh->do(<<'SQL'); + $dbh->do(<<'SQL'); CREATE TABLE track ( trackid INT IDENTITY PRIMARY KEY, cd INT, @@ -40,66 +53,67 @@ CREATE TABLE track ( last_updated_on DATETIME, ) SQL + }); -}); - -my %seen_id; + my %seen_id; -# fresh $schema so we start unconnected -$schema = DBICTest::Schema->connect($dsn, $user, $pass, {AutoCommit => 1}); +# so we start unconnected + $schema->storage->disconnect; # test primary key handling -my $new = $schema->resultset('Artist')->create({ name => 'foo' }); -ok($new->artistid > 0, "Auto-PK worked"); + my $new = $schema->resultset('Artist')->create({ name => 'foo' }); + ok($new->artistid > 0, "Auto-PK worked"); -$seen_id{$new->artistid}++; + $seen_id{$new->artistid}++; # test LIMIT support -for (1..6) { + for (1..6) { $new = $schema->resultset('Artist')->create({ name => 'Artist ' . $_ }); is ( $seen_id{$new->artistid}, undef, "id for Artist $_ is unique" ); $seen_id{$new->artistid}++; -} + } -my $it = $schema->resultset('Artist')->search( {}, { + my $it = $schema->resultset('Artist')->search( {}, { rows => 3, order_by => 'artistid', -}); + }); -TODO: { + TODO: { local $TODO = 'Sybase is very very fucked in the limit department'; is( $it->count, 3, "LIMIT count ok" ); -} + } -# The iterator still works correctly with rows => 3, even though the sql is -# fucked, very interesting. + is( $it->next->name, "foo", "iterator->next ok" ); + $it->next; + is( $it->next->name, "Artist 2", "iterator->next ok" ); + is( $it->next, undef, "next past end of resultset ok" ); -is( $it->next->name, "foo", "iterator->next ok" ); -$it->next; -is( $it->next->name, "Artist 2", "iterator->next ok" ); -is( $it->next, undef, "next past end of resultset ok" ); + SKIP: { + skip 'quoting bug with NoBindVars', 4 + if $storage_type eq 'DBI::Sybase::NoBindVars'; # Test DateTime inflation - -my $dt = DBIx::Class::Storage::DBI::Sybase::DateTime - ->parse_datetime('2004-08-21T14:36:48.080Z'); - -my $row; -ok( $row = $schema->resultset('Track')->create({ - last_updated_on => $dt, - cd => 1, -})); -ok( $row = $schema->resultset('Track') - ->search({ trackid => $row->trackid }, { select => ['last_updated_on'] }) - ->first -); -is( $row->updated_date, $dt, 'DateTime inflation works' ); + ok(my $dt = DBIx::Class::Storage::DBI::Sybase::DateTime + ->parse_datetime('2004-08-21T14:36:48.080Z')); + + my $row; + ok( $row = $schema->resultset('Track')->create({ + last_updated_on => $dt, + cd => 1, + })); + ok( $row = $schema->resultset('Track') + ->search({ trackid => $row->trackid }, { select => ['last_updated_on'] }) + ->first + ); + is( $row->updated_date, $dt, 'DateTime inflation works' ); + } +} # clean up our mess END { - if (my $dbh = eval { $schema->storage->_dbh }) { - $dbh->do('DROP TABLE artist'); - $dbh->do('DROP TABLE track'); - } + if (my $dbh = eval { $schema->storage->_dbh }) { + $dbh->do('DROP TABLE artist'); + $dbh->do('DROP TABLE track'); + } }