X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FTranslator%2FSchema%2FTable.pm;h=adcd7b1bf089f89a9bbbd3a676e70dae7f9fc78f;hb=3d6c9056fc529b57d10d322fce4d7be07c61bc62;hp=e9efc88bad81c6f4b7711f33b8bdeca8e6decb9e;hpb=3dd9026c224459bd7d1443bc93ede935661a53d7;p=dbsrgits%2FSQL-Translator.git diff --git a/lib/SQL/Translator/Schema/Table.pm b/lib/SQL/Translator/Schema/Table.pm index e9efc88..adcd7b1 100644 --- a/lib/SQL/Translator/Schema/Table.pm +++ b/lib/SQL/Translator/Schema/Table.pm @@ -1,7 +1,7 @@ package SQL::Translator::Schema::Table; # ---------------------------------------------------------------------- -# $Id: Table.pm,v 1.13 2003-08-21 18:10:47 kycl4rk Exp $ +# $Id: Table.pm,v 1.22 2003-09-25 17:29:25 allenday Exp $ # ---------------------------------------------------------------------- # Copyright (C) 2003 Ken Y. Clark # @@ -46,11 +46,12 @@ use SQL::Translator::Schema::Constants; use SQL::Translator::Schema::Constraint; use SQL::Translator::Schema::Field; use SQL::Translator::Schema::Index; +use Data::Dumper; use base 'Class::Base'; use vars qw( $VERSION $FIELD_ORDER ); -$VERSION = sprintf "%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/; +$VERSION = sprintf "%d.%02d", q$Revision: 1.22 $ =~ /(\d+)\.(\d+)/; # ---------------------------------------------------------------------- sub init { @@ -88,10 +89,10 @@ sub add_constraint { Add a constraint to the table. Returns the newly created C object. - my $c1 = $table->add_constraint( - name => 'pk', - type => PRIMARY_KEY, - fields => [ 'foo_id' ], + my $c1 = $table->add_constraint( + name => 'pk', + type => PRIMARY_KEY, + fields => [ 'foo_id' ], ); my $c2 = SQL::Translator::Schema::Constraint->new( name => 'uniq' ); @@ -125,6 +126,13 @@ C object. $constraint = $pk; $ok = 0; } + elsif ( $constraint->type eq PRIMARY_KEY ) { + for my $fname ( $constraint->fields ) { + if ( my $f = $self->get_field( $fname ) ) { + $f->is_primary_key( 1 ); + } + } + } # # See if another constraint of the same type # covers the same fields. @@ -164,7 +172,7 @@ sub add_index { Add an index to the table. Returns the newly created C object. - my $i1 = $table->add_index( + my $i1 = $table->add_index( name => 'name', fields => [ 'name' ], type => 'normal', @@ -206,17 +214,17 @@ C object. The "name" parameter is required. If you try to create a field with the same name as an existing field, you will get an error and the field will not be created. - my $f1 = $table->add_field( + my $f1 = $table->add_field( name => 'foo_id', data_type => 'integer', size => 11, ); - my $f2 = SQL::Translator::Schema::Field->new( + my $f2 = SQL::Translator::Schema::Field->new( name => 'name', table => $table, ); - $f2 = $table->add_field( $field2 ) or die $table->error; + $f2 = $table->add_field( $field2 ) or die $table->error; =cut @@ -412,6 +420,154 @@ Determine whether the view is valid or not. } # ---------------------------------------------------------------------- +sub is_trivial_link { + +=pod + +=head2 is_data + +=cut + + my $self = shift; + return 0 if $self->is_data; + return $self->{'is_trivial_link'} if defined $self->{'is_trivial_link'}; + + $self->{'is_trivial_link'} = 1; + + my %fk = (); + + foreach my $field ( $self->get_fields ) { + next unless $field->is_foreign_key; + $fk{$field->foreign_key_reference->reference_table}++; + } + + foreach my $referenced (keys %fk){ + if($fk{$referenced} > 1){ + $self->{'is_trivial_link'} = 0; + last; + } + } + + return $self->{'is_trivial_link'}; + +} + +sub is_data { + +=pod + +=head2 is_data + +=cut + + my $self = shift; + return $self->{'is_data'} if defined $self->{'is_data'}; + + $self->{'is_data'} = 0; + + foreach my $field ( $self->get_fields ) { + if ( !$field->is_primary_key and !$field->is_foreign_key ) { + $self->{'is_data'} = 1; + return $self->{'is_data'}; + } + } + + return $self->{'is_data'}; +} + +# ---------------------------------------------------------------------- +sub can_link { + +=pod + +=head2 can_link + +Determine whether the table can link two arg tables via many-to-many. + + my $ok = $table->can_link($table1,$table2); + +=cut + + my ( $self, $table1, $table2 ) = @_; + + return $self->{'can_link'}{ $table1->name }{ $table2->name } + if defined $self->{'can_link'}{ $table1->name }{ $table2->name }; + + if ( $self->is_data == 1 ) { + $self->{'can_link'}{ $table1->name }{ $table2->name } = [0]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = [0]; + return $self->{'can_link'}{ $table1->name }{ $table2->name }; + } + + my %fk = (); + + foreach my $field ( $self->get_fields ) { + if ( $field->is_foreign_key ) { + push @{ $fk{ $field->foreign_key_reference->reference_table } }, + $field->foreign_key_reference; + } + } + + if ( !defined( $fk{ $table1->name } ) or !defined( $fk{ $table2->name } ) ) + { + $self->{'can_link'}{ $table1->name }{ $table2->name } = [0]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = [0]; + return $self->{'can_link'}{ $table1->name }{ $table2->name }; + } + + # trivial traversal, only one way to link the two tables + if ( scalar( @{ $fk{ $table1->name } } == 1 ) + and scalar( @{ $fk{ $table2->name } } == 1 ) ) + { + $self->{'can_link'}{ $table1->name }{ $table2->name } = + [ 'one2one', $fk{ $table1->name }, $fk{ $table2->name } ]; + $self->{'can_link'}{ $table1->name }{ $table2->name } = + [ 'one2one', $fk{ $table2->name }, $fk{ $table1->name } ]; + + # non-trivial traversal. one way to link table2, + # many ways to link table1 + } + elsif ( scalar( @{ $fk{ $table1->name } } > 1 ) + and scalar( @{ $fk{ $table2->name } } == 1 ) ) + { + $self->{'can_link'}{ $table1->name }{ $table2->name } = + [ 'many2one', $fk{ $table1->name }, $fk{ $table2->name } ]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = + [ 'one2many', $fk{ $table2->name }, $fk{ $table1->name } ]; + + # non-trivial traversal. one way to link table1, + # many ways to link table2 + } + elsif ( scalar( @{ $fk{ $table1->name } } == 1 ) + and scalar( @{ $fk{ $table2->name } } > 1 ) ) + { + $self->{'can_link'}{ $table1->name }{ $table2->name } = + [ 'one2many', $fk{ $table1->name }, $fk{ $table2->name } ]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = + [ 'many2one', $fk{ $table2->name }, $fk{ $table1->name } ]; + + # non-trivial traversal. many ways to link table1 and table2 + } + elsif ( scalar( @{ $fk{ $table1->name } } > 1 ) + and scalar( @{ $fk{ $table2->name } } > 1 ) ) + { + $self->{'can_link'}{ $table1->name }{ $table2->name } = + [ 'many2many', $fk{ $table1->name }, $fk{ $table2->name } ]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = + [ 'many2many', $fk{ $table2->name }, $fk{ $table1->name } ]; + + # one of the tables didn't export a key + # to this table, no linking possible + } + else { + $self->{'can_link'}{ $table1->name }{ $table2->name } = [0]; + $self->{'can_link'}{ $table2->name }{ $table1->name } = [0]; + } + + return $self->{'can_link'}{ $table1->name }{ $table2->name }; +} + +# ---------------------------------------------------------------------- sub name { =pod @@ -468,7 +624,7 @@ sub primary_key { =pod -=head2 options +=head2 primary_key Gets or sets the table's primary key(s). Takes one or more field names (as a string, list or array[ref]) as an argument. If the field @@ -593,8 +749,9 @@ sub DESTROY { =pod -=head1 AUTHOR +=head1 AUTHORS -Ken Y. Clark Ekclark@cpan.orgE +Ken Y. Clark Ekclark@cpan.orgE, +Allen Day Eallenday@ucla.eduE. =cut