From: Rafael Kitover Date: Sun, 21 Mar 2010 11:45:10 +0000 (-0400) Subject: better type info for Pg: sets sequence for serials, handles numerics without precision X-Git-Tag: 0.06000~41 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=df956aad09bce14245ebcbd13063ca2119b6c042 better type info for Pg: sets sequence for serials, handles numerics without precision --- diff --git a/Changes b/Changes index b6e72c7..d004d3b 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - better type info for Pg: sets sequence for serials, handles numerics + without precision - better _tables_list for MSSQL - pick up views in SQLite too - better rel inflection using Lingua::EN::Inflect::Phrase diff --git a/lib/DBIx/Class/Schema/Loader/DBI.pm b/lib/DBIx/Class/Schema/Loader/DBI.pm index a9d7161..0eef7aa 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI.pm @@ -284,10 +284,10 @@ sub _columns_info_for { my $sth = $dbh->column_info( undef, $self->db_schema, $table, '%' ); while ( my $info = $sth->fetchrow_hashref() ){ my $column_info = {}; - $column_info->{data_type} = $info->{TYPE_NAME}; - $column_info->{size} = $info->{COLUMN_SIZE}; + $column_info->{data_type} = $info->{TYPE_NAME}; + $column_info->{size} = $info->{COLUMN_SIZE} if defined $info->{COLUMN_SIZE}; $column_info->{is_nullable} = $info->{NULLABLE} ? 1 : 0; - $column_info->{default_value} = $info->{COLUMN_DEF}; + $column_info->{default_value} = $info->{COLUMN_DEF} if defined $info->{COLUMN_DEF}; my $col_name = $info->{COLUMN_NAME}; $col_name =~ s/^\"(.*)\"$/$1/; @@ -310,7 +310,7 @@ sub _columns_info_for { for my $i ( 0 .. $#columns ){ my $column_info = {}; $column_info->{data_type} = $sth->{TYPE}->[$i]; - $column_info->{size} = $sth->{PRECISION}->[$i]; + $column_info->{size} = $sth->{PRECISION}->[$i] if $sth->{PRECISION}->[$i]; $column_info->{is_nullable} = $sth->{NULLABLE}->[$i] ? 1 : 0; if ($column_info->{data_type} =~ m/^(.*?)\((.*?)\)$/) { diff --git a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm index 6d26474..cee52e2 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm @@ -186,28 +186,23 @@ EOF $result->{$col}{size} = $precision; } - elsif ($data_type =~ /^(?:numeric|decimal)\z/i) { - my $size = $result->{$col}{size}; + elsif ($data_type =~ /^(?:numeric|decimal)\z/i && (my $size = $result->{$col}{size})) { $size =~ s/\s*//g; my ($scale, $precision) = split /,/, $size; $result->{$col}{size} = [ $precision, $scale ]; } - } - - return $result; -} -sub _extra_column_info { - my ($self, $table, $column, $info, $dbi_info) = @_; - my %extra_info; - - if ($dbi_info->{COLUMN_DEF} && $dbi_info->{COLUMN_DEF} =~ /\bnextval\(/i) { - $extra_info{is_auto_increment} = 1; +# process SERIAL columns + if (ref($result->{$col}{default_value}) eq 'SCALAR' && ${ $result->{$col}{default_value} } =~ /\bnextval\(['"](\w+)/i) { + $result->{$col}{is_auto_increment} = 1; + $result->{$col}{sequence} = $1; + delete $result->{$col}{default_value}; + } } - return \%extra_info; + return $result; } =head1 SEE ALSO diff --git a/t/12pg_common.t b/t/12pg_common.t index fb31fb7..157decf 100644 --- a/t/12pg_common.t +++ b/t/12pg_common.t @@ -16,51 +16,51 @@ my $tester = dbixcsl_common_tests->new( user => $user, password => $password, data_types => { - 'bigint' => { size => undef, data_type => 'bigint' }, - 'int8' => { size => undef, data_type => 'bigint' }, - 'bigserial' => { size => undef, data_type => 'bigint', is_auto_increment => 1 }, - 'serial8' => { size => undef, data_type => 'bigint', is_auto_increment => 1 }, - 'bit' => { size => undef, data_type => 'bit' }, - 'boolean' => { size => undef, data_type => 'boolean' }, - 'bool' => { size => undef, data_type => 'boolean' }, - 'box' => { size => undef, data_type => 'box' }, - 'bytea' => { size => undef, data_type => 'bytea' }, - 'cidr' => { size => undef, data_type => 'cidr' }, - 'circle' => { size => undef, data_type => 'circle' }, - 'date' => { size => undef, data_type => 'date' }, - 'double precision' => { size => undef, data_type => 'double precision' }, - 'float8' => { size => undef, data_type => 'double precision' }, - 'inet' => { size => undef, data_type => 'inet' }, - 'integer' => { size => undef, data_type => 'integer' }, - 'int' => { size => undef, data_type => 'integer' }, - 'int4' => { size => undef, data_type => 'integer' }, - 'interval' => { size => undef, data_type => 'interval' }, + 'bigint' => { data_type => 'bigint' }, + 'int8' => { data_type => 'bigint' }, + 'bigserial' => { data_type => 'bigint', is_auto_increment => 1 }, + 'serial8' => { data_type => 'bigint', is_auto_increment => 1 }, + 'bit' => { data_type => 'bit' }, + 'boolean' => { data_type => 'boolean' }, + 'bool' => { data_type => 'boolean' }, + 'box' => { data_type => 'box' }, + 'bytea' => { data_type => 'bytea' }, + 'cidr' => { data_type => 'cidr' }, + 'circle' => { data_type => 'circle' }, + 'date' => { data_type => 'date' }, + 'double precision' => { data_type => 'double precision' }, + 'float8' => { data_type => 'double precision' }, + 'inet' => { data_type => 'inet' }, + 'integer' => { data_type => 'integer' }, + 'int' => { data_type => 'integer' }, + 'int4' => { data_type => 'integer' }, + 'interval' => { data_type => 'interval' }, 'interval(2)' => { size => 2, data_type => 'interval' }, - 'line' => { size => undef, data_type => 'line' }, - 'lseg' => { size => undef, data_type => 'lseg' }, - 'macaddr' => { size => undef, data_type => 'macaddr' }, - 'money' => { size => undef, data_type => 'money' }, - 'path' => { size => undef, data_type => 'path' }, - 'point' => { size => undef, data_type => 'point' }, - 'polygon' => { size => undef, data_type => 'polygon' }, - 'real' => { size => undef, data_type => 'real' }, - 'float4' => { size => undef, data_type => 'real' }, - 'smallint' => { size => undef, data_type => 'smallint' }, - 'int2' => { size => undef, data_type => 'smallint' }, - 'serial' => { size => undef, data_type => 'integer', is_auto_increment => 1 }, - 'serial4' => { size => undef, data_type => 'integer', is_auto_increment => 1 }, - 'text' => { size => undef, data_type => 'text' }, - 'time' => { size => undef, data_type => 'time without time zone' }, + 'line' => { data_type => 'line' }, + 'lseg' => { data_type => 'lseg' }, + 'macaddr' => { data_type => 'macaddr' }, + 'money' => { data_type => 'money' }, + 'path' => { data_type => 'path' }, + 'point' => { data_type => 'point' }, + 'polygon' => { data_type => 'polygon' }, + 'real' => { data_type => 'real' }, + 'float4' => { data_type => 'real' }, + 'smallint' => { data_type => 'smallint' }, + 'int2' => { data_type => 'smallint' }, + 'serial' => { data_type => 'integer', is_auto_increment => 1 }, + 'serial4' => { data_type => 'integer', is_auto_increment => 1 }, + 'text' => { data_type => 'text' }, + 'time' => { data_type => 'time without time zone' }, 'time(2)' => { size => 2, data_type => 'time without time zone' }, - 'time without time zone' => { size => undef, data_type => 'time without time zone' }, + 'time without time zone' => { data_type => 'time without time zone' }, 'time(2) without time zone' => { size => 2, data_type => 'time without time zone' }, - 'time with time zone' => { size => undef, data_type => 'time with time zone' }, + 'time with time zone' => { data_type => 'time with time zone' }, 'time(2) with time zone' => { size => 2, data_type => 'time with time zone' }, - 'timestamp' => { size => undef, data_type => 'timestamp without time zone' }, + 'timestamp' => { data_type => 'timestamp without time zone' }, 'timestamp(2)' => { size => 2, data_type => 'timestamp without time zone' }, - 'timestamp without time zone' => { size => undef, data_type => 'timestamp without time zone' }, + 'timestamp without time zone' => { data_type => 'timestamp without time zone' }, 'timestamp(2) without time zone' => { size => 2, data_type => 'timestamp without time zone' }, - 'timestamp with time zone' => { size => undef, data_type => 'timestamp with time zone' }, + 'timestamp with time zone' => { data_type => 'timestamp with time zone' }, 'timestamp(2) with time zone' => { size => 2, data_type => 'timestamp with time zone' }, 'bit varying(2)' => { size => 2, data_type => 'bit varying' }, 'varbit(2)' => { size => 2, data_type => 'bit varying' }, @@ -70,9 +70,11 @@ my $tester = dbixcsl_common_tests->new( 'char(2)' => { size => 2, data_type => 'character' }, 'numeric(6, 3)' => { size => [6,3], data_type => 'numeric' }, 'decimal(6, 3)' => { size => [6,3], data_type => 'numeric' }, - 'float(24)' => { size => undef, data_type => 'real' }, - 'float(53)' => { size => undef, data_type => 'double precision' }, - 'float' => { size => undef, data_type => 'double precision' }, + 'numeric' => { data_type => 'numeric' }, + 'decimal' => { data_type => 'numeric' }, + 'float(24)' => { data_type => 'real' }, + 'float(53)' => { data_type => 'double precision' }, + 'float' => { data_type => 'double precision' }, }, extra => { create => [ diff --git a/t/lib/dbixcsl_common_tests.pm b/t/lib/dbixcsl_common_tests.pm index 8dff6ec..dd97705 100644 --- a/t/lib/dbixcsl_common_tests.pm +++ b/t/lib/dbixcsl_common_tests.pm @@ -871,17 +871,25 @@ sub test_schema { my $rsrc = $conn->resultset($data_type_tests->{table_moniker})->result_source; while (my ($col_name, $expected_info) = each %$columns) { - while (my ($info_key, $info_val) = each %$expected_info) { - my $text_info_val = do { - my $dd = Dumper; - $dd->Indent(0); - $dd->Values([$info_val]); - $dd->Dump; - }; - - is_deeply $rsrc->column_info($col_name)->{$info_key}, $info_val, - "column of type $col_name has $info_key => $text_info_val"; - } + my %info = %{ $rsrc->column_info($col_name) }; + delete @info{qw/is_nullable timezone locale sequence/}; + + my $text_col_def = do { + my $dd = Dumper; + $dd->Indent(0); + $dd->Values([\%info]); + $dd->Dump; + }; + + my $text_expected_info = do { + my $dd = Dumper; + $dd->Indent(0); + $dd->Values([$expected_info]); + $dd->Dump; + }; + + is_deeply \%info, $expected_info, + "test column $col_name has definition: $text_col_def expecting: $text_expected_info"; } } @@ -1559,7 +1567,7 @@ sub setup_data_type_tests { $cols->{$col_name} = $expected_info; - $test_count += scalar keys %$expected_info; + $test_count++; } $ddl =~ s/,\n\z/\n)/; @@ -1579,3 +1587,4 @@ sub DESTROY { } 1; +# vim:et sts=4 sw=4 tw=0: