From: Peter Rabbitson Date: Wed, 10 Nov 2010 22:57:56 +0000 (+0000) Subject: Support a custom_type_name hint for Pg enum creation X-Git-Tag: v0.11008~34 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=79f55d7e4a831344ac22f5ecd613f472f07f3680;p=dbsrgits%2FSQL-Translator.git Support a custom_type_name hint for Pg enum creation --- diff --git a/AUTHORS b/AUTHORS index 242b3ab..5ca471f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,6 +28,7 @@ The following people have contributed to the SQLFairy project: - Ross Smith II - Ryan D Johnson - Sam Angiuoli +- Stephen Bennett - Stephen Clouse - Wallace Reis - Ying Zhang diff --git a/Changes b/Changes index b30bfb3..0081690 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,7 @@ * Add explicit Scalar::Util to the deplist for really old perls * Add support for PostGIS Geometry and Geography data types in the Pg producer * Some minor fixes to squash warnings on new perls +* Support a custom_type_name hint when creating enum types in PostgreSQL # ---------------------------------------------------------- # 0.11006 2010-06-03 diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index f8f5438..485fae4 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -195,6 +195,7 @@ sub produce { push @output, header_comment unless ($no_comments); my (@table_defs, @fks); + my %type_defs; for my $table ( $schema->get_tables ) { my ($table_def, $fks) = create_table($table, { @@ -203,6 +204,7 @@ sub produce { no_comments => $no_comments, postgres_version => $postgres_version, add_drop_table => $add_drop_table, + type_defs => \%type_defs, }); push @table_defs, $table_def; @@ -218,6 +220,7 @@ sub produce { }); } + push @output, map { "$_;\n\n" } values %type_defs; push @output, map { "$_;\n\n" } @table_defs; if ( @fks ) { push @output, "--\n-- Foreign Key Definitions\n--\n\n" unless $no_comments; @@ -335,6 +338,7 @@ sub create_table my $no_comments = $options->{no_comments} || 0; my $add_drop_table = $options->{add_drop_table} || 0; my $postgres_version = $options->{postgres_version} || 0; + my $type_defs = $options->{type_defs} || {}; my $table_name = $table->name or next; my ( $fql_tbl_name ) = ( $table_name =~ s/\W(.*)$// ) ? $1 : q{}; @@ -344,7 +348,7 @@ sub create_table $table->name($table_name_ur); # print STDERR "$table_name table_name\n"; - my ( @comments, @field_defs, @sequence_defs, @constraint_defs, @type_defs, @type_drops, @fks ); + my ( @comments, @field_defs, @sequence_defs, @constraint_defs, @fks ); push @comments, "--\n-- Table: $table_name_ur\n--\n" unless $no_comments; @@ -364,8 +368,7 @@ sub create_table quote_field_names => $qf, table_name => $table_name_ur, postgres_version => $postgres_version, - type_defs => \@type_defs, - type_drops => \@type_drops, + type_defs => $type_defs, constraint_defs => \@constraint_defs,}); } @@ -412,14 +415,10 @@ sub create_table if ($add_drop_table) { if ($postgres_version >= 8.002) { $create_statement .= qq[DROP TABLE IF EXISTS $qt$table_name_ur$qt CASCADE;\n]; - $create_statement .= join (";\n", @type_drops) . ";\n" - if $postgres_version >= 8.003 && scalar @type_drops; } else { $create_statement .= qq[DROP TABLE $qt$table_name_ur$qt CASCADE;\n]; } } - $create_statement .= join(";\n", @type_defs) . ";\n" - if $postgres_version >= 8.003 && scalar @type_defs; $create_statement .= qq[CREATE ${temporary}TABLE $qt$table_name_ur$qt (\n]. join( ",\n", map { " $_" } @field_defs, @constraint_defs ). "\n)" @@ -488,8 +487,7 @@ sub create_view { my $table_name = $field->table->name; my $constraint_defs = $options->{constraint_defs} || []; my $postgres_version = $options->{postgres_version} || 0; - my $type_defs = $options->{type_defs} || []; - my $type_drops = $options->{type_drops} || []; + my $type_defs = $options->{type_defs} || {}; $field_name_scope{$table_name} ||= {}; my $field_name = $field->name; @@ -512,10 +510,15 @@ sub create_view { my $commalist = join( ', ', map { qq['$_'] } @$list ); if ($postgres_version >= 8.003 && $field->data_type eq 'enum') { - my $type_name = $field->table->name . '_' . $field->name . '_type'; + my $type_name = $extra{'custom_type_name'} || $field->table->name . '_' . $field->name . '_type'; $field_def .= ' '. $type_name; - push @$type_defs, "CREATE TYPE $type_name AS ENUM ($commalist)"; - push @$type_drops, "DROP TYPE IF EXISTS $type_name"; + my $new_type_def = "DROP TYPE IF EXISTS $type_name;\n" . + "CREATE TYPE $type_name AS ENUM ($commalist)"; + if (! exists $type_defs->{$type_name} ) { + $type_defs->{$type_name} = $new_type_def; + } elsif ( $type_defs->{$type_name} ne $new_type_def ) { + die "Attempted to redefine type name '$type_name' as a different type.\n"; + } } else { $field_def .= ' '. convert_datatype($field); } diff --git a/t/47postgres-producer.t b/t/47postgres-producer.t index ec31cd6..01969d7 100644 --- a/t/47postgres-producer.t +++ b/t/47postgres-producer.t @@ -14,7 +14,7 @@ use FindBin qw/$Bin/; #============================================================================= BEGIN { - maybe_plan(25, + maybe_plan(26, 'SQL::Translator::Producer::PostgreSQL', 'Test::Differences', ) @@ -269,6 +269,20 @@ my $field12_sql = SQL::Translator::Producer::PostgreSQL::create_field($field12,{ is($field12_sql, 'time_field timestamp NOT NULL', 'time with precision'); +my $field13 = SQL::Translator::Schema::Field->new( name => 'enum_field_with_type_name', + table => $table, + data_type => 'enum', + extra => { list => [ 'Foo', 'Bar' ], + custom_type_name => 'real_enum_type' }, + is_auto_increment => 0, + is_nullable => 0, + is_foreign_key => 0, + is_unique => 0 ); + +my $field13_sql = SQL::Translator::Producer::PostgreSQL::create_field($field13,{ postgres_version => 8.3 }); + +is($field13_sql, 'enum_field_with_type_name real_enum_type NOT NULL', 'Create real enum field works'); + { # let's test default values! -- rjbs, 2008-09-30