File Coverage

blib/lib/OPM/Maker/Command/sopm.pm
Criterion Covered Total %
statement 341 366 93.1
branch 114 166 68.6
condition 23 41 56.1
subroutine 32 36 88.8
pod 6 6 100.0
total 516 615 83.9


line stmt bran cond sub pod time code
1             package OPM::Maker::Command::sopm;
2             $OPM::Maker::Command::sopm::VERSION = '1.1.1';
3 33     33   29112 use v5.10;
  33         132  
4              
5 33     33   193 use strict;
  33         109  
  33         734  
6 33     33   159 use warnings;
  33         86  
  33         974  
7              
8             # ABSTRACT: Build .sopm file based on metadata
9              
10 33     33   231 use Carp;
  33         69  
  33         2276  
11 33     33   16591 use File::Find::Rule;
  33         274975  
  33         293  
12 33     33   1806 use File::Basename;
  33         83  
  33         2160  
13 33     33   211 use File::Spec;
  33         70  
  33         619  
14 33     33   16812 use IO::File;
  33         261211  
  33         4238  
15 33     33   21152 use JSON;
  33         263537  
  33         295  
16 33     33   5148 use List::Util qw(first max);
  33         90  
  33         2203  
17 33     33   13480 use Path::Class ();
  33         845356  
  33         876  
18 33     33   22828 use XML::LibXML;
  33         1394659  
  33         275  
19 33     33   21817 use XML::LibXML::PrettyPrint;
  33         252640  
  33         335  
20              
21 33     33   20351 use OPM::Maker -command;
  33         1592029  
  33         369  
22 33     33   223348 use OPM::Maker::Utils::OTRS3;
  33         101  
  33         6145  
23 33     33   18264 use OPM::Maker::Utils::OTRS4;
  33         86  
  33         146638  
24              
25             sub abstract {
26 0     0 1 0 return "build sopm file based on metadata";
27             }
28              
29             sub usage_desc {
30 0     0 1 0 return "opmbuild sopm [--config ] [--cvs] ";
31             }
32              
33             sub opt_spec {
34             return (
35 0     0 1 0 [ 'config=s', 'JSON file that provides all the metadata' ],
36             [ 'cvs' , 'Add CVS tag to .sopm' ],
37             );
38             }
39              
40             sub validate_args {
41 0     0 1 0 my ($self, $opt, $args) = @_;
42              
43 0 0       0 if ( !$opt->{config} ) {
44 0   0     0 my @json_files = File::Find::Rule->file->name( '*.json' )->in( $args->[0] || '.' );
45              
46             @json_files > 1 ?
47             $self->usage_error( 'found more than one json file, please specify the config file to use' ) :
48 0 0       0 do{ $opt->{config} = $json_files[0] };
  0         0  
49             }
50            
51 0 0       0 if ( !$opt->{config} ) {
52 0         0 $self->usage_error( 'Please specify the config file to use' );
53             }
54            
55 0         0 my $config = Path::Class::File->new( $opt->{config} );
56 0         0 my $json = JSON->new->relaxed;
57 0         0 my $json_text = $config->slurp;
58 0 0       0 $self->usage_error( 'config file has to be in JSON format: ' . $@ ) if ! eval{ $json->decode( $json_text ); 1; };
  0         0  
  0         0  
59             }
60              
61             sub execute {
62 36     36 1 55333 my ($self, $opt, $args) = @_;
63              
64 36 50       165 if ( !$opt->{config} ) {
65 0         0 print $self->usage->text;
66 0         0 return;
67             }
68            
69 36         388 my $config = Path::Class::File->new( $opt->{config} );
70 36         8987 my $json_text = $config->slurp;
71 36         12059 my $object = JSON->new->relaxed;
72 36         1017 my $json = $object->decode( $json_text );
73 36         106 my $name = $json->{name};
74              
75 36 50       855 chdir $args->[0] if $args->[0];
76              
77             # check needed info
78 36         127 for my $needed (qw(name version framework)) {
79 108 50       391 if ( !$json->{$needed} ) {
80 0         0 carp "Need $needed in config file";
81 0         0 exit 1;
82             }
83             }
84            
85 36         83 my @xml_parts;
86             my %major_versions;
87              
88             {
89 36         81 for my $framework ( @{ $json->{framework} } ) {
  36         72  
  36         96  
90 61         121 my $version = $framework;
91 61         103 my $min = '';
92 61         99 my $max = '';
93              
94 61 100       181 if ( 'HASH' eq ref $framework ) {
95 3         5 $version = $framework->{version};
96 3         5 $min = $framework->{min};
97 3         5 $max = $framework->{max};
98             }
99              
100 61 100       425 push @xml_parts, sprintf " %s",
    100          
101             ( $min ? qq~ Minimum="$min"~ : '' ),
102             ( $max ? qq~ Maximum="$max"~ : '' ),
103             $version;
104              
105 61         192 my $major_version = (split /\./, $version)[0];
106 61         193 $major_versions{$major_version}++;
107             }
108              
109 36 100       168 if ( 2 <= keys %major_versions ) {
110 2         1241 carp "Two major versions declared in framework settings. Those might be incompatible.\n";
111             }
112             }
113              
114 36         472 my %utils_versions = (
115             OTRS => {
116             '3' => 'OTRS3',
117             '4' => 'OTRS4',
118             '5' => 'OTRS4',
119             '6' => 'OTRS4',
120             '7' => 'OTRS4',
121             },
122             KIX => {
123             '5' => 'OTRS4',
124             },
125             OTOBO => {
126             '10' => 'OTRS4',
127             },
128             );
129              
130 36         283 my ($max) = max keys %major_versions;
131              
132 36   100     286 my $product = uc ( $json->{product} // 'OTRS' );
133 36 100       196 if ( $product eq 'KIX' ) {
134 1         5 $max = 5;
135             }
136              
137 36   33     133 my $mod = $utils_versions{$product}->{$max} || $utils_versions{OTRS}->{4};
138 36         98 my $utils = 'OPM::Maker::Utils::' . $mod;
139              
140 36 100       161 if ( $json->{requires} ) {
141             {
142 16         23 for my $name ( sort keys %{ $json->{requires}->{package} } ) {
  16         77  
143 16         82 push @xml_parts, sprintf ' %s', $json->{requires}->{package}->{$name}, $name;
144             }
145             }
146            
147             {
148 16         30 for my $name ( sort keys %{ $json->{requires}->{module} } ) {
  16         45  
  16         28  
  16         65  
149 16         70 push @xml_parts, sprintf ' %s', $json->{requires}->{module}->{$name}, $name;
150             }
151             }
152             }
153              
154 36   50     201 push @xml_parts, sprintf " %s", $json->{vendor}->{name} || '';
155 36   50     207 push @xml_parts, sprintf " %s", $json->{vendor}->{url} || '';
156              
157 36 50       137 if ( $json->{description} ) {
158 36         94 for my $lang ( sort keys %{ $json->{description} } ) {
  36         194  
159 36         175 push @xml_parts, sprintf ' %s', $lang, $json->{description}->{$lang};
160             }
161             }
162              
163 36 50       152 if ( $json->{license} ) {
164 36         140 push @xml_parts, sprintf ' %s', $json->{license};
165             }
166              
167             # create filelist
168             {
169 36         71 my @files = File::Find::Rule->file->in( '.' );
  36         1489  
170              
171             # remove "hidden" files from list; and do not list .sopm
172             @files = grep{
173 36         37779 ( substr( $_, 0, 1 ) ne '.' ) &&
174             $_ !~ m{[\\/]\.} &&
175 166 50 33     1139 $_ ne $json->{name} . '.sopm'
176             }sort @files;
177              
178 36 100 66     147 if ( $json->{exclude_files} and 'ARRAY' eq ref $json->{exclude_files} ) {
179 1         3 for my $index ( reverse 0 .. $#files ) {
180 2         4 my $file = $files[$index];
181             my $excluded = first {
182 2     2   4 eval{ $file =~ /$_\z/ };
  2         22  
183 2         7 }@{ $json->{exclude_files} };
  2         8  
184              
185 2 100       10 splice @files, $index, 1 if $excluded;
186             }
187             }
188              
189 36         277 $utils->filecheck( \@files );
190              
191             push @xml_parts,
192             sprintf " \n%s\n ",
193 36 50       85 join "\n", map{ my $permission = $_ =~ /^bin/ ? 755 : 644; qq~ ~ }@files;
  164         363  
  164         651  
194             }
195              
196 36 100 66     161 if ( $json->{changes_file} && -f $config->dir . "/" . $json->{changes_file} ) {
197 1         67 my $changes_file = Path::Class::File->new( $config->dir, $json->{changes_file} );
198 1         112 my $lines = $changes_file->slurp( iomode => '<:encoding(UTF-8)' );
199              
200 1   50     1538 my @entries = grep{ ( $_ // '' ) ne '' }split m{
  5         16  
201             (?:\s+)?
202             ( # headline with version and date
203             ^
204             \d+\.\d+ (?:\.\d+)? # version
205             \s+ - \s+
206             \d{4}-\d{2}-\d{2} \s # date
207             \d{2}:\d{2}:\d{2} # time
208             )
209             \s+
210             }xms, $lines;
211              
212 1         4 while ( @entries ) {
213 2         6 my ($header, $desc) = ( shift(@entries), shift(@entries) );
214              
215 2   50     14 my ($version, $date) = split /\s+-\s+/, $header // '';
216              
217 2         10 $desc =~ s{\s+\z}{};
218              
219 2         26 push @xml_parts, sprintf qq~ ~, $version, $date, $desc;
220             }
221             }
222              
223             # changelog
224             {
225 36         67 CHANGE:
226 36 100       65 for my $change ( @{ $json->{changes} || [] } ) {
  36         192  
227 2         4 my $version = '';
228 2         4 my $date = '';
229 2         2 my $info = '';
230              
231 2 100       7 if ( !ref $change ) {
    50          
232 1         2 $info = $change;
233             }
234             elsif ( 'HASH' eq ref $change ) {
235 1         2 $info = $change->{message};
236 1 50       6 $version = sprintf( ' Version="%s"', $change->{version} ) if $change->{version};
237 1 50       10 $date = sprintf( ' Date="%s"', $change->{date} ) if $change->{date};
238             }
239              
240 2 50       4 next CHANGE if !length $info;
241              
242 2         7 push @xml_parts, sprintf " %s", $version, $date, $info;
243             }
244             }
245              
246 36         163 my %actions = (
247             Install => 'post',
248             Uninstall => 'pre',
249             Upgrade => 'post',
250             );
251              
252 36         260 my %action_code = (
253             TableCreate => \&_TableCreate,
254             Insert => \&_Insert,
255             TableDrop => \&_TableDrop,
256             ColumnAdd => \&_ColumnAdd,
257             ColumnDrop => \&_ColumnDrop,
258             ColumnChange => \&_ColumnChange,
259             ForeignKeyCreate => \&_ForeignKeyCreate,
260             ForeignKeyDrop => \&_ForeignKeyDrop,
261             UniqueDrop => \&_UniqueDrop,
262             UniqueCreate => \&_UniqueCreate,
263             );
264            
265 36         160 my %tables_to_delete;
266             my %own_tables;
267 36         0 my @columns_to_delete;
268 36         0 my %db_actions;
269              
270 36         68 my $table_counter = 0;
271 36         64 my $column_counter;
272              
273             ACTION:
274 36 100       63 for my $action ( @{ $json->{database} || [] } ) {
  36         166  
275 32         68 my $tmp_version = $action->{version};
276 32 100       89 my @versions = ref $tmp_version ? @{$tmp_version} : ($tmp_version);
  8         20  
277              
278             VERSION:
279 32         59 for my $version ( @versions ) {
280 40 100       85 my $action_type = $version ? 'Upgrade' : 'Install';
281 40         75 my $op = $action->{type};
282              
283 40 100       89 if ( $action->{uninstall} ) {
284 1         3 $action_type = 'Uninstall';
285             }
286              
287 40 50       118 next VERSION if !$action_code{$op};
288              
289 40   66     142 my $phase = $action->{phase} || $actions{ $action_type };
290              
291 40 100       114 if ( $op eq 'TableCreate' ) {
    50          
292 15         27 my $table = $action->{name};
293 15         35 $tables_to_delete{$table} = $table_counter++;
294 15         33 $own_tables{$table} = 1;
295             }
296             elsif ( $op eq 'TableDrop' ) {
297 0         0 my $table = $action->{name};
298 0         0 delete $tables_to_delete{$table};
299             }
300              
301 40 100       90 if ( $op eq 'ColumnAdd' ) {
302 3         5 my $table = $action->{name};
303 3 100       7 if ( !$own_tables{$table} ) {
304             unshift @columns_to_delete, +{
305             name => $table,
306 2 50       10 columns => [ map { $_->{name} } @{ $action->{columns} || [] } ],
  2         11  
  2         9  
307             };
308             }
309             }
310            
311 40         64 $action->{version} = $version;
312 40         62 push @{ $db_actions{$action_type}->{$phase} }, $action_code{$op}->($action);
  40         140  
313             }
314             }
315            
316 33         85 for my $columns_delete ( @columns_to_delete ) {
317 1         1 push @{ $db_actions{Uninstall}->{pre} }, _ColumnDrop($columns_delete);
  1         4  
318             }
319              
320 33 100       117 if ( %tables_to_delete ) {
321 11         61 for my $table ( sort { $tables_to_delete{$b} <=> $tables_to_delete{$a} }keys %tables_to_delete ) {
  3         12  
322 14         24 push @{ $db_actions{Uninstall}->{pre} }, _TableDrop({ name => $table });
  14         79  
323             }
324             }
325              
326 33         87 for my $action_type ( qw/Install Upgrade Uninstall/ ) {
327 99         176 for my $phase ( qw/pre post/ ) {
328            
329 198 100       567 next if !$db_actions{$action_type}->{$phase};
330            
331             push @xml_parts,
332             sprintf qq~
333             %s
334 34         110 ~, join "\n", @{ $db_actions{$action_type}->{$phase} };
  34         318  
335             }
336             }
337              
338             CODE:
339 33 100       58 for my $code ( @{ $json->{code} || [] } ) {
  33         204  
340 30 100       89 if ( !ref $code ) {
341 4 100       15 $code = {
342             type => $code,
343             version => 0,
344             phase => ( $code eq 'Uninstall' ? 'pre' : 'post' ),
345             };
346             }
347              
348 30         79 $code->{type} = 'Code' . $code->{type};
349              
350 30 100       71 if ( $code->{inline} ) {
351 1         3 push @xml_parts, _InlineCode( $code );
352 1         4 next CODE;
353             }
354              
355             push @xml_parts, $utils->packagesetup(
356             $code->{type},
357             $code->{version},
358             $code->{function} || $code->{type},
359             $code->{phase},
360             $code->{package},
361 29   66     201 );
362             }
363              
364 33 100       129 for my $intro ( @{ $json->{intro} || [] } ) {
  33         180  
365 2         12 push @xml_parts, _IntroTemplate( $intro );
366             }
367              
368 33         85 my $cvs = "";
369 33 100       175 if ( $opt->{cvs} ) {
370 1         4 $cvs = sprintf qq~\n \$Id: %s.sopm,v 1.1.1.1 2011/04/15 07:49:58 rb Exp \$~, $name;
371             }
372              
373 33         141 my %product_start_tags = (
374             OTRS => 'otrs_package',
375             KIX => 'otrs_package',
376             OTOBO => 'otobo_package',
377             );
378              
379 33         106 my $start_tag = $product_start_tags{$product};
380            
381             my $xml = sprintf q~
382             <%s version="1.0">
383             %s
384             %s
385             %s
386             %s
387            
388             ~,
389             $start_tag,
390             __PACKAGE__->VERSION(),
391             $cvs,
392             $name,
393             $json->{version},
394 33         253 join( "\n", @xml_parts ),
395             $start_tag;
396              
397 33 50       347 my $fh = IO::File->new( $name . '.sopm', 'w' ) or die $!;
398 33         6202 $fh->print( $xml );
399 33         1135 $fh->close;
400             }
401              
402             sub _InlineCode {
403 1     1   2 my ($code) = @_;
404              
405 1         5 my @parts = split /::/, $code->{inline};
406              
407 1         2 my $method = pop @parts;
408 1         2 $parts[-1] .= '.pm';
409 1         6 my $file = Path::Class::File->new( @parts );
410              
411 1         39 my $content = $file->slurp( iomode => '<:encoding(utf-8)' );
412              
413 1         1401 my ($method_body) = $content =~ m{
414             ^sub \s+ \Q$method\E \s* \{ \s+
415             (.*?)
416             ^\}\s+
417             }xms;
418              
419             my $version = $code->{version} ?
420 1 50       5 ' Version="' . $code->{version} . '"' :
421             '';
422              
423             my $xml = sprintf q~ <%s Type="%s"%s>
424             %s
425 1   50     14 ]]>~, $code->{type}, $code->{phase} // 'post', $version, $method_body, $code->{type};
426              
427 1         11 return $xml;
428             }
429              
430             sub _IntroTemplate {
431 2     2   5 my ($intro) = @_;
432              
433 2 50       6 my $version = $intro->{version} ? ' Version="' . $intro->{version} . '"' : '';
434 2         3 my $type = $intro->{type};
435 2 100       6 my $text = ref $intro->{text} ? join( "
\n", @{ $intro->{text} } ) : $intro->{text};
  1         3  
436 2   100     6 my $phase = $intro->{time} || "post";
437 2 100       7 my $lang = $intro->{lang} ? ' Lang="' . $intro->{lang} . '"' : '';
438 2 100       4 my $title = $intro->{title} ? ' Title="' . $intro->{title} . '"' : '';
439              
440 2         9 return qq~
441             $text
442             ]]>~;
443             }
444              
445             sub _Insert {
446 16     16   31 my ($action) = @_;
447              
448              
449 16         27 my $table = $action->{name};
450 16         25 my $version = $action->{version};
451              
452 16 100       36 my $version_string = $version ? ' Version="' . $version . '"' : '';
453              
454 16         43 my $string = ' \n";
455              
456             COLUMN:
457 16 50       21 for my $column ( @{ $action->{columns} || [] } ) {
  16         65  
458 112 100       226 my $value = ref $column->{value} ? join( "\n", @{ $column->{value} } ) : $column->{value};
  6         15  
459 112   50     215 $value //= '';
460              
461             $string .= sprintf ' %s' . "\n",
462             $column->{name},
463             ( $column->{type} ?
464 112 100       388 (' Type="' . $column->{type} . '"', '' ) :
465             ("", $value)
466             );
467             }
468              
469 16         39 $string .= ' ';
470              
471 16         71 return $string;
472             }
473              
474             sub _TableDrop {
475 14     14   44 my ($action) = @_;
476              
477 14         27 my $table = $action->{name};
478              
479 14         86 return ' ';
480             }
481              
482             sub _TableCreate {
483 15     15   31 my ($action) = @_;
484              
485 15         26 my $table = $action->{name};
486 15         25 my $version = $action->{version};
487              
488 15 50       35 my $version_string = $version ? ' Version="' . $version . '"' : '';
489              
490 15         62 my $string = ' \n";
491              
492             COLUMN:
493 15 50       114 for my $column ( @{ $action->{columns} || [] } ) {
  15         48  
494 43         101 my $type = _TypeCheck( $column->{type}, 'TableCreate' );
495             $string .= sprintf ' ' . "\n",
496             $column->{name},
497             $column->{required},
498             $type,
499             ( $column->{size} ? ' Size="' . $column->{size} . '"' : "" ),
500             ( $column->{auto_increment} ? ' AutoIncrement="true"' : "" ),
501 42 100       332 ( $column->{primary_key} ? ' PrimaryKey="true"' : "" ),
    100          
    100          
502             }
503              
504             UNIQUE:
505 14 100       203 for my $unique ( @{ $action->{unique} || [] } ) {
  14         77  
506 4         7 my $table = $unique->{name};
507 4   66     24 $string .= ' {columns} || ["unique$table"] } ) ) . '">' . "\n";
508              
509 4 50       8 for my $column ( @{ $unique->{columns} || [] } ) {
  4         11  
510 8         19 $string .= ' ' . "\n";
511             }
512              
513 4         8 $string .= ' ' . "\n";
514             }
515              
516             KEY:
517 14 100       29 for my $key ( @{ $action->{keys} || [] } ) {
  14         81  
518 10         18 my $table = $key->{name};
519 10         28 $string .= ' ' . "\n";
520              
521 10 50       47 for my $reference ( @{ $key->{references} || [] } ) {
  10         31  
522 10         20 my $local = $reference->{local};
523 10         42 my $foreign = $reference->{foreign};
524 10         32 $string .= ' ' . "\n";
525             }
526              
527 10         20 $string .= ' ' . "\n";
528             }
529              
530 14         34 $string .= ' ';
531              
532 14         55 return $string;
533             }
534              
535             sub _ColumnAdd {
536 3     3   7 my ($action) = @_;
537              
538 3         6 my $table = $action->{name};
539 3         4 my $version = $action->{version};
540              
541 3 50       9 my $version_string = $version ? ' Version="' . $version . '"' : '';
542              
543 3         7 my $string = ' \n";
544              
545             COLUMN:
546 3 50       4 for my $column ( @{ $action->{columns} || [] } ) {
  3         10  
547 3         7 my $type = _TypeCheck( $column->{type}, 'ColumnAdd' );
548             $string .= sprintf ' ' . "\n",
549             $column->{name},
550             $column->{required},
551             $type,
552             ( $column->{size} ? ' Size="' . $column->{size} . '"' : "" ),
553             ( $column->{auto_increment} ? ' AutoIncrement="true"' : "" ),
554 2 50       23 ( $column->{primary_key} ? ' PrimaryKey="true"' : "" ),
    50          
    50          
555             }
556              
557 2         6 $string .= ' ';
558              
559 2         6 return $string;
560             }
561              
562             sub _ColumnDrop {
563 2     2   4 my ($action) = @_;
564              
565 2         3 my $table = $action->{name};
566 2         4 my $version = $action->{version};
567              
568 2 50       5 my $version_string = $version ? ' Version="' . $version . '"' : '';
569              
570 2         6 my $string = ' \n";
571              
572             COLUMN:
573 2 50       3 for my $column ( @{ $action->{columns} || [] } ) {
  2         6  
574 2         14 $string .= sprintf qq~ \n~, $column;
575             }
576              
577 2         7 $string .= ' ';
578              
579 2         7 return $string;
580             }
581              
582             sub _ForeignKeyCreate {
583 1     1   19 my ($action) = @_;
584              
585 1         4 my $table = $action->{name};
586 1         2 my $version = $action->{version};
587              
588 1 50       4 my $version_string = $version ? ' Version="' . $version . '"' : '';
589              
590 1         3 my $string = ' \n";
591              
592             COLUMN:
593 1 50       1 for my $reference ( @{ $action->{references} || [] } ) {
  1         4  
594             $string .= sprintf '
595            
596             ' . "\n",
597             $reference->{name},
598             $reference->{local},
599 2         10 $reference->{foreign};
600             }
601              
602 1         2 $string .= ' ';
603              
604 1         4 return $string;
605             }
606              
607             sub _ForeignKeyDrop {
608 1     1   20 my ($action) = @_;
609              
610 1         4 my $table = $action->{name};
611 1         2 my $version = $action->{version};
612              
613 1 50       4 my $version_string = $version ? ' Version="' . $version . '"' : '';
614              
615 1         3 my $string = ' \n";
616              
617             COLUMN:
618 1 50       1 for my $reference ( @{ $action->{references} || [] } ) {
  1         4  
619             $string .= sprintf '
620            
621             ' . "\n",
622             $reference->{name},
623             $reference->{local},
624 2         9 $reference->{foreign};
625             }
626              
627 1         2 $string .= ' ';
628              
629 1         5 return $string;
630             }
631              
632             sub _UniqueCreate {
633 1     1   22 my ($action) = @_;
634              
635 1         5 my $table = $action->{name};
636 1         2 my $version = $action->{version};
637              
638 1 50       4 my $version_string = $version ? ' Version="' . $version . '"' : '';
639              
640 1         2 my $string = ' \n";
641 1         5 $string .= sprintf qq~ \n~, $action->{unique_name};
642              
643             COLUMN:
644 1 50       1 for my $column ( @{ $action->{columns} || [] } ) {
  1         4  
645 2         6 $string .= sprintf qq~ \n~,
646             $column;
647             }
648              
649 1         2 $string .= qq~ \n~;
650 1         2 $string .= ' ';
651              
652 1         4 return $string;
653             }
654              
655             sub _UniqueDrop {
656 1     1   19 my ($action) = @_;
657              
658 1         4 my $table = $action->{name};
659 1         2 my $version = $action->{version};
660              
661 1 50       4 my $version_string = $version ? ' Version="' . $version . '"' : '';
662              
663 1         3 my $string = ' \n";
664              
665             $string .= sprintf qq~ \n~,
666 1         4 $action->{unique_name};
667              
668 1         3 $string .= ' ';
669              
670 1         4 return $string;
671             }
672              
673             sub _ColumnChange {
674 1     1   3 my ($action) = @_;
675              
676 1         2 my $table = $action->{name};
677 1         1 my $version = $action->{version};
678              
679 1 50       3 my $version_string = $version ? ' Version="' . $version . '"' : '';
680              
681 1         3 my $string = ' \n";
682              
683             COLUMN:
684 1 50       2 for my $column ( @{ $action->{columns} || [] } ) {
  1         4  
685 1         2 my $type = _TypeCheck( $column->{type}, 'ColumnChange' );
686             $string .= sprintf ' ' . "\n",
687             $column->{new_name},
688             $column->{old_name},
689             $column->{required},
690             $type,
691             ( $column->{size} ? ' Size="' . $column->{size} . '"' : "" ),
692             ( $column->{auto_increment} ? ' AutoIncrement="true"' : "" ),
693 0 0       0 ( $column->{primary_key} ? ' PrimaryKey="true"' : "" ),
    0          
    0          
694             }
695              
696 0         0 $string .= ' ';
697              
698 0         0 return $string;
699             }
700              
701             sub _TypeCheck {
702 47     47   99 my ($type, $action) = @_;
703              
704 47         186 my %types = (
705             DATE => 1,
706             SMALLINT => 1,
707             BIGINT => 1,
708             INTEGER => 1,
709             DECIMAL => 1,
710             VARCHAR => 1,
711             LONGBLOB => 1,
712             );
713              
714 47 100       108 if ( !$types{$type} ) {
715 3         82 croak "$type is not allowed in $action. Allowed types: ", join ', ', sort keys %types;
716             }
717              
718 44         223 return $type;
719             }
720              
721             sub VERSION {
722 33   50 33 1 665 return $OPM::Maker::Command::sopm::VERSION || '1.0.0';
723             }
724              
725             1;
726              
727             __END__