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   81 use strict;
  11         27  
  11         341  
6 11     11   65 use warnings;
  11         30  
  11         321  
7              
8 11     11   70 use List::MoreUtils qw(all);
  11         173  
  11         118  
9 11     11   8153 use Moo;
  11         35  
  11         87  
10 11     11   3986 use Scalar::Util qw(blessed);
  11         26  
  11         589  
11 11     11   79 use YAML::Tiny;
  11         49  
  11         566  
12              
13 11     11   5296 use MySQL::Workbench::Parser::Column;
  11         1298  
  11         474  
14 11     11   5683 use MySQL::Workbench::Parser::Index;
  11         34  
  11         14787  
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 246 my $self = shift;
94 27         92 $self->_parse;
95             }
96              
97              
98             sub as_hash {
99 13     13 1 30 my $self = shift;
100              
101 13         24 my @columns;
102 13         25 for my $column ( @{$self->columns} ) {
  13         249  
103 35         186 push @columns, $column->as_hash;
104             }
105              
106 13         25 my @indexes;
107 13         25 for my $index ( @{ $self->indexes } ) {
  13         239  
108 25         177 push @indexes, $index->as_hash;
109             }
110              
111 13         106 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       52 $info{comment} = $self->comment if $self->comment;
120              
121 13         49 return \%info;
122             }
123              
124             sub _parse {
125 27     27   54 my $self = shift;
126              
127 27         81 my $node = $self->node;
128              
129 27         57 my @columns;
130 27         96 my @column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Column"]' );
131 27         5452 for my $column_node ( @column_nodes ) {
132 69         1500 my $column_obj = MySQL::Workbench::Parser::Column->new(
133             node => $column_node,
134             table => $self,
135             );
136 69         231 push @columns, $column_obj;
137             }
138 27         723 $self->_set_columns( \@columns );
139              
140 27         351 my $comment = $node->findvalue( './value[@key="comment"]' );
141 27 100       3496 $self->_set_comment( $comment ) if $comment;
142              
143 27         94 my $name = $node->findvalue( './value[@key="name"]' );
144 27         3145 $self->_set_name( $name );
145              
146 27         62 my %foreign_keys;
147 27         79 my @foreign_key_nodes = $node->findnodes( './value[@key="foreignKeys"]/value[@struct-name="db.mysql.ForeignKey"]' );
148 27         2131 for my $foreign_key_node ( @foreign_key_nodes ) {
149 13         53 my $foreign_table_id = $foreign_key_node->findvalue( 'link[@key="referencedTable"]' );
150 13         1035 my $foreign_column_id = $foreign_key_node->findvalue( 'value[@key="referencedColumns"]/link' );
151              
152 13         1227 my $foreign_data = $self->_foreign_data(
153             table_id => $foreign_table_id,
154             column_id => $foreign_column_id,
155             );
156              
157 13         171 my $table = $foreign_data->{table};
158 13         28 my $column = $foreign_data->{column};
159              
160 13         43 my $me_column_id = $foreign_key_node->findvalue( './/value[@key="columns"]/link' );
161 13         1203 my $me_column = $node->findvalue( './/value[@id="' . $me_column_id . '"]/value[@key="name"]' );
162              
163 13         3428 my %actions;
164 13         55 my $delete_action = $foreign_key_node->findvalue( './/value[@key="deleteRule"]' );
165 13         1141 $actions{on_delete} = lc $delete_action;
166              
167 13         43 my $update_action = $foreign_key_node->findvalue( './/value[@key="updateRule"]' );
168 13         1136 $actions{on_update} = lc $update_action;
169              
170 13         30 push @{ $foreign_keys{$table} }, { %actions, me => $me_column, foreign => $column };
  13         170  
171             }
172              
173 27         56 my @indexes;
174 27         95 my @index_column_nodes = $node->findnodes( './/value[@struct-name="db.mysql.Index"]' );
175 27         4455 for my $index_column_node ( @index_column_nodes ) {
176 51         492 my $type = $index_column_node->findvalue( './/value[@key="indexType"]' );
177              
178 51         6138 my $index_obj = MySQL::Workbench::Parser::Index->new(
179             node => $index_column_node,
180             table => $self,
181             );
182 51         134 push @indexes, $index_obj;
183              
184 51 100       194 next if $type ne 'PRIMARY';
185              
186 27         96 my @column_nodes = $index_column_node->findnodes( './/link[@key="referencedColumn"]' );
187             my @column_names = map{
188 27         1141 my $id = $_->textContent;
  33         1790  
189 33         164 $node->findvalue( './/value[@id="' . $id . '"]/value[@key="name"]' );
190             }@column_nodes;
191              
192 27         7046 $self->_set_primary_key( \@column_names );
193             }
194              
195 27         800 $self->_set_foreign_keys( \%foreign_keys );
196 27         597 $self->_set_indexes( \@indexes );
197             }
198              
199              
200             sub get_datatype {
201 69     69 1 131 my $self = shift;
202              
203 69         313 return $self->parser->get_datatype( @_ );
204             }
205              
206             sub _foreign_data {
207 13     13   32 my $self = shift;
208 13         55 my %ids = @_;
209              
210             my ($foreign_table_node) = $self->node->parentNode->findnodes(
211 13         149 'value[@struct-name="db.mysql.Table" and @id="' . $ids{table_id} . '"]'
212             );
213              
214 13         631 my $foreign_table_name = $foreign_table_node->findvalue( 'value[@key="name"]' );
215             my $foreign_column_name = $foreign_table_node->findvalue(
216 13         1644 './/value[@id="' . $ids{column_id} . '"]/value[@key="name"]'
217             );
218              
219 13         3012 return { table => $foreign_table_name, column => $foreign_column_name };
220             }
221              
222             1;
223              
224             __END__