Mercurial > pub > Impl
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 |