Skip to content

Commit

Permalink
fix type info for MSSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
rkitover committed Apr 10, 2010
1 parent 103e90d commit 81ade4d
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 3 deletions.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -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
Expand Down
77 changes: 75 additions & 2 deletions lib/DBIx/Class/Schema/Loader/DBI/MSSQL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
88 changes: 87 additions & 1 deletion t/16mssql_common.t
Original file line number Diff line number Diff line change
Expand Up @@ -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 => [
Expand Down

0 comments on commit 81ade4d

Please sign in to comment.