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