Add JSON parser and producer modules
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / JSON.pm
1 package SQL::Translator::Parser::JSON;
2
3 use strict;
4 use warnings;
5 our $VERSION = '1.00';
6
7 use SQL::Translator::Schema;
8 use SQL::Translator::Utils qw(header_comment);
9 use Data::Dumper;
10 use JSON;
11
12 sub parse {
13     my ($translator, $data) = @_;
14     $data = from_json($data);
15     $data = $data->{'schema'};
16
17     warn "JSON data:", Dumper($data) if $translator->debug;
18
19     my $schema = $translator->schema;
20
21     #
22     # Tables
23     #
24     my @tables =
25         map   { $data->{'tables'}{ $_->[1] } }
26         sort  { $a->[0] <=> $b->[0] }
27         map   { [ $data->{'tables'}{ $_ }{'order'} || 0, $_ ] }
28         keys %{ $data->{'tables'} }
29     ;
30
31     for my $tdata ( @tables ) {
32
33         my $table = $schema->add_table(
34             map {
35               $tdata->{$_} ? ($_ => $tdata->{$_}) : ()
36             } (qw/name extra options/)
37         ) or die $schema->error;
38
39         my @fields =
40             map   { $tdata->{'fields'}{ $_->[1] } }
41             sort  { $a->[0] <=> $b->[0] }
42             map   { [ $tdata->{'fields'}{ $_ }{'order'}, $_ ] }
43             keys %{ $tdata->{'fields'} }
44         ;
45
46         for my $fdata ( @fields ) {
47             $table->add_field( %$fdata ) or die $table->error;
48             $table->primary_key( $fdata->{'name'} )
49                 if $fdata->{'is_primary_key'};
50         }
51
52         for my $idata ( @{ $tdata->{'indices'} || [] } ) {
53             $table->add_index( %$idata ) or die $table->error;
54         }
55
56         for my $cdata ( @{ $tdata->{'constraints'} || [] } ) {
57             $table->add_constraint( %$cdata ) or die $table->error;
58         }
59     }
60
61     #
62     # Views
63     #
64     my @views =
65         map   { $data->{'views'}{ $_->[1] } }
66         sort  { $a->[0] <=> $b->[0] }
67         map   { [ $data->{'views'}{ $_ }{'order'}, $_ ] }
68         keys %{ $data->{'views'} }
69     ;
70
71     for my $vdata ( @views ) {
72         $schema->add_view( %$vdata ) or die $schema->error;
73     }
74
75     #
76     # Triggers
77     #
78     my @triggers =
79         map   { $data->{'triggers'}{ $_->[1] } }
80         sort  { $a->[0] <=> $b->[0] }
81         map   { [ $data->{'triggers'}{ $_ }{'order'}, $_ ] }
82         keys %{ $data->{'triggers'} }
83     ;
84
85     for my $tdata ( @triggers ) {
86         $schema->add_trigger( %$tdata ) or die $schema->error;
87     }
88
89     #
90     # Procedures
91     #
92     my @procedures =
93         map   { $data->{'procedures'}{ $_->[1] } }
94         sort  { $a->[0] <=> $b->[0] }
95         map   { [ $data->{'procedures'}{ $_ }{'order'}, $_ ] }
96         keys %{ $data->{'procedures'} }
97     ;
98
99     for my $tdata ( @procedures ) {
100         $schema->add_procedure( %$tdata ) or die $schema->error;
101     }
102
103     if ( my $tr_data = $data->{'translator'} ) {
104         $translator->add_drop_table( $tr_data->{'add_drop_table'} );
105         $translator->filename( $tr_data->{'filename'} );
106         $translator->no_comments( $tr_data->{'no_comments'} );
107         $translator->parser_args( $tr_data->{'parser_args'} );
108         $translator->producer_args( $tr_data->{'producer_args'} );
109         $translator->parser_type( $tr_data->{'parser_type'} );
110         $translator->producer_type( $tr_data->{'producer_type'} );
111         $translator->show_warnings( $tr_data->{'show_warnings'} );
112         $translator->trace( $tr_data->{'trace'} );
113     }
114
115     return 1;
116 }
117
118 1;
119
120 __END__
121
122 =head1 NAME
123
124 SQL::Translator::Parser::JSON - Parse a JSON representation of a schema
125
126 =head1 SYNOPSIS
127
128     use SQL::Translator;
129
130     my $translator = SQL::Translator->new(parser => "JSON");
131
132 =head1 DESCRIPTION
133
134 C<SQL::Translator::Parser::JSON> parses a schema serialized with JSON.
135
136 =head1 AUTHORS
137
138 Darren Chamberlain E<lt>darren@cpan.orgE<gt>,
139 Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
140 Jon Jensen E<lt>jonj@cpan.orgE<gt>.