line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MySQL::Workbench::Parser::Table; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# ABSTRACT: A table of the ER model |
4
|
|
|
|
|
|
|
|
5
|
11
|
|
|
11
|
|
69
|
use strict; |
|
11
|
|
|
|
|
37
|
|
|
11
|
|
|
|
|
285
|
|
6
|
11
|
|
|
11
|
|
51
|
use warnings; |
|
11
|
|
|
|
|
20
|
|
|
11
|
|
|
|
|
273
|
|
7
|
|
|
|
|
|
|
|
8
|
11
|
|
|
11
|
|
53
|
use List::MoreUtils qw(all); |
|
11
|
|
|
|
|
101
|
|
|
11
|
|
|
|
|
106
|
|
9
|
11
|
|
|
11
|
|
6559
|
use Moo; |
|
11
|
|
|
|
|
27
|
|
|
11
|
|
|
|
|
89
|
|
10
|
11
|
|
|
11
|
|
3313
|
use Scalar::Util qw(blessed); |
|
11
|
|
|
|
|
21
|
|
|
11
|
|
|
|
|
533
|
|
11
|
11
|
|
|
11
|
|
61
|
use YAML::Tiny; |
|
11
|
|
|
|
|
34
|
|
|
11
|
|
|
|
|
457
|
|
12
|
|
|
|
|
|
|
|
13
|
11
|
|
|
11
|
|
4405
|
use MySQL::Workbench::Parser::Column; |
|
11
|
|
|
|
|
37
|
|
|
11
|
|
|
|
|
1704
|
|
14
|
11
|
|
|
11
|
|
5407
|
use MySQL::Workbench::Parser::Index; |
|
11
|
|
|
|
|
30
|
|
|
11
|
|
|
|
|
12113
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = '1.09'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has node => ( |
19
|
|
|
|
|
|
|
is => 'ro', |
20
|
|
|
|
|
|
|
required => 1, |
21
|
|
|
|
|
|
|
isa => sub { |
22
|
|
|
|
|
|
|
blessed $_[0] && $_[0]->isa( 'XML::LibXML::Node' ); |
23
|
|
|
|
|
|
|
}, |
24
|
|
|
|
|
|
|
); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has parser => ( |
27
|
|
|
|
|
|
|
is => 'ro', |
28
|
|
|
|
|
|
|
required => 1, |
29
|
|
|
|
|
|
|
isa => sub { |
30
|
|
|
|
|
|
|
blessed $_[0] && $_[0]->isa( 'MySQL::Workbench::Parser' ); |
31
|
|
|
|
|
|
|
}, |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has columns => ( |
35
|
|
|
|
|
|
|
is => 'rwp', |
36
|
|
|
|
|
|
|
isa => sub { |
37
|
|
|
|
|
|
|
ref $_[0] && ref $_[0] eq 'ARRAY' && |
38
|
|
|
|
|
|
|
all{ blessed $_ && $_->isa( 'MySQL::Workbench::Parser::Column' ) }@{$_[0]} |
39
|
|
|
|
|
|
|
}, |
40
|
|
|
|
|
|
|
lazy => 1, |
41
|
|
|
|
|
|
|
default => sub { [] }, |
42
|
|
|
|
|
|
|
); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
has indexes => ( |
45
|
|
|
|
|
|
|
is => 'rwp', |
46
|
|
|
|
|
|
|
isa => sub { |
47
|
|
|
|
|
|
|
ref $_[0] && ref $_[0] eq 'ARRAY' && |
48
|
|
|
|
|
|
|
all{ blessed $_ && $_->isa( 'MySQL::Workbench::Parser::Index' ) }@{$_[0]} |
49
|
|
|
|
|
|
|
}, |
50
|
|
|
|
|
|
|
lazy => 1, |
51
|
|
|
|
|
|
|
default => sub { [] }, |
52
|
|
|
|
|
|
|
); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
has foreign_keys => ( |
55
|
|
|
|
|
|
|
is => 'rwp', |
56
|
|
|
|
|
|
|
isa => sub { |
57
|
|
|
|
|
|
|
ref $_[0] && ref $_[0] eq 'HASH' |
58
|
|
|
|
|
|
|
}, |
59
|
|
|
|
|
|
|
default => sub { {} }, |
60
|
|
|
|
|
|
|
); |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
has primary_key => ( |
63
|
|
|
|
|
|
|
is => 'rwp', |
64
|
|
|
|
|
|
|
isa => sub { |
65
|
|
|
|
|
|
|
ref $_[0] && ref $_[0] eq 'ARRAY' |
66
|
|
|
|
|
|
|
}, |
67
|
|
|
|
|
|
|
default => sub { [] }, |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
has comment => (is => 'rwp'); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
has name => ( is => 'rwp' ); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
has column_mapping => ( |
75
|
|
|
|
|
|
|
is => 'rwp', |
76
|
|
|
|
|
|
|
lazy => 1, |
77
|
|
|
|
|
|
|
isa => sub { |
78
|
|
|
|
|
|
|
ref $_[0] && ref $_[0] eq 'HASH' |
79
|
|
|
|
|
|
|
}, |
80
|
|
|
|
|
|
|
default => sub { |
81
|
|
|
|
|
|
|
my $self = shift; |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
my %map = map{ |
84
|
|
|
|
|
|
|
$_->id => $_->name |
85
|
|
|
|
|
|
|
}@{ $self->columns || [] }; |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
\%map; |
88
|
|
|
|
|
|
|
}, |
89
|
|
|
|
|
|
|
); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub BUILD { |
93
|
27
|
|
|
27
|
1
|
192
|
my $self = shift; |
94
|
27
|
|
|
|
|
77
|
$self->_parse; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub as_hash { |
99
|
13
|
|
|
13
|
1
|
22
|
my $self = shift; |
100
|
|
|
|
|
|
|
|
101
|
13
|
|
|
|
|
22
|
my @columns; |
102
|
13
|
|
|
|
|
21
|
for my $column ( @{$self->columns} ) { |
|
13
|
|
|
|
|
226
|
|
103
|
35
|
|
|
|
|
156
|
push @columns, $column->as_hash; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
13
|
|
|
|
|
51
|
my @indexes; |
107
|
13
|
|
|
|
|
23
|
for my $index ( @{ $self->indexes } ) { |
|
13
|
|
|
|
|
209
|
|
108
|
25
|
|
|
|
|
156
|
push @indexes, $index->as_hash; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
13
|
|
|
|
|
103
|
my %info = ( |
112
|
|
|
|
|
|
|
name => $self->name, |
113
|
|
|
|
|
|
|
columns => \@columns, |
114
|
|
|
|
|
|
|
indexes => \@indexes, |
115
|
|
|
|
|
|
|
foreign_keys => $self->foreign_keys, |
116
|
|
|
|
|
|
|
primary_key => $self->primary_key, |
117
|
|
|
|
|
|
|
); |
118
|
|
|
|
|
|
|
|
119
|
13
|
100
|
|
|
|
45
|
$info{comment} = $self->comment if $self->comment; |
120
|
|
|
|
|
|
|
|
121
|
13
|
|
|
|
|
38
|
return \%info; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub _parse { |
125
|
27
|
|
|
27
|
|
54
|
my $self = shift; |
126
|
|
|
|
|
|
|
|
127
|
27
|
|
|
|
|
79
|
my $node = $self->node; |
128
|
|
|
|
|
|
|
|
129
|
27
|
|
|
|
|
41
|
my @columns; |
130
|
27
|
|
|
|
|
91
|
my @column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Column"]' ); |
131
|
27
|
|
|
|
|
4673
|
for my $column_node ( @column_nodes ) { |
132
|
69
|
|
|
|
|
1229
|
my $column_obj = MySQL::Workbench::Parser::Column->new( |
133
|
|
|
|
|
|
|
node => $column_node, |
134
|
|
|
|
|
|
|
table => $self, |
135
|
|
|
|
|
|
|
); |
136
|
69
|
|
|
|
|
187
|
push @columns, $column_obj; |
137
|
|
|
|
|
|
|
} |
138
|
27
|
|
|
|
|
558
|
$self->_set_columns( \@columns ); |
139
|
|
|
|
|
|
|
|
140
|
27
|
|
|
|
|
264
|
my $comment = $node->findvalue( './value[@key="comment"]' ); |
141
|
27
|
100
|
|
|
|
2817
|
$self->_set_comment( $comment ) if $comment; |
142
|
|
|
|
|
|
|
|
143
|
27
|
|
|
|
|
65
|
my $name = $node->findvalue( './value[@key="name"]' ); |
144
|
27
|
|
|
|
|
2446
|
$self->_set_name( $name ); |
145
|
|
|
|
|
|
|
|
146
|
27
|
|
|
|
|
44
|
my %foreign_keys; |
147
|
27
|
|
|
|
|
69
|
my @foreign_key_nodes = $node->findnodes( './value[@key="foreignKeys"]/value[@struct-name="db.mysql.ForeignKey"]' ); |
148
|
27
|
|
|
|
|
1640
|
for my $foreign_key_node ( @foreign_key_nodes ) { |
149
|
13
|
|
|
|
|
39
|
my $foreign_table_id = $foreign_key_node->findvalue( 'link[@key="referencedTable"]' ); |
150
|
13
|
|
|
|
|
788
|
my $foreign_column_id = $foreign_key_node->findvalue( 'value[@key="referencedColumns"]/link' ); |
151
|
|
|
|
|
|
|
|
152
|
13
|
|
|
|
|
856
|
my $foreign_data = $self->_foreign_data( |
153
|
|
|
|
|
|
|
table_id => $foreign_table_id, |
154
|
|
|
|
|
|
|
column_id => $foreign_column_id, |
155
|
|
|
|
|
|
|
); |
156
|
|
|
|
|
|
|
|
157
|
13
|
|
|
|
|
121
|
my $table = $foreign_data->{table}; |
158
|
13
|
|
|
|
|
38
|
my $column = $foreign_data->{column}; |
159
|
|
|
|
|
|
|
|
160
|
13
|
|
|
|
|
33
|
my $me_column_id = $foreign_key_node->findvalue( './/value[@key="columns"]/link' ); |
161
|
13
|
|
|
|
|
995
|
my $me_column = $node->findvalue( './/value[@id="' . $me_column_id . '"]/value[@key="name"]' ); |
162
|
|
|
|
|
|
|
|
163
|
13
|
|
|
|
|
2876
|
my %actions; |
164
|
13
|
|
|
|
|
33
|
my $delete_action = $foreign_key_node->findvalue( './/value[@key="deleteRule"]' ); |
165
|
13
|
|
|
|
|
923
|
$actions{on_delete} = lc $delete_action; |
166
|
|
|
|
|
|
|
|
167
|
13
|
|
|
|
|
36
|
my $update_action = $foreign_key_node->findvalue( './/value[@key="updateRule"]' ); |
168
|
13
|
|
|
|
|
905
|
$actions{on_update} = lc $update_action; |
169
|
|
|
|
|
|
|
|
170
|
13
|
|
|
|
|
23
|
push @{ $foreign_keys{$table} }, { %actions, me => $me_column, foreign => $column }; |
|
13
|
|
|
|
|
114
|
|
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
27
|
|
|
|
|
51
|
my @indexes; |
174
|
27
|
|
|
|
|
70
|
my @index_column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Index"]' ); |
175
|
27
|
|
|
|
|
3735
|
for my $index_column_node ( @index_column_nodes ) { |
176
|
51
|
|
|
|
|
388
|
my $type = $index_column_node->findvalue( './/value[@key="indexType"]' ); |
177
|
|
|
|
|
|
|
|
178
|
51
|
|
|
|
|
4901
|
my $index_obj = MySQL::Workbench::Parser::Index->new( |
179
|
|
|
|
|
|
|
node => $index_column_node, |
180
|
|
|
|
|
|
|
table => $self, |
181
|
|
|
|
|
|
|
); |
182
|
51
|
|
|
|
|
103
|
push @indexes, $index_obj; |
183
|
|
|
|
|
|
|
|
184
|
51
|
100
|
|
|
|
155
|
next if $type ne 'PRIMARY'; |
185
|
|
|
|
|
|
|
|
186
|
27
|
|
|
|
|
69
|
my @column_nodes = $index_column_node->findnodes( './/link[@key="referencedColumn"]' ); |
187
|
|
|
|
|
|
|
my @column_names = map{ |
188
|
27
|
|
|
|
|
890
|
my $id = $_->textContent; |
|
33
|
|
|
|
|
1456
|
|
189
|
33
|
|
|
|
|
135
|
$node->findvalue( './/value[@id="' . $id . '"]/value[@key="name"]' ); |
190
|
|
|
|
|
|
|
}@column_nodes; |
191
|
|
|
|
|
|
|
|
192
|
27
|
|
|
|
|
5909
|
$self->_set_primary_key( \@column_names ); |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
27
|
|
|
|
|
630
|
$self->_set_foreign_keys( \%foreign_keys ); |
196
|
27
|
|
|
|
|
482
|
$self->_set_indexes( \@indexes ); |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub get_datatype { |
201
|
69
|
|
|
69
|
1
|
111
|
my $self = shift; |
202
|
|
|
|
|
|
|
|
203
|
69
|
|
|
|
|
263
|
return $self->parser->get_datatype( @_ ); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub _foreign_data { |
207
|
13
|
|
|
13
|
|
23
|
my $self = shift; |
208
|
13
|
|
|
|
|
47
|
my %ids = @_; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
my ($foreign_table_node) = $self->node->parentNode->findnodes( |
211
|
13
|
|
|
|
|
126
|
'value[@struct-name="db.mysql.Table" and @id="' . $ids{table_id} . '"]' |
212
|
|
|
|
|
|
|
); |
213
|
|
|
|
|
|
|
|
214
|
13
|
|
|
|
|
483
|
my $foreign_table_name = $foreign_table_node->findvalue( 'value[@key="name"]' ); |
215
|
|
|
|
|
|
|
my $foreign_column_name = $foreign_table_node->findvalue( |
216
|
13
|
|
|
|
|
1325
|
'.//value[@id="' . $ids{column_id} . '"]/value[@key="name"]' |
217
|
|
|
|
|
|
|
); |
218
|
|
|
|
|
|
|
|
219
|
13
|
|
|
|
|
2451
|
return { table => $foreign_table_name, column => $foreign_column_name }; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
1; |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
__END__ |