comparison 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
comparison
equal deleted inserted replaced
166:4267a2ac3d46 167:1f7a6d762394
1 use strict; 1 use strict;
2 package IMPL::SQL::Schema::Table; 2 package IMPL::SQL::Schema::Table;
3 3
4 use IMPL::lang; 4 use IMPL::lang qw(:declare :constants is);
5 5
6 use parent qw( 6 use parent qw(
7 IMPL::Object 7 IMPL::Object
8 IMPL::Object::Disposable 8 IMPL::Object::Disposable
9 ); 9 );
10 10
11 use IMPL::SQL::Schema::Column(); 11 require IMPL::SQL::Schema::Column;
12 use IMPL::SQL::Schema::Constraint(); 12 require IMPL::SQL::Schema::Constraint;
13 use IMPL::SQL::Schema::Constraint::PrimaryKey(); 13 require IMPL::SQL::Schema::Constraint::PrimaryKey;
14 use IMPL::SQL::Schema::Constraint::ForeignKey(); 14 require IMPL::SQL::Schema::Constraint::ForeignKey;
15 15
16 use IMPL::Class::Property;
17 use IMPL::Class::Property::Direct; 16 use IMPL::Class::Property::Direct;
18 17
19 BEGIN { 18 BEGIN {
20 public _direct property name => prop_get; 19 public _direct property name => PROP_GET;
21 public _direct property schema => prop_get; 20 public _direct property schema => PROP_GET;
22 public _direct property columns => prop_get; 21 public _direct property columns => PROP_GET;
23 public _direct property constraints => prop_get; 22 public _direct property constraints => PROP_GET;
24 public _direct property columnsByName => prop_none; 23 public _direct property columnsByName => 0;
25 public _direct property primaryKey => prop_get; 24 public _direct property primaryKey => PROP_GET;
26 public _direct property tag => prop_all; 25 public _direct property tag => PROP_ALL;
27 } 26 }
28 27
29 sub CTOR { 28 sub CTOR {
30 my ($this,%args) = @_; 29 my ($this,%args) = @_;
31 30
99 } else { 98 } else {
100 die new IMPL::InvalidOperationException("The column not found",$NameOrColumn->name); 99 die new IMPL::InvalidOperationException("The column not found",$NameOrColumn->name);
101 } 100 }
102 } 101 }
103 102
104 sub Column { 103 sub GetColumn {
105 my ($this,$name) = @_; 104 my ($this,$name) = @_;
106 105
107 return $this->{$columnsByName}->{$name}; 106 return $this->{$columnsByName}->{$name};
108 } 107 }
109 108
110 sub ColumnAt { 109 sub GetColumnAt {
111 my ($this,$index) = @_; 110 my ($this,$index) = @_;
112 111
113 die new IMPL::InvalidArgumentException("The index is out of range") 112 die new IMPL::InvalidArgumentException("The index is out of range")
114 if $index < 0 || $index >= ($this->{$columns} ? scalar(@{$this->{$columns}}) : 0); 113 if $index < 0 || $index >= ($this->{$columns} ? scalar(@{$this->{$columns}}) : 0);
115 114
165 my ($this,$name) = @_; 164 my ($this,$name) = @_;
166 165
167 return $this->{$constraints}{$name}; 166 return $this->{$constraints}{$name};
168 } 167 }
169 168
169 sub GetConstraints {
170 my ($this) = @_;
171
172 return wantarray ? values %{$this->{$constraints}} : [values %{$this->{$constraints}}];
173 }
174
170 sub GetColumnConstraints { 175 sub GetColumnConstraints {
171 my ($this,@Columns) = @_; 176 my ($this,@Columns) = @_;
172 177
173 my @cn = map { UNIVERSAL::isa($_ ,'IMPL::SQL::Schema::Column') ? $_ ->name : $_ } @Columns; 178 my @cn = map { UNIVERSAL::isa($_ ,'IMPL::SQL::Schema::Column') ? $_ ->name : $_ } @Columns;
174 exists $this->{$columnsByName}->{$_} or die new IMPL::InvalidOperationException('The specified column isn\'t found',$_) foreach @cn; 179 exists $this->{$columnsByName}->{$_} or die new IMPL::InvalidOperationException('The specified column isn\'t found',$_) foreach @cn;
184 189
185 sub LinkTo { 190 sub LinkTo {
186 my ($this,$table,@ColumnList) = @_; 191 my ($this,$table,@ColumnList) = @_;
187 $table->primaryKey or die new IMPL::InvalidOperationException('The referenced table must have a primary key'); 192 $table->primaryKey or die new IMPL::InvalidOperationException('The referenced table must have a primary key');
188 my $constraintName = $this->{$name}.'_'.$table->name.'_FK_'.join('_',map {ref $_ ? $_->name : $_} @ColumnList); 193 my $constraintName = $this->{$name}.'_'.$table->name.'_FK_'.join('_',map {ref $_ ? $_->name : $_} @ColumnList);
189 $this->AddConstraint(new IMPL::SQL::Schema::Constraint::ForeignKey(name => $constraintName, table => $this, columns => \@ColumnList, referencedTable => $table, referencedColumns => $table->primaryKey->columns)); 194 $this->AddConstraint(new IMPL::SQL::Schema::Constraint::ForeignKey(name => $constraintName, table => $this, columns => \@ColumnList, referencedTable => $table, referencedColumns => scalar $table->primaryKey->columns));
190 } 195 }
191 196
192 sub Dispose { 197 sub Dispose {
193 my ($this) = @_; 198 my ($this) = @_;
194 199
196 201
197 undef %{$this}; 202 undef %{$this};
198 $this->SUPER::Dispose(); 203 $this->SUPER::Dispose();
199 } 204 }
200 205
206 sub SameValue {
207 my ($this,$other) = @_;
208
209 return 0 unless is $other, typeof $this;
210
211 return 0 unless $this->name eq $other->name;
212 return 0 unless $this->ColumnsCount eq $other->ColumnsCount;
213
214 for (my $i = 0; $i < $this->ColumsCount; $i ++) {
215 return 0 unless $this->($i)->SameValue($other->GetColumnAt($i));
216 }
217
218 my %thisConstraints = map { $_->name, $_ } $this->GetConstraints();
219 my %otherConstraints = map { $_->name, $_ } $other->GetConstraints();
220
221 foreach my $name ( keys %thisConstraints ) {
222 return 0 unless $otherConstraints{$name};
223 return 0 unless $thisConstraints{$name}->SameValue(delete $otherConstraints{$name});
224 }
225
226 return 0 if %otherConstraints;
227
228 return 1;
229 }
230
201 1; 231 1;
202 232
203 233