X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FODBC%2FMicrosoft_SQL_Server.pm;h=03053c6cb87b353eaf5236567ff013d9db075f38;hb=384b8bce2c9e4081cb131bba591627fda2672a5a;hp=028d9d6b4f963005041cffd30c9459a2a229f83a;hpb=18ac986d17b9f8f16d29d4a175867b6d8dde32b1;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI/ODBC/Microsoft_SQL_Server.pm b/lib/DBIx/Class/Storage/DBI/ODBC/Microsoft_SQL_Server.pm index 028d9d6..03053c6 100644 --- a/lib/DBIx/Class/Storage/DBI/ODBC/Microsoft_SQL_Server.pm +++ b/lib/DBIx/Class/Storage/DBI/ODBC/Microsoft_SQL_Server.pm @@ -4,11 +4,13 @@ use warnings; use base qw/DBIx::Class::Storage::DBI::MSSQL/; use mro 'c3'; +use Scalar::Util 'reftype'; +use Try::Tiny; use Carp::Clan qw/^DBIx::Class/; -use List::Util(); +use namespace::clean; __PACKAGE__->mk_group_accessors(simple => qw/ - _scope_identity _using_dynamic_cursors + _using_dynamic_cursors /); =head1 NAME @@ -18,29 +20,85 @@ to Microsoft SQL Server over ODBC =head1 DESCRIPTION -This class implements support specific to Microsoft SQL Server over ODBC, -including auto-increment primary keys and SQL::Abstract::Limit dialect. It -is loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it -detects a MSSQL back-end. +This class implements support specific to Microsoft SQL Server over ODBC. It is +loaded automatically by by DBIx::Class::Storage::DBI::ODBC when it detects a +MSSQL back-end. -=head1 IMPLEMENTATION NOTES +Most of the functionality is provided from the superclass +L. -Microsoft SQL Server supports three methods of retrieving the C -value for inserted row: C, C<@@IDENTITY>, and C. -C is used here because it is the safest. However, it must -be called is the same execute statement, not just the same connection. +=head1 MULTIPLE ACTIVE STATEMENTS -So, this implementation appends a C is used instead. +In order of preference, they are: -=head1 MULTIPLE ACTIVE STATEMENTS +=over 8 -The following options are alternative ways to enable concurrent executing -statement support. Each has its own advantages and drawbacks. +=item * L + +=item * L + +=item * L + +=back + +=head1 METHODS + +=head2 connect_call_use_mars + +Use as: + + on_connect_call => 'use_mars' + +Use to enable a feature of SQL Server 2005 and later, "Multiple Active Result +Sets". See L +for more information. + +This does not work on FreeTDS drivers at the time of this writing, and only +works with the Native Client, later versions of the Windows MS ODBC driver, and +the Easysoft driver. + +=cut + +sub connect_call_use_mars { + my $self = shift; + + my $dsn = $self->_dbi_connect_info->[0]; + + if (ref($dsn) eq 'CODE') { + $self->throw_exception('cannot change the DBI DSN on a CODE ref connect_info'); + } + + if ($dsn !~ /MARS_Connection=/) { + if ($self->using_freetds) { + $self->throw_exception('FreeTDS does not support MARS at the time of ' + .'writing.'); + } + + if (exists $self->_server_info->{normalized_dbms_version} && + $self->_server_info->{normalized_dbms_version} < 9) { + $self->throw_exception('SQL Server 2005 or later required to use MARS.'); + } + + if (my ($data_source) = $dsn =~ /^dbi:ODBC:([\w-]+)\z/i) { # prefix with DSN + warn "Bare DSN in ODBC connect string, rewriting to DSN=$data_source\n"; + $dsn = "dbi:ODBC:DSN=$data_source"; + } + + $self->_dbi_connect_info->[0] = "$dsn;MARS_Connection=Yes"; + $self->disconnect; + $self->ensure_connected; + } +} + +sub connect_call_use_MARS { + carp "'connect_call_use_MARS' has been deprecated, use " + ."'connect_call_use_mars' instead."; + shift->connect_call_use_mars(@_) +} =head2 connect_call_use_dynamic_cursors @@ -48,14 +106,18 @@ Use as: on_connect_call => 'use_dynamic_cursors' -in your L as one way to enable multiple +in your L as one way to enable multiple concurrent statements. Will add C<< odbc_cursortype => 2 >> to your DBI connection attributes. See L for more information. -This will not work with CODE ref connect_info's and will do nothing if you set -C yourself. +Alternatively, you can add it yourself and dynamic cursor support will be +automatically enabled. + +If you're using FreeTDS, C must be set to at least C<8.0>. + +This will not work with CODE ref connect_info's. B this will break C, and C