From: Rafael Kitover Date: Sat, 10 Apr 2010 01:18:30 +0000 (-0400) Subject: fix type info for MSSQL X-Git-Tag: 0.06001~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=81ade4d9da9b861849c51894b7e8f380e74192d4;p=dbsrgits%2FDBIx-Class-Schema-Loader.git fix type info for MSSQL --- diff --git a/Changes b/Changes index da58fa4..ba34f30 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - fix type info for MSSQL - fix MSSQL collation detection on freetds tds version 8.0 0.06000 2010-04-06 01:12:25 diff --git a/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm b/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm index 7a019d9..bdd3212 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm @@ -37,9 +37,9 @@ We attempt to detect the database collation at startup, and set the column lowercasing behavior accordingly, as lower-cased column names do not work on case-sensitive databases. -To manually set or unset case-sensitive mode, put: +To manually control case-sensitive mode, put: - case_sensitive_collation => 1 + case_sensitive_collation => 1|0 in your Loader options. @@ -186,6 +186,7 @@ sub _columns_info_for { while (my ($col, $info) = each %$result) { my $dbh = $self->schema->storage->dbh; +# find identities my $sth = $dbh->prepare(qq{ SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS @@ -198,6 +199,78 @@ AND lower(table_name) = @{[ $dbh->quote(lc $table) ]} AND lower(column_name) = @ delete $info->{size}; } +# fix types + if ($info->{data_type} eq 'int') { + $info->{data_type} = 'integer'; + } + elsif ($info->{data_type} eq 'timestamp') { + $info->{inflate_datetime} = 0; + } + elsif ($info->{data_type} =~ /^(?:numeric|decimal)\z/) { + if (ref($info->{size}) && $info->{size}[0] == 18 && $info->{size}[1] == 0) { + delete $info->{size}; + } + } + elsif ($info->{data_type} eq 'real') { + $info->{data_type} = 'float'; + $info->{size} = 24; + } + elsif ($info->{data_type} eq 'float') { + $info->{data_type} = 'double precision'; + } + elsif ($info->{data_type} =~ /^(?:small)?datetime\z/) { + # fixup for DBD::Sybase + if ($info->{default_value} && $info->{default_value} eq '3') { + delete $info->{default_value}; + } + } + elsif ($info->{data_type} eq 'datetimeoffset') { + $info->{size} = { + 26 => 0, + 28 => 1, + 29 => 2, + 30 => 3, + 31 => 4, + 32 => 5, + 33 => 6, + 34 => 7, + }->{$info->{size}}; + + delete $info->{size} if $info->{size} == 7; + } + elsif ($info->{data_type} eq 'datetime2') { + $info->{size} = { + 19 => 0, + 21 => 1, + 22 => 2, + 23 => 3, + 24 => 4, + 25 => 5, + 26 => 6, + 27 => 7, + }->{$info->{size}}; + + delete $info->{size} if $info->{size} == 7; + } + elsif ($info->{data_type} eq 'time') { + $info->{size} = { + 8 => 0, + 10 => 1, + 11 => 2, + 12 => 3, + 13 => 4, + 14 => 5, + 15 => 6, + 16 => 7, + }->{$info->{size}}; + + delete $info->{size} if $info->{size} == 7; + } + + if ($info->{data_type} !~ /^(?:n?char|n?varchar|binary|varbinary|numeric|decimal|float|datetime(?:2|offset)|time)\z/) { + delete $info->{size}; + } + # get default $sth = $dbh->prepare(qq{ SELECT column_default diff --git a/t/16mssql_common.t b/t/16mssql_common.t index 22369a0..0791bb4 100644 --- a/t/16mssql_common.t +++ b/t/16mssql_common.t @@ -38,7 +38,93 @@ my $tester = dbixcsl_common_tests->new( } : ()), ], data_types => { - 'int identity' => { data_type => 'int', is_auto_increment => 1 }, + # http://msdn.microsoft.com/en-us/library/ms187752.aspx + + # numeric types + 'int identity' => { data_type => 'integer', is_auto_increment => 1 }, + bigint => { data_type => 'bigint' }, + int => { data_type => 'integer' }, + integer => { data_type => 'integer' }, + smallint => { data_type => 'smallint' }, + tinyint => { data_type => 'tinyint' }, + money => { data_type => 'money' }, + smallmoney => { data_type => 'smallmoney' }, + bit => { data_type => 'bit' }, + real => { data_type => 'float', size => 24 }, + 'float(14)' => { data_type => 'float', size => 24 }, + 'float(24)' => { data_type => 'float', size => 24 }, + 'float(25)' => { data_type => 'double precision' }, + 'float(53)' => { data_type => 'double precision' }, + float => { data_type => 'double precision' }, + 'double precision' + => { data_type => 'double precision' }, + 'numeric(6,3)' => { data_type => 'numeric', size => [6,3] }, + 'decimal(6,3)' => { data_type => 'decimal', size => [6,3] }, + 'dec(6,3)' => { data_type => 'decimal', size => [6,3] }, + numeric => { data_type => 'numeric' }, + decimal => { data_type => 'decimal' }, + dec => { data_type => 'decimal' }, + + # datetime types + date => { data_type => 'date' }, + datetime => { data_type => 'datetime' }, + 'datetime DEFAULT getdate()' + => { data_type => 'datetime', default_value => \'getdate()' }, + smalldatetime => { data_type => 'smalldatetime' }, + time => { data_type => 'time' }, + 'time(0)'=> { data_type => 'time', size => 0 }, + 'time(1)'=> { data_type => 'time', size => 1 }, + 'time(2)'=> { data_type => 'time', size => 2 }, + 'time(3)'=> { data_type => 'time', size => 3 }, + 'time(4)'=> { data_type => 'time', size => 4 }, + 'time(5)'=> { data_type => 'time', size => 5 }, + 'time(6)'=> { data_type => 'time', size => 6 }, + 'time(7)'=> { data_type => 'time' }, + datetimeoffset => { data_type => 'datetimeoffset' }, + 'datetimeoffset(0)' => { data_type => 'datetimeoffset', size => 0 }, + 'datetimeoffset(1)' => { data_type => 'datetimeoffset', size => 1 }, + 'datetimeoffset(2)' => { data_type => 'datetimeoffset', size => 2 }, + 'datetimeoffset(3)' => { data_type => 'datetimeoffset', size => 3 }, + 'datetimeoffset(4)' => { data_type => 'datetimeoffset', size => 4 }, + 'datetimeoffset(5)' => { data_type => 'datetimeoffset', size => 5 }, + 'datetimeoffset(6)' => { data_type => 'datetimeoffset', size => 6 }, + 'datetimeoffset(7)' => { data_type => 'datetimeoffset' }, + datetime2 => { data_type => 'datetime2' }, + 'datetime2(0)' => { data_type => 'datetime2', size => 0 }, + 'datetime2(1)' => { data_type => 'datetime2', size => 1 }, + 'datetime2(2)' => { data_type => 'datetime2', size => 2 }, + 'datetime2(3)' => { data_type => 'datetime2', size => 3 }, + 'datetime2(4)' => { data_type => 'datetime2', size => 4 }, + 'datetime2(5)' => { data_type => 'datetime2', size => 5 }, + 'datetime2(6)' => { data_type => 'datetime2', size => 6 }, + 'datetime2(7)' => { data_type => 'datetime2' }, + + # string types + char => { data_type => 'char', size => 1 }, + 'char(2)' => { data_type => 'char', size => 2 }, + 'varchar(2)' => { data_type => 'varchar', size => 2 }, + nchar => { data_type => 'nchar', size => 1 }, + 'nchar(2)' => { data_type => 'nchar', size => 2 }, + 'nvarchar(2)' => { data_type => 'nvarchar', size => 2 }, + + # binary types + 'binary(2)' => { data_type => 'binary', size => 2 }, + 'varbinary(2)' => { data_type => 'varbinary', size => 2 }, + + # blob types + 'varchar(max)' => { data_type => 'text' }, + text => { data_type => 'text' }, + 'nvarchar(max)' => { data_type => 'ntext' }, + ntext => { data_type => 'ntext' }, + 'varbinary(max)' => { data_type => 'image' }, + image => { data_type => 'image' }, + + # other types + timestamp => { data_type => 'timestamp', inflate_datetime => 0 }, + uniqueidentifier => { data_type => 'uniqueidentifier' }, + hierarchyid => { data_type => 'hierarchyid' }, + sql_variant => { data_type => 'sql_variant' }, + xml => { data_type => 'xml' }, }, extra => { create => [