Changes to quit using "SqlfXML."
[dbsrgits/SQL-Translator.git] / bin / sqlt-dumper.pl
CommitLineData
b6feba5b 1#!/usr/bin/perl
2
3# -------------------------------------------------------------------
7bd4664a 4# $Id: sqlt-dumper.pl,v 1.3 2003-08-21 00:29:57 kycl4rk Exp $
b6feba5b 5# -------------------------------------------------------------------
6# Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20# 02111-1307 USA
21# -------------------------------------------------------------------
22
7bd4664a 23=head1 NAME
24
25sqlt-dumper.pl - create a dumper script from a schema
b6feba5b 26
b6feba5b 27=head1 SYNOPSIS
28
29 ./sqlt-dumper.pl -d Oracle [options] schema.sql > dumper.pl
30 ./dumper.pl > data.sql
31
32 Options:
33
d05353b4 34 -h|--help Show help and exit
b6feba5b 35 --add-truncate Add "TRUNCATE TABLE" statements for each table
d05353b4 36 --skip=t1[,t2] Skip tables in comma-separated list
37 -u|--user Database username
38 -p|--password Database password
39 --dsn DSN for DBI
40
41=head1 DESCRIPTION
42
43This script uses SQL::Translator to parse the SQL schema and create a
44Perl script that can connect to the database and dump the data as
45INSERT statements a la mysqldump. If you enable "add-truncate" or
46specify tables to "skip," then the generated dumper script will have
47those hardcoded. However, these will also be options in the generated
48dumper, so you can wait to specify these options when you dump your
49database. The database username, password, and DSN can be hardcoded
50into the generated script, or part of the DSN can be intuited from the
51"database" argument.
b6feba5b 52
53=cut
54
55use strict;
56use Pod::Usage;
57use Getopt::Long;
58use SQL::Translator;
59
d05353b4 60my ( $help, $db, $add_truncate, $skip, $db_user, $db_pass, $dsn );
b6feba5b 61GetOptions(
d05353b4 62 'h|help' => \$help,
63 'd|f|from|db=s' => \$db,
64 'add-truncate' => \$add_truncate,
65 'skip:s' => \$skip,
66 'u|user:s' => \$db_user,
67 'p|password:s' => \$db_pass,
68 'dsn:s' => \$dsn,
69) or pod2usage;
70
71pod2usage(0) if $help;
72pod2usage( 'No database driver specified' ) unless $db;
73$db_user ||= 'username';
74$db_pass ||= 'password';
75$dsn ||= "dbi:$db:_";
b6feba5b 76
77my $file = shift @ARGV or pod2usage( -msg => 'No input file' );
78
d05353b4 79my $t = SQL::Translator->new;
80$t->parser( $db ) or die $t->error, "\n";
81$t->filename( $file ) or die $t->error, "\n";
b6feba5b 82
d05353b4 83my %skip = map { $_, 1 } map { s/^\s+|\s+$//; $_ } split (/,/, $skip);
b6feba5b 84my $parser = $t->parser or die $t->error;
85$parser->($t, $t->data);
86my $schema = $t->schema;
d05353b4 87my $now = localtime;
b6feba5b 88
89my $out = <<"EOF";
90#!/usr/bin/perl
91
d05353b4 92#
93# Generated $now
94# By sqlt-dumper.pl, part of the SQLFairy project
95# For more info, see http://sqlfairy.sourceforge.net/
96#
97
b6feba5b 98use strict;
99use DBI;
d05353b4 100use Getopt::Long;
101
102my ( \$help, \$add_truncate, \$skip );
103GetOptions(
104 'h|help' => \\\$help,
105 'add-truncate' => \\\$add_truncate,
106 'skip:s' => \\\$skip,
107);
108
109if ( \$help ) {
110 print <<"USAGE";
111Usage:
112 \$0 [options]
113
114 Options:
115 -h|--help Show help and exit
116 --add-truncate Add "TRUNCATE TABLE" statements
117 --skip=t1[,t2] Comma-separated list of tables to skip
118
119USAGE
120 exit(0);
121}
b6feba5b 122
d05353b4 123my \%skip = map { \$_, 1 } map { s/^\\s+|\\s+\$//; \$_ } split (/,/, \$skip);
124my \$db = DBI->connect('$dsn', '$db_user', '$db_pass');
b6feba5b 125
126EOF
127
128for my $table ( $schema->get_tables ) {
129 my $table_name = $table->name;
d05353b4 130 next if $skip{ $table_name };
b6feba5b 131 my ( @field_names, %types );
132 for my $field ( $table->get_fields ) {
133 $types{ $field->name } = $field->data_type =~ m/(char|str|long|text)/
134 ? 'string' : 'number';
135 push @field_names, $field->name;
136 }
137
138 $out .= join('',
d05353b4 139 "#\n# Table: $table_name\n#\n{\n",
140 " next if \$skip{'$table_name'};\n",
141 " print \"--\\n-- Data for table '$table_name'\\n--\\n\";\n\n",
142 " if ( \$add_truncate ) {\n",
143 " print \"TRUNCATE TABLE $table_name;\\n\";\n",
144 " }\n\n",
b6feba5b 145 );
146
147 my $insert = "INSERT INTO $table_name (". join(', ', @field_names).
148 ') VALUES (';
149
150 if ( $add_truncate ) {
151 $out .= " print \"TRUNCATE TABLE $table_name;\\n\";\n";
152 }
153
154 $out .= join('',
155 " my \%types = (\n",
156 join("\n", map { " $_ => '$types{ $_ }'," } @field_names),
157 "\n );\n\n",
158 " my \$data = \$db->selectall_arrayref(\n",
159 " 'select ", join(', ', @field_names), " from $table_name',\n",
160 " { Columns => {} },\n",
161 " );\n\n",
162 " for my \$rec ( \@{ \$data } ) {\n",
163 " my \@vals;\n",
164 " for my \$fld ( qw[", join(' ', @field_names), "] ) {\n",
165 " my \$val = \$rec->{ \$fld };\n",
166 " if ( \$types{ \$fld } eq 'string' ) {\n",
167 " \$val =~ s/'/\\'/g;\n",
168 " \$val = defined \$val ? qq['\$val'] : qq[''];\n",
169 " }\n",
170 " else {\n",
171 " \$val = defined \$val ? \$val : 'NULL';\n",
172 " }\n",
173 " push \@vals, \$val;\n",
174 " }\n",
175 " print \"$insert\", join(', ', \@vals), \");\\n\";\n",
176 " }\n",
d05353b4 177 " print \"\\n\";\n",
b6feba5b 178 "}\n\n",
179 );
180}
181
182print $out;