From: Ken Youens-Clark Date: Tue, 26 Aug 2003 03:56:43 +0000 (+0000) Subject: Adding new files. X-Git-Tag: v0.04~223 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=354b180736349e2507cc6819e09d77ce9822cf74;p=dbsrgits%2FSQL-Translator.git Adding new files. --- diff --git a/bin/sqlt-dumper b/bin/sqlt-dumper new file mode 100755 index 0000000..6993097 --- /dev/null +++ b/bin/sqlt-dumper @@ -0,0 +1,203 @@ +#!/usr/bin/perl + +# ------------------------------------------------------------------- +# $Id: sqlt-dumper,v 1.1 2003-08-26 03:56:43 kycl4rk Exp $ +# ------------------------------------------------------------------- +# Copyright (C) 2003 Ken Y. Clark +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA +# ------------------------------------------------------------------- + +=head1 NAME + +sqlt-dumper - create a dumper script from a schema + +=head1 SYNOPSIS + + sqlt-dumper -d Oracle [options] schema.sql > dumper.pl + + ./dumper.pl > data.sql + + Options: + + -h|--help Show help and exit + --add-truncate Add "TRUNCATE TABLE" statements for each table + --skip=t1[,t2] Skip tables in comma-separated list + -u|--user Database username + -p|--password Database password + --dsn DSN for DBI + +=head1 DESCRIPTION + +This script uses SQL::Translator to parse the SQL schema and create a +Perl script that can connect to the database and dump the data as +INSERT statements a la mysqldump. If you enable "add-truncate" or +specify tables to "skip," then the generated dumper script will have +those hardcoded. However, these will also be options in the generated +dumper, so you can wait to specify these options when you dump your +database. The database username, password, and DSN can be hardcoded +into the generated script, or part of the DSN can be intuited from the +"database" argument. + +=cut + +# ------------------------------------------------------------------- + +use strict; +use Pod::Usage; +use Getopt::Long; +use SQL::Translator; + +use vars '$VERSION'; +$VERSION = sprintf "%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/; + +my ( $help, $db, $add_truncate, $skip, $db_user, $db_pass, $dsn ); +GetOptions( + 'h|help' => \$help, + 'd|f|from|db=s' => \$db, + 'add-truncate' => \$add_truncate, + 'skip:s' => \$skip, + 'u|user:s' => \$db_user, + 'p|password:s' => \$db_pass, + 'dsn:s' => \$dsn, +) or pod2usage; + +pod2usage(0) if $help; +pod2usage( 'No database driver specified' ) unless $db; +$db_user ||= 'username'; +$db_pass ||= 'password'; +$dsn ||= "dbi:$db:_"; + +my $file = shift @ARGV or pod2usage( -msg => 'No input file' ); + +my $t = SQL::Translator->new; +$t->parser( $db ) or die $t->error, "\n"; +$t->filename( $file ) or die $t->error, "\n"; + +my %skip = map { $_, 1 } map { s/^\s+|\s+$//; $_ } split (/,/, $skip); +my $parser = $t->parser or die $t->error; +$parser->($t, $t->data); +my $schema = $t->schema; +my $now = localtime; + +my $out = <<"EOF"; +#!/usr/bin/perl + +# +# Generated $now +# By sqlt-dumper.pl, part of the SQLFairy project +# For more info, see http://sqlfairy.sourceforge.net/ +# + +use strict; +use DBI; +use Getopt::Long; + +my ( \$help, \$add_truncate, \$skip ); +GetOptions( + 'h|help' => \\\$help, + 'add-truncate' => \\\$add_truncate, + 'skip:s' => \\\$skip, +); + +if ( \$help ) { + print <<"USAGE"; +Usage: + \$0 [options] + + Options: + -h|--help Show help and exit + --add-truncate Add "TRUNCATE TABLE" statements + --skip=t1[,t2] Comma-separated list of tables to skip + +USAGE + exit(0); +} + +my \%skip = map { \$_, 1 } map { s/^\\s+|\\s+\$//; \$_ } split (/,/, \$skip); +my \$db = DBI->connect('$dsn', '$db_user', '$db_pass'); + +EOF + +for my $table ( $schema->get_tables ) { + my $table_name = $table->name; + next if $skip{ $table_name }; + my ( @field_names, %types ); + for my $field ( $table->get_fields ) { + $types{ $field->name } = $field->data_type =~ m/(char|str|long|text)/ + ? 'string' : 'number'; + push @field_names, $field->name; + } + + $out .= join('', + "#\n# Table: $table_name\n#\n{\n", + " next if \$skip{'$table_name'};\n", + " print \"--\\n-- Data for table '$table_name'\\n--\\n\";\n\n", + " if ( \$add_truncate ) {\n", + " print \"TRUNCATE TABLE $table_name;\\n\";\n", + " }\n\n", + ); + + my $insert = "INSERT INTO $table_name (". join(', ', @field_names). + ') VALUES ('; + + if ( $add_truncate ) { + $out .= " print \"TRUNCATE TABLE $table_name;\\n\";\n"; + } + + $out .= join('', + " my \%types = (\n", + join("\n", map { " $_ => '$types{ $_ }'," } @field_names), + "\n );\n\n", + " my \$data = \$db->selectall_arrayref(\n", + " 'select ", join(', ', @field_names), " from $table_name',\n", + " { Columns => {} },\n", + " );\n\n", + " for my \$rec ( \@{ \$data } ) {\n", + " my \@vals;\n", + " for my \$fld ( qw[", join(' ', @field_names), "] ) {\n", + " my \$val = \$rec->{ \$fld };\n", + " if ( \$types{ \$fld } eq 'string' ) {\n", + " \$val =~ s/'/\\'/g;\n", + " \$val = defined \$val ? qq['\$val'] : qq[''];\n", + " }\n", + " else {\n", + " \$val = defined \$val ? \$val : 'NULL';\n", + " }\n", + " push \@vals, \$val;\n", + " }\n", + " print \"$insert\", join(', ', \@vals), \");\\n\";\n", + " }\n", + " print \"\\n\";\n", + "}\n\n", + ); +} + +print $out; +exit(0); + +# ------------------------------------------------------------------- + +=pod + +=head1 AUTHOR + +Ken Y. Clark Ekclark@cpan.orgE. + +=head1 SEE ALSO + +perl, SQL::Translator. + +=cut diff --git a/bin/sqlt-graph b/bin/sqlt-graph new file mode 100755 index 0000000..fca4aba --- /dev/null +++ b/bin/sqlt-graph @@ -0,0 +1,166 @@ +#!/usr/bin/perl + +# ------------------------------------------------------------------- +# $Id: sqlt-graph,v 1.1 2003-08-26 03:56:43 kycl4rk Exp $ +# ------------------------------------------------------------------- +# Copyright (C) 2002 Ken Y. Clark +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +# 02111-1307 USA +# ------------------------------------------------------------------- + +=head1 NAME + +sqlt-graph - Automatically create a graph from a database schema + +=head1 SYNOPSIS + + ./sqlt-graph -d|--db|-f|--from=db_parser [options] schema.sql + + Options: + + -l|--layout Layout schema for GraphViz + ("dot," "neato," "twopi"; default "dot") + -n|--node-shape Shape of the nodes ("record," "plaintext," + "ellipse," "circle," "egg," "triangle," "box," + "diamond," "trapezium," "parallelogram," "house," + "hexagon," "octagon," default "record") + -o|--output Output file name (default STDOUT) + -t|--output-type Output file type ("canon", "text," "ps," "hpgl," + "pcl," "mif," "pic," "gd," "gd2," "gif," "jpeg," + "png," "wbmp," "cmap," "ismap," "imap," "vrml," + "vtx," "mp," "fig," "svg," "plain," default "png") + -c|--color Add colors + --no-fields Don't show field names + --height Image height (in inches, default "11", + set to "0" to undefine) + --width Image width (in inches, default "8.5", + set to "0" to undefine) + --natural-join Perform natural joins + --natural-join-pk Perform natural joins from primary keys only + -s|--skip Fields to skip in natural joins + --debug Print debugging information + +=head1 DESCRIPTION + +This script will create a graph of your schema. Only the database +driver argument (for SQL::Translator) is required. If no output file +name is given, then image will be printed to STDOUT, so you should +redirect the output into a file. + +The default action is to assume the presence of foreign key +relationships defined via "REFERNCES" or "FOREIGN KEY" constraints on +the tables. If you are parsing the schema of a file that does not +have these, you will find the natural join options helpful. With +natural joins, like-named fields will be considered foreign keys. +This can prove too permissive, however, as you probably don't want a +field called "name" to be considered a foreign key, so you could +include it in the "skip" option, and all fields called "name" will be +excluded from natural joins. A more efficient method, however, might +be to simply deduce the foriegn keys from primary keys to other fields +named the same in other tables. Use the "natural-join-pk" option +to acheive this. + +If the schema defines foreign keys, then the graph produced will be +directed showing the direction of the relationship. If the foreign +keys are intuited via natural joins, the graph will be undirected. + +=cut + +# ------------------------------------------------------------------- + +use strict; +use Data::Dumper; +use Getopt::Long; +use GraphViz; +use Pod::Usage; +use SQL::Translator; + +use vars '$VERSION'; +$VERSION = sprintf "%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/; + +# +# Get arguments. +# +my ( + $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color, + $natural_join, $join_pk_only, $skip_fields, $debug, $help, $height, + $width, $no_fields +); + +GetOptions( + 'd|db|f|from=s' => \$db_driver, + 'o|output:s' => \$out_file, + 'l|layout:s' => \$layout, + 'n|node-shape:s' => \$node_shape, + 't|output-type:s' => \$output_type, + 'height:i' => \$height, + 'width:i' => \$width, + 'c|color' => \$add_color, + 'no-fields' => \$no_fields, + 'natural-join' => \$natural_join, + 'natural-join-pk' => \$join_pk_only, + 's|skip:s' => \$skip_fields, + 'debug' => \$debug, + 'h|help' => \$help, +) or die pod2usage; +my @files = @ARGV; # the create script(s) for the original db + +pod2usage(1) if $help; +pod2usage( -message => "No db driver specified" ) unless $db_driver; +pod2usage( -message => 'No input file' ) unless @files; + +my $translator = SQL::Translator->new( + from => $db_driver, + to => 'GraphViz', + debug => $debug || 0, + producer_args => { + out_file => $out_file, + layout => $layout, + node_shape => $node_shape, + output_type => $output_type, + add_color => $add_color, + natural_join => $natural_join, + natural_join_pk => $join_pk_only, + skip_fields => $skip_fields, + height => $height || 0, + width => $width || 0, + show_fields => $no_fields ? 0 : 1, + }, +) or die SQL::Translator->error; + +for my $file (@files) { + my $output = $translator->translate( $file ) or die + "Error: " . $translator->error; + if ( $out_file ) { + print "Image written to '$out_file'. Done.\n"; + } + else { + print $output; + } +} + +# ------------------------------------------------------------------- + +=pod + +=head1 AUTHOR + +Ken Y. Clark Ekclark@cpan.orgE. + +=head1 SEE ALSO + +perl, SQL::Translator. + +=cut