File Coverage

blib/lib/OTRS/OPM/Maker/Command/sopm.pm
Criterion Covered Total %
statement 326 351 92.8
branch 111 162 68.5
condition 19 34 55.8
subroutine 30 34 88.2
pod 5 5 100.0
total 491 586 83.7


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