Mercurial > pub > Impl
diff Lib/IMPL/SQL/Schema/Traits/Diff.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/Traits/Diff.pm Sat Apr 23 23:12:06 2011 +0400 +++ b/Lib/IMPL/SQL/Schema/Traits/Diff.pm Thu May 12 08:57:19 2011 +0400 @@ -24,12 +24,110 @@ my $dstTable = delete $dstTables{$srcTable->name}; if (not $dstTable) { + # if a source table doesn't have a corresponding destination table, it should be deleted push @operations, new IMPL::SQL::Schema::Traits::DropTable() } else { - + # a source table needs to be updated + push @operations, $self->_DiffTables($srcTable,$dstTable); + } + + foreach my $tbl ( values %dstTables ) { + push @operations, new IMPL::SQL::Schema::Traits::CreateTable( + new IMPL::SQL::Schema::Traits::Table( + $tbl->name, + [ map _Column2Traits($_), $tbl->columns ], + [ map _Constraint2Traits($_), $tbl->constraints], + $tbl->{tag} + ) + ) } } } +sub _DiffTables { + my ($self,$src,$dst) = @_; + + my @dropConstraints; + my @createConstraints; + + my %srcConstraints = map { $_->name, $_ } $src->GetConstraints(); + my %dstConstraints = map { $_->name, $_ } $dst->GetConstraints(); + + foreach my $cnSrcName (keys %srcConstraints) { + if ( my $cnDst = delete $dstConstraints{$cnSrcName} ) { + unless ( $srcConstraints{$cnSrcName}->SameValue($cnDst) ) { + push @dropConstraints, + IMPL::SQL::Schema::Traits::AlterTableDropConstraint->new( $src->name, $cnSrcName ); + push @createConstraints, + IMPL::SQL::Schema::Traits::AlterTableAddConstraint->new( $dst->name, _Constraint2Traits($cnDst) ); + } + } else { + push @dropConstraints, IMPL::SQL::Schema::Traits::AlterTableDropConstrait->new( $src->name, $cnSrcName ); + } + } + + foreach my $cnDst (values %dstConstraints) { + push @createConstraints, + IMPL::SQL::Schema::Traits::AlterTableAddConstraint->new( $dst->name, _Constraint2Traits($cnDst) ); + } + + my @deleteColumns; + my @addColumns; + my @updateColumns; + + my %dstColumnIndexes = map { + my $col = $dst->GetColumnAt($_); + ($col->name, { column => $col, index => $_ }) + } 0 .. $dst->ColumnsCount-1; + + # get changed and + + my @columns; + + for( my $i=0; $i < $src->ColumnsCount; $i++) { + my $colSrc = $src->GetColumnAt($i); + + if ( my $infoDst = delete $dstColumnIndexes{$colSrc->name} ) { + $infoDst->{update} = 1 unless $infoDst->{column}->SameValue($colSrc); + push @columns,$infoDst; + } else { + push @deleteColumns, IMPL::SQL::Schema::Traits::AlterTableDropColumn($src->name,$colSrc->name); + } + } + + splice(@columns,$_->{index},0,$_) foreach ( sort { $a->{index} <=> $b->{index} } values %dstColumnIndexes ); + + for(my $i =0; $i< @columns; $i ++) { + + } + + # determine constraints to be dropped, + # drop columns + # create columns + # update/reorder columns + # create constraints +} + +sub _Column2Traits { + my ($column) = @_; + + return new IMPL::SQL::Schema::Traits::Columns( + $column->name, + $column->type, + $column->isNullable, + $column->defaultValue, + $column->tag + ); +} + +sub _Constraint2Traits { + my ($constraint) = @_; + + return new IMPL::SQL::Schema::Traits::Constraint( + $constraint->name, + [ map $_->name, $_->columns ] + ) +} + 1; \ No newline at end of file