diff Lib/IMPL/SQL/Schema/Table.pm @ 167:1f7a6d762394

SQL schema in progress
author sourcer
date Thu, 12 May 2011 08:57:19 +0400
parents 76515373dac0
children 6148f89bb7bf
line wrap: on
line diff
--- a/Lib/IMPL/SQL/Schema/Table.pm	Sat Apr 23 23:12:06 2011 +0400
+++ b/Lib/IMPL/SQL/Schema/Table.pm	Thu May 12 08:57:19 2011 +0400
@@ -1,29 +1,28 @@
 use strict;
 package IMPL::SQL::Schema::Table;
 
-use IMPL::lang;
+use IMPL::lang qw(:declare :constants is);
 
 use parent qw(
 	IMPL::Object
 	IMPL::Object::Disposable
 );
 
-use IMPL::SQL::Schema::Column();
-use IMPL::SQL::Schema::Constraint();
-use IMPL::SQL::Schema::Constraint::PrimaryKey();
-use IMPL::SQL::Schema::Constraint::ForeignKey();
+require IMPL::SQL::Schema::Column;
+require IMPL::SQL::Schema::Constraint;
+require IMPL::SQL::Schema::Constraint::PrimaryKey;
+require IMPL::SQL::Schema::Constraint::ForeignKey;
 
-use IMPL::Class::Property;
 use IMPL::Class::Property::Direct;
 
 BEGIN {
-    public _direct property name => prop_get;
-    public _direct property schema => prop_get;
-    public _direct property columns => prop_get;
-    public _direct property constraints => prop_get;
-    public _direct property columnsByName => prop_none;
-    public _direct property primaryKey => prop_get;
-    public _direct property tag => prop_all;
+    public _direct property name => PROP_GET;
+    public _direct property schema => PROP_GET;
+    public _direct property columns => PROP_GET;
+    public _direct property constraints => PROP_GET;
+    public _direct property columnsByName => 0;
+    public _direct property primaryKey => PROP_GET;
+    public _direct property tag => PROP_ALL;
 }
 
 sub CTOR {
@@ -101,13 +100,13 @@
     }
 }
 
-sub Column {
+sub GetColumn {
     my ($this,$name) = @_;
     
     return $this->{$columnsByName}->{$name};
 }
 
-sub ColumnAt {
+sub GetColumnAt {
     my ($this,$index) = @_;
     
     die new IMPL::InvalidArgumentException("The index is out of range")
@@ -167,6 +166,12 @@
 	return $this->{$constraints}{$name};
 }
 
+sub GetConstraints {
+	my ($this) = @_;
+	
+	return wantarray ? values %{$this->{$constraints}} : [values %{$this->{$constraints}}];
+}
+
 sub GetColumnConstraints {
     my ($this,@Columns) = @_;
     
@@ -186,7 +191,7 @@
     my ($this,$table,@ColumnList) = @_;
     $table->primaryKey or die new IMPL::InvalidOperationException('The referenced table must have a primary key');
     my $constraintName = $this->{$name}.'_'.$table->name.'_FK_'.join('_',map {ref $_ ? $_->name : $_} @ColumnList);
-    $this->AddConstraint(new IMPL::SQL::Schema::Constraint::ForeignKey(name => $constraintName, table => $this, columns => \@ColumnList, referencedTable => $table, referencedColumns => $table->primaryKey->columns));
+    $this->AddConstraint(new IMPL::SQL::Schema::Constraint::ForeignKey(name => $constraintName, table => $this, columns => \@ColumnList, referencedTable => $table, referencedColumns => scalar $table->primaryKey->columns));
 }
 
 sub Dispose {
@@ -198,6 +203,31 @@
     $this->SUPER::Dispose();
 }
 
+sub SameValue {
+	my ($this,$other) = @_;
+	
+	return 0 unless is $other, typeof $this;
+	
+	return 0 unless $this->name eq $other->name;
+	return 0 unless $this->ColumnsCount eq $other->ColumnsCount;
+	
+	for (my $i = 0; $i < $this->ColumsCount; $i ++) {
+		return 0 unless $this->($i)->SameValue($other->GetColumnAt($i));
+	}
+	
+	my %thisConstraints = map { $_->name, $_ } $this->GetConstraints();
+	my %otherConstraints = map { $_->name, $_ } $other->GetConstraints();
+	
+	foreach my $name ( keys %thisConstraints ) {
+		return 0 unless $otherConstraints{$name};
+		return 0 unless $thisConstraints{$name}->SameValue(delete $otherConstraints{$name});
+	}
+	
+	return 0 if %otherConstraints;
+	
+	return 1;
+}
+
 1;