From: Rafael Kitover Date: Sat, 2 Jan 2010 15:35:39 +0000 (+0000) Subject: better "size" column_info for postgres, still unlikely to be perfect X-Git-Tag: 0.04999_13~3 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=baff904e0c46bfb7f53cdad710bf785c0d64c435;p=dbsrgits%2FDBIx-Class-Schema-Loader.git better "size" column_info for postgres, still unlikely to be perfect --- diff --git a/Changes b/Changes index 596be1d..5eb9d70 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,9 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - exclude 'size' column_info for postgres when unnecessary, correct + datetime_precision in 'size' for time|timestamp|interval types - 'naming' attribute and backward compatibility with 0.04006 + (in progress) - added relationship_attrs option for setting attributes in generated relationships - added overwrite_modifications option that ignores md5sums on diff --git a/Makefile.PL b/Makefile.PL index 9537779..ff027be 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -11,6 +11,7 @@ test_requires 'File::Copy'; test_requires 'File::Temp' => '0.16'; test_requires 'File::Path' => '2.07'; test_requires 'IPC::Open3' => 0; +test_requires 'List::MoreUtils' => 0; requires 'File::Spec' => 0; requires 'Scalar::Util' => 0; diff --git a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm index b4876ee..d198a15 100644 --- a/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm +++ b/lib/DBIx/Class/Schema/Loader/DBI/Pg.pm @@ -122,6 +122,44 @@ sub _column_comment { $column_number ); } +# Make sure data_type's that don't need it don't have a 'size' column_info, and +# set the correct precision for datetime types. +sub _columns_info_for { + my $self = shift; + my ($table) = @_; + + my $result = $self->next::method(@_); + + foreach my $col (keys %$result) { + my $data_type = $result->{$col}{data_type}; + + # these types are fixed size + if ($data_type =~ +/^(?:bigint|int8|bigserial|serial8|bit|boolean|bool|box|bytea|cidr|circle|date|double precision|float8|inet|integer|int|int4|line|lseg|macaddr|money|path|point|polygon|real|float4|smallint|int2|serial|serial4|text)\z/i) { + delete $result->{$col}{size}; + } + + # for datetime types, check if it has a precision or not + if ($data_type =~ /^(?:interval|time|timestamp)\b/) { + my ($precision) = $self->schema->storage->dbh + ->selectrow_array(<{$col}{size}; + } + else { + $result->{$col}{size} = $precision; + } + } + } + + return $result; +} + sub _extra_column_info { my ($self, $info) = @_; my %extra_info; diff --git a/t/12pg_common.t b/t/12pg_common.t index dd4412a..bf1775c 100644 --- a/t/12pg_common.t +++ b/t/12pg_common.t @@ -2,6 +2,7 @@ use strict; use lib qw(t/lib); use dbixcsl_common_tests; use Test::More; +use List::MoreUtils 'apply'; my $dsn = $ENV{DBICTEST_PG_DSN} || ''; my $user = $ENV{DBICTEST_PG_USER} || ''; @@ -27,9 +28,63 @@ my $tester = dbixcsl_common_tests->new( q{ COMMENT ON COLUMN pg_loader_test1.value IS 'The Column' }, + # Test to make sure data_types that don't need a size => don't + # have one. + q{ + CREATE TABLE pg_loader_test2 ( + id SERIAL NOT NULL PRIMARY KEY, + a_bigint BIGINT, + an_int8 INT8, + a_bigserial BIGSERIAL, + a_serial8 SERIAL8, + a_bit BIT, + a_bit_varying_with_precision BIT VARYING(8), + a_boolean BOOLEAN, + a_bool BOOL, + a_box BOX, + a_bytea BYTEA, + a_cidr CIDR, + a_circle CIRCLE, + a_date DATE, + a_double_precision DOUBLE PRECISION, + a_float8 FLOAT8, + an_inet INET, + an_integer INTEGER, + an_int INT, + an_int4 INT4, + an_interval INTERVAL, + an_interval_with_precision INTERVAL(2), + a_line LINE, + an_lseg LSEG, + a_macaddr MACADDR, + a_money MONEY, + a_path PATH, + a_point POINT, + a_polygon POLYGON, + a_real REAL, + a_float4 FLOAT4, + a_smallint SMALLINT, + an_int2 INT2, + a_serial SERIAL, + a_serial4 SERIAL4, + a_text TEXT, + a_time TIME, + a_time_with_precision TIME(2), + a_time_without_time_zone TIME WITHOUT TIME ZONE, + a_time_without_time_zone_with_precision TIME(2) WITHOUT TIME ZONE, + a_time_with_time_zone TIME WITH TIME ZONE, + a_time_with_time_zone_with_precision TIME(2) WITH TIME ZONE, + a_timestamp TIMESTAMP, + a_timestamp_with_precision TIMESTAMP(2), + a_timestamp_without_time_zone TIMESTAMP WITHOUT TIME ZONE, + a_timestamp_without_time_zone_with_precision TIMESTAMP(2) WITHOUT TIME ZONE, + a_timestamp_with_time_zone TIMESTAMP WITH TIME ZONE, + a_timestamp_with_time_zone_with_precision TIMESTAMP(2) WITH TIME ZONE + ) + }, ], - drop => [ qw/ pg_loader_test1 / ], - count => 2, + drop => [ qw/ pg_loader_test1 pg_loader_test2 / ], + count => 49, run => sub { my ($schema, $monikers, $classes) = @_; @@ -46,6 +101,33 @@ my $tester = dbixcsl_common_tests->new( like $code, qr/^=head2 value\n\n(.+:.+\n)+\nThe Column\n\n/m, 'column comment and attrs'; + + my $rsrc = $schema->resultset('PgLoaderTest2')->result_source; + my @type_columns = grep !/^id\z/, $rsrc->columns; + my @without_precision = grep !/_with_precision\z/, @type_columns; + my @with_precision = grep /_with_precision\z/, @type_columns; + my %with_precision; + @with_precision{ + apply { s/_with_precision\z// } @with_precision + } = (); + + for my $col (@without_precision) { + my ($data_type) = $col =~ /^an?_(.*)/; + ($data_type = uc $data_type) =~ s/_/ /g; + + ok((not exists $rsrc->column_info($col)->{size}), + "$data_type " . + (exists $with_precision{$col} ? 'without precision ' : '') . + "has no 'size' column_info"); + } + + for my $col (@with_precision) { + my ($data_type) = $col =~ /^an?_(.*)_with_precision\z/; + ($data_type = uc $data_type) =~ s/_/ /g; + + ok($rsrc->column_info($col)->{size}, + "$data_type with precision has a 'size' column_info"); + } }, }, );