Mercurial > pub > Impl
diff Lib/Schema/DB/Table.pm @ 49:16ada169ca75
migrating to the Eclipse IDE
author | wizard@linux-odin.local |
---|---|
date | Fri, 26 Feb 2010 10:49:21 +0300 |
parents | 03e58a454b20 |
children |
line wrap: on
line diff
--- a/Lib/Schema/DB/Table.pm Fri Feb 26 01:43:42 2010 +0300 +++ b/Lib/Schema/DB/Table.pm Fri Feb 26 10:49:21 2010 +0300 @@ -1,168 +1,168 @@ -use strict; -package Schema::DB::Table; -use Carp; -use Common; - -use Schema::DB::Column; -use Schema::DB::Constraint; -use Schema::DB::Constraint::PrimaryKey; -use Schema::DB::Constraint::ForeignKey; - -our @ISA = qw(Object); - -srand time; - -BEGIN { - DeclareProperty Name => ACCESS_READ; - DeclareProperty Schema => ACCESS_READ; - DeclareProperty Columns => ACCESS_READ; - DeclareProperty Constraints => ACCESS_READ; - DeclareProperty ColumnsByName => ACCESS_NONE; - DeclareProperty PrimaryKey => ACCESS_READ; - DeclareProperty Tag => ACCESS_ALL; -} - -sub CTOR { - my ($this,%args) = @_; - - $this->{$Name} = $args{'Name'} or die new Exception('a table name is required'); - $this->{$Schema} = $args{'Schema'} or die new Exception('a parent schema is required'); -} - -sub InsertColumn { - my ($this,$column,$index) = @_; - - $index = ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0) if not defined $index; - - die new Exception("Index is out of range") if ($index < 0 || $index > ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0)); - - if (UNIVERSAL::isa($column,'Schema::DB::Column')) { - - } elsif (UNIVERSAL::isa($column,'HASH')) { - $column = new Schema::DB::Column(%{$column}); - } else { - die new Exception("The invalid parameter"); - } - - if (exists $this->{$ColumnsByName}->{$column->Name}) { - die new Exception("The column already exists",$column->name); - } else { - $this->{$ColumnsByName}->{$column->Name} = $column; - splice @{$this->{$Columns}},$index,0,$column; - } - - return $column; -} - -sub RemoveColumn { - my ($this,$NameOrColumn,$Force) = @_; - - my $ColName; - if (UNIVERSAL::isa($NameOrColumn,'Schema::DB::Column')) { - $ColName = $NameOrColumn->Name; - } elsif (not ref $NameOrColumn) { - $ColName = $NameOrColumn; - } - - if (exists $this->{$ColumnsByName}->{$ColName}) { - my $index = 0; - foreach my $column(@{$this->{$Columns}}) { - last if $column->Name eq $ColName; - $index++; - } - - my $column = $this->{$Columns}[$index]; - if (my @constraints = $this->GetColumnConstraints($column)){ - $Force or die new Exception('Can\'t remove column which is used in the constraints',@constraints); - $this->RemoveConstraint($_) foreach @constraints; - } - - my $removed = splice @{$this->{$Columns}},$index,1; - delete $this->{$ColumnsByName}->{$ColName}; - return $removed; - } else { - die new Exception("The column not found",$NameOrColumn->Name); - } -} - -sub Column { - my ($this,$name) = @_; - - return $this->{$ColumnsByName}->{$name}; -} - -sub ColumnAt { - my ($this,$index) = @_; - - die new Exception("The index is out of range") if $index < 0 || $index >= ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0); - - return $this->{$Columns}[$index]; -} - -sub AddConstraint { - my ($this,$Constraint) = @_; - - die new Exception('The invalid parameter') if not UNIVERSAL::isa($Constraint,'Schema::DB::Constraint'); - - $Constraint->Table == $this or die new Exception('The constaint must belong to the target table'); - - if (exists $this->{$Constraints}->{$Constraint->Name}) { - die new Exception('The table already has the specified constraint',$Constraint->Name); - } else { - if (UNIVERSAL::isa($Constraint,'Schema::DB::Constraint::PrimaryKey')) { - not $this->{$PrimaryKey} or die new Exception('The table already has a primary key'); - $this->{$PrimaryKey} = $Constraint; - } - - $this->{$Constraints}->{$Constraint->Name} = $Constraint; - } -} - -sub RemoveConstraint { - my ($this,$Constraint,$Force) = @_; - - my $cn = UNIVERSAL::isa($Constraint,'Schema::DB::Constraint') ? $Constraint->Name : $Constraint; - $Constraint = $this->{$Constraints}->{$cn} or die new Exception('The specified constraint doesn\'t exists',$cn); - - if (UNIVERSAL::isa($Constraint,'Schema::DB::Constraint::PrimaryKey')) { - not scalar keys %{$this->{$PrimaryKey}->ConnectedFK} or die new Exception('Can\'t remove Primary Key unless some foreign keys referenses it'); - - delete $this->{$PrimaryKey}; - } - $Constraint->Dispose; - delete $this->{$Constraints}->{$cn}; - return $cn; -} - -sub GetColumnConstraints { - my ($this,@Columns) = @_; - - my @cn = map { UNIVERSAL::isa($_ ,'Schema::DB::Column') ? $_ ->Name : $_ } @Columns; - exists $this->{$ColumnsByName}->{$_} or die new Exception('The specified column isn\'t found',$_) foreach @cn; - - return grep {$_->HasColumn(@cn)} values %{$this->{$Constraints}}; -} - -sub SetPrimaryKey { - my ($this,@ColumnList) = @_; - - $this->AddConstraint(new Schema::DB::Constraint::PrimaryKey(Name => $this->{$Name}.'_PK', Table => $this,Columns => \@ColumnList)); -} - -sub LinkTo { - my ($this,$table,@ColumnList) = @_; - $table->PrimaryKey or die new Exception('The referenced table must have a primary key'); - my $constraintName = $this->{$Name}.'_'.$table->Name.'_FK_'.join('_',map {ref $_ ? $_->Name : $_} @ColumnList); - $this->AddConstraint(new Schema::DB::Constraint::ForeignKey(Name => $constraintName, Table => $this,Columns => \@ColumnList, ReferencedTable => $table, ReferencedColumns => scalar($table->PrimaryKey->Columns))); -} - -sub Dispose { - my ($this) = @_; - - $_->Dispose() foreach values %{$this->{$Constraints}}; - - undef %{$this}; - $this->SUPER::Dispose(); -} - -1; +use strict; +package Schema::DB::Table; +use Carp; +use Common; + +use Schema::DB::Column; +use Schema::DB::Constraint; +use Schema::DB::Constraint::PrimaryKey; +use Schema::DB::Constraint::ForeignKey; + +our @ISA = qw(Object); + +srand time; + +BEGIN { + DeclareProperty Name => ACCESS_READ; + DeclareProperty Schema => ACCESS_READ; + DeclareProperty Columns => ACCESS_READ; + DeclareProperty Constraints => ACCESS_READ; + DeclareProperty ColumnsByName => ACCESS_NONE; + DeclareProperty PrimaryKey => ACCESS_READ; + DeclareProperty Tag => ACCESS_ALL; +} + +sub CTOR { + my ($this,%args) = @_; + + $this->{$Name} = $args{'Name'} or die new Exception('a table name is required'); + $this->{$Schema} = $args{'Schema'} or die new Exception('a parent schema is required'); +} + +sub InsertColumn { + my ($this,$column,$index) = @_; + + $index = ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0) if not defined $index; + + die new Exception("Index is out of range") if ($index < 0 || $index > ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0)); + + if (UNIVERSAL::isa($column,'Schema::DB::Column')) { + + } elsif (UNIVERSAL::isa($column,'HASH')) { + $column = new Schema::DB::Column(%{$column}); + } else { + die new Exception("The invalid parameter"); + } + + if (exists $this->{$ColumnsByName}->{$column->Name}) { + die new Exception("The column already exists",$column->name); + } else { + $this->{$ColumnsByName}->{$column->Name} = $column; + splice @{$this->{$Columns}},$index,0,$column; + } + + return $column; +} + +sub RemoveColumn { + my ($this,$NameOrColumn,$Force) = @_; + + my $ColName; + if (UNIVERSAL::isa($NameOrColumn,'Schema::DB::Column')) { + $ColName = $NameOrColumn->Name; + } elsif (not ref $NameOrColumn) { + $ColName = $NameOrColumn; + } + + if (exists $this->{$ColumnsByName}->{$ColName}) { + my $index = 0; + foreach my $column(@{$this->{$Columns}}) { + last if $column->Name eq $ColName; + $index++; + } + + my $column = $this->{$Columns}[$index]; + if (my @constraints = $this->GetColumnConstraints($column)){ + $Force or die new Exception('Can\'t remove column which is used in the constraints',@constraints); + $this->RemoveConstraint($_) foreach @constraints; + } + + my $removed = splice @{$this->{$Columns}},$index,1; + delete $this->{$ColumnsByName}->{$ColName}; + return $removed; + } else { + die new Exception("The column not found",$NameOrColumn->Name); + } +} + +sub Column { + my ($this,$name) = @_; + + return $this->{$ColumnsByName}->{$name}; +} + +sub ColumnAt { + my ($this,$index) = @_; + + die new Exception("The index is out of range") if $index < 0 || $index >= ($this->{$Columns} ? scalar(@{$this->{$Columns}}) : 0); + + return $this->{$Columns}[$index]; +} + +sub AddConstraint { + my ($this,$Constraint) = @_; + + die new Exception('The invalid parameter') if not UNIVERSAL::isa($Constraint,'Schema::DB::Constraint'); + + $Constraint->Table == $this or die new Exception('The constaint must belong to the target table'); + + if (exists $this->{$Constraints}->{$Constraint->Name}) { + die new Exception('The table already has the specified constraint',$Constraint->Name); + } else { + if (UNIVERSAL::isa($Constraint,'Schema::DB::Constraint::PrimaryKey')) { + not $this->{$PrimaryKey} or die new Exception('The table already has a primary key'); + $this->{$PrimaryKey} = $Constraint; + } + + $this->{$Constraints}->{$Constraint->Name} = $Constraint; + } +} + +sub RemoveConstraint { + my ($this,$Constraint,$Force) = @_; + + my $cn = UNIVERSAL::isa($Constraint,'Schema::DB::Constraint') ? $Constraint->Name : $Constraint; + $Constraint = $this->{$Constraints}->{$cn} or die new Exception('The specified constraint doesn\'t exists',$cn); + + if (UNIVERSAL::isa($Constraint,'Schema::DB::Constraint::PrimaryKey')) { + not scalar keys %{$this->{$PrimaryKey}->ConnectedFK} or die new Exception('Can\'t remove Primary Key unless some foreign keys referenses it'); + + delete $this->{$PrimaryKey}; + } + $Constraint->Dispose; + delete $this->{$Constraints}->{$cn}; + return $cn; +} + +sub GetColumnConstraints { + my ($this,@Columns) = @_; + + my @cn = map { UNIVERSAL::isa($_ ,'Schema::DB::Column') ? $_ ->Name : $_ } @Columns; + exists $this->{$ColumnsByName}->{$_} or die new Exception('The specified column isn\'t found',$_) foreach @cn; + + return grep {$_->HasColumn(@cn)} values %{$this->{$Constraints}}; +} + +sub SetPrimaryKey { + my ($this,@ColumnList) = @_; + + $this->AddConstraint(new Schema::DB::Constraint::PrimaryKey(Name => $this->{$Name}.'_PK', Table => $this,Columns => \@ColumnList)); +} + +sub LinkTo { + my ($this,$table,@ColumnList) = @_; + $table->PrimaryKey or die new Exception('The referenced table must have a primary key'); + my $constraintName = $this->{$Name}.'_'.$table->Name.'_FK_'.join('_',map {ref $_ ? $_->Name : $_} @ColumnList); + $this->AddConstraint(new Schema::DB::Constraint::ForeignKey(Name => $constraintName, Table => $this,Columns => \@ColumnList, ReferencedTable => $table, ReferencedColumns => scalar($table->PrimaryKey->Columns))); +} + +sub Dispose { + my ($this) = @_; + + $_->Dispose() foreach values %{$this->{$Constraints}}; + + undef %{$this}; + $this->SUPER::Dispose(); +} + +1;