From: Ben Faga Date: Fri, 10 Nov 2006 21:21:52 +0000 (+0000) Subject: Applied patch sent in by Daniel Westermann-Clark on Oct 11 2006. X-Git-Tag: v0.11008~393 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b08b5416f45bfbe381637ee3091202524c78ecab;p=dbsrgits%2FSQL-Translator.git Applied patch sent in by Daniel Westermann-Clark on Oct 11 2006. His message: Attached is a patch to modify the Producer::DB2 to output foreign key definitions as ALTER TABLE statements after the CREATE TABLE statements (to avoid dependency issues). The patch also removes single quotes for numeric default values in Producer::DB2, which caused problems here on my v7 instance. To add tests for the foreign key output, I added a table to the schema.xml file. This required updating some of the other tests, and exposed a few other minor issues in the test suite relating to foreign key output. --- diff --git a/lib/SQL/Translator/Producer/DB2.pm b/lib/SQL/Translator/Producer/DB2.pm index 2f0fb32..6605f6b 100644 --- a/lib/SQL/Translator/Producer/DB2.pm +++ b/lib/SQL/Translator/Producer/DB2.pm @@ -1,7 +1,7 @@ package SQL::Translator::Producer::DB2; # ------------------------------------------------------------------- -# $Id: DB2.pm,v 1.4 2006-08-26 11:30:31 schiffbruechige Exp $ +# $Id: DB2.pm,v 1.5 2006-11-10 21:21:51 mwz444 Exp $ # ------------------------------------------------------------------- # Copyright (C) 2002-4 SQLFairy Authors # @@ -39,7 +39,7 @@ Creates an SQL DDL suitable for DB2. use warnings; use strict; use vars qw[ $VERSION $DEBUG $WARN ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/; $DEBUG = 0 unless defined $DEBUG; use SQL::Translator::Schema::Constants; @@ -205,12 +205,14 @@ sub produce my $indent = ' '; $output .= header_comment unless($no_comments); - my (@table_defs, @index_defs); + my (@table_defs, @fks, @index_defs); foreach my $table ($schema->get_tables) { push @table_defs, 'DROP TABLE ' . $table->name . ";" if $add_drop_table; - push @table_defs, create_table($table, { + my ($table_def, $fks) = create_table($table, { no_comments => $no_comments}); + push @table_defs, $table_def; + push @fks, @$fks; foreach my $index ($table->get_indices) { @@ -229,8 +231,8 @@ sub produce push @trigger_defs, create_trigger($trigger); } - return wantarray ? (@table_defs, @index_defs, @view_defs, @trigger_defs) : - $output . join("\n\n", @table_defs, @index_defs, @view_defs, @trigger_defs) . "\n"; + return wantarray ? (@table_defs, @fks, @index_defs, @view_defs, @trigger_defs) : + $output . join("\n\n", @table_defs, @fks, @index_defs, @view_defs, @trigger_defs) . "\n"; } { my %objnames; @@ -275,22 +277,21 @@ sub create_table { push @field_defs, create_field($field); } - my @con_defs; + my (@con_defs, @fks); foreach my $con ($table->get_constraints) { - push @con_defs, create_constraint($con); + my ($cdefs, $fks) = create_constraint($con); + push @con_defs, @$cdefs; + push @fks, @$fks; } - my $pkey = join(", ", $table->primary_key()->fields); my $tablespace = $table->extra()->{'TABLESPACE'} || ''; my $table_def = "CREATE TABLE $table_name (\n"; - $table_def .= join (",\n", @field_defs); - $table_def .= join (",\n", @con_defs); - $table_def .= ",\n PRIMARY KEY($pkey)"; + $table_def .= join (",\n", map { " $_" } @field_defs, @con_defs); $table_def .= "\n)"; $table_def .= $tablespace ? "IN $tablespace;" : ';'; - return $table_def; + return $table_def, \@fks; } sub create_field @@ -307,14 +308,16 @@ sub create_field my $field_def = "$field_name $data_type"; $field_def .= $field->is_auto_increment ? ' GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1)' : ''; - $field_def .= $data_type =~ /CHAR/i ? "(${size})" : ''; + $field_def .= $data_type =~ /(CHAR|CLOB)/i ? "(${size})" : ''; $field_def .= !$field->is_nullable ? ' NOT NULL':''; # $field_def .= $field->is_primary_key ? ' PRIMARY KEY':''; $field_def .= !defined $field->default_value ? '' : $field->default_value =~ /current( |_)timestamp/i || $field->default_value =~ /\Qnow()\E/i ? - 'DEFAULT CURRENT TIMESTAMP' : defined $field->default_value ? - (" DEFAULT '" . $field->default_value . "'") : ''; + ' DEFAULT CURRENT TIMESTAMP' : defined $field->default_value ? + (" DEFAULT " . ($data_type =~ /(INT|DOUBLE)/i ? + $field->default_value : "'" . $field->default_value . "'") + ) : ''; return $field_def; } @@ -336,29 +339,36 @@ sub create_constraint { my ($constraint) = @_; - return '' if($constraint->type =~ /^PRIMARY(_|\s)KEY$/i); + my (@con_defs, @fks); my $ctype = $constraint->type =~ /^PRIMARY(_|\s)KEY$/i ? 'PRIMARY KEY' : $constraint->type =~ /^UNIQUE$/i ? 'UNIQUE' : $constraint->type =~ /^CHECK_C$/i ? 'CHECK' : - $constraint->type =~ /^FOREIGN_KEY$/i ? 'FOREIGN KEY' : ''; + $constraint->type =~ /^FOREIGN(_|\s)KEY$/i ? 'FOREIGN KEY' : ''; my $expr = $constraint->type =~ /^CHECK_C$/i ? $constraint->expression : ''; - my $ref = $constraint->type =~ /^FOREIGN_KEY$/i ? ('REFERENCES ' . $constraint->reference_table . '(' . join(', ', $constraint->reference_fields) . ')') : ''; + my $ref = $constraint->type =~ /^FOREIGN(_|\s)KEY$/i ? ('REFERENCES ' . $constraint->reference_table . '(' . join(', ', $constraint->reference_fields) . ')') : ''; my $update = $constraint->on_update ? $constraint->on_update : ''; my $delete = $constraint->on_delete ? $constraint->on_delete : ''; - my $out = sprintf('%s %s %s %s %s %s', + my $out = join(' ', grep { $_ } $constraint->name ? ('CONSTRAINT ' . $constraint->name) : '', $ctype, '(' . join (', ', $constraint->fields) . ')', $expr ? $expr : $ref, $update, $delete); + if ($constraint->type eq FOREIGN_KEY) { + my $table_name = $constraint->table->name; + $out = "ALTER TABLE $table_name ADD $out;"; + push @fks, $out; + } + else { + push @con_defs, $out; + } - - return $out; + return \@con_defs, \@fks; } diff --git a/lib/SQL/Translator/Producer/PostgreSQL.pm b/lib/SQL/Translator/Producer/PostgreSQL.pm index c3e67b9..eb12613 100644 --- a/lib/SQL/Translator/Producer/PostgreSQL.pm +++ b/lib/SQL/Translator/Producer/PostgreSQL.pm @@ -1,7 +1,7 @@ package SQL::Translator::Producer::PostgreSQL; # ------------------------------------------------------------------- -# $Id: PostgreSQL.pm,v 1.26 2006-11-09 18:16:24 schiffbruechige Exp $ +# $Id: PostgreSQL.pm,v 1.27 2006-11-10 21:21:51 mwz444 Exp $ # ------------------------------------------------------------------- # Copyright (C) 2002-4 SQLFairy Authors # @@ -39,7 +39,7 @@ producer. use strict; use warnings; use vars qw[ $DEBUG $WARN $VERSION ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.26 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.27 $ =~ /(\d+)\.(\d+)/; $DEBUG = 1 unless defined $DEBUG; use SQL::Translator::Schema::Constants; @@ -207,7 +207,7 @@ sub produce { $output = join("\n\n", @table_defs); if ( @fks ) { $output .= "--\n-- Foreign Key Definitions\n--\n\n" unless $no_comments; - $output .= join( "\n\n", @fks ); + $output .= join( "\n\n", @fks ) . "\n"; } if ( $WARN ) { diff --git a/t/16xml-parser.t b/t/16xml-parser.t index 433ec08..bb9aecd 100644 --- a/t/16xml-parser.t +++ b/t/16xml-parser.t @@ -27,7 +27,7 @@ use constant DEBUG => (exists $opt{d} ? 1 : 0); #============================================================================= BEGIN { - maybe_plan(162, 'SQL::Translator::Parser::XML::SQLFairy'); + maybe_plan(204, 'SQL::Translator::Parser::XML::SQLFairy'); } my $testschema = "$Bin/data/xml/schema.xml"; @@ -120,6 +120,14 @@ schema_ok( $scma, { comments => "Hello emptytagdef", }, { + name => "another_id", + data_type => "int", + size => "10", + default_value => 2, + is_nullable => 1, + is_foreign_key => 1, + }, + { name => "timest", data_type => "timestamp", size => "0", @@ -140,7 +148,13 @@ schema_ok( $scma, { name => 'emailuniqueindex', type => UNIQUE, fields => ["email"], - } + }, + { + type => FOREIGN_KEY, + fields => ["another_id"], + reference_table => "Another", + reference_fields => ["id"], + }, ], indices => [ { @@ -153,7 +167,27 @@ schema_ok( $scma, { }, }, ], - } # end table Basic + }, # end table Basic + { + name => "Another", + extra => { + foo => "bar", + hello => "world", + bar => "baz", + mysql_table_type => "InnoDB", + }, + fields => [ + { + name => "id", + data_type => "int", + default_value => undef, + is_nullable => 0, + size => 10, + is_primary_key => 1, + is_auto_increment => 1, + }, + ], + }, # end table Another ], # end tables views => [ diff --git a/t/18ttschema-producer.t b/t/18ttschema-producer.t index 9b9d8ac..a9b6510 100644 --- a/t/18ttschema-producer.t +++ b/t/18ttschema-producer.t @@ -81,7 +81,8 @@ use SQL::Translator::Producer::TTSchema; ok $out ne "" ,"Produced something!"; local $/ = undef; # slurp eq_or_diff $out, q{ - Table: Basic} + Table: Basic + Table: Another} ,"Output looks right"; } @@ -195,6 +196,20 @@ Fields order: 7 table: Basic + another_id + data_type: int + size: 10 + is_nullable: 1 + default_value: 2 + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 1 + foreign_key_reference: Another + is_valid: 1 + order: 8 + table: Basic + timest data_type: timestamp size: 0 @@ -206,7 +221,7 @@ Fields is_foreign_key: 0 foreign_key_reference: is_valid: 1 - order: 8 + order: 9 table: Basic @@ -246,3 +261,51 @@ Constraints options: is_valid: 1 + ? + type: FOREIGN KEY + fields: another_id + expression: + match_type: + reference_fields: id + reference_table: Another + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + +Table: Another +========================================================================== + +Fields + id + data_type: int + size: 10 + is_nullable: 0 + default_value: + is_primary_key: 1 + is_unique: 0 + is_auto_increment: 1 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 10 + table: Another + + +Indices + +Constraints + ? + type: PRIMARY KEY + fields: id + expression: + match_type: + reference_fields: + reference_table: + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + diff --git a/t/34tt-base.t b/t/34tt-base.t index 8808b1d..02fdca8 100644 --- a/t/34tt-base.t +++ b/t/34tt-base.t @@ -42,8 +42,13 @@ eq_or_diff $out, ,"Output looks right"; __DATA__ Hello World -Tables: Basic +Tables: Basic, Another Basic ------ -Fields: id title description email explicitnulldef explicitemptystring emptytagdef timest +Fields: id title description email explicitnulldef explicitemptystring emptytagdef another_id timest + +Another +------ +Fields: id + diff --git a/t/43xml-to-db2.t b/t/43xml-to-db2.t index 8a430b6..a8afc2f 100644 --- a/t/43xml-to-db2.t +++ b/t/43xml-to-db2.t @@ -36,18 +36,28 @@ is($sql, << "SQL"); DROP TABLE Basic; CREATE TABLE Basic ( -id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, -title VARCHAR(100) NOT NULL DEFAULT 'hello', -description VARCHAR(0) DEFAULT '', -email VARCHAR(255), -explicitnulldef VARCHAR(0), -explicitemptystring VARCHAR(0) DEFAULT '', -emptytagdef VARCHAR(0) DEFAULT '', -timest TIMESTAMP, -CONSTRAINT emailuniqueindex UNIQUE (email) , - PRIMARY KEY(id) + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + title VARCHAR(100) NOT NULL DEFAULT 'hello', + description VARCHAR(0) DEFAULT '', + email VARCHAR(255), + explicitnulldef VARCHAR(0), + explicitemptystring VARCHAR(0) DEFAULT '', + emptytagdef VARCHAR(0) DEFAULT '', + another_id INTEGER DEFAULT 2, + timest TIMESTAMP, + PRIMARY KEY (id), + CONSTRAINT emailuniqueindex UNIQUE (email) ); +DROP TABLE Another; + +CREATE TABLE Another ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + PRIMARY KEY (id) +); + +ALTER TABLE Basic ADD FOREIGN KEY (another_id) REFERENCES Another(id); + CREATE INDEX titleindex ON Basic ( title ); CREATE VIEW email_list AS diff --git a/t/44-xml-to-db2-array.t b/t/44-xml-to-db2-array.t index 9285ded..37c69cc 100644 --- a/t/44-xml-to-db2-array.t +++ b/t/44-xml-to-db2-array.t @@ -34,18 +34,28 @@ my @sql = $sqlt->translate( my $want = [ 'DROP TABLE Basic;', q|CREATE TABLE Basic ( -id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, -title VARCHAR(100) NOT NULL DEFAULT 'hello', -description VARCHAR(0) DEFAULT '', -email VARCHAR(255), -explicitnulldef VARCHAR(0), -explicitemptystring VARCHAR(0) DEFAULT '', -emptytagdef VARCHAR(0) DEFAULT '', -timest TIMESTAMP, -CONSTRAINT emailuniqueindex UNIQUE (email) , - PRIMARY KEY(id) + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + title VARCHAR(100) NOT NULL DEFAULT 'hello', + description VARCHAR(0) DEFAULT '', + email VARCHAR(255), + explicitnulldef VARCHAR(0), + explicitemptystring VARCHAR(0) DEFAULT '', + emptytagdef VARCHAR(0) DEFAULT '', + another_id INTEGER DEFAULT 2, + timest TIMESTAMP, + PRIMARY KEY (id), + CONSTRAINT emailuniqueindex UNIQUE (email) );|, +'DROP TABLE Another;', + +q|CREATE TABLE Another ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL, + PRIMARY KEY (id) +);|, + +'ALTER TABLE Basic ADD FOREIGN KEY (another_id) REFERENCES Another(id);', + 'CREATE INDEX titleindex ON Basic ( title );', 'CREATE VIEW email_list AS diff --git a/t/46xml-to-pg.t b/t/46xml-to-pg.t index 7bb025f..de42837 100644 --- a/t/46xml-to-pg.t +++ b/t/46xml-to-pg.t @@ -43,9 +43,20 @@ CREATE TABLE "Basic" ( "explicitemptystring" character varying DEFAULT '', -- Hello emptytagdef "emptytagdef" character varying DEFAULT '', + "another_id" integer DEFAULT '2', "timest" timestamp(0), PRIMARY KEY ("id"), Constraint "emailuniqueindex" UNIQUE ("email") ); CREATE INDEX "titleindex" on "Basic" ("title"); + + +DROP TABLE "Another"; +CREATE TABLE "Another" ( + "id" serial NOT NULL, + PRIMARY KEY ("id") +); + +ALTER TABLE "Basic" ADD FOREIGN KEY ("another_id") + REFERENCES "Another" ("id"); SQL diff --git a/t/48xml-to-sqlite.t b/t/48xml-to-sqlite.t index 6ed2a22..53f37db 100644 --- a/t/48xml-to-sqlite.t +++ b/t/48xml-to-sqlite.t @@ -48,11 +48,18 @@ CREATE TABLE Basic ( explicitemptystring varchar DEFAULT '', -- Hello emptytagdef emptytagdef varchar DEFAULT '', + another_id int(10) DEFAULT '2', timest timestamp ); CREATE INDEX titleindex_Basic on Basic (title); CREATE UNIQUE INDEX emailuniqueindex_Basic on Basic (email); +DROP TABLE Another; +CREATE TABLE Another ( + id INTEGER PRIMARY KEY NOT NULL +); + + COMMIT; SQL diff --git a/t/data/template/basic.tt b/t/data/template/basic.tt index 6011a1c..9e7045a 100644 --- a/t/data/template/basic.tt +++ b/t/data/template/basic.tt @@ -19,7 +19,7 @@ Fields is_unique: [% field.is_unique %] is_auto_increment: [% field.is_auto_increment %] is_foreign_key: [% field.is_foreign_key %] - foreign_key_reference: [% field.foreign_key_reference %] + foreign_key_reference: [% field.foreign_key_reference.reference_table %] is_valid: [% field.is_valid %] order: [% field.order %] table: [% field.table %] diff --git a/t/data/xml/schema.xml b/t/data/xml/schema.xml index 3a1f2de..d31daa4 100644 --- a/t/data/xml/schema.xml +++ b/t/data/xml/schema.xml @@ -34,6 +34,8 @@ Created on Fri Aug 15 15:08:18 2003 data_type="varchar" order="7" default_value="" > Hello emptytagdef + @@ -52,10 +54,34 @@ Created on Fri Aug 15 15:08:18 2003 + + + + + + + + + + + + + + + +
diff --git a/t/lib/Producer/BaseTest.pm b/t/lib/Producer/BaseTest.pm index a31c682..57cf39c 100644 --- a/t/lib/Producer/BaseTest.pm +++ b/t/lib/Producer/BaseTest.pm @@ -20,9 +20,10 @@ sub tt_config { ( INTERPOLATE => 1 ); } __DATA__ Hello World -Tables: [% schema.get_tables %] -[% table = schema.get_tables.first -%] +Tables: [% schema.get_tables.join(', ') %] +[% FOREACH table IN schema.get_tables -%] $table ------ Fields: $table.field_names.join +[% END %]