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