From: Rafael Kitover Date: Fri, 10 Jun 2011 04:55:58 +0000 (-0400) Subject: fix enum/set detection for MySQL (RT#68717) X-Git-Tag: 0.07011~78 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=698c11d8a10d3b45a621e37674b6d83a7cccb4df fix enum/set detection for MySQL (RT#68717) --- diff --git a/Changes b/Changes index baf4363..84aeffe 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - fix enum/set detection for MySQL (RT#68717) - fix is_nullable detection on MS Access - remove '$table has no primary key' warning - added uniq_to_primary option to promote unique keys to primary keys diff --git a/lib/DBIx/Class/Schema/Loader/DBI.pm b/lib/DBIx/Class/Schema/Loader/DBI.pm index 0f53430..964e923 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI.pm @@ -381,7 +381,7 @@ sub _columns_info_for { $column_info->{size} = $2; } - my $extra_info = $self->_extra_column_info($table, $columns[$i], $column_info) || {}; + my $extra_info = $self->_extra_column_info($table, $columns[$i], $column_info, $sth) || {}; $column_info = { %$column_info, %$extra_info }; $result{ $self->_lc($columns[$i]) } = $column_info; diff --git a/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm b/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm index 4712fdf..d037e98 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/mysql.pm @@ -133,14 +133,15 @@ sub _columns_info_for { my $dbh = $self->schema->storage->dbh; while (my ($col, $info) = each %$result) { - delete $info->{size} if $info->{data_type} !~ /^(?: (?:var)?(?:char(?:acter)?|binary) | bit | year)\z/ix; - if ($info->{data_type} eq 'int') { $info->{data_type} = 'integer'; } elsif ($info->{data_type} eq 'double') { $info->{data_type} = 'double precision'; } + my $data_type = $info->{data_type}; + + delete $info->{size} if $data_type !~ /^(?: (?:var)?(?:char(?:acter)?|binary) | bit | year)\z/ix; # information_schema is available in 5.0+ my ($precision, $scale, $column_type, $default) = eval { $dbh->selectrow_array(<<'EOF', {}, $table, $col) }; @@ -148,14 +149,14 @@ SELECT numeric_precision, numeric_scale, column_type, column_default FROM information_schema.columns WHERE table_name = ? AND column_name = ? EOF - my $has_information_schema = not defined $@; + my $has_information_schema = not $@; $column_type = '' if not defined $column_type; - if ($info->{data_type} eq 'bit' && (not exists $info->{size})) { + if ($data_type eq 'bit' && (not exists $info->{size})) { $info->{size} = $precision if defined $precision; } - elsif ($info->{data_type} =~ /^(?:float|double precision|decimal)\z/i) { + elsif ($data_type =~ /^(?:float|double precision|decimal)\z/i) { if (defined $precision && defined $scale) { if ($precision == 10 && $scale == 0) { delete $info->{size}; @@ -165,7 +166,7 @@ EOF } } } - elsif ($info->{data_type} eq 'year') { + elsif ($data_type eq 'year') { if ($column_type =~ /\(2\)/) { $info->{size} = 2; } @@ -173,11 +174,20 @@ EOF delete $info->{size}; } } - elsif ($info->{data_type} =~ /^(?:date(?:time)?|timestamp)\z/) { + elsif ($data_type =~ /^(?:date(?:time)?|timestamp)\z/) { if (not (defined $self->datetime_undef_if_invalid && $self->datetime_undef_if_invalid == 0)) { $info->{datetime_undef_if_invalid} = 1; } } + elsif ($data_type =~ /^(?:enum|set)\z/ && $has_information_schema + && $column_type =~ /^(?:enum|set)\(/) { + + delete $info->{extra}{list}; + + while ($column_type =~ /'([^']+)',?/g) { + push @{ $info->{extra}{list} }, $1; + } + } # Sometimes apparently there's a bug where default_value gets set to '' # for things that don't actually have or support that default (like ints.) @@ -188,7 +198,7 @@ EOF } } else { # just check if it's a char/text type, otherwise remove - delete $info->{default_value} unless $info->{data_type} =~ /char|text/i; + delete $info->{default_value} unless $data_type =~ /char|text/i; } } } diff --git a/t/10_02mysql_common.t b/t/10_02mysql_common.t index 9f1a366..8f674a7 100644 --- a/t/10_02mysql_common.t +++ b/t/10_02mysql_common.t @@ -124,6 +124,13 @@ my $tester = dbixcsl_common_tests->new( => { data_type => 'enum', extra => { list => [qw/foo bar baz/] } }, "set('foo','bar','baz')" => { data_type => 'set', extra => { list => [qw/foo bar baz/] } }, + + # RT#68717 + "enum('11,10 (<500)/0 DUN','4,90 (<120)/0 EUR') NOT NULL default '11,10 (<500)/0 DUN'" + => { data_type => 'enum', extra => { list => ['11,10 (<500)/0 DUN', '4,90 (<120)/0 EUR'] }, default_value => '11,10 (<500)/0 DUN' }, + "set('11_10 (<500)/0 DUN','4_90 (<120)/0 EUR') NOT NULL default '11_10 (<500)/0 DUN'" + => { data_type => 'set', extra => { list => ['11_10 (<500)/0 DUN', '4_90 (<120)/0 EUR'] }, default_value => '11_10 (<500)/0 DUN' }, + }, extra => { create => [