handle
- Improve identity/autoinc retrieval code in MSSQL and Sybase -
should reduce weird side-effects especially with populate()
+ - Explicitly disable DBD::ODBC batch operations (as of DBD::ODBC 1.35)
+ when using freetds - the freetds driver is just too buggy to handle
+ the optimized path
+ - Explicitly disable DBD::ODBC dynamic_cursors when using freetds 0.83
+ or later - they made enough ODBC incompatible making it impossible
+ to support
- Fix leakage of $schema on in-memory new_related() calls
- Fix more cases of $schema leakage in SQLT::Parser::DBIC
- Fix leakage of $storage in ::Storage::DBI::Oracle
sub DESTROY {
# None of the reasons this would die matter if we're in DESTROY anyways
if (my $sth = $_[0]->sth) {
+ local $SIG{__WARN__} = sub {};
try { $sth->finish } if $sth->FETCH('Active');
}
}
use namespace::clean;
__PACKAGE__->mk_group_accessors(simple => qw/
- _identity _identity_method
+ _identity _identity_method _no_scope_identity_query
/);
__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::MSSQL');
# point we don't have many guarantees we will get what we expected.
# http://msdn.microsoft.com/en-us/library/ms190315.aspx
# http://davidhayden.com/blog/dave/archive/2006/01/17/2736.aspx
- if ($self->_perform_autoinc_retrieval) {
+ if ($self->_perform_autoinc_retrieval and not $self->_no_scope_identity_query) {
$sql .= "\nSELECT SCOPE_IDENTITY()";
}
if ($self->_perform_autoinc_retrieval) {
- # this should bring back the result of SELECT SCOPE_IDENTITY() we tacked
+ # attempt to bring back the result of SELECT SCOPE_IDENTITY() we tacked
# on in _prep_for_execute above
- my ($identity) = try { $sth->fetchrow_array };
+ my $identity;
+
+ # we didn't even try on ftds
+ unless ($self->_no_scope_identity_query) {
+ ($identity) = try { $sth->fetchrow_array };
+ $sth->finish;
+ }
# SCOPE_IDENTITY failed, but we can do something else
if ( (! $identity) && $self->_identity_method) {
}
$self->_identity($identity);
- $sth->finish;
}
return wantarray ? ($rv, $sth, @bind) : $rv;
B<WARNING:> on FreeTDS, changes made in one statement (e.g. an insert) may not
be visible from a following statement (e.g. a select.)
+B<WARNING:> FreeTDS versions > 0.82 seem to have completely broken the ODBC
+protocol. DBIC will not allow dynamic cursor support with such versions to
+protect your data. Please hassle the authors of FreeTDS to act on the bugs that
+make their driver not overly usable with DBD::ODBC.
+
=cut
sub connect_call_use_dynamic_cursors {
$self->_using_dynamic_cursors(1);
$self->_identity_method('@@identity');
+ $self->_no_scope_identity_query($self->using_freetds);
}
else {
$self->_using_dynamic_cursors(0);
$self->_identity_method(undef);
+ $self->_no_scope_identity_query(undef);
}
}
$self->next::method (@_);
+
+ # freetds is too damn broken, some fixups
+ if ($self->using_freetds) {
+
+ # no dynamic cursors starting from 0.83
+ if ($self->_using_dynamic_cursors) {
+ my $fv = $self->_dbh_get_info('SQL_DRIVER_VER');
+ $self->throw_exception(
+ 'Dynamic cursors (odbc_cursortype => 2) are not supported with FreeTDS > 0.82 '
+ . "(you have $fv). Please hassle FreeTDS authors to fix the outstanding bugs in "
+ . 'their driver.'
+ ) if $fv > 0.82
+ }
+
+ # FreeTDS is too broken wrt execute_for_fetch batching
+ # just disable it outright until things quiet down
+ $self->_get_dbh->{odbc_disable_array_operations} = 1;
+ }
}
=head2 connect_call_use_server_cursors
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 =>
is_deeply \@result, \@map, "multiple active statements in $opts_name";
$artist_rs->delete;
+
+ is($artist_rs->count, 0, '$dbh still viable');
}
# Test populate