1d9d448546438d7e82aa02e4409715c65bcb49cf
[dbsrgits/SQL-Translator-2.0-ish.git] / lib / SQL / Translator / Parser / DDL / YAML.pm
1 use MooseX::Declare;
2 role SQL::Translator::Parser::DDL::YAML { 
3     use MooseX::Types::Moose qw(Str);
4     use SQL::Translator::Types qw(Schema);
5     use aliased 'SQL::Translator::Object::Column';
6     use aliased 'SQL::Translator::Object::Constraint';
7     use aliased 'SQL::Translator::Object::Index';
8     use aliased 'SQL::Translator::Object::Procedure';
9     use aliased 'SQL::Translator::Object::Table';
10     use aliased 'SQL::Translator::Object::Trigger';
11     use aliased 'SQL::Translator::Object::View';
12     use YAML qw(Load);
13     use MooseX::MultiMethods;
14
15     multi method parse(Schema $data) { $data }
16
17     multi method parse(Str $data) {
18         $data = Load($data);
19         $data = $data->{schema};
20     
21         my $schema = $self->schema;
22         my $translator = $self->translator;
23     
24         #
25         # Tables
26         #
27         my @tables = 
28             map   { $data->{'tables'}{ $_->[1] } }
29             map   { [ $data->{'tables'}{ $_ }{'order'} || 0, $_ ] }
30             keys %{ $data->{'tables'} };
31     
32         for my $tdata ( @tables ) {
33             my $table = Table->new({ name => $tdata->{name}, schema => $schema });
34             $table->extra($tdata->{extra}) if $tdata->{extra};
35             $table->options($tdata->{options}) if $tdata->{options};
36             $schema->add_table($table);
37
38             my @fields = 
39                 map   { $tdata->{'fields'}{ $_->[1] } }
40                 map   { [ $tdata->{'fields'}{ $_ }{'order'} || 0, $_ ] }
41                 keys %{ $tdata->{'fields'} };
42     
43             for my $fdata ( @fields ) {
44                 $fdata->{sql_data_type} = $self->data_type_mapping->{$fdata->{data_type}} || -99999;
45                 $fdata->{table} = $table;
46
47                 my $column = Column->new($fdata);
48                 $table->add_column($column);
49                 $column->is_primary_key(1) if $fdata->{is_primary_key};
50             }
51     
52             for my $idata ( @{ $tdata->{'indices'} || [] } ) { 
53                  $idata->{table} = $table;
54                  my $columns = delete $idata->{fields};
55
56                  my $index = Index->new($idata);
57                  $index->add_column($table->get_column($_)) for @$columns;
58                  $table->add_index($index);
59             }
60     
61             for my $cdata ( @{ $tdata->{'constraints'} || [] } ) {
62                  $cdata->{table} = $table;
63                  $cdata->{reference_columns} = delete $cdata->{reference_fields} || [];
64                  my $columns = delete $cdata->{fields} || [];
65                  $columns = ref $columns eq 'ARRAY' ? $columns : [ $columns ];
66                  my $constraint = Constraint->new($cdata);
67                  $constraint->add_column($table->get_column($_)) for @$columns;
68                  $table->add_constraint($constraint);
69             }
70         }
71     
72         #
73         # Views
74         #
75         my @views = 
76             map   { $data->{'views'}{ $_->[1] } }
77             map   { [ $data->{'views'}{ $_ }{'order'}, $_ ] }
78             keys %{ $data->{'views'} };
79     
80         for my $vdata ( @views ) {
81             my $view = View->new($vdata);
82             $schema->add_view($view);
83         }
84     
85         #
86         # Triggers
87         #
88         my @triggers = 
89             map   { $data->{'triggers'}{ $_->[1] } }
90             map   { [ $data->{'triggers'}{ $_ }{'order'}, $_ ] }
91             keys %{ $data->{'triggers'} };
92     
93         for my $tdata ( @triggers ) {
94             my $columns = delete $tdata->{fields} || ();
95             my $trigger = Trigger->new($tdata);
96             $trigger->add_column($schema->get_table($tdata->{on_table})->get_column($_)) for @$columns; 
97             $schema->add_trigger($trigger);
98         }
99     
100         #
101         # Procedures
102         #
103         my @procedures = 
104             map   { $data->{'procedures'}{ $_->[1] } }
105             map   { [ $data->{'procedures'}{ $_ }{'order'}, $_ ] }
106             keys %{ $data->{'procedures'} };
107     
108         for my $tdata ( @procedures ) {
109              my $procedure = Procedure->new($tdata);
110              $schema->add_procedure($procedure);
111         }
112     
113         if ( my $tr_data = $data->{'translator'} ) {
114             $translator->add_drop_table( $tr_data->{'add_drop_table'} );
115             $translator->filename( $tr_data->{'filename'} );
116             $translator->no_comments( $tr_data->{'no_comments'} );
117             $translator->parser_args( $tr_data->{'parser_args'} );
118             $translator->producer_args( $tr_data->{'producer_args'} );
119             $translator->parser_type( $tr_data->{'parser_type'} );
120             $translator->producer_type( $tr_data->{'producer_type'} );
121             $translator->show_warnings( $tr_data->{'show_warnings'} );
122             $translator->trace( $tr_data->{'trace'} );
123         }
124     
125         return 1;
126     }
127 }