annotate lib/IMPL/SQL/Schema/MySQL/Processor.pm @ 411:ee36115f6a34 ref20150831

sync
author cin
date Mon, 21 Sep 2015 00:53:10 +0300
parents c6e90e02dd17
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
407
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
1 package IMPL::SQL::Schema::MySQL::Processor;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
2 use strict;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
3
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
4 use mro;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
5 use IMPL::Const qw(:prop);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
6 use IMPL::declare {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
7 require => {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
8 MySQLFormatter => 'IMPL::SQL::Schema::MySQL::Formatter',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
9 AlterTableDropConstraint => '-IMPL::SQL::Schema::Traits::AlterTableDropConstraint',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
10 AlterTableAddConstraint => '-IMPL::SQL::Schema::Traits::AlterTableAddConstraint',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
11 DropTable => '-IMPL::SQL::Schema::Traits::DropTable',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
12 PrimitiveDropTable => '-IMPL::SQL::Schema::MySQL::Processor::PrimitiveDropTable',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
13 CreateTable => '-IMPL::SQL::Schema::Traits::CreateTable',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
14 Table => '-IMPL::SQL::Schema::Traits::Table',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
15 ForeignKey => '-IMPL::SQL::Schema::Traits::ForeignKey',
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
16
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
17 },
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
18 base => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
19 'IMPL::SQL::Schema::Processor' => sub { $_[0] }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
20 ],
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
21 props => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
22 formatter => PROP_RO,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
23 sqlBatch => PROP_RO
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
24 ]
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
25 };
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
26 use IMPL::lang qw(is);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
27
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
28 sub CTOR {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
29 my ( $this, $schema, %opts ) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
30
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
31 $this->formatter( $opts{formatter} || MySQLFormatter );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
32 $this->sqlBatch([]);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
33 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
34
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
35 sub AddSqlBatch {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
36 my $this = shift;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
37
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
38 push @{$this->sqlBatch}, @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
39 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
40
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
41 sub ApplyOperation {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
42 my ($this, $op, $iteration ) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
43
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
44 my @formatterParams;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
45
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
46 if ( is( $op, AlterTableDropConstraint ) ) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
47 my $constraint = $this
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
48 ->dbSchema
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
49 ->GetTable($op->tableName)
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
50 ->GetConstraint($op->constraintName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
51
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
52 push @formatterParams, ref $constraint;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
53 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
54 push @formatterParams, $this->dbSchema;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
55 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
56
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
57 if ( is( $op, CreateTable ) ) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
58 my @constraints;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
59 my @fk;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
60 my $table = $op->table;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
61
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
62 # отделяем создание внешних ключей от таблиц
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
63
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
64 foreach my $c (@{$table->{constraints} || []}) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
65 if ( is($c,ForeignKey)) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
66 push @fk,$c;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
67 } else {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
68 push @constraints, $c;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
69 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
70 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
71
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
72 if (@fk) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
73 $op = CreateTable->new(
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
74 Table->new(
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
75 $table->{name},
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
76 $table->{columns},
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
77 \@constraints,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
78 $table->{options}
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
79 )
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
80 );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
81
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
82 $this->AddPendingOperations(
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
83 map AlterTableAddConstraint->new($table->{name},$_), @fk
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
84 );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
85 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
86 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
87
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
88 if (is($op, DropTable)) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
89 my $table = $this->dbSchema->GetTable($op->tableName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
90
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
91 if(my $pk = $table->primaryKey) {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
92 $this->ApplyOperation($_,$iteration)
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
93 foreach
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
94 map
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
95 AlterTableDropConstraint->new($_->table->name,$_->name),
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
96 values %{$pk->connectedFK || {}};
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
97 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
98 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
99
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
100 $this->next::method($op,$iteration);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
101
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
102 $this->AddSqlBatch(
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
103 $this->formatter->Format($op,@formatterParams)
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
104 );
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
105 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
106
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
107 package IMPL::SQL::Schema::MySQL::Processor::PrimitiveDropTable;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
108 use IMPL::Const qw(:prop);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
109 use IMPL::declare {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
110 require => {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
111 ArgException => '-IMPL::InvalidArgumentException'
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
112 },
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
113 base => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
114 'IMPL::Object' => undef
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
115 ],
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
116 props => [
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
117 tableName => PROP_RO,
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
118 ]
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
119 };
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
120
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
121 sub CTOR {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
122 my ($this,$tableName) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
123
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
124 $this->tableName($tableName) or die ArgException->new("tableName is required");
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
125 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
126
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
127 sub CanApply {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
128 my ($this,$schema) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
129
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
130 my $table = $schema->GetTable( $this->tableName )
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
131 or return 0;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
132
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
133 my $pk = $table->primaryKey
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
134 or return 1;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
135
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
136 my $canDrop = keys(%{$pk->connectedFK || {}}) ? 0 : 1;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
137
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
138 warn "Can drop ", $this->tableName
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
139 if $canDrop;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
140
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
141 return $canDrop;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
142 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
143
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
144 sub Apply {
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
145 my ($this,$schema) = @_;
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
146
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
147 $schema->RemoveTable($this->tableName);
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
148 }
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
149
c6e90e02dd17 renamed Lib->lib
cin
parents:
diff changeset
150 1;