Added FKeys from associations
Mark Addison [Wed, 1 Oct 2003 17:47:02 +0000 (17:47 +0000)]
lib/SQL/Translator/Parser/XML/XMI/Rational.pm

index 784dfb6..3a3f800 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Parser::XML::XMI::Rational;
 
 # -------------------------------------------------------------------
-# $Id: Rational.pm,v 1.1 2003-09-22 11:41:07 grommit Exp $
+# $Id: Rational.pm,v 1.2 2003-10-01 17:47:02 grommit Exp $
 # -------------------------------------------------------------------
 # Copyright (C) 2003 Mark Addison <mark.addison@itn.co.uk>,
 #
@@ -39,6 +39,11 @@ sub parse {
        return SQL::Translator::Parser::XML::XMI::parse(@_);
 }
 
+sub _parameters_in {
+       my $params = shift;
+       return grep {$_->{kind} ne "return"} @$params;
+}
+
 sub classes2schema {
        my ($schema, $classes) = @_;
 
@@ -98,9 +103,10 @@ sub classes2schema {
                                $data{type} = "PRIMARY_KEY";
                        }
                        # TODO We need to work out the ref table
-                       #elsif ( $stereo eq "FK" ) {
-                       #       $data{type} = "FOREIGN_KEY";
-                       #}
+                       elsif ( $stereo eq "FK" ) {
+                               $data{type} = "FOREIGN_KEY";
+                               _add_fkey_refs($class,$op,\%data);
+                       }
 
                        # Add the constraint or index
                        if ( $data{type} ) {
@@ -111,12 +117,34 @@ sub classes2schema {
                                $table->add_index( %data ) or die $schema->error;
                        }
 
-
                } # Ops loop
 
     } # Classes loop
 }
 
+use Data::Dumper;
+sub _add_fkey_refs {
+       my ($class,$op,$data) = @_;
+
+       # Find the association ends
+       my ($end) = grep { $_->{name} eq $op->{name} } @{$class->{associationEnds}};
+       #my $end;
+       #foreach $end ( @{$class->{associationEnds}} ) {
+       #       warn "END: $end->{name} $op->{name}\n";
+       #       last if $end->{name} eq $op->{name};
+       #}
+warn "END: ",Dumper($end),"\n";
+       return unless $end;
+       # Find the fkey op
+       my ($refop) = grep { $_->{name} eq $end->{otherEnd}{name} }
+               @{$end->{otherEnd}{participant}{operations}};
+       return unless $refop;
+
+       $data->{reference_table} = $end->{otherEnd}{participant}{name};
+       $data->{reference_fields} = [ map("$_->{name}", _parameters_in($refop->{parameters})) ];
+       return $data;
+}
+
 1; #---------------------------------------------------------------------------
 
 __END__
@@ -162,6 +190,12 @@ B<Constraints> Stereotyped operations, with the names of the parameters
 indicating which fields it applies to. Can use <<PK>>, <<FK>>, <<Unique>> or
 <<Index>>.
 
+B<Relationships> You can model the relationships in the diagram and have the
+translator add the foreign key constraints for you. The forign keys are defined
+as <<FK>> operations as show above. To show which table they point to join the
+class to the taget classwith an association where the role names are the names
+of the constraints to join.
+
 e.g.
 
  +------------------------------------------------------+
@@ -172,16 +206,43 @@ e.g.
  | <<Column>> name { dataType=VARCHAR size=255 }        |
  | <<Column>> description { dataType=TEXT }             |
  +------------------------------------------------------+
- | <<PK>>     con1( fooID )                             |
+ | <<PK>>     pkcon( fooID )                             |
  | <<Unique>> con2( name )                              |
  +------------------------------------------------------+
+                           |
+                           | pkcon
+                           |
+                           |
+                           |
+                           |
+                           | fkcon
+                           |
+ +------------------------------------------------------+
+ |                      <<Table>>                       |
+ |                         Bar                          |
+ +------------------------------------------------------+
+ | <<PK>>     barID { dataType=INT size=10 nullable=0 } |
+ | <<FK>>     fooID { dataType=INT size=10 nullable=0 } |
+ | <<Column>> name  { dataType=VARCHAR size=255 }       |
+ +------------------------------------------------------+
+ | <<PK>>     pkcon( barID )                            |
+ | <<FK>>     fkcon( fooID )                            |
+ +------------------------------------------------------+
 
  CREATE TABLE Foo (
    fooID INT(10) NOT NULL,
    name VARCHAR(255),
    description TEXT,
    PRIMARY KEY (fooID),
-   UNIQUE (name)
+   UNIQUE con2 (name)
+ );
+
+ CREATE TABLE Bar (
+   barID INT(10) NOT NULL,
+   fooID INT(10) NOT NULL,
+   name VARCHAR(255),
+   PRIMARY KEY (fooID),
+   FOREIGN KEY fkcon (fooID) REFERENCES Foo (fooID)
  );
 
 =head1 ARGS
@@ -190,7 +251,8 @@ e.g.
 
 =head1 TODO
 
-Relationships from associations.
+The Rational profile also defines ways to model stuff above tables such as the
+actuall db.
 
 =head1 AUTHOR