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