comparison lib/IMPL/SQL/Schema/MySQL/Processor.pm @ 407:c6e90e02dd17 ref20150831

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