X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2F746mssql.t;h=57c44fbc60c71f5f63f7950a6094a0712b68a0f4;hb=people%2Fabraxxa%2Fhas_relationship_loaded;hp=bafbef2b1ae0c534d060a345c331dedcb3a7468c;hpb=2112fa3bca913f9340c6d315ab333a9dc36b1726;p=dbsrgits%2FDBIx-Class.git diff --git a/t/746mssql.t b/t/746mssql.t index bafbef2..57c44fb 100644 --- a/t/746mssql.t +++ b/t/746mssql.t @@ -4,14 +4,15 @@ use warnings; use Test::More; use Test::Exception; use Try::Tiny; -use DBIx::Class::SQLMaker::LimitDialects; + use DBIx::Class::Optional::Dependencies (); +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'); + use lib qw(t/lib); use DBICTest; use DBIC::SqlMakerTest; - -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'); +use DBIx::Class::SQLMaker::LimitDialects; my $OFFSET = DBIx::Class::SQLMaker::LimitDialects->__offset_bindtype; my $TOTAL = DBIx::Class::SQLMaker::LimitDialects->__total_bindtype; @@ -43,10 +44,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 { @@ -57,10 +57,12 @@ my %opts = ( use_mars => { opts => { on_connect_call => 'use_mars' } }, use_dynamic_cursors => - { opts => { on_connect_call => 'use_dynamic_cursors' }, required => 1 }, + { opts => { on_connect_call => 'use_dynamic_cursors' }, + required => $schema->storage->_using_freetds ? 0 : 1, + }, use_server_cursors => { opts => { on_connect_call => 'use_server_cursors' } }, - NO_OPTION => + plain => { opts => {}, required => 1 }, ); @@ -74,12 +76,13 @@ for my $opts_name (keys %opts) { } catch { if ($opts{$opts_name}{required}) { - BAIL_OUT "on_connect_call option '$opts_name' is not functional: $_"; + die "on_connect_call option '$opts_name' is not functional: $_"; } else { skip -"on_connect_call option '$opts_name' not functional in this configuration: $_", -1; + "on_connect_call option '$opts_name' not functional in this configuration: $_", + 1 + ; } }; @@ -109,30 +112,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 @@ -239,7 +252,7 @@ SQL my $test_type = "Dialect:$dialect Quoted:$quoted"; # basic limit support - TODO: { + { my $art_rs = $schema->resultset ('Artist'); $art_rs->delete; $art_rs->create({ name => 'Artist ' . $_ }) for (1..6); @@ -360,28 +373,82 @@ SQL }, ); - my ($sql, @bind) = @${$owners->page(3)->as_query}; - is_same_bind ( - \@bind, + is_same_sql_bind ( + $owners->page(3)->as_query, + $dialect eq 'Top' + ? '( + SELECT TOP 2147483647 [me].[id], [me].[name], + [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price] + FROM ( + SELECT TOP 2147483647 [me].[id], [me].[name] + FROM ( + SELECT TOP 3 [me].[id], [me].[name], [ORDER__BY__001] + FROM ( + SELECT TOP 9 [me].[id], [me].[name], name + ? AS [ORDER__BY__001] + FROM [owners] [me] + LEFT JOIN [books] [books] + ON [books].[owner] = [me].[id] + WHERE [books].[id] IS NOT NULL AND [me].[name] != ? + GROUP BY [me].[id], [me].[name] + ORDER BY name + ? ASC, [me].[id] + ) [me] + ORDER BY [ORDER__BY__001] DESC, [me].[id] DESC + ) [me] + ORDER BY [ORDER__BY__001] ASC, [me].[id] + ) [me] + LEFT JOIN [books] [books] + ON [books].[owner] = [me].[id] + WHERE [books].[id] IS NOT NULL AND [me].[name] != ? + ORDER BY name + ? ASC, [me].[id] + )' + : '( + SELECT TOP 2147483647 [me].[id], [me].[name], + [books].[id], [books].[source], [books].[owner], [books].[title], [books].[price] + FROM ( + SELECT TOP 2147483647 [me].[id], [me].[name] + FROM ( + SELECT [me].[id], [me].[name], + ROW_NUMBER() OVER( ORDER BY [ORDER__BY__001] ASC, [me].[id] ) AS [rno__row__index] + FROM ( + SELECT [me].[id], [me].[name], name + ? AS [ORDER__BY__001] + FROM [owners] [me] + LEFT JOIN [books] [books] + ON [books].[owner] = [me].[id] + WHERE [books].[id] IS NOT NULL AND [me].[name] != ? + GROUP BY [me].[id], [me].[name] + ) [me] + ) [me] + WHERE [rno__row__index] >= ? AND [rno__row__index] <= ? + ) [me] + LEFT JOIN [books] [books] + ON [books].[owner] = [me].[id] + WHERE [books].[id] IS NOT NULL AND [me].[name] != ? + ORDER BY name + ? ASC, [me].[id] + )' + , [ - ($dialect eq 'Top' ? [ { dbic_colname => 'test' } => 'xxx' ] : ()), # the extra re-order bind - [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'me.name' } - => 'somebogusstring' ], [ { dbic_colname => 'test' } => 'xxx' ], - ($dialect ne 'Top' ? ( [ $OFFSET => 7 ], [ $TOTAL => 9 ] ) : ()), # parameterised RNO + [ { 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' ], ], - ); + ) if $quoted; is ($owners->page(1)->all, 3, "$test_type: has_many prefetch returns correct number of rows"); is ($owners->page(1)->count, 3, "$test_type: has-many prefetch returns correct count"); is ($owners->page(3)->count, 2, "$test_type: has-many prefetch returns correct count"); - TODO: { + { local $TODO = "Top-limit does not work when your limit ends up past the resultset" if $dialect eq 'Top'; is ($owners->page(3)->all, 2, "$test_type: has_many prefetch returns correct number of rows"); @@ -404,9 +471,61 @@ SQL }, ); - ($sql, @bind) = @${$books->page(3)->as_query}; - is_same_bind ( - \@bind, + is_same_sql_bind ( + $books->page(3)->as_query, + $dialect eq 'Top' + ? '( + SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price], + [owner].[id], [owner].[name] + FROM ( + SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + FROM ( + SELECT TOP 2 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + FROM ( + SELECT TOP 6 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + FROM [books] [me] + JOIN [owners] [owner] + ON [owner].[id] = [me].[owner] + WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? + GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + HAVING 1 = ? + ORDER BY [me].[owner] DESC, [me].[id] + ) [me] + ORDER BY [me].[owner] ASC, [me].[id] DESC + ) [me] + ORDER BY [me].[owner] DESC, [me].[id] + ) [me] + JOIN [owners] [owner] + ON [owner].[id] = [me].[owner] + WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? + ORDER BY [me].[owner] DESC, [me].[id] + )' + : '( + SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price], + [owner].[id], [owner].[name] + FROM ( + SELECT TOP 2147483647 [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + FROM ( + SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price], + ROW_NUMBER() OVER( ORDER BY [me].[owner] DESC, [me].[id] ) AS [rno__row__index] + FROM ( + SELECT [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + FROM [books] [me] + JOIN [owners] [owner] + ON [owner].[id] = [me].[owner] + WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? + GROUP BY [me].[id], [me].[source], [me].[owner], [me].[title], [me].[price] + HAVING 1 = ? + ) [me] + ) [me] + WHERE [rno__row__index] >= ? AND [rno__row__index] <= ? + ) [me] + JOIN [owners] [owner] + ON [owner].[id] = [me].[owner] + WHERE ( [owner].[name] = ? OR [owner].[name] = ? ) AND [source] = ? + ORDER BY [me].[owner] DESC, [me].[id] + )' + , [ # inner [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } @@ -418,8 +537,12 @@ SQL [ { dbic_colname => 'test' } => '1' ], - # rno(?) - $dialect ne 'Top' ? ( [ $OFFSET => 5 ], [ $TOTAL => 6 ] ) : (), + # top(?) + $dialect eq 'Top' + ? () + : ( [ $OFFSET => 5 ], [ $TOTAL => 6 ] ) + , + # outer [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'owner.name' } => 'wiggle' ], @@ -428,13 +551,13 @@ SQL [ { sqlt_datatype => 'varchar', sqlt_size => 100, dbic_colname => 'source' } => 'Library' ], ], - ); + ) if $quoted; is ($books->page(1)->all, 2, "$test_type: Prefetched grouped search returns correct number of rows"); is ($books->page(1)->count, 2, "$test_type: Prefetched grouped search returns correct count"); is ($books->page(2)->count, 1, "$test_type: Prefetched grouped search returns correct count"); - TODO: { + { local $TODO = "Top-limit does not work when your limit ends up past the resultset" if $dialect eq 'Top'; is ($books->page(2)->all, 1, "$test_type: Prefetched grouped search returns correct number of rows"); @@ -504,10 +627,10 @@ CREATE TABLE money_test ( SQL }); - TODO: { + { my $freetds_and_dynamic_cursors = 1 if $opts_name eq 'use_dynamic_cursors' && - $schema->storage->using_freetds; + $schema->storage->_using_freetds; local $TODO = 'these tests fail on freetds with dynamic cursors for some reason'