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   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__