Mercurial > pub > Impl
view Lib/IMPL/SQL/Schema/MySQL/Processor.pm @ 378:2eed076cb944
rewritten IMPL::Resources::Strings + tests
author | cin |
---|---|
date | Wed, 15 Jan 2014 17:20:54 +0400 |
parents | 2f06250bab5f |
children |
line wrap: on
line source
package IMPL::SQL::Schema::MySQL::Processor; use strict; use mro; use IMPL::Const qw(:prop); use IMPL::declare { require => { MySQLFormatter => 'IMPL::SQL::Schema::MySQL::Formatter', AlterTableDropConstraint => '-IMPL::SQL::Schema::Traits::AlterTableDropConstraint', AlterTableAddConstraint => '-IMPL::SQL::Schema::Traits::AlterTableAddConstraint', DropTable => '-IMPL::SQL::Schema::Traits::DropTable', PrimitiveDropTable => '-IMPL::SQL::Schema::MySQL::Processor::PrimitiveDropTable', CreateTable => '-IMPL::SQL::Schema::Traits::CreateTable', Table => '-IMPL::SQL::Schema::Traits::Table', ForeignKey => '-IMPL::SQL::Schema::Traits::ForeignKey', }, base => [ 'IMPL::SQL::Schema::Processor' => sub { $_[0] } ], props => [ formatter => PROP_RO, sqlBatch => PROP_RO ] }; use IMPL::lang qw(is); sub CTOR { my ( $this, $schema, %opts ) = @_; $this->formatter( $opts{formatter} || MySQLFormatter ); $this->sqlBatch([]); } sub AddSqlBatch { my $this = shift; push @{$this->sqlBatch}, @_; } sub ApplyOperation { my ($this, $op, $iteration ) = @_; my @formatterParams; if ( is( $op, AlterTableDropConstraint ) ) { my $constraint = $this ->dbSchema ->GetTable($op->tableName) ->GetConstraint($op->constraintName); push @formatterParams, ref $constraint; } else { push @formatterParams, $this->dbSchema; } if ( is( $op, CreateTable ) ) { my @constraints; my @fk; my $table = $op->table; # отделяем создание внешних ключей от таблиц foreach my $c (@{$table->{constraints} || []}) { if ( is($c,ForeignKey)) { push @fk,$c; } else { push @constraints, $c; } } if (@fk) { $op = CreateTable->new( Table->new( $table->{name}, $table->{columns}, \@constraints, $table->{options} ) ); $this->AddPendingOperations( map AlterTableAddConstraint->new($table->{name},$_), @fk ); } } if (is($op, DropTable)) { my $table = $this->dbSchema->GetTable($op->tableName); if(my $pk = $table->primaryKey) { $this->ApplyOperation($_,$iteration) foreach map AlterTableDropConstraint->new($_->table->name,$_->name), values %{$pk->connectedFK || {}}; } } $this->next::method($op,$iteration); $this->AddSqlBatch( $this->formatter->Format($op,@formatterParams) ); } package IMPL::SQL::Schema::MySQL::Processor::PrimitiveDropTable; use IMPL::Const qw(:prop); use IMPL::declare { require => { ArgException => '-IMPL::InvalidArgumentException' }, base => [ 'IMPL::Object' => undef ], props => [ tableName => PROP_RO, ] }; sub CTOR { my ($this,$tableName) = @_; $this->tableName($tableName) or die ArgException->new("tableName is required"); } sub CanApply { my ($this,$schema) = @_; my $table = $schema->GetTable( $this->tableName ) or return 0; my $pk = $table->primaryKey or return 1; my $canDrop = keys(%{$pk->connectedFK || {}}) ? 0 : 1; warn "Can drop ", $this->tableName if $canDrop; return $canDrop; } sub Apply { my ($this,$schema) = @_; $schema->RemoveTable($this->tableName); } 1;