Force everything to 1.99, hopefully will work
[dbsrgits/SQL-Translator.git] / bin / sqlt-diff
CommitLineData
e12ca55a 1#!/usr/bin/perl -w
2# vim: set ft=perl:
3
4# -------------------------------------------------------------------
d4f84dd1 5# $Id: sqlt-diff 1440 2009-01-17 16:31:57Z jawnsy $
e12ca55a 6# -------------------------------------------------------------------
478f608d 7# Copyright (C) 2002-2009 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
0b1b149e 46 -c|--case-insensitive Compare tables/columns case-insensitively
d990d84b 47 --ignore-index-names Ignore index name differences
48 --ignore-constraint-names Ignore constraint name differences
0b1b149e 49 --mysql_parser_version=<#####> Specify a target MySQL parser version
50 for dealing with /*! comments
51 --output-db=<Producer> This Producer will be used instead of one
52 corresponding to parser1 to format output
53 for new tables
d1a895ce 54 --ignore-view-sql Ignore view SQL differences
55 --ignore-proc-sql Ignore procedure SQL differences
54b6e490 56 --no-batch-alters Do not clump multile alters to the same table into a
57 single ALTER TABLE statement where possible.
e12ca55a 58
59=head1 DESCRIPTION
60
942485ea 61sqlt-diff is a utility for creating a file of SQL commands necessary to
62transform the first schema provided to the second. While not yet
63exhaustive in its ability to mutate the entire schema, it will report the
64following
65
66=over
67
68=item * New tables
69
70Using the Producer class of the target (second) schema, any tables missing
71in the first schema will be generated in their entirety (fields, constraints,
72indices).
73
74=item * Missing/altered fields
75
76Any fields missing or altered between the two schemas will be reported
77as:
78
79 ALTER TABLE <table_name>
80 [DROP <field_name>]
81 [CHANGE <field_name> <datatype> (<size>)] ;
82
83=item * Missing/altered indices
84
85Any indices missing or of a different type or on different fields will be
86indicated. Indices that should be dropped will be reported as such:
87
88 DROP INDEX <index_name> ON <table_name> ;
89
90An index of a different type or on different fields will be reported as a
91new index as such:
92
93 CREATE [<index_type>] INDEX [<index_name>] ON <table_name>
94 ( <field_name>[,<field_name>] ) ;
95
96=back
97
da5a1bae 98ALTER, CREATE, DROP statements are created by
99SQL::Translator::Producer::*, see there for support/problems.
100
101Currently (v0.0900), only MySQL is supported by this code.
e12ca55a 102
103=cut
104
105# -------------------------------------------------------------------
106
107use strict;
108use Pod::Usage;
109use Data::Dumper;
110use SQL::Translator;
51ffe5ee 111use SQL::Translator::Diff;
942485ea 112use SQL::Translator::Schema::Constants;
e12ca55a 113
da06ac74 114use vars qw( $VERSION );
115$VERSION = '1.99';
116
d1a895ce 117my ( @input, $list, $help, $debug, $trace, $caseopt, $ignore_index_names,
118 $ignore_constraint_names, $output_db, $mysql_parser_version,
54b6e490 119 $ignore_view_sql, $ignore_proc_sql, $no_batch_alters );
e12ca55a 120for my $arg ( @ARGV ) {
121 if ( $arg =~ m/^-?-l(ist)?$/ ) {
122 $list = 1;
123 }
124 elsif ( $arg =~ m/^-?-h(elp)?$/ ) {
125 $help = 1;
126 }
127 elsif ( $arg =~ m/^-?-d(ebug)?$/ ) {
128 $debug = 1;
129 }
51ffe5ee 130 elsif ( $arg =~ m/^-?-t(race)?$/ ) {
131 $trace = 1;
132 }
d990d84b 133 elsif ( $arg =~ m/^-?-c(ase-insensitive)?$/ ) {
51ffe5ee 134 $caseopt = 1;
135 }
d990d84b 136 elsif ( $arg =~ m/^--ignore-index-names$/ ) {
137 $ignore_index_names = 1;
138 }
fb5ab406 139 elsif ( $arg =~ m/^--ignore-constraint-names$/ ) {
d990d84b 140 $ignore_constraint_names = 1;
141 }
0b1b149e 142 elsif ( $arg =~ m/^--mysql-parser-version=(.+)$/ ) {
143 $mysql_parser_version = $1;
144 }
fb5ab406 145 elsif ( $arg =~ m/^--output-db=(.+)$/ ) {
146 $output_db = $1;
147 }
d1a895ce 148 elsif ( $arg =~ m/^--ignore-view-sql$/ ) {
149 $ignore_view_sql = 1;
150 }
151 elsif ( $arg =~ m/^--ignore-proc-sql$/ ) {
152 $ignore_proc_sql = 1;
153 }
e12ca55a 154 elsif ( $arg =~ m/^([^=]+)=(.+)$/ ) {
155 push @input, { file => $1, parser => $2 };
156 }
54b6e490 157 elsif ( $arg =~ m/^--no-batch-alters$/ ) {
158 $no_batch_alters = 1;
159 }
e12ca55a 160 else {
161 pod2usage( msg => "Unknown argument '$arg'" );
162 }
163}
164
54b6e490 165print STDERR <<'EOM';
166This code is experimental, currently the new code only supports MySQL or
167SQLite diffing. To add support for other databases, please patch the relevant
168SQL::Translator::Producer:: module. If you need compatibility with the old
169sqlt-diff, please use sqlt-diff-old, and look into helping us make this one
170work for you
171EOM
da5a1bae 172
51ffe5ee 173pod2usage(1) if $help || !@ARGV;
942485ea 174pod2usage('Please specify only two schemas to diff') if scalar @input > 2;
e12ca55a 175
176my $tr = SQL::Translator->new;
177my @parsers = $tr->list_parsers;
178my %valid_parsers = map { $_, 1 } @parsers;
179
180if ( $list ) {
181 print "\nParsers:\n", map { "\t$_\n" } sort @parsers;
182 print "\n";
183 exit(0);
184}
185
186pod2usage( msg => 'Too many file args' ) if @input > 2;
187
51ffe5ee 188my ( $source_schema, $source_db, $target_schema, $target_db ) = map {
189 my $file = $_->{'file'};
190 my $parser = $_->{'parser'};
e12ca55a 191
192 die "Unable to read file '$file'\n" unless -r $file;
193 die "'$parser' is an invalid parser\n" unless $valid_parsers{ $parser };
194
d1a895ce 195 my $t = SQL::Translator->new(parser_args => {mysql_parser_version => $mysql_parser_version});
e12ca55a 196 $t->debug( $debug );
51ffe5ee 197 $t->trace( $trace );
e12ca55a 198 $t->parser( $parser ) or die $tr->error;
e12ca55a 199 my $out = $t->translate( $file ) or die $tr->error;
200 my $schema = $t->schema;
201 unless ( $schema->name ) {
202 $schema->name( $file );
203 }
204
51ffe5ee 205 ($schema, $parser);
206} @input;
207
208my $result = SQL::Translator::Diff::schema_diff($source_schema, $source_db,
209 $target_schema, $target_db,
d990d84b 210 { caseopt => $caseopt,
211 ignore_index_names => $ignore_index_names,
212 ignore_constraint_names => $ignore_constraint_names,
d1a895ce 213 ignore_view_sql => $ignore_view_sql,
214 ignore_proc_sql => $ignore_proc_sql,
2d4796c7 215 output_db => $output_db,
54b6e490 216 no_batch_alters => $no_batch_alters,
d990d84b 217 debug => $debug,
218 trace => $trace });
51ffe5ee 219if($result)
220{
221 print $result;
e12ca55a 222}
51ffe5ee 223else
224{
225 print "No differences found.";
e12ca55a 226}
227
228# -------------------------------------------------------------------
229# Bring out number weight & measure in a year of dearth.
230# William Blake
231# -------------------------------------------------------------------
232
233=pod
234
235=head1 AUTHOR
236
237Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
238
239=head1 SEE ALSO
240
241SQL::Translator, L<http://sqlfairy.sourceforge.net>.
242
243=cut