Added output_db option
[dbsrgits/SQL-Translator.git] / bin / sqlt-diff
CommitLineData
e12ca55a 1#!/usr/bin/perl -w
2# vim: set ft=perl:
3
4# -------------------------------------------------------------------
fb5ab406 5# $Id: sqlt-diff,v 1.15 2007-03-06 23:49:42 duality72 Exp $
e12ca55a 6# -------------------------------------------------------------------
daf4f623 7# Copyright (C) 2002-4 The SQLFairy Authors
e12ca55a 8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; version 2.
12#
13# This program is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21# 02111-1307 USA
22# -------------------------------------------------------------------
23
24=head1 NAME
25
26sqlt-diff - find the differences b/w two schemas
27
28=head1 SYNOPSIS
29
30For help:
31
32 sqlt-diff -h|--help
33
34For a list of all valid parsers:
35
36 sqlt -l|--list
37
38To diff two schemas:
39
fb5ab406 40 sqlt-diff [options] file_name1=parser1 file_name2=parser2
e12ca55a 41
42Options:
43
44 -d|--debug Show debugging info
51ffe5ee 45 -t|--trace Turn on tracing for Parse::RecDescent
46 -c|--case-insensitive Compare tables/columns case-insenstiviely
d990d84b 47 --ignore-index-names Ignore index name differences
48 --ignore-constraint-names Ignore constraint name differences
fb5ab406 49 --output-db This Producer will be used instead of one corresponding to
50 parser1 to format output for new tables
e12ca55a 51
52=head1 DESCRIPTION
53
942485ea 54sqlt-diff is a utility for creating a file of SQL commands necessary to
55transform the first schema provided to the second. While not yet
56exhaustive in its ability to mutate the entire schema, it will report the
57following
58
59=over
60
61=item * New tables
62
63Using the Producer class of the target (second) schema, any tables missing
64in the first schema will be generated in their entirety (fields, constraints,
65indices).
66
67=item * Missing/altered fields
68
69Any fields missing or altered between the two schemas will be reported
70as:
71
72 ALTER TABLE <table_name>
73 [DROP <field_name>]
74 [CHANGE <field_name> <datatype> (<size>)] ;
75
76=item * Missing/altered indices
77
78Any indices missing or of a different type or on different fields will be
79indicated. Indices that should be dropped will be reported as such:
80
81 DROP INDEX <index_name> ON <table_name> ;
82
83An index of a different type or on different fields will be reported as a
84new index as such:
85
86 CREATE [<index_type>] INDEX [<index_name>] ON <table_name>
87 ( <field_name>[,<field_name>] ) ;
88
89=back
90
91"ALTER/DROP TABLE" and "CREATE INDEX" statements B<are not> generated by
92the Producer, unfortunately, and may require massaging before being passed to
93your target database.
e12ca55a 94
95=cut
96
97# -------------------------------------------------------------------
98
99use strict;
100use Pod::Usage;
101use Data::Dumper;
102use SQL::Translator;
51ffe5ee 103use SQL::Translator::Diff;
942485ea 104use SQL::Translator::Schema::Constants;
e12ca55a 105
106use vars qw( $VERSION );
fb5ab406 107$VERSION = sprintf "%d.%02d", q$Revision: 1.15 $ =~ /(\d+)\.(\d+)/;
e12ca55a 108
fb5ab406 109my ( @input, $list, $help, $debug, $trace, $caseopt , $ignore_index_names, $ignore_constraint_names, $output_db );
e12ca55a 110for my $arg ( @ARGV ) {
111 if ( $arg =~ m/^-?-l(ist)?$/ ) {
112 $list = 1;
113 }
114 elsif ( $arg =~ m/^-?-h(elp)?$/ ) {
115 $help = 1;
116 }
117 elsif ( $arg =~ m/^-?-d(ebug)?$/ ) {
118 $debug = 1;
119 }
51ffe5ee 120 elsif ( $arg =~ m/^-?-t(race)?$/ ) {
121 $trace = 1;
122 }
d990d84b 123 elsif ( $arg =~ m/^-?-c(ase-insensitive)?$/ ) {
51ffe5ee 124 $caseopt = 1;
125 }
d990d84b 126 elsif ( $arg =~ m/^--ignore-index-names$/ ) {
127 $ignore_index_names = 1;
128 }
fb5ab406 129 elsif ( $arg =~ m/^--ignore-constraint-names$/ ) {
d990d84b 130 $ignore_constraint_names = 1;
131 }
fb5ab406 132 elsif ( $arg =~ m/^--output-db=(.+)$/ ) {
133 $output_db = $1;
134 }
e12ca55a 135 elsif ( $arg =~ m/^([^=]+)=(.+)$/ ) {
136 push @input, { file => $1, parser => $2 };
137 }
138 else {
139 pod2usage( msg => "Unknown argument '$arg'" );
140 }
141}
142
51ffe5ee 143pod2usage(1) if $help || !@ARGV;
942485ea 144pod2usage('Please specify only two schemas to diff') if scalar @input > 2;
e12ca55a 145
146my $tr = SQL::Translator->new;
147my @parsers = $tr->list_parsers;
148my %valid_parsers = map { $_, 1 } @parsers;
149
150if ( $list ) {
151 print "\nParsers:\n", map { "\t$_\n" } sort @parsers;
152 print "\n";
153 exit(0);
154}
155
156pod2usage( msg => 'Too many file args' ) if @input > 2;
157
51ffe5ee 158my ( $source_schema, $source_db, $target_schema, $target_db ) = map {
159 my $file = $_->{'file'};
160 my $parser = $_->{'parser'};
e12ca55a 161
162 die "Unable to read file '$file'\n" unless -r $file;
163 die "'$parser' is an invalid parser\n" unless $valid_parsers{ $parser };
164
165 my $t = SQL::Translator->new;
166 $t->debug( $debug );
51ffe5ee 167 $t->trace( $trace );
e12ca55a 168 $t->parser( $parser ) or die $tr->error;
e12ca55a 169 my $out = $t->translate( $file ) or die $tr->error;
170 my $schema = $t->schema;
171 unless ( $schema->name ) {
172 $schema->name( $file );
173 }
174
51ffe5ee 175 ($schema, $parser);
176} @input;
177
178my $result = SQL::Translator::Diff::schema_diff($source_schema, $source_db,
179 $target_schema, $target_db,
d990d84b 180 { caseopt => $caseopt,
181 ignore_index_names => $ignore_index_names,
182 ignore_constraint_names => $ignore_constraint_names,
183 debug => $debug,
184 trace => $trace });
51ffe5ee 185if($result)
186{
187 print $result;
e12ca55a 188}
51ffe5ee 189else
190{
191 print "No differences found.";
e12ca55a 192}
193
194# -------------------------------------------------------------------
195# Bring out number weight & measure in a year of dearth.
196# William Blake
197# -------------------------------------------------------------------
198
199=pod
200
201=head1 AUTHOR
202
203Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
204
205=head1 SEE ALSO
206
207SQL::Translator, L<http://sqlfairy.sourceforge.net>.
208
209=cut