Added "template" option for TTSchema produce, added docs for "pretty" and
[dbsrgits/SQL-Translator.git] / bin / sqlt-dumper.pl
CommitLineData
b6feba5b 1#!/usr/bin/perl
2
3# -------------------------------------------------------------------
d05353b4 4# $Id: sqlt-dumper.pl,v 1.2 2003-06-24 21:00:24 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
23=head1 sqlt-dumper.pl - create a dumper script from a schema
24
b6feba5b 25=head1 SYNOPSIS
26
27 ./sqlt-dumper.pl -d Oracle [options] schema.sql > dumper.pl
28 ./dumper.pl > data.sql
29
30 Options:
31
d05353b4 32 -h|--help Show help and exit
b6feba5b 33 --add-truncate Add "TRUNCATE TABLE" statements for each table
d05353b4 34 --skip=t1[,t2] Skip tables in comma-separated list
35 -u|--user Database username
36 -p|--password Database password
37 --dsn DSN for DBI
38
39=head1 DESCRIPTION
40
41This script uses SQL::Translator to parse the SQL schema and create a
42Perl script that can connect to the database and dump the data as
43INSERT statements a la mysqldump. If you enable "add-truncate" or
44specify tables to "skip," then the generated dumper script will have
45those hardcoded. However, these will also be options in the generated
46dumper, so you can wait to specify these options when you dump your
47database. The database username, password, and DSN can be hardcoded
48into the generated script, or part of the DSN can be intuited from the
49"database" argument.
b6feba5b 50
51=cut
52
53use strict;
54use Pod::Usage;
55use Getopt::Long;
56use SQL::Translator;
57
d05353b4 58my ( $help, $db, $add_truncate, $skip, $db_user, $db_pass, $dsn );
b6feba5b 59GetOptions(
d05353b4 60 'h|help' => \$help,
61 'd|f|from|db=s' => \$db,
62 'add-truncate' => \$add_truncate,
63 'skip:s' => \$skip,
64 'u|user:s' => \$db_user,
65 'p|password:s' => \$db_pass,
66 'dsn:s' => \$dsn,
67) or pod2usage;
68
69pod2usage(0) if $help;
70pod2usage( 'No database driver specified' ) unless $db;
71$db_user ||= 'username';
72$db_pass ||= 'password';
73$dsn ||= "dbi:$db:_";
b6feba5b 74
75my $file = shift @ARGV or pod2usage( -msg => 'No input file' );
76
d05353b4 77my $t = SQL::Translator->new;
78$t->parser( $db ) or die $t->error, "\n";
79$t->filename( $file ) or die $t->error, "\n";
b6feba5b 80
d05353b4 81my %skip = map { $_, 1 } map { s/^\s+|\s+$//; $_ } split (/,/, $skip);
b6feba5b 82my $parser = $t->parser or die $t->error;
83$parser->($t, $t->data);
84my $schema = $t->schema;
d05353b4 85my $now = localtime;
b6feba5b 86
87my $out = <<"EOF";
88#!/usr/bin/perl
89
d05353b4 90#
91# Generated $now
92# By sqlt-dumper.pl, part of the SQLFairy project
93# For more info, see http://sqlfairy.sourceforge.net/
94#
95
b6feba5b 96use strict;
97use DBI;
d05353b4 98use Getopt::Long;
99
100my ( \$help, \$add_truncate, \$skip );
101GetOptions(
102 'h|help' => \\\$help,
103 'add-truncate' => \\\$add_truncate,
104 'skip:s' => \\\$skip,
105);
106
107if ( \$help ) {
108 print <<"USAGE";
109Usage:
110 \$0 [options]
111
112 Options:
113 -h|--help Show help and exit
114 --add-truncate Add "TRUNCATE TABLE" statements
115 --skip=t1[,t2] Comma-separated list of tables to skip
116
117USAGE
118 exit(0);
119}
b6feba5b 120
d05353b4 121my \%skip = map { \$_, 1 } map { s/^\\s+|\\s+\$//; \$_ } split (/,/, \$skip);
122my \$db = DBI->connect('$dsn', '$db_user', '$db_pass');
b6feba5b 123
124EOF
125
126for my $table ( $schema->get_tables ) {
127 my $table_name = $table->name;
d05353b4 128 next if $skip{ $table_name };
b6feba5b 129 my ( @field_names, %types );
130 for my $field ( $table->get_fields ) {
131 $types{ $field->name } = $field->data_type =~ m/(char|str|long|text)/
132 ? 'string' : 'number';
133 push @field_names, $field->name;
134 }
135
136 $out .= join('',
d05353b4 137 "#\n# Table: $table_name\n#\n{\n",
138 " next if \$skip{'$table_name'};\n",
139 " print \"--\\n-- Data for table '$table_name'\\n--\\n\";\n\n",
140 " if ( \$add_truncate ) {\n",
141 " print \"TRUNCATE TABLE $table_name;\\n\";\n",
142 " }\n\n",
b6feba5b 143 );
144
145 my $insert = "INSERT INTO $table_name (". join(', ', @field_names).
146 ') VALUES (';
147
148 if ( $add_truncate ) {
149 $out .= " print \"TRUNCATE TABLE $table_name;\\n\";\n";
150 }
151
152 $out .= join('',
153 " my \%types = (\n",
154 join("\n", map { " $_ => '$types{ $_ }'," } @field_names),
155 "\n );\n\n",
156 " my \$data = \$db->selectall_arrayref(\n",
157 " 'select ", join(', ', @field_names), " from $table_name',\n",
158 " { Columns => {} },\n",
159 " );\n\n",
160 " for my \$rec ( \@{ \$data } ) {\n",
161 " my \@vals;\n",
162 " for my \$fld ( qw[", join(' ', @field_names), "] ) {\n",
163 " my \$val = \$rec->{ \$fld };\n",
164 " if ( \$types{ \$fld } eq 'string' ) {\n",
165 " \$val =~ s/'/\\'/g;\n",
166 " \$val = defined \$val ? qq['\$val'] : qq[''];\n",
167 " }\n",
168 " else {\n",
169 " \$val = defined \$val ? \$val : 'NULL';\n",
170 " }\n",
171 " push \@vals, \$val;\n",
172 " }\n",
173 " print \"$insert\", join(', ', \@vals), \");\\n\";\n",
174 " }\n",
d05353b4 175 " print \"\\n\";\n",
b6feba5b 176 "}\n\n",
177 );
178}
179
180print $out;