#!/usr/bin/perl -w
-#-----------------------------------------------------
-# $Id: sql_translator.pl,v 1.3 2002-07-08 14:42:56 dlc Exp $
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+# $Id: sql_translator.pl,v 1.4 2002-11-20 04:03:02 kycl4rk Exp $
+# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
#
use Getopt::Long;
use Pod::Usage;
use SQL::Translator;
+
+use Data::Dumper;
+
use vars qw( $VERSION );
-$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
my $from; # the original database
my $to; # the destination database
#
# If everything is OK, translate file(s).
#
-my $translator = SQL::Translator->new;
+my $translator = SQL::Translator->new( debug => $verbose );
$translator->parser($from);
$translator->producer($to);
for my $file (@files) {
- my $output = $translator->translate($file)
- or die "Error: " . $translator->error;
- print "Output:\n", $output;
+ my $output = $translator->translate( $file ) or die
+ "Error: " . $translator->error;
+ print $output;
+ warn "parser = ", Dumper( $translator->parser );
}
-__END__
-#-----------------------------------------------------
+# ----------------------------------------------------
# It is not all books that are as dull as their readers.
# Henry David Thoreau
-#-----------------------------------------------------
+# ----------------------------------------------------
=head1 NAME
-sql_translator.pl - convert schema to Oracle syntax
+sql_translator.pl - convert an SQL database schema
=head1 SYNOPSIS
./sql_translator.pl -h|--help
- ./sql_translator.pl -f|--from mysql -t|--to oracle [options] file
+ ./sql_translator.pl -f|--from MySQL -t|--to Oracle [options] file
Options:
Part of the SQL Fairy project (sqlfairy.sourceforge.net), this script
will try to convert any database syntax for which it has a grammar
-into some other format will accept.
+into some other format it knows about.
=head1 AUTHOR
-Ken Y. Clark, kclark@logsoft.com
+Ken Y. Clark, E<lt>kclark@logsoft.comE<gt>
=head1 SEE ALSO
-perl(1), SQL::Transport.
+perl(1), SQL::Translator.
=cut
package SQL::Translator;
# ----------------------------------------------------------------------
-# $Id: Translator.pm,v 1.9 2002-07-23 19:21:16 dlc Exp $
+# $Id: Translator.pm,v 1.10 2002-11-20 04:03:03 kycl4rk Exp $
# ----------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
use SQL::Translator;
my $translator = SQL::Translator->new;
-
- my $output = $translator->translate(
- from => "MySQL",
- to => "Oracle",
- filename => $file,
- ) or die $translator->error;
+ my $output = $translator->translate(
+ from => "MySQL",
+ to => "Oracle",
+ filename => $file,
+ ) or die $translator->error;
print $output;
=head1 DESCRIPTION
=cut
use strict;
-use vars qw($VERSION $DEFAULT_SUB $DEBUG $ERROR);
-use base qw(Class::Base);
+use vars qw( $VERSION $DEFAULT_SUB $DEBUG $ERROR );
+use base 'Class::Base';
-$VERSION = sprintf "%d.%02d", q$Revision: 1.9 $ =~ /(\d+)\.(\d+)/;
-$DEBUG = 1 unless defined $DEBUG;
-$ERROR = "";
+$VERSION = sprintf "%d.%02d", q$Revision: 1.10 $ =~ /(\d+)\.(\d+)/;
+$DEBUG = 0 unless defined $DEBUG;
+$ERROR = "";
use Carp qw(carp);
# what each expects/accepts.
# ----------------------------------------------------------------------
sub init {
- my ($self, $config) = @_;
+ my ( $self, $config ) = @_;
- # ------------------------------------------------------------------
+ #
# Set the parser and producer.
#
# If a 'parser' or 'from' parameter is passed in, use that as the
# parser; if a 'producer' or 'to' parameter is passed in, use that
# as the producer; both default to $DEFAULT_SUB.
- # ------------------------------------------------------------------
- $self->parser( $config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
+ #
+ $self->parser ($config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
$self->producer($config->{'producer'} || $config->{'to'} || $DEFAULT_SUB);
- # ------------------------------------------------------------------
+ #
# Set the parser_args and producer_args
- # ------------------------------------------------------------------
- for my $pargs (qw(parser_args producer_args)) {
- $self->$pargs($config->{$pargs}) if defined $config->{$pargs};
+ #
+ for my $pargs ( qw[ parser_args producer_args ] ) {
+ $self->$pargs( $config->{$pargs} ) if defined $config->{ $pargs };
}
- # ------------------------------------------------------------------
+ #
# Set the data source, if 'filename' or 'file' is provided.
- # ------------------------------------------------------------------
+ #
$config->{'filename'} ||= $config->{'file'} || "";
- $self->filename($config->{'filename'}) if $config->{'filename'};
+ $self->filename( $config->{'filename'} ) if $config->{'filename'};
- # ------------------------------------------------------------------
- # Finally, if there is a 'data' parameter, use that in preference
- # to filename and file
- # ------------------------------------------------------------------
- if (my $data = $config->{'data'}) {
- $self->data($data);
+ #
+ # Finally, if there is a 'data' parameter, use that in
+ # preference to filename and file
+ #
+ if ( my $data = $config->{'data'} ) {
+ $self->data( $data );
}
- $self->{'debug'} = $DEBUG;
- $self->{'debug'} = $config->{'debug'} if (defined $config->{'debug'});
+ $self->{'debug'} = defined $config->{'debug'} ? $config->{'debug'} : $DEBUG;
return $self;
}
# get code reference and assign
$self->{'producer'} = \&{ "$producer\::$func_name" };
$self->{'producer_type'} = $producer;
- $self->debug("Got producer: $producer\::$func_name");
+ $self->debug("Got producer: $producer\::$func_name\n");
}
# passed an anonymous subroutine reference
elsif (isa($producer, 'CODE')) {
$self->{'producer'} = $producer;
$self->{'producer_type'} = "CODE";
- $self->debug("Got producer: code ref");
+ $self->debug("Got producer: code ref\n");
}
# passed a string containing no "::"; relative package name
load($Pp) or die "Can't load $Pp: $@";
$self->{'producer'} = \&{ "$Pp\::produce" };
$self->{'producer_type'} = $Pp;
- $self->debug("Got producer: $Pp");
+ $self->debug("Got producer: $Pp\n");
}
# At this point, $self->{'producer'} contains a subroutine
# get code reference and assign
$self->{'parser'} = \&{ "$parser\::$func_name" };
$self->{'parser_type'} = $parser;
- $self->debug("Got parser: $parser\::$func_name");
+ $self->debug("Got parser: $parser\::$func_name\n");
}
# passed an anonymous subroutine reference
- elsif (isa($parser, 'CODE')) {
- $self->{'parser'} = $parser;
+ elsif ( isa( $parser, 'CODE' ) ) {
+ $self->{'parser'} = $parser;
$self->{'parser_type'} = "CODE";
- $self->debug("Got parser: code ref");
+ $self->debug("Got parser: code ref\n");
}
# passed a string containing no "::"; relative package name
else {
- my $Pp = sprintf "SQL::Translator::Parser::$parser";
- load($Pp) or die "Can't load $Pp: $@";
- $self->{'parser'} = \&{ "$Pp\::parse" };
+ my $Pp = "SQL::Translator::Parser::$parser";
+ load( $Pp ) or die "Can't load $Pp: $@";
+ $self->{'parser'} = \&{ "$Pp\::parse" };
$self->{'parser_type'} = $Pp;
- $self->debug("Got parser: $Pp");
+ $self->debug("Got parser: $Pp\n");
}
+ #
# At this point, $self->{'parser'} contains a subroutine
# reference that is ready to run
-
- $self->parser_args(@_) if (@_);
+ #
+ $self->parser_args( @_ ) if (@_);
}
return $self->{'parser'};
return $self->error($msg);
} elsif (-f _ && -r _) {
$self->{'filename'} = $filename;
- $self->debug("Got filename: $self->{'filename'}");
+ $self->debug("Got filename: '$self->{'filename'}'\n");
} else {
my $msg = "Cannot use '$filename' as input source: ".
"file does not exist or is not readable.";
# If we have a filename but no data yet, populate.
if (not $self->{'data'} and my $filename = $self->filename) {
- $self->debug("Opening '$filename' to get contents...");
+ $self->debug("Opening '$filename' to get contents.\n");
local *FH;
local $/;
my $data;
unless (open FH, $filename) {
- return $self->error("Can't open $filename for reading: $!");
+ return $self->error("Can't read file '$filename': $!");
}
$data = <FH>;
$self->{'data'} = \$data;
unless (close FH) {
- return $self->error("Can't close $filename: $!");
+ return $self->error("Can't close file '$filename': $!");
}
}
# Passed a reference to a hash?
if (isa($_[0], 'HASH')) {
# yep, a hashref
- $self->debug("translate: Got a hashref");
+ $self->debug("translate: Got a hashref\n");
$args = $_[0];
}
# Passed a reference to a string containing the data
elsif (isa($_[0], 'SCALAR')) {
# passed a ref to a string
- $self->debug("translate: Got a SCALAR reference (string)");
+ $self->debug("translate: Got a SCALAR reference (string)\n");
$self->data($_[0]);
}
# Not a reference; treat it as a filename
elsif (! ref $_[0]) {
# Not a ref, it's a filename
- $self->debug("translate: Got a filename");
+ $self->debug("translate: Got a filename\n");
$self->filename($_[0]);
}
1;
-__END__
#-----------------------------------------------------
# Rescue the drowning and tie your shoestrings.
# Henry David Thoreau
#-----------------------------------------------------
+=pod
+
=head1 AUTHORS
Ken Y. Clark, E<lt>kclark@logsoft.comE<gt>,
package SQL::Translator::Parser;
# ----------------------------------------------------------------------
-# $Id: Parser.pm,v 1.3 2002-03-25 14:25:58 dlc Exp $
+# $Id: Parser.pm,v 1.4 2002-11-20 04:03:03 kycl4rk Exp $
# ----------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
use strict;
use vars qw( $VERSION );
-$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
sub parse { "" }
1;
-#-----------------------------------------------------
+# ----------------------------------------------------------------------
# Enough! or Too much.
# William Blake
-#-----------------------------------------------------
-__END__
+# ----------------------------------------------------------------------
+
+=pod
=head1 NAME
example, if the database does not have multiple options). For MySQL,
this value might include MyISAM, HEAP, or similar.
-=item B<indeces>
+=item B<indices>
-The indeces keys is a reference to an array of hashrefs. Each hashref
+The indices keys is a reference to an array of hashrefs. Each hashref
defines one index, and has the keys 'name' (if defined, it will be a
string), 'type' (a string), and 'fields' (a reference to another
array). For example, a table in a MySQL database with two indexes,
KEY foo_idx (foo),
KEY foo_bar_idx (foo, bar),
-would be described in the indeces element as:
+would be described in the indices element as:
[
{
is_primary_key => undef,
},
},
- 'indeces' => [
+ 'indices' => [
{
'name' => 'username_idx',
'fields' => [
=head1 AUTHORS
-Ken Y. Clark, E<lt>kclark@logsoft.comE<gt>, darren chamberlain E<lt>darren@cpan.orgE<gt>
+Ken Y. Clark, E<lt>kclark@logsoft.comE<gt>,
+darren chamberlain E<lt>darren@cpan.orgE<gt>.
=head1 SEE ALSO
package SQL::Translator::Parser::MySQL;
-#-----------------------------------------------------
-# $Id: MySQL.pm,v 1.4 2002-10-11 21:09:49 cmungall Exp $
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+# $Id: MySQL.pm,v 1.5 2002-11-20 04:03:04 kycl4rk Exp $
+# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
#
use strict;
use vars qw($VERSION $GRAMMAR @EXPORT_OK);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/;
#use SQL::Translator::Parser; # This is not necessary!
use Parse::RecDescent;
if ( $line->{'is_primary_key'} ) {
push
- @{ $tables{ $item{'table_name'} }{'indeces'} },
+ @{ $tables{ $item{'table_name'} }{'indices'} },
{
type => 'primary_key',
fields => [ $field_name ],
}
}
else {
- push @{ $tables{ $item{'table_name'} }{'indeces'} },
+ push @{ $tables{ $item{'table_name'} }{'indices'} },
$line;
}
$tables{ $item{'table_name'} }{'type'} =
| field
| <error>
- comment : /^\s*#.*\n/
+ comment : /^\s*[#-]+.*\n/
blank : /\s*/
package SQL::Translator::Parser::Sybase;
#-----------------------------------------------------
-# $Id: Sybase.pm,v 1.1.1.1 2002-03-01 02:26:25 kycl4rk Exp $
+# $Id: Sybase.pm,v 1.2 2002-11-20 04:03:04 kycl4rk Exp $
#
# File : SQL/Translator/Parser/Sybase.pm
# Programmer : Ken Y. Clark, kclark@logsoft.com
if ( $line->{'is_primary_key'} ) {
push
- @{ $tables{ $item{'table_name'} }{'indeces'} },
+ @{ $tables{ $item{'table_name'} }{'indices'} },
{
type => 'primary_key',
fields => [ $field_name ],
}
}
else {
- push @{ $tables{ $item{'table_name'} }{'indeces'} },
+ push @{ $tables{ $item{'table_name'} }{'indices'} },
$line;
}
$tables{ $item{'table_name'} }{'type'} =
package SQL::Translator::Parser::xSV;
-#-----------------------------------------------------
-# $Id: xSV.pm,v 1.1 2002-03-25 14:27:23 dlc Exp $
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+# $Id: xSV.pm,v 1.2 2002-11-20 04:03:04 kycl4rk Exp $
+# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
#
use strict;
use vars qw($VERSION @EXPORT);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/;
use Exporter;
use Text::ParseWords qw(quotewords);
my $parsed = {
table1 => {
"type" => undef,
- "indeces" => [ { } ],
+ "indices" => [ { } ],
"fields" => { },
},
};
}
# Field 0 is primary key, by default, so add an index
- for ($parsed->{"table1"}->{"indeces"}->[0]) {
+ for ($parsed->{"table1"}->{"indices"}->[0]) {
$_->{"type"} = "primary_key";
$_->{"name"} = undef;
$_->{"fields"} = [ $parsed[0] ];
return $parsed;
}
-
1;
__END__
package SQL::Translator::Producer;
-#-----------------------------------------------------
-# $Id: Producer.pm,v 1.2 2002-03-21 18:50:53 dlc Exp $
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+# $Id: Producer.pm,v 1.3 2002-11-20 04:03:03 kycl4rk Exp $
+# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
#
use strict;
use vars qw($VERSION);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
sub produce { "" }
1;
-#-----------------------------------------------------
+# -------------------------------------------------------------------
# A burnt child loves the fire.
# Oscar Wilde
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+
+=pod
=head1 NAME
=head1 SYNOPSIS
-
=head1 DESCRIPTION
Producer modules designed to be used with SQL::Translator need to
package SQL::Translator::Producer::MySQL;
-#-----------------------------------------------------
-# $Id: MySQL.pm,v 1.2 2002-03-29 13:08:19 dlc Exp $
-#-----------------------------------------------------
+# -------------------------------------------------------------------
+# $Id: MySQL.pm,v 1.3 2002-11-20 04:03:04 kycl4rk Exp $
+# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
#
use strict;
use vars qw($VERSION $DEBUG);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
$DEBUG = 1 unless defined $DEBUG;
use Data::Dumper;
sub produce {
my ($translator, $data) = @_;
- debug("Beginning");
+ debug("Beginning production\n");
my $create = sprintf
"# ----------------------------------------------------------------------
# Created by %s
__PACKAGE__, scalar localtime;
for my $table (keys %{$data}) {
- debug("Looking a '$table'");
+ debug("Looking at table '$table'\n");
my $table_data = $data->{$table};
my @fields = sort { $table_data->{'fields'}->{$a}->{'order'} <=>
$table_data->{'fields'}->{$b}->{'order'}
# --------------------------------------------------------------
for (my $i = 0; $i <= $#fields; $i++) {
my $field = $fields[$i];
- debug("Looking at field: $field");
+ debug("Looking at field '$field'\n");
my $field_data = $table_data->{'fields'}->{$field};
my @fdata = ("", $field);
$create .= "\n";
# --------------------------------------------------------------
# Other keys
# --------------------------------------------------------------
- my @indeces = @{$table_data->{'indeces'}};
- for (my $i = 0; $i <= $#indeces; $i++) {
+ my @indices = @{$table_data->{'indices'}};
+ for (my $i = 0; $i <= $#indices; $i++) {
$create .= ",\n";
- my $key = $indeces[$i];
+ my $key = $indices[$i];
my ($name, $type, $fields) = @{$key}{qw(name type fields)};
if ($type eq "primary_key") {
$create .= " PRIMARY KEY (@{$fields})"
SQL::Translator::Producer::MySQL - mysql-specific producer for SQL::Translator
-
=head1 AUTHOR
darren chamberlain E<lt>darren@cpan.orgE<gt>
package SQL::Translator::Producer::Oracle;
# -------------------------------------------------------------------
-# $Id: Oracle.pm,v 1.2 2002-03-21 18:50:53 dlc Exp $
+# $Id: Oracle.pm,v 1.3 2002-11-20 04:03:04 kycl4rk Exp $
# -------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
use strict;
use vars qw( $VERSION );
-$VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
my $max_identifier_length = 30;
my %used_identifiers = ();
# Index Declarations
#
my @index_decs = ();
- for my $index ( @{ $table->{'indeces'} } ) {
+ for my $index ( @{ $table->{'indices'} } ) {
my $index_name = $index->{'name'} || '';
my $index_type = $index->{'type'} || 'normal';
my @fields = @{ $index->{'fields'} } or next;
package SQL::Translator::Validator;
# ----------------------------------------------------------------------
-# $Id: Validator.pm,v 1.3 2002-06-11 12:09:13 dlc Exp $
+# $Id: Validator.pm,v 1.4 2002-11-20 04:03:03 kycl4rk Exp $
# ----------------------------------------------------------------------
# Copyright (C) 2002 Ken Y. Clark <kycl4rk@users.sourceforge.net>,
# darren chamberlain <darren@cpan.org>
use strict;
use vars qw($VERSION @EXPORT);
-$VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
use Exporter;
use base qw(Exporter);
"Table `$table' is not a HASH reference";
}
- # Table must contain three elements: type, indeces, and fields
+ # Table must contain three elements: type, indices, and fields
# XXX If there are other keys, is this an error?
unless (exists $table_data->{"type"}) {
return by_context $wa, 0, "Missing type for table `$table'";
}
# Indices: array of hashes
- unless (defined $table_data->{"indeces"} &&
- UNIVERSAL::isa($table_data->{"indeces"}, "ARRAY")) {
+ unless (defined $table_data->{"indices"} &&
+ UNIVERSAL::isa($table_data->{"indices"}, "ARRAY")) {
return by_context $wa, 0, "Indices is missing or is not an ARRAY";
} else {
- my @indeces = @{$table_data->{"indeces"}};
+ my @indices = @{$table_data->{"indices"}};
$log .= "\n\tIndices:";
- if (@indeces) {
- for my $index (@indeces) {
+ if (@indices) {
+ for my $index (@indices) {
$log .= "\n\t\t" . ($index->{"name"} || "(unnamed)")
. " on "
. join ", ", @{$index->{"fields"}};