#!/usr/bin/perl use SQL::Translator; use SQL::Translator::Schema::Constants; use SQL::Translator::Parser::XML::Xmldoom; use SQL::Translator::Producer::XML::Xmldoom; use Getopt::Long; use IO::File; use strict; # for debugging use Data::Dumper; use Carp; $SIG{__DIE__} = sub { Carp::confess(@_); #Carp::confess; }; sub drop_fkeys { my $schema = shift; foreach my $table ( $schema->get_tables ) { my @constraints = $table->get_constraints; foreach my $cons ( @constraints ) { if ( $cons->type eq FOREIGN_KEY ) { $table->drop_constraint( $cons ); } } } } sub drop_other_tables { my $schema = shift; my $translator = $schema->translator; my $producer_args = $translator->producer_args; my $allowed_tables = $producer_args->{allowed_tables}; my @tables = $schema->get_tables; foreach my $table ( @tables ) { my $drop = 1; foreach my $name ( @$allowed_tables ) { if ( $table->name eq $name ) { $drop = 0; last; } } if ( $drop ) { $schema->drop_table( $table ); } } } sub main_convert { my $database_xml; my $output; my $producer; my @allowed_tables; my $drop_foreign_keys = 0; my $result = GetOptions( 'database-xml|D:s' => \$database_xml, 'output|o:s' => \$output, 'producer|P:s' => \$producer, 'only-table|t:s' => \@allowed_tables, 'drop-foreign-keys' => \$drop_foreign_keys, ); if ( not defined $database_xml ) { die "Must specify a file with --database-xml"; } if ( not defined $producer ) { die "Must specify a producer name with --producer"; } my $translator = SQL::Translator->new( filename => $database_xml, parser => 'SQL::Translator::Parser::XML::Xmldoom', producer => $producer, ); if ( scalar @allowed_tables > 0 ) { $translator->producer_args( allowed_tables => \@allowed_tables ); $translator->filters( \&drop_other_tables ); } if ( $drop_foreign_keys ) { $translator->filters( \&drop_fkeys ); } my $result = $translator->translate() or die $translator->error; if ( defined $output ) { my $fd = IO::File->new($output, 'w'); $fd->write($result); $fd->close(); } else { print $result; } } sub main_create { my $output; my $parser; my $dsn; my $username; my $password; my @allowed_tables; my $result = GetOptions( 'output|o:s' => \$output, 'parser|P:s' => \$parser, 'dsn:s' => \$dsn, 'username|u:s' => \$username, 'password|p:s' => \$password, 'only-table|t:s' => \@allowed_tables, ); my $filename = shift @ARGV; if ( scalar @ARGV ) { die "Can specify one and only one file"; } if ( not defined $parser ) { die "Must specify a parser name with --parser"; } my $translator = SQL::Translator->new( filename => $filename, producer => 'SQL::Translator::Producer::XML::Xmldoom', parser => $parser, parser_args => { dsn => $dsn, db_user => $username, db_password => $password } ); if ( scalar @allowed_tables > 0 ) { $translator->producer_args( allowed_tables => \@allowed_tables ); $translator->filters( \&drop_other_tables ); } my $result = $translator->translate() or die $translator->error; if ( defined $output ) { my $fd = IO::File->new($output, 'w'); $fd->write($result); $fd->close(); } else { print $result; } } sub main { my $mode = shift @ARGV; if ( $mode eq 'convert' ) { main_convert; } elsif ( $mode eq 'create' ) { main_create; } else { die "Must specify a valid mode."; } } main;