From: Justin Hunter Date: Mon, 17 Aug 2009 18:34:35 +0000 (-0700) Subject: YAML parsing X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cac60624dd22a5adef500421c965f89d81586538;p=dbsrgits%2FSQL-Translator-2.0-ish.git YAML parsing --- diff --git a/lib/SQL/Translator/Grammar/YAML.pm b/lib/SQL/Translator/Grammar/YAML.pm new file mode 100644 index 0000000..47fd0fe --- /dev/null +++ b/lib/SQL/Translator/Grammar/YAML.pm @@ -0,0 +1,3 @@ +use MooseX::Declare; +role SQL::Translator::Grammar::YAML { +} diff --git a/lib/SQL/Translator/Parser/DDL/YAML.pm b/lib/SQL/Translator/Parser/DDL/YAML.pm new file mode 100644 index 0000000..23b5dd3 --- /dev/null +++ b/lib/SQL/Translator/Parser/DDL/YAML.pm @@ -0,0 +1,125 @@ +use MooseX::Declare; +role SQL::Translator::Parser::DDL::YAML { + use MooseX::Types::Moose qw(Any Str); + use SQL::Translator::Types qw(Schema); + use aliased 'SQL::Translator::Object::Column'; + use aliased 'SQL::Translator::Object::Constraint'; + use aliased 'SQL::Translator::Object::Index'; + use aliased 'SQL::Translator::Object::Table'; + use aliased 'SQL::Translator::Object::Schema' => 'SchemaObj'; + use YAML qw(Load); + use MooseX::MultiMethods; + +# multi method parse(Any $data) { use Data::Dumper; die Dumper($data); } + multi method parse(Schema $data) { return $data } + + multi method parse(Str $data) { + return $data if blessed $data && $data->isa('SQL::Translator::Object::Schema'); + $data = Load($data); + $data = $data->{schema}; + +# warn "YAML data:",Dumper( $data ) if $self->debug; + + my $schema = SchemaObj->new; #$self->schema; + + # + # Tables + # + my @tables = + map { $data->{'tables'}{ $_->[1] } } +# sort { $a->[0] <=> $b->[0] } + map { [ $data->{'tables'}{ $_ }{'order'} || 0, $_ ] } + keys %{ $data->{'tables'} } ; + + for my $tdata ( @tables ) { + my $table = Table->new({ map { $tdata->{$_} ? ($_ => $tdata->{$_}) : () } qw/name extra options/ }); + $schema->add_table($table); +# my $table = $schema->add_table( +# map { +# $tdata->{$_} ? ($_ => $tdata->{$_}) : () +# } (qw/name extra options/) +# ) or die $schema->error; + + my @fields = + map { $tdata->{'fields'}{ $_->[1] } } +# sort { $a->[0] <=> $b->[0] } + map { [ $tdata->{'fields'}{ $_ }{'order'}, $_ ] } + keys %{ $tdata->{'fields'} } ; + + for my $fdata ( @fields ) { +# $table->add_field( %$fdata ) or die $table->error; + $fdata->{sql_data_type} = $self->data_type_mapping->{$fdata->{data_type}} || -99999; + my $column = Column->new($fdata); + $table->add_column($column); + $table->primary_key($column->name) if $fdata->{is_primary_key}; + } + + for my $idata ( @{ $tdata->{'indices'} || [] } ) { +# $table->add_index( %$idata ) or die $table->error; + my $index = Index->new($idata); + $table->add_index($index); + } + + for my $cdata ( @{ $tdata->{'constraints'} || [] } ) { +# $table->add_constraint( %$cdata ) or die $table->error; + my $constraint = Constraint->new($cdata); + $table->add_constraint($constraint); + } + } + + # + # Views + # + my @views = + map { $data->{'views'}{ $_->[1] } } + sort { $a->[0] <=> $b->[0] } + map { [ $data->{'views'}{ $_ }{'order'}, $_ ] } + keys %{ $data->{'views'} } ; + + for my $vdata ( @views ) { +# $schema->add_view( %$vdata ) or die $schema->error; + } + + # + # Triggers + # + my @triggers = + map { $data->{'triggers'}{ $_->[1] } } + sort { $a->[0] <=> $b->[0] } + map { [ $data->{'triggers'}{ $_ }{'order'}, $_ ] } + keys %{ $data->{'triggers'} } + ; + + for my $tdata ( @triggers ) { +# $schema->add_trigger( %$tdata ) or die $schema->error; + } + + # + # Procedures + # + my @procedures = + map { $data->{'procedures'}{ $_->[1] } } + sort { $a->[0] <=> $b->[0] } + map { [ $data->{'procedures'}{ $_ }{'order'}, $_ ] } + keys %{ $data->{'procedures'} } + ; + + for my $tdata ( @procedures ) { +# $schema->add_procedure( %$tdata ) or die $schema->error; + } + + if ( my $tr_data = $data->{'translator'} ) { + $self->add_drop_table( $tr_data->{'add_drop_table'} ); + $self->filename( $tr_data->{'filename'} ); + $self->no_comments( $tr_data->{'no_comments'} ); + $self->parser_args( $tr_data->{'parser_args'} ); + $self->producer_args( $tr_data->{'producer_args'} ); + $self->parser_type( $tr_data->{'parser_type'} ); + $self->producer_type( $tr_data->{'producer_type'} ); + $self->show_warnings( $tr_data->{'show_warnings'} ); + $self->trace( $tr_data->{'trace'} ); + } + + return $schema; + } +} diff --git a/lib/SQL/Translator/Producer/YAML.pm b/lib/SQL/Translator/Producer/YAML.pm new file mode 100644 index 0000000..e86d7f7 --- /dev/null +++ b/lib/SQL/Translator/Producer/YAML.pm @@ -0,0 +1,159 @@ +use MooseX::Declare; +role SQL::Translator::Producer::YAML { +use YAML qw(Dump); +use SQL::Translator::Types qw(Table); + +method produce { + my $translator = $self; + my $schema = $translator->schema; +# use Data::Dumper; warn Dumper($schema); + + my $r = Dump({ + schema => { + tables => { + map { ($_->name => view_table($_)) } + $schema->get_tables, + }, + views => { +# map { ($_->name => view_view($_)) } +# $schema->get_views, + }, + triggers => { +# map { ($_->name => view_trigger($_)) } +# $schema->get_triggers, + }, + procedures => { +# map { ($_->name => view_procedure($_)) } +# $schema->get_procedures, + }, + }, +# translator => { +# add_drop_table => $translator->add_drop_table, +# filename => $translator->filename, +# no_comments => $translator->no_comments, +# parser_args => $translator->parser_args, +# producer_args => $translator->producer_args, +# parser_type => $translator->parser_type, +# producer_type => $translator->producer_type, +# show_warnings => $translator->show_warnings, +# trace => $translator->trace, +# version => $translator->version, +# }, +# keys %{$schema->extra} ? ('extra' => { $schema->extra } ) : (), + }); +# use Data::Dumper; warn Dumper($r); + $r; +} + +sub view_table { + my ($table) = shift; + + return { + 'name' => $table->name, +# 'order' => $table->order, + 'options' => $table->options || [], + $table->comments ? ('comments' => $table->comments ) : (), + 'constraints' => [ + map { view_constraint($_) } $table->get_constraints + ], + 'indices' => [ + map { view_index($_) } $table->get_indices + ], + 'fields' => { + map { ($_->name => view_field($_)) } + $table->get_fields + }, + #keys %{$table->extra} ? ('extra' => { $table->extra } ) : (), + }; +} + +sub view_constraint { + my $constraint = shift; + + return { + 'deferrable' => scalar $constraint->deferrable, + 'expression' => scalar $constraint->expression, + 'fields' => [ map { ref $_ ? $_->name : $_ } $constraint->field_names ], + 'match_type' => scalar $constraint->match_type, + 'name' => scalar $constraint->name, + 'options' => scalar $constraint->options, +# 'on_delete' => scalar $constraint->on_delete, +# 'on_update' => scalar $constraint->on_update, +# 'reference_fields' => [ map { ref $_ ? $_->name : $_ } $constraint->reference_fields ], +# 'reference_table' => scalar $constraint->reference_table, + 'type' => scalar $constraint->type, + #keys %{$constraint->extra} ? ('extra' => { $constraint->extra } ) : (), + }; +} + +sub view_field { + my $field = shift; + + return { + 'order' => scalar $field->order, + 'name' => scalar $field->name, + 'data_type' => scalar $field->data_type, + 'size' => [ $field->size ], + 'default_value' => scalar $field->default_value, + 'is_nullable' => scalar $field->is_nullable, + 'is_primary_key' => scalar $field->is_primary_key, + 'is_unique' => scalar $field->is_unique, + $field->is_auto_increment ? ('is_auto_increment' => 1) : (), + $field->comments ? ('comments' => $field->comments) : (), + #keys %{$field->extra} ? ('extra' => { $field->extra } ) : (), + }; +} + +sub view_procedure { + my $procedure = shift; + + return { + 'order' => scalar $procedure->order, + 'name' => scalar $procedure->name, + 'sql' => scalar $procedure->sql, + 'parameters' => scalar $procedure->parameters, + 'owner' => scalar $procedure->owner, + 'comments' => scalar $procedure->comments, + #keys %{$procedure->extra} ? ('extra' => { $procedure->extra } ) : (), + }; +} + +sub view_trigger { + my $trigger = shift; + + return { + 'order' => scalar $trigger->order, + 'name' => scalar $trigger->name, + 'perform_action_when' => scalar $trigger->perform_action_when, + 'database_events' => scalar $trigger->database_events, + 'fields' => scalar $trigger->fields, + 'on_table' => scalar $trigger->on_table, + 'action' => scalar $trigger->action, + #keys %{$trigger->extra} ? ('extra' => { $trigger->extra } ) : (), + }; +} + +sub view_view { + my $view = shift; + + return { + 'order' => scalar $view->order, + 'name' => scalar $view->name, + 'sql' => scalar $view->sql, + 'fields' => scalar $view->fields, + #keys %{$view->extra} ? ('extra' => { $view->extra } ) : (), + }; +} + +sub view_index { + my $index = shift; + + return { + 'name' => scalar $index->name, + 'type' => scalar $index->type, + 'fields' => scalar $index->fields, + 'options' => scalar $index->options, + #keys %{$index->extra} ? ('extra' => { $index->extra } ) : (), + }; +} +}