annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
165
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
1 package IMPL::SQL::Schema::Traits::Diff;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
2 use strict;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
3 use warnings;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
4 use IMPL::lang;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
5
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
6 use IMPL::SQL::Schema();
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
7 use IMPL::SQL::Schema::Traits();
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
8
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
9 use constant {
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
10 schema_t => typeof IMPL::SQL::Schema # defining a constant is a good style to enable compile checks
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
11 };
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
12
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
13 sub Diff {
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
14 my ($self,$src,$dst) = @_;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
15
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
16 die new IMPL::InvalidArgumentException( src => "A valid source schema is required") unless is($src,schema_t);
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
17 die new IMPL::InvalidArgumentException( dst => "A valid desctination schema is requried" ) unless is($src,schema_t);
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
18
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
19 my %dstTables = map { $_->name, $_ } $dst->GetTables;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
20
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
21 my @operations;
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
22
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
23 foreach my $srcTable ( $src->GetTables) {
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
24 my $dstTable = delete $dstTables{$srcTable->name};
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
25
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
26 if (not $dstTable) {
167
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
27 # if a source table doesn't have a corresponding destination table, it should be deleted
165
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
28 push @operations, new IMPL::SQL::Schema::Traits::DropTable()
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
29 } else {
167
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
30 # a source table needs to be updated
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
31 push @operations, $self->_DiffTables($srcTable,$dstTable);
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
32 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
33
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
34 foreach my $tbl ( values %dstTables ) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
35 push @operations, new IMPL::SQL::Schema::Traits::CreateTable(
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
36 new IMPL::SQL::Schema::Traits::Table(
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
37 $tbl->name,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
38 [ map _Column2Traits($_), $tbl->columns ],
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
39 [ map _Constraint2Traits($_), $tbl->constraints],
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
40 $tbl->{tag}
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
41 )
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
42 )
165
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
43 }
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
44
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
45 }
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
46 }
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
47
167
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
48 sub _DiffTables {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
49 my ($self,$src,$dst) = @_;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
50
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
51 my @dropConstraints;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
52 my @createConstraints;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
53
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
54 my %srcConstraints = map { $_->name, $_ } $src->GetConstraints();
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
55 my %dstConstraints = map { $_->name, $_ } $dst->GetConstraints();
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
56
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
57 foreach my $cnSrcName (keys %srcConstraints) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
58 if ( my $cnDst = delete $dstConstraints{$cnSrcName} ) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
59 unless ( $srcConstraints{$cnSrcName}->SameValue($cnDst) ) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
60 push @dropConstraints,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
61 IMPL::SQL::Schema::Traits::AlterTableDropConstraint->new( $src->name, $cnSrcName );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
62 push @createConstraints,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
63 IMPL::SQL::Schema::Traits::AlterTableAddConstraint->new( $dst->name, _Constraint2Traits($cnDst) );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
64 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
65 } else {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
66 push @dropConstraints, IMPL::SQL::Schema::Traits::AlterTableDropConstrait->new( $src->name, $cnSrcName );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
67 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
68 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
69
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
70 foreach my $cnDst (values %dstConstraints) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
71 push @createConstraints,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
72 IMPL::SQL::Schema::Traits::AlterTableAddConstraint->new( $dst->name, _Constraint2Traits($cnDst) );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
73 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
74
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
75 my @deleteColumns;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
76 my @addColumns;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
77 my @updateColumns;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
78
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
79 my %dstColumnIndexes = map {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
80 my $col = $dst->GetColumnAt($_);
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
81 ($col->name, { column => $col, index => $_ })
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
82 } 0 .. $dst->ColumnsCount-1;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
83
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
84 # get changed and
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
85
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
86 my @columns;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
87
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
88 for( my $i=0; $i < $src->ColumnsCount; $i++) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
89 my $colSrc = $src->GetColumnAt($i);
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
90
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
91 if ( my $infoDst = delete $dstColumnIndexes{$colSrc->name} ) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
92 $infoDst->{update} = 1 unless $infoDst->{column}->SameValue($colSrc);
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
93 push @columns,$infoDst;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
94 } else {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
95 push @deleteColumns, IMPL::SQL::Schema::Traits::AlterTableDropColumn($src->name,$colSrc->name);
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
96 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
97 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
98
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
99 splice(@columns,$_->{index},0,$_) foreach ( sort { $a->{index} <=> $b->{index} } values %dstColumnIndexes );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
100
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
101 for(my $i =0; $i< @columns; $i ++) {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
102
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
103 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
104
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
105 # determine constraints to be dropped,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
106 # drop columns
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
107 # create columns
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
108 # update/reorder columns
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
109 # create constraints
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
110 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
111
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
112 sub _Column2Traits {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
113 my ($column) = @_;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
114
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
115 return new IMPL::SQL::Schema::Traits::Columns(
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
116 $column->name,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
117 $column->type,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
118 $column->isNullable,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
119 $column->defaultValue,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
120 $column->tag
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
121 );
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
122 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
123
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
124 sub _Constraint2Traits {
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
125 my ($constraint) = @_;
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
126
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
127 return new IMPL::SQL::Schema::Traits::Constraint(
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
128 $constraint->name,
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
129 [ map $_->name, $_->columns ]
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
130 )
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
131 }
1f7a6d762394 SQL schema in progress
sourcer
parents: 165
diff changeset
132
165
76515373dac0 Added Class::Template,
wizard
parents:
diff changeset
133 1;