From: Mark Addison Date: Tue, 14 Oct 2003 23:19:44 +0000 (+0000) Subject: Added m:n joins. Can now model m:n association in your class diag and the X-Git-Tag: v0.04~78 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ae15bb990ded38681d389d4c8f1365150504a4e1;p=dbsrgits%2FSQL-Translator.git Added m:n joins. Can now model m:n association in your class diag and the parser will create a link table for it when creating the schema :) --- diff --git a/lib/SQL/Translator/Parser/XML/XMI/SQLFairy.pm b/lib/SQL/Translator/Parser/XML/XMI/SQLFairy.pm index 6bf9c3b..1861a5f 100644 --- a/lib/SQL/Translator/Parser/XML/XMI/SQLFairy.pm +++ b/lib/SQL/Translator/Parser/XML/XMI/SQLFairy.pm @@ -1,7 +1,7 @@ package SQL::Translator::Parser::XML::XMI::SQLFairy; # ------------------------------------------------------------------- -# $Id: SQLFairy.pm,v 1.2 2003-10-13 17:05:55 grommit Exp $ +# $Id: SQLFairy.pm,v 1.3 2003-10-14 23:19:43 grommit Exp $ # ------------------------------------------------------------------- # Copyright (C) 2003 Mark Addison , # @@ -29,7 +29,7 @@ SQL::Translator::Parser::XML::XMI::SQLFairy - Create Schema from UML Models. use strict; use vars qw[ $DEBUG $VERSION @EXPORT_OK ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/; $DEBUG = 0 unless defined $DEBUG; use Exporter; use base qw(Exporter); @@ -151,7 +151,8 @@ sub classes2schema { else { # m:n - warn "Sorry, n:m associations not yet implimented for xmi.id=".$assoc->{"xmi.id"}."\n"; + many2many($assoc); + #warn "Sorry, n:m associations not yet implimented for xmi.id=".$assoc->{"xmi.id"}."\n"; } } @@ -232,7 +233,8 @@ sub add_pkey { } # Maps a 1:M association into the schema -sub one2many { +sub one2many +{ my ($assoc) = @_; my @ends = @{$assoc->{associationEnds}}; my ($end1) = grep $_->{multiplicity}{rangeUpper} == 1, @ends; @@ -272,6 +274,48 @@ sub one2many { ) or die $schema->error; } +# Maps m:n into schema by building a link table. +sub many2many +{ + my ($assoc) = @_; + my @end = @{$assoc->{associationEnds}}; + + # Create the link table + my $name = $end[0]->{participant}{name}."_".$end[1]->{participant}{name}; + my $link_table = $schema->add_table( name => $name ) + or die "Schema Error: ".$schema->error; + + # Export the pkey(s) from the ends into the link table + my @pkeys; + foreach (@end) { + my $table = $schema->get_table($_->{participant}{name}); + my @fkeys = $table->primary_key->fields; + push @pkeys,@fkeys; + foreach ( @fkeys ) { + my $fld = $table->get_field($_); + my %data; + $data{$_} = $fld->$_() + foreach ( + qw/name size data_type default_value is_nullable is_unique/); + $data{is_auto_increment} = 0; + $data{extra} = { $fld->extra }; # Copy + $link_table->add_field(%data) or die $table->error; + } + $link_table->add_constraint( + type => "FOREIGN_KEY", + fields => [@fkeys], + reference_table => $table->{name}, + reference_fields => [@fkeys], + ) or die $schema->error; + + } + # Add pkey constraint + $link_table->add_constraint( type => "PRIMARY KEY", fields => [@pkeys] ) + or die $link_table->error; + + + # Add fkeys to our participants +} 1; #--------------------------------------------------------------------------- __END__ diff --git a/t/28xml-xmi-parser-sqlfairy.t b/t/28xml-xmi-parser-sqlfairy.t index a3e2f21..71c2d38 100644 --- a/t/28xml-xmi-parser-sqlfairy.t +++ b/t/28xml-xmi-parser-sqlfairy.t @@ -133,7 +133,7 @@ sub test_table { # Testing 1,2,3,.. #============================================================================= -plan tests => 94; +plan tests => 151; my $testschema = "$Bin/data/xmi/OrderDB.sqlfairy.poseidon2.xmi"; die "Can't find test schema $testschema" unless -e $testschema; @@ -158,8 +158,9 @@ my $scma = $obj->schema; is( $scma->is_valid, 1, 'Schema is valid' ); my @tblnames = map {$_->name} $scma->get_tables; is(scalar(@{$scma->get_tables}), scalar(@tblnames), "Right number of tables"); -is_deeply( \@tblnames, [qw/Order OrderLine Customer/] - ,"tables"); +is_deeply( \@tblnames, + [qw/Order OrderLine Customer ContactDetails ContactDetails_Customer/] +,"tables"); test_table( $scma->get_table("Customer"), name => "Customer", @@ -202,6 +203,85 @@ test_table( $scma->get_table("Customer"), ], ); +test_table( $scma->get_table("ContactDetails_Customer"), + name => "ContactDetails_Customer", + fields => [ + { + name => "ContactDetailsID", + data_type => "INT", + size => 10, + default_value => undef, + is_nullable => 0, + is_primary_key => 1, + is_auto_increment => 0, + }, + { + name => "CustomerID", + data_type => "INT", + size => 10, + default_value => undef, + is_nullable => 0, + is_primary_key => 1, + is_auto_increment => 0, + }, + ], + constraints => [ + { + type => "FOREIGN KEY", + fields => "ContactDetailsID", + reference_table => "ContactDetails", + reference_fields => "ContactDetailsID", + }, + { + type => "FOREIGN KEY", + fields => "CustomerID", + reference_table => "Customer", + reference_fields => "CustomerID", + }, + { + type => "PRIMARY KEY", + fields => "ContactDetailsID,CustomerID", + }, + ], +); + +test_table( $scma->get_table("ContactDetails"), + name => "ContactDetails", + fields => [ + { + name => "address", + data_type => "VARCHAR", + size => "255", + default_value => undef, + is_nullable => 1, + is_primary_key => 0, + }, + { + name => "telephone", + data_type => "VARCHAR", + size => "255", + default_value => undef, + is_nullable => 1, + is_primary_key => 0, + }, + { + name => "ContactDetailsID", + data_type => "INT", + size => 10, + default_value => undef, + is_nullable => 0, + is_primary_key => 1, + is_auto_increment => 1, + }, + ], + constraints => [ + { + type => "PRIMARY KEY", + fields => "ContactDetailsID", + }, + ], +); + test_table( $scma->get_table("Order"), name => "Order", fields => [ diff --git a/t/data/xmi/OrderDB.sqlfairy.poseidon2.xmi b/t/data/xmi/OrderDB.sqlfairy.poseidon2.xmi index 55ea6bf..70bf1bc 100644 --- a/t/data/xmi/OrderDB.sqlfairy.poseidon2.xmi +++ b/t/data/xmi/OrderDB.sqlfairy.poseidon2.xmi @@ -1,5 +1,5 @@ - + Netbeans XMI Writer @@ -27,6 +27,21 @@ + + + + + + + + + + + + + + + @@ -271,7 +286,7 @@ ModelElement + isSpecification = 'false' body = 'sqlfSize override on customerID'> @@ -305,6 +320,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +