X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2F746mssql.t;h=c494be8004f29a62a3bac6d7b0fb9045724b8217;hb=16120b2279b09ec32c1c7801400809137fb0e843;hp=bb0b25458818a0f304574616357b8dd1ab4443a7;hpb=e56b1c2d9508b46a185b404413a85cd738e187a5;p=dbsrgits%2FDBIx-Class.git diff --git a/t/746mssql.t b/t/746mssql.t index bb0b254..c494be8 100644 --- a/t/746mssql.t +++ b/t/746mssql.t @@ -3,10 +3,18 @@ use warnings; use Test::More; use Test::Exception; +use Try::Tiny; +use DBIx::Class::SQLMaker::LimitDialects; +use DBIx::Class::Optional::Dependencies (); use lib qw(t/lib); use DBICTest; use DBIC::SqlMakerTest; -use Try::Tiny; + +plan skip_all => 'Test needs ' . DBIx::Class::Optional::Dependencies->req_missing_for ('test_rdbms_mssql_odbc') + unless DBIx::Class::Optional::Dependencies->req_ok_for ('test_rdbms_mssql_odbc'); + +my $OFFSET = DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype; +my $TOTAL = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype; my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MSSQL_ODBC_${_}" } qw/DSN USER PASS/}; @@ -35,10 +43,9 @@ my $schema = DBICTest::Schema->connect($dsn, $user, $pass); isa_ok( $schema->storage, 'DBIx::Class::Storage::DBI::ODBC::Microsoft_SQL_Server' ); { - my $schema2 = $schema->connect ($schema->storage->connect_info); + my $schema2 = $schema->connect (@{$schema->storage->connect_info}); ok (! $schema2->storage->connected, 'a re-connected cloned schema starts unconnected'); } - $schema->storage->_dbh->disconnect; lives_ok { @@ -47,25 +54,35 @@ lives_ok { my %opts = ( use_mars => - { on_connect_call => 'use_mars' }, + { opts => { on_connect_call => 'use_mars' } }, use_dynamic_cursors => - { on_connect_call => 'use_dynamic_cursors' }, + { opts => { on_connect_call => 'use_dynamic_cursors' }, + required => $schema->storage->_using_freetds ? 0 : 1, + }, use_server_cursors => - { on_connect_call => 'use_server_cursors' }, + { opts => { on_connect_call => 'use_server_cursors' } }, plain => - {}, + { opts => {}, required => 1 }, ); for my $opts_name (keys %opts) { SKIP: { - my $opts = $opts{$opts_name}; + my $opts = $opts{$opts_name}{opts}; $schema = DBICTest::Schema->connect($dsn, $user, $pass, $opts); try { $schema->storage->ensure_connected } catch { - skip "$opts_name not functional in this configuration: $_", 1; + if ($opts{$opts_name}{required}) { + BAIL_OUT "on_connect_call option '$opts_name' is not functional: $_"; + } + else { + skip + "on_connect_call option '$opts_name' not functional in this configuration: $_", + 1 + ; + } }; $schema->storage->dbh_do (sub { @@ -94,30 +111,40 @@ SQL skip 'not a multiple active statements configuration', 1 if $opts_name eq 'plain'; - my $artist_rs = $schema->resultset('Artist'); + $schema->storage->ensure_connected; - $artist_rs->delete; + lives_ok { - $artist_rs->create({ name => "Artist$_" }) for (1..3); + no warnings 'redefine'; + local *DBI::connect = sub { die "NO RECONNECTS!!!" }; - my $forward = $artist_rs->search({}, - { order_by => { -asc => 'artistid' } }); - my $backward = $artist_rs->search({}, - { order_by => { -desc => 'artistid' } }); + my $artist_rs = $schema->resultset('Artist'); - my @map = ( - [qw/Artist1 Artist3/], [qw/Artist2 Artist2/], [qw/Artist3 Artist1/] - ); - my @result; + $artist_rs->delete; - while (my $forward_row = $forward->next) { - my $backward_row = $backward->next; - push @result, [$forward_row->name, $backward_row->name]; - } + $artist_rs->create({ name => "Artist$_" }) for (1..3); + + my $forward = $artist_rs->search({}, + { order_by => { -asc => 'artistid' } }); + my $backward = $artist_rs->search({}, + { order_by => { -desc => 'artistid' } }); + + my @map = ( + [qw/Artist1 Artist3/], [qw/Artist2 Artist2/], [qw/Artist3 Artist1/] + ); + my @result; - is_deeply \@result, \@map, "multiple active statements in $opts_name"; + while (my $forward_row = $forward->next) { + my $backward_row = $backward->next; + push @result, [$forward_row->name, $backward_row->name]; + } + + is_deeply \@result, \@map, "multiple active statements in $opts_name"; - $artist_rs->delete; + $artist_rs->delete; + + is($artist_rs->count, 0, '$dbh still viable'); + } "Multiple active statements survive $opts_name"; } # Test populate @@ -263,35 +290,6 @@ SQL ); } - { - my $book_owner_ids = $schema->resultset ('BooksInLibrary')->search ({}, { - rows => 6, - offset => 2, - join => 'owner', - distinct => 1, - order_by => 'owner.name', - unsafe_subselect_ok => 1 - })->get_column ('owner'); - - my @ids = $book_owner_ids->all; - - is (@ids, 6, 'Limit works'); - - my $book_owners = $schema->resultset ('Owners')->search ({ - id => { -in => $book_owner_ids->as_query } - }); - - TODO: { - local $TODO = "Correlated limited IN subqueries will probably never preserve order"; - - is_deeply ( - [ map { $_->id } ($book_owners->all) ], - [ $book_owner_ids->all ], - "$test_type: Sort is preserved across IN subqueries", - ); - } - } - # still even with lost order of IN, we should be getting correct # sets { @@ -367,7 +365,7 @@ SQL }, { prefetch => 'books', - order_by => { -asc => \['name + ?', [ test => 'xxx' ]] }, # test bindvar propagation + order_by => [ { -asc => \['name + ?', [ test => 'xxx' ]] }, 'me.id' ], # test bindvar propagation group_by => [ map { "me.$_" } $schema->source('Owners')->columns ], # the literal order_by requires an explicit group_by rows => 3, # 8 results total unsafe_subselect_ok => 1, @@ -375,11 +373,24 @@ SQL ); my ($sql, @bind) = @${$owners->page(3)->as_query}; - is_deeply ( + # not testing the SQL as it is quite different between top/rno + is_same_bind ( \@bind, [ - $dialect eq 'Top' ? [ test => 'xxx' ] : (), # the extra re-order bind - ([ 'me.name' => 'somebogusstring' ], [ test => 'xxx' ]) x 2 # double because of the prefetch subq + [ { dbic_colname => 'test' } + => 'xxx' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' } + => 'somebogusstring' ], + + ($dialect eq 'Top' + ? [ { dbic_colname => 'test' } => 'xxx' ] # the extra re-order bind + : ([ $OFFSET => 7 ], [ $TOTAL => 9 ]) # parameterised RNO + ), + + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' } + => 'somebogusstring' ], + [ { dbic_colname => 'test' } + => 'xxx' ], ], ); @@ -405,19 +416,35 @@ SQL having => \['1 = ?', [ test => 1 ] ], #test having propagation prefetch => 'owner', rows => 2, # 3 results total - order_by => { -desc => 'me.owner' }, + order_by => [{ -desc => 'me.owner' }, 'me.id'], unsafe_subselect_ok => 1, }, ); ($sql, @bind) = @${$books->page(3)->as_query}; - is_deeply ( + # not testing the SQL as it is quite different between top/rno + is_same_bind ( \@bind, [ # inner - [ 'owner.name' => 'wiggle' ], [ 'owner.name' => 'woggle' ], [ source => 'Library' ], [ test => '1' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } + => 'wiggle' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } + => 'woggle' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } + => 'Library' ], + [ { dbic_colname => 'test' } + => '1' ], + + # rno(?) + $dialect ne 'Top' ? ( [ $OFFSET => 5 ], [ $TOTAL => 6 ] ) : (), # outer - [ 'owner.name' => 'wiggle' ], [ 'owner.name' => 'woggle' ], [ source => 'Library' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } + => 'wiggle' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } + => 'woggle' ], + [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } + => 'Library' ], ], ); @@ -495,27 +522,41 @@ CREATE TABLE money_test ( SQL }); - my $rs = $schema->resultset('Money'); - my $row; + TODO: { + my $freetds_and_dynamic_cursors = 1 + if $opts_name eq 'use_dynamic_cursors' && + $schema->storage->_using_freetds; - lives_ok { - $row = $rs->create({ amount => 100 }); - } 'inserted a money value'; + local $TODO = +'these tests fail on freetds with dynamic cursors for some reason' + if $freetds_and_dynamic_cursors; + local $ENV{DBIC_NULLABLE_KEY_NOWARN} = 1 + if $freetds_and_dynamic_cursors; - cmp_ok $rs->find($row->id)->amount, '==', 100, 'money value round-trip'; + my $rs = $schema->resultset('Money'); + my $row; - lives_ok { - $row->update({ amount => 200 }); - } 'updated a money value'; + lives_ok { + $row = $rs->create({ amount => 100 }); + } 'inserted a money value'; - cmp_ok $rs->find($row->id)->amount, '==', 200, - 'updated money value round-trip'; + cmp_ok ((try { $rs->find($row->id)->amount })||0, '==', 100, + 'money value round-trip'); - lives_ok { - $row->update({ amount => undef }); - } 'updated a money value to NULL'; + lives_ok { + $row->update({ amount => 200 }); + } 'updated a money value'; + + cmp_ok ((try { $rs->find($row->id)->amount })||0, '==', 200, + 'updated money value round-trip'); - is $rs->find($row->id)->amount, undef,'updated money value to NULL round-trip'; + lives_ok { + $row->update({ amount => undef }); + } 'updated a money value to NULL'; + + is try { $rs->find($row->id)->amount }, undef, + 'updated money value to NULL round-trip'; + } } } } @@ -528,5 +569,6 @@ END { eval { $dbh->do("DROP TABLE $_") } for qw/artist artist_guid money_test books owners/; } + undef $schema; } # vim:sw=2 sts=2