X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI%2FADO%2FMicrosoft_SQL_Server.pm;h=7e08098f499410fb5615d4fff144a2787c682759;hb=aadfe180819e0cec3ab07f41a4fbd454d3694ee6;hp=4082a93f3d4ea8e2e8219b8ef8b5fa1933852688;hpb=4ffa57005fd6e9ecadbfc11157686e8d770e0df6;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Storage/DBI/ADO/Microsoft_SQL_Server.pm b/lib/DBIx/Class/Storage/DBI/ADO/Microsoft_SQL_Server.pm index 4082a93..7e08098 100644 --- a/lib/DBIx/Class/Storage/DBI/ADO/Microsoft_SQL_Server.pm +++ b/lib/DBIx/Class/Storage/DBI/ADO/Microsoft_SQL_Server.pm @@ -9,16 +9,9 @@ use base qw/ /; use mro 'c3'; -sub _rebless { - my $self = shift; - $self->_identity_method('@@identity'); -} - -1; - =head1 NAME -DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server - Support for Microsoft +DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server - Support for Microsoft SQL Server via DBD::ADO =head1 SYNOPSIS @@ -30,16 +23,163 @@ This subclass supports MSSQL server connections via L. The MSSQL specific functionality is provided by L. +=head1 EXAMPLE DSN + + dbi:ADO:provider=sqlncli10;server=EEEBOX\SQLEXPRESS + +=head1 CAVEATS + +=head2 identities + C<_identity_method> is set to C<@@identity>, as C doesn't work with L. See L for caveats regarding this. +=head2 truncation bug + +There is a bug with MSSQL ADO providers where data gets truncated based on the +size of the bind sizes in the first prepare call: + +L + +The C workaround is used (see L) with the +approximate maximum size of the data_type of the bound column, or 8000 (maximum +VARCHAR size) if the data_type is not available. + +This code is incomplete and may be buggy. Particularly, C is not +supported yet. The data_type list for other DBs is also incomplete. Please +report problems (and send patches.) + +=head2 fractional seconds + +Fractional seconds with L are not +currently supported, datetimes are truncated at the second. + +=cut + +__PACKAGE__->datetime_parser_type ( + 'DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server::DateTime::Format' +); + +sub _rebless { + my $self = shift; + $self->_identity_method('@@identity'); +} + +# work around a bug in the ADO driver - use the max VARCHAR size for all +# binds that do not specify one via bind_attributes_by_data_type() +sub _dbi_attrs_for_bind { + my $attrs = shift->next::method(@_); + + for (@$attrs) { + $_->{ado_size} ||= 8000 if $_; + } + + $attrs; +} + +sub bind_attribute_by_data_type { + my ($self, $data_type) = @_; + + ($data_type = lc($data_type)) =~ s/\s+.*//; + + my $max_size = + $self->_mssql_max_data_type_representation_size_in_bytes->{$data_type}; + + my $res = {}; + $res->{ado_size} = $max_size if $max_size; + + return $res; +} + +# approximate +# XXX needs to support varchar(max) and varbinary(max) +sub _mssql_max_data_type_representation_size_in_bytes { + my $self = shift; + + my $blob_max = $self->_get_dbh->{LongReadLen} || 32768; + + return +{ +# MSSQL types + char => 8000, + varchar => 8000, + binary => 8000, + varbinary => 8000, + nchar => 8000, + nvarchar => 8000, + numeric => 100, + smallint => 100, + tinyint => 100, + smallmoney => 100, + bigint => 100, + bit => 100, + decimal => 100, + integer => 100, + int => 100, + money => 100, + float => 100, + real => 100, + uniqueidentifier => 100, + ntext => $blob_max, + text => $blob_max, + image => $blob_max, + date => 100, + datetime => 100, + datetime2 => 100, + datetimeoffset => 100, + smalldatetime => 100, + time => 100, + timestamp => 100, + cursor => 100, + hierarchyid => 100, + sql_variant => 100, + table => 100, + xml => $blob_max, # ??? + +# some non-MSSQL types + serial => 100, + bigserial => 100, + varchar2 => 8000, + blob => $blob_max, + clob => $blob_max, + } +} + +package # hide from PAUSE + DBIx::Class::Storage::DBI::ADO::Microsoft_SQL_Server::DateTime::Format; + +my $datetime_format = '%m/%d/%Y %I:%M:%S %p'; +my $datetime_parser; + +sub parse_datetime { + shift; + require DateTime::Format::Strptime; + $datetime_parser ||= DateTime::Format::Strptime->new( + pattern => $datetime_format, + on_error => 'croak', + ); + return $datetime_parser->parse_datetime(shift); +} + +sub format_datetime { + shift; + require DateTime::Format::Strptime; + $datetime_parser ||= DateTime::Format::Strptime->new( + pattern => $datetime_format, + on_error => 'croak', + ); + return $datetime_parser->format_datetime(shift); +} + +1; + =head1 AUTHOR -See L. +See L and L. =head1 LICENSE You may distribute this code under the same terms as Perl itself. =cut +# vim:sts=2 sw=2: