Release commit for 1.62
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / DB2.pm
CommitLineData
f85aea79 1package SQL::Translator::Parser::DB2;
bdf60588 2
c13f5f6a 3=head1 NAME
4
5SQL::Translator::Parser::DB2 - parser for DB2
6
7=head1 SYNOPSIS
8
9 use SQL::Translator;
10 use SQL::Translator::Parser::DB2;
11
12 my $translator = SQL::Translator->new;
13 $translator->parser("SQL::Translator::Parser::DB2");
14
15=head1 DESCRIPTION
16
17This is a grammar for parsing CREATE statements for DB2
18
19=cut
20
bdf60588 21use warnings;
22use strict;
23
f85aea79 24use base qw(Exporter);
bdf60588 25our @EXPORT_OK = qw(parse);
26
27our $DEBUG;
28
29use Data::Dumper;
30use SQL::Translator::Utils qw/ddl_parser_instance/;
31
7e666ece 32# !!!!!!
33# THIS GRAMMAR IS INCOMPLETE!!!
34# Khisanth is slowly working on a replacement
35# !!!!!!
bdf60588 36our $GRAMMAR = <<'END_OF_GRAMMAR';
37
38{
39 my ( %tables, $table_order, @table_comments, @views, @triggers );
40}
41
42#
43# The "eofile" rule makes the parser fail if any "statement" rule
44# fails. Otherwise, the first successful match by a "statement"
45# won't cause the failure needed to know that the parse, as a whole,
46# failed. -ky
47#
48startrule : statement(s) eofile {
49 $return = {
50 tables => \%tables,
51 views => \@views,
52 triggers => \@triggers,
53 }
54}
55
56eofile : /^\Z/
57
aee4b66e 58statement :
bdf60588 59 comment
60 | create
61 | <error>
62
63comment : /^\s*-{2}.*\n/
64 {
65 my $comment = $item[1];
66 $comment =~ s/^\s*(-{2})\s*//;
67 $comment =~ s/\s*$//;
68 $return = $comment;
69 }
70
71
72create: CREATE TRIGGER trigger_name before type /ON/i table_name reference_b(?) /FOR EACH ROW/i 'MODE DB2SQL' triggered_action
73{
74 my $table_name = $item{'table_name'}{'name'};
75 $return = {
76 table => $table_name,
77 schema => $item{'trigger_name'}{'schema'},
78 name => $item{'trigger_name'}{'name'},
79 when => 'before',
80 db_event => $item{'type'}->{'event'},
81 fields => $item{'type'}{'fields'},
82 condition => $item{'triggered_action'}{'condition'},
83 reference => $item{'reference_b'},
84 granularity => $item[9],
85 action => $item{'triggered_action'}{'statement'}
86 };
87
88 push @triggers, $return;
89}
90
91create: CREATE TRIGGER trigger_name after type /ON/i table_name reference_a(?) /FOR EACH ROW|FOR EACH STATEMENT/i 'MODE DB2SQL' triggered_action
92{
93 my $table_name = $item{'table_name'}{'name'};
94 $return = {
95 table => $table_name,
96 schema => $item{'trigger_name'}{'schema'},
97 name => $item{'trigger_name'}{'name'},
98 when => 'after',
99 db_event => $item{'type'}{'event'},
100 fields => $item{'type'}{'fields'},
101 condition => $item{'triggered_action'}{'condition'},
102 reference => $item{'reference_a'},
103 granularity => $item[9],
104 action => $item{'triggered_action'}{'statement'}
105 };
106
107 push @triggers, $return;
108}
109
110create: CREATE /FEDERATED|/i VIEW view_name column_list(?) /AS/i with_expression(?) SQL_procedure_statement
111{
112 $return = {
113 name => $item{view_name}{name},
114 sql => $item{SQL_procedure_statement},
115 with => $item{'with_expression(?)'},
116 fields => $item{'column_list(?)'}
117 };
118 push @views, $return;
119}
120
121# create: CREATE /FEDERATED/i VIEW view_name col_list_or_of(?) /AS/i with_expression(?) fullselect options(?)
122
123# col_list_or_of: column_list | /OF/i ( root_view_definition | subview_definition )
124
125with_expression: /WITH/i common_table_expression(s /,/)
126{
127 $return = $item{'common_table_expression'};
128}
129
130SQL_procedure_statement: /[^;]*/ /(;|\z)/ { $return = $item[1] . $item[2] }
131
132column_list: '(' column_name(s /,/) ')'
133{
134 $return = join(' ', '(', @{$item[2]}, ')');
135}
136
137CREATE: /create/i
138
139TRIGGER: /trigger/i
140
141VIEW: /view/i
142
143INNER: /inner/i
144
145LEFT: /left/i
146
147RIGHT: /right/i
148
149FULL: /full/i
150
151OUTER: /outer/i
152
153WHERE: /where/i
aee4b66e 154
bdf60588 155trigger_name: SCHEMA '.' NAME
156 { $return = { schema => $item[1], name => $item[3] } }
157 | NAME
aee4b66e 158 { $return = { name => $item[1] } }
bdf60588 159
160table_name: SCHEMA '.' NAME
161 { $return = { schema => $item[1], name => $item[3] } }
162 | NAME
aee4b66e 163 { $return = { name => $item[1] } }
bdf60588 164
165view_name: SCHEMA '.' NAME
166 { $return = { schema => $item[1], name => $item[3] } }
167 | NAME
aee4b66e 168 { $return = { name => $item[1] } }
bdf60588 169
170column_name: NAME
171
172identifier: NAME
173
174correlation_name: NAME
175
176numeric_constant: /\d+/
177
178SCHEMA: /\w+/
179
180SCHEMA: /\w{1,128}/
181
182NAME: /\w+/
183
184NAME: /\w{1,18}/
aee4b66e 185
bdf60588 186options: /WITH/i ( /CASCADED/i | /LOCAL/i ) /CHECK\s+OPTION/i
187
188# root_view_definition: /MODE\s+DB2SQL/i '(' oid_column ( /,/ with_options )(?) ')'
189
190# subview_definition: /MODE\s+DB2SQL/i under_clause ( '(' with_options ')' )(?) /EXTEND/i(?)
191
192# oid_column: /REF\s+IS/i oid_column_name /USER\s+GENERATED\s+UNCHECKED/i(?)
193
194# with_options: ( column_name /WITH\s+OPTIONS/i ( /SCOPE/i ( typed_table_name | typed_view_name ) | /READ\s+ONLY/i )(s /,/) )(s /,/)
195
196# under_clause: /UNDER/i superview_name /INHERIT\s+SELECT\s+PRIVILEGES/i
197
198common_table_expression: table_name column_list /AS/i get_bracketed
199{
aee4b66e 200 $return = { name => $item{table_name}{name},
bdf60588 201 query => $item[4]
202 };
203}
204
aee4b66e 205get_bracketed:
206{
bdf60588 207 extract_bracketed($text, '(');
208}
209
210common_table_expression: table_name column_list /AS/i '(' fullselect ')'
211
212# fullselect: ( subselect | '(' fullselect ')' | values_clause ) ( ( /UNION/i | /UNION/i /ALL/i | /EXCEPT/i | /EXCEPT/i /ALL/i | /INTERSECT/i | /INTERSECT/i /ALL/i ) ( subselect | '(' fullselect ')' | values_clause ) )(s)
213
aee4b66e 214# values_clause: /VALUES/i values_row(s /,/)
bdf60588 215
216# values_row: ( expression | /NULL/i ) | '(' ( expression | /NULL/i )(s /,/) ')'
217
218# subselect: select_clause from_clause where_clause(?) group_by_clause(?) having_clause(?)
219
220# select_clause: SELECT ( /ALL/i | /DISTINCT )(?) ( '*' | ( expression ( /AS|/i new_column_name )(?) | exposed_name '.*' )(s /,/) )
221
222# from_clause: /FROM/i table_name(s /,/)
223
224# from_clause: /FROM/i table_reference(s /,/)
225
aee4b66e 226# table_reference:
227# (
228# ( nickname
229# | table_name
230# | view_name
231# )
bdf60588 232# | ( /ONLY/i
aee4b66e 233# | /OUTER/i
234# ) '('
235# ( table_name
236# | view_name
237# ) ')'
238# ) correlation_clause(?)
239# | TABLE '(' function_name '(' expression(s? /,/) ')' ')' correlation_clause
240# | TABLE(?) '(' fullselect ')' correlation_clause
241# | joined_table
242
bdf60588 243
244# correlation_clause: /AS/i(?) correlation_name column_list(?)
245
aee4b66e 246# joined_table:
247# table_reference ( INNER
248# | outer
bdf60588 249# )(?) JOIN table_reference ON join_condition
250# | '(' joined_table ')'
aee4b66e 251
bdf60588 252# outer: ( LEFT | RIGHT | FULL ) OUTER(?)
253
254where_clause: WHERE search_condition
255
aee4b66e 256# group_by_clause: /GROUP\s+BY/i ( grouping_expression
bdf60588 257# | grouping_sets
258# | super_groups
259# )(s /,/)
260
261# grouping_expression: expression
262
263# orderby_clause: /ORDER\s+BY/i ( sort_key ( /ASC/i | /DESC/i)(?) )(s /,/)
264
265# sort_key: simple_column_name | simple_integer | sort_key_expression
266
267# # Name of one of the selected columns!
268# simple_column_name: NAME
f85aea79 269
aee4b66e 270# simple_integer: /\d+/
bdf60588 271# { $item[1] <= $numberofcolumns && $item[1] > 1 }
f85aea79 272
bdf60588 273# sort_key_expression: expression
274# { expression from select columns list, grouping_expression, column function.. }
275
aee4b66e 276# grouping_sets: /GROUPING\s+SETS/i '(' (
277# ( grouping_expression
278# | super_groups
279# )
280# | '(' ( grouping_expression
281# | super_groups
282# )(s /,/) ')'
283# )(s /,/) ')'
bdf60588 284
aee4b66e 285# super_groups: /ROLLUP/i '(' grouping_expression_list ')'
bdf60588 286# | /CUBE/i '(' grouping_expression_list ')'
287# | grand_total
288
aee4b66e 289# grouping_expression_list: ( grouping_expression
290# | '(' grouping_expression(s /,/) ')'
bdf60588 291# )(s /,/)
292
293# grand_total: '(' ')'
294
295# having_clause: /HAVING/i search_condition
296
297when_clause: /WHEN/i '(' search_condition ')' {$return = $item[3]}
298
299triggered_action: when_clause(?) SQL_procedure_statement
300{ $return = { 'condition' => $item[1][0],
301 'statement' => $item{'SQL_procedure_statement'} };
302}
303
304before: /NO CASCADE BEFORE/i
305
306after: /AFTER/i
307
aee4b66e 308type: /UPDATE/i /OF/i column_name(s /,/)
bdf60588 309{ $return = { event => 'update_on',
310 fields => $item[3] }
311}
312
313type: ( /INSERT/i | /DELETE/i | /UPDATE/i )
314{ $return = { event => $item[1] } }
315
316reference_b: /REFERENCING/i old_new_corr(0..2)
317{ $return = join(' ', $item[1], join(' ', @{$item[2]}) ) }
318
aee4b66e 319reference_a: /REFERENCING/i old_new_corr(0..2) old_new_table(0..2)
bdf60588 320{ $return = join(' ', $item[1], join(' ', @{$item[2]}), join(' ', @{$item[3]}) ) }
321
aee4b66e 322old_new_corr: /OLD/i /(AS)?/i correlation_name
bdf60588 323{ $return = join(' ', @item[1..3] ) }
324| /NEW/i /(AS)?/i correlation_name
325{ $return = join(' ', @item[1..3] ) }
326
327old_new_table: /OLD_TABLE/i /(AS)?/i identifier
328{ $return = join(' ', @item[1..3] ) }
329| /NEW_TABLE/i /(AS)?/i identifier
330{ $return = join(' ', @item[1..3] ) }
331
332# Just parsing simple search conditions for now.
333search_condition: /[^)]+/
334
aee4b66e 335expression: (
336 ( '+'
337 | '-'
338 )(?)
bdf60588 339 ( function
340 | '(' expression ')'
341 | constant
342 | column_name
343 | host_variable
344 | special_register
aee4b66e 345 | '(' scalar_fullselect ')'
bdf60588 346 | labeled_duration
347 | case_expression
348 | cast_specification
349# | dereference_operation
350 | OLAP_function
351 | method_invocation
352 | subtype_treatment
aee4b66e 353 | sequence_reference
bdf60588 354 )
355 )(s /operator/)
356
aee4b66e 357operator: ( /CONCAT/i | '||' ) | '/' | '*' | '+' | '-'
bdf60588 358
aee4b66e 359function: ( /SYSIBM\.|/i sysibm_function
bdf60588 360 | /SYSFUN\.|/i sysfun_function
aee4b66e 361 | userdefined_function
bdf60588 362 ) '(' func_args(s /,/) ')'
363
364constant: int_const | float_const | dec_const | char_const | hex_const | grastr_const
365
366func_args: expression
367
368sysibm_function: ( /ABS/i | /ABSVAL/i )
369 | /AVG/i
370 | /BIGINT/i
371 | /BLOB/i
372 | /CHAR/i
373 | /CLOB/i
374 | /COALESCE/i
375 | ( /CONCAT/ | '||' )
376 | ( /CORRELATION/i | /CORR/ )
377 | /COUNT/i
378 | /COUNT_BIG/i
379 | (/COVARIANCE/i | /COVAR/i )
380 | /DATE/i
381 | /DAY/i
382 | /DAYS/i
383 | /DBCLOB/i
384 | ( /DECIMAL/i | /DEC/i )
385 | /DECRYPT_BIN/i
386 | /DECRYPT_CHAR/i
387 | /DEREF/i
388 | /DIGITS/i
389 | /DLCOMMENT/i
390 | /DLLINKTYPE/i
391 | /DLURLCOMPLETE/i
392 | /DLURLPATH/i
393 | /DLURLPATHONLY/i
394 | /DLURLSCHEME/i
395 | /DLURLSERVER/i
396 | /DLVALUE/i
397 | ( /DOUBLE/i | /DOUBLE_PRECISION/i )
398 | /ENCRYPT/i
399 | /EVENT_MON_STATE/i
400 | /FLOAT/i
401 | /GETHINT/i
402 | /GENERATE_UNIQUE/i
403 | /GRAPHIC/i
404 | /GROUPING/i
405 | /HEX/i
406 | /HOUR/i
407 | /IDENTITY_VAL_LOCAL/i
408 | ( /INTEGER/i | /INT/ )
409 | ( /LCASE/i | /LOWER/ )
410 | /LENGTH/i
411 | /LONG_VARCHAR/i
412 | /LONG_VARGRAPHIC/i
413 | /LTRIM/i
414 | /MAX/i
415 | /MICROSECOND/i
416 | /MIN/i
417 | /MINUTE/i
418 | /MONTH/i
419 | /MULTIPLY_ACT/i
420 | /NODENUMBER/i
421 | /NULLIF/i
422 | /PARTITON/i
423 | /POSSTR/i
424 | /RAISE_ERROR/i
425 | /REAL/i
426 | /REC2XML/i
427 | /REGR_AVGX/i
428 | /REGR_AVGY/i
429 | /REGR_COUNT/i
430 | ( /REGR_INTERCEPT/i | /REGR_ICPT/i )
431 | /REGR_R2/i
432 | /REGR_SLOPE/i
433 | /REGR_SXX/i
434 | /REGR_SXY/i
435 | /REGR_SYY/i
436 | /RTRIM/i
437 | /SECOND/i
438 | /SMALLINT/i
439 | /STDDEV/i
440 | /SUBSTR/i
441 | /SUM/i
442 | /TABLE_NAME/i
443 | /TABLE_SCHEMA/i
444 | /TIME/i
445 | /TIMESTAMP/i
446 | /TRANSLATE/i
447 | /TYPE_ID/i
448 | /TYPE_NAME/i
449 | /TYPE_SCHEMA/i
450 | ( /UCASE/i | /UPPER/i )
451 | /VALUE/i
452 | /VARCHAR/i
453 | /VARGRAPHIC/i
454 | ( /VARIANCE/i | /VAR/i )
455 | /YEAR/i
456
457sysfun: ( /ABS/i | /ABSVAL/i )
458 | /ACOS/i
459 | /ASCII/i
460 | /ASIN/i
461 | /ATAN/i
462 | /ATAN2/i
463 | ( /CEIL/i | /CEILING/i )
464 | /CHAR/i
465 | /CHR/i
466 | /COS/i
467 | /COT/i
468 | /DAYNAME/i
469 | /DAYOFWEEK/i
470 | /DAYOFWEEK_ISO/i
471 | /DAYOFYEAR/i
472 | /DEGREES/i
473 | /DIFFERENCE/i
474 | /DOUBLE/i
475 | /EXP/i
476 | /FLOOR/i
477 | /GET_ROUTINE_SAR/i
478 | /INSERT/i
479 | /JULIAN_DAY/i
480 | /LCASE/i
481 | /LEFT/i
482 | /LN/i
483 | /LOCATE/i
484 | /LOG/i
485 | /LOG10/i
486 | /LTRIM/i
487 | /MIDNIGHT_SECONDS/i
488 | /MOD/i
489 | /MONTHNAME/i
490 | /POWER/i
491 | /PUT_ROUTINE_SAR/i
492 | /QUARTER/i
493 | /RADIANS/i
494 | /RAND/i
495 | /REPEAT/i
496 | /REPLACE/i
497 | /RIGHT/i
498 | /ROUND/i
499 | /RTRIM/I
500 | /SIGN/i
501 | /SIN/i
502 | /SOUNDEX/i
503 | /SPACE/i
504 | /SQLCACHE_SNAPSHOT/i
505 | /SQRT/i
506 | /TAN/i
507 | /TIMESTAMP_ISO/i
508 | /TIMESTAMPDIFF/i
509 | ( /TRUNCATE/i | /TRUNC/i )
510 | /UCASE/i
511 | /WEEK/i
512 | /WEEK_ISO/i
513
514scalar_fullselect: '(' fullselect ')'
515
516labeled_duration: ld_type ld_duration
517
aee4b66e 518ld_type: function
519 | '(' expression ')'
520 | constant
521 | column_name
bdf60588 522 | host_variable
523
aee4b66e 524ld_duration: /YEARS?/i
525 | /MONTHS?/i
526 | /DAYS?/i
527 | /HOURS?/i
bdf60588 528 | /MINUTES?/i
529 | /SECONDS?/i
530 | /MICROSECONDS?/i
531
aee4b66e 532case_expression: /CASE/i ( searched_when_clause
533 | simple_when_clause
534 )
535 ( /ELSE\s+NULL/i
536 | /ELSE/i result_expression
bdf60588 537 )(?) /END/i
538
aee4b66e 539searched_when_clause: ( /WHEN/i search_condition /THEN/i
540 ( result_expression
bdf60588 541 | /NULL/i
542 )
543 )(s)
544
aee4b66e 545simple_when_clause: expression ( /WHEN/i search_condition /THEN/i
546 ( result_expression
bdf60588 547 | /NULL/i
548 )
549 )(s)
550
aee4b66e 551result_expression: expression
bdf60588 552
aee4b66e 553cast_specification: /CAST/i '(' ( expression
bdf60588 554 | /NULL/i
555 | parameter_marker
aee4b66e 556 ) /AS/i data_type
557 ( /SCOPE/ ( typed_table_name
bdf60588 558 | typed_view_name
559 )
560 )(?) ')'
561
aee4b66e 562dereference_operation: scoped_reference_expression '->' name1
bdf60588 563 ( '(' expression(s) ')' )(?)
564# ( '(' expression(s /,/) ')' )(?)
565
566
567
aee4b66e 568scoped_reference_expression: expression
569{ # scoped, reference
bdf60588 570}
571
572name1: NAME
573
aee4b66e 574OLAP_function: ranking_function
bdf60588 575 | numbering_function
576 | aggregation_function
577
aee4b66e 578ranking_function: ( /RANK/ '()'
579 | /DENSE_RANK|DENSERANK/i '()'
bdf60588 580 ) /OVER/i '(' window_partition_clause(?) window_order_clause ')'
581
aee4b66e 582numbering_function: /ROW_NUMBER|ROWNUMBER/i '()' /OVER/i '(' window_partition_clause(?)
583 ( window_order_clause window_aggregation_group_clause(?)
584 )(?)
585 ( /RANGE\s+BETWEEN\s+UNBOUNDED\s+PRECEDING\s+AND\s+UNBBOUNDED\s+FOLLOWING/i
bdf60588 586 | window_aggregation_group_clause
587 )(?) ')'
588
589window_partition_clause: /PARTITION\s+BY/i partitioning_expression(s /,/)
590
aee4b66e 591window_order_clause: /ORDER\s+BY/i
592 ( sort_key_expression
593 ( asc_option
594 | desc_option
bdf60588 595 )(?)
596 )(s /,/)
597
598asc_option: /ASC/i ( /NULLS\s+FIRST/i | /NULLS\s+LAST/i )(?)
599
600desc_option: /DESC/i ( /NULLS\s+FIRST/i | /NULLS\s+LAST/i )(?)
601
602window_aggregation_group_clause: ( /ROWS/i
603 | /RANGE/i
aee4b66e 604 )
bdf60588 605 ( group_start
606 | group_between
607 | group_end
608 )
609
aee4b66e 610group_start: /UNBOUNDED\s+PRECEDING/i
bdf60588 611 | unsigned_constant /PRECEDING/i
612 | /CURRENT\s+ROW/i
613
614group_between: /BETWEEN/i group_bound1 /AND/i group_bound2
615
aee4b66e 616group_bound1: /UNBOUNDED\s+PRECEDING/i
bdf60588 617 | unsigned_constant /PRECEDING/i
618 | unsigned_constant /FOLLOWING/i
619 | /CURRENT\s+ROW/i
620
aee4b66e 621group_bound2: /UNBOUNDED\s+PRECEDING/i
bdf60588 622 | unsigned_constant /PRECEDING/i
623 | unsigned_constant /FOLLOWING/i
624 | /CURRENT\s+ROW/i
625
aee4b66e 626group_end: /UNBOUNDED\s+PRECEDING/i
627 | unsigned_constant /FOLLOWING/i
bdf60588 628
629method_invocation: subject_expression '..' method_name
aee4b66e 630 ( '(' expression(s) ')'
631# ( '(' expression(s /,/) ')'
bdf60588 632 )(?)
633
634subject_expression: expression
aee4b66e 635{ # with static result type that is a used-defined struct type
bdf60588 636}
637
638method_name: NAME
aee4b66e 639{ # must be a method of subject_expression
bdf60588 640}
641
642subtype_treatment: /TREAT/i '(' expression /AS/i data_type ')'
643
644sequence_reference: nextval_expression
645 | prevval_expression
646
647nextval_expression: /NEXTVAL\s+FOR/i sequence_name
648
649prevval_expression: /PREVVAL\s+FOR/i sequence_name
650
651sequence_name: NAME
652
653
654search_condition: /NOT|/i ( predicate ( /SELECTIVITY/i numeric_constant )(?) | '(' search_condition ')' ) cond(s?)
655
656cond: ( /AND/i | /OR/i ) /NOT|/i ( predicate ( /SELECTIVITY/i numeric_constant )(?) | '(' search_condition ')' )
657
aee4b66e 658predicate: basic_p | quantified_p | between_p | exists_p | in_p | like_p | null_p | type_p
bdf60588 659
660basic_p: expression /(=|<>|<|>|<=|=>|\^=|\^<|\^>|\!=)/ expression
661
662quantified_p: expression1 /(=|<>|<|>|<=|=>|\^=|\^<|\^>|\!=)/ /SOME|ANY|ALL/i '(' fullselect ')'
663
664END_OF_GRAMMAR
f85aea79 665
f85aea79 666sub parse {
667 my ( $translator, $data ) = @_;
bdf60588 668
669 # Enable warnings within the Parse::RecDescent module.
670 local $::RD_ERRORS = 1 unless defined $::RD_ERRORS; # Make sure the parser dies when it encounters an error
671 local $::RD_WARN = 1 unless defined $::RD_WARN; # Enable warnings. This will warn on unused rules &c.
672 local $::RD_HINT = 1 unless defined $::RD_HINT; # Give out hints to help fix problems.
f85aea79 673
674 local $::RD_TRACE = $translator->trace ? 1 : undef;
675 local $DEBUG = $translator->debug;
676
bdf60588 677 my $parser = ddl_parser_instance('DB2');
f85aea79 678
679 my $result = $parser->startrule($data);
680 return $translator->error( "Parse failed." ) unless defined $result;
681 warn Dumper( $result ) if $DEBUG;
682
683 my $schema = $translator->schema;
ea93df61 684 my @tables =
f85aea79 685 map { $_->[1] }
ea93df61 686 sort { $a->[0] <=> $b->[0] }
f85aea79 687 map { [ $result->{'tables'}{ $_ }->{'order'}, $_ ] }
688 keys %{ $result->{'tables'} };
689
690 for my $table_name ( @tables ) {
691 my $tdata = $result->{'tables'}{ $table_name };
ea93df61 692 my $table = $schema->add_table(
f85aea79 693 name => $tdata->{'name'},
694 ) or die $schema->error;
695
696 $table->comments( $tdata->{'comments'} );
697
698 for my $fdata ( @{ $tdata->{'fields'} } ) {
699 my $field = $table->add_field(
700 name => $fdata->{'name'},
701 data_type => $fdata->{'data_type'},
702 size => $fdata->{'size'},
703 default_value => $fdata->{'default'},
704 is_auto_increment => $fdata->{'is_auto_inc'},
705 is_nullable => $fdata->{'is_nullable'},
706 comments => $fdata->{'comments'},
707 ) or die $table->error;
708
709 $table->primary_key( $field->name ) if $fdata->{'is_primary_key'};
710
711 for my $cdata ( @{ $fdata->{'constraints'} } ) {
712 next unless $cdata->{'type'} eq 'foreign_key';
713 $cdata->{'fields'} ||= [ $field->name ];
714 push @{ $tdata->{'constraints'} }, $cdata;
715 }
716 }
717
718 for my $idata ( @{ $tdata->{'indices'} || [] } ) {
719 my $index = $table->add_index(
720 name => $idata->{'name'},
721 type => uc $idata->{'type'},
722 fields => $idata->{'fields'},
723 ) or die $table->error;
724 }
725
726 for my $cdata ( @{ $tdata->{'constraints'} || [] } ) {
727 my $constraint = $table->add_constraint(
728 name => $cdata->{'name'},
729 type => $cdata->{'type'},
730 fields => $cdata->{'fields'},
731 reference_table => $cdata->{'reference_table'},
732 reference_fields => $cdata->{'reference_fields'},
733 match_type => $cdata->{'match_type'} || '',
100684f3 734 on_delete => $cdata->{'on_delete'} || $cdata->{'on_delete_do'},
735 on_update => $cdata->{'on_update'} || $cdata->{'on_update_do'},
f85aea79 736 ) or die $table->error;
737 }
738 }
739
740 for my $def ( @{ $result->{'views'} || [] } ) {
741 my $view = $schema->add_view(
742 name => $def->{'name'},
743 sql => $def->{'sql'},
744 );
745 }
746
747 for my $def ( @{ $result->{'triggers'} || [] } ) {
748 my $trig = $schema->add_trigger(
749 name => $def->{'name'},
750 perform_action_when => $def->{'when'},
751 database_event => $def->{'db_event'},
752 action => $def->{'action'},
753 fields => $def->{'fields'},
754 on_table => $def->{'table'}
755 );
756 $trig->extra( reference => $def->{'reference'},
757 condition => $def->{'condition'},
758 granularity => $def->{'granularity'} );
759 }
760
761 return 1;
762}
763
7641;
c13f5f6a 765
766=pod
767
768=head1 AUTHOR
769
770Jess Robinson <cpan@desert-island.me.uk>
771
772=head1 SEE ALSO
773
774perl(1), Parse::RecDescent, SQL::Translator::Schema.
775
776=cut