File Coverage

blib/lib/MySQL/Workbench/Parser/Table.pm
Criterion Covered Total %
statement 89 89 100.0
branch 6 6 100.0
condition n/a
subroutine 13 13 100.0
pod 3 3 100.0
total 111 111 100.0


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   89 use strict;
  11         29  
  11         1486  
6 11     11   86 use warnings;
  11         30  
  11         373  
7              
8 11     11   73 use List::MoreUtils qw(all);
  11         125  
  11         472  
9 11     11   8005 use Moo;
  11         34  
  11         88  
10 11     11   3871 use Scalar::Util qw(blessed);
  11         25  
  11         635  
11 11     11   65 use YAML::Tiny;
  11         34  
  11         551  
12              
13 11     11   5529 use MySQL::Workbench::Parser::Column;
  11         43  
  11         587  
14 11     11   6056 use MySQL::Workbench::Parser::Index;
  11         37  
  11         15357  
15              
16             our $VERSION = '1.10';
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 265 my $self = shift;
94 27         111 $self->_parse;
95             }
96              
97              
98             sub as_hash {
99 13     13 1 29 my $self = shift;
100              
101 13         24 my @columns;
102 13         25 for my $column ( @{$self->columns} ) {
  13         236  
103 35         212 push @columns, $column->as_hash;
104             }
105              
106 13         30 my @indexes;
107 13         23 for my $index ( @{ $self->indexes } ) {
  13         245  
108 25         205 push @indexes, $index->as_hash;
109             }
110              
111 13         111 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       56 $info{comment} = $self->comment if $self->comment;
120              
121 13         49 return \%info;
122             }
123              
124             sub _parse {
125 27     27   61 my $self = shift;
126              
127 27         88 my $node = $self->node;
128              
129 27         50 my @columns;
130 27         97 my @column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Column"]' );
131 27         5265 for my $column_node ( @column_nodes ) {
132 69         1496 my $column_obj = MySQL::Workbench::Parser::Column->new(
133             node => $column_node,
134             table => $self,
135             );
136 69         238 push @columns, $column_obj;
137             }
138 27         688 $self->_set_columns( \@columns );
139              
140 27         392 my $comment = $node->findvalue( './value[@key="comment"]' );
141 27 100       3306 $self->_set_comment( $comment ) if $comment;
142              
143 27         133 my $name = $node->findvalue( './value[@key="name"]' );
144 27         3468 $self->_set_name( $name );
145              
146 27         52 my %foreign_keys;
147 27         84 my @foreign_key_nodes = $node->findnodes( './value[@key="foreignKeys"]/value[@struct-name="db.mysql.ForeignKey"]' );
148 27         2223 for my $foreign_key_node ( @foreign_key_nodes ) {
149 13         58 my $foreign_table_id = $foreign_key_node->findvalue( 'link[@key="referencedTable"]' );
150 13         990 my $foreign_column_id = $foreign_key_node->findvalue( 'value[@key="referencedColumns"]/link' );
151              
152 13         1089 my $foreign_data = $self->_foreign_data(
153             table_id => $foreign_table_id,
154             column_id => $foreign_column_id,
155             );
156              
157 13         163 my $table = $foreign_data->{table};
158 13         34 my $column = $foreign_data->{column};
159              
160 13         38 my $me_column_id = $foreign_key_node->findvalue( './/value[@key="columns"]/link' );
161 13         1171 my $me_column = $node->findvalue( './/value[@id="' . $me_column_id . '"]/value[@key="name"]' );
162              
163 13         3538 my %actions;
164 13         50 my $delete_action = $foreign_key_node->findvalue( './/value[@key="deleteRule"]' );
165 13         1155 $actions{on_delete} = lc $delete_action;
166              
167 13         41 my $update_action = $foreign_key_node->findvalue( './/value[@key="updateRule"]' );
168 13         1068 $actions{on_update} = lc $update_action;
169              
170 13         33 push @{ $foreign_keys{$table} }, { %actions, me => $me_column, foreign => $column };
  13         146  
171             }
172              
173 27         66 my @indexes;
174 27         88 my @index_column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Index"]' );
175 27         4582 for my $index_column_node ( @index_column_nodes ) {
176 51         555 my $type = $index_column_node->findvalue( './/value[@key="indexType"]' );
177              
178 51         6033 my $index_obj = MySQL::Workbench::Parser::Index->new(
179             node => $index_column_node,
180             table => $self,
181             );
182 51         130 push @indexes, $index_obj;
183              
184 51 100       203 next if $type ne 'PRIMARY';
185              
186 27         85 my @column_nodes = $index_column_node->findnodes( './/link[@key="referencedColumn"]' );
187             my @column_names = map{
188 27         1115 my $id = $_->textContent;
  33         1743  
189 33         168 $node->findvalue( './/value[@id="' . $id . '"]/value[@key="name"]' );
190             }@column_nodes;
191              
192 27         7097 $self->_set_primary_key( \@column_names );
193             }
194              
195 27         802 $self->_set_foreign_keys( \%foreign_keys );
196 27         607 $self->_set_indexes( \@indexes );
197             }
198              
199              
200             sub get_datatype {
201 69     69 1 163 my $self = shift;
202              
203 69         320 return $self->parser->get_datatype( @_ );
204             }
205              
206             sub _foreign_data {
207 13     13   29 my $self = shift;
208 13         59 my %ids = @_;
209              
210             my ($foreign_table_node) = $self->node->parentNode->findnodes(
211 13         147 'value[@struct-name="db.mysql.Table" and @id="' . $ids{table_id} . '"]'
212             );
213              
214 13         617 my $foreign_table_name = $foreign_table_node->findvalue( 'value[@key="name"]' );
215             my $foreign_column_name = $foreign_table_node->findvalue(
216 13         1702 './/value[@id="' . $ids{column_id} . '"]/value[@key="name"]'
217             );
218              
219 13         2969 return { table => $foreign_table_name, column => $foreign_column_name };
220             }
221              
222             1;
223              
224             __END__