Awesome non-quoted numeric default patch by Stephen Clouse
[dbsrgits/SQL-Translator.git] / t / 30sqlt-new-diff-mysql.t
CommitLineData
4d438549 1#!/usr/bin/perl
2# vim: set ft=perl:
3
4use strict;
5use warnings;
6use SQL::Translator;
7
8use File::Spec::Functions qw(catfile updir tmpdir);
9use FindBin qw($Bin);
10use Test::More;
11use Test::Differences;
12use Test::SQL::Translator qw(maybe_plan);
f9ed5d54 13use SQL::Translator::Schema::Constants;
14use Storable 'dclone';
4d438549 15
4863ba22 16plan tests => 9;
4d438549 17
18use_ok('SQL::Translator::Diff') or die "Cannot continue\n";
19
4863ba22 20my $tr = SQL::Translator->new;
4d438549 21
07d6e5f7 22my ( $source_schema, $target_schema, $parsed_sql_schema ) = map {
4d438549 23 my $t = SQL::Translator->new;
24 $t->parser( 'YAML' )
25 or die $tr->error;
26 my $out = $t->translate( catfile($Bin, qw/data diff/, $_ ) )
27 or die $tr->error;
28
29 my $schema = $t->schema;
30 unless ( $schema->name ) {
31 $schema->name( $_ );
32 }
33 ($schema);
07d6e5f7 34} (qw( create1.yml create2.yml ));
4d438549 35
36# Test for differences
4863ba22 37my @out = SQL::Translator::Diff::schema_diff(
38 $source_schema, 'MySQL',
39 $target_schema, 'MySQL',
40 {
41 no_batch_alters => 1,
1f5b2625 42 producer_args => { quote_table_names => 0 }
4863ba22 43 }
44);
45
46ok( @out, 'Got a list' );
47
48my $out = join('', @out);
49
4d438549 50eq_or_diff($out, <<'## END OF DIFF', "Diff as expected");
24d9fe69 51-- Convert schema 'create1.yml' to 'create2.yml':;
4d438549 52
f9ed5d54 53BEGIN;
4d438549 54
55SET foreign_key_checks=0;
56
4d438549 57CREATE TABLE added (
58 id integer(11)
59);
60
4d438549 61SET foreign_key_checks=1;
62
46bf5655 63ALTER TABLE old_name RENAME TO new_name;
24d9fe69 64
4d438549 65ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E;
24d9fe69 66
74ca32ce 67ALTER TABLE person DROP INDEX UC_age_name;
24d9fe69 68
4d438549 69ALTER TABLE person DROP INDEX u_name;
24d9fe69 70
4d438549 71ALTER TABLE employee DROP COLUMN job_title;
24d9fe69 72
46bf5655 73ALTER TABLE new_name ADD COLUMN new_field integer;
24d9fe69 74
06baeb21 75ALTER TABLE person ADD COLUMN is_rock_star tinyint(4) DEFAULT 1;
24d9fe69 76
4d438549 77ALTER TABLE person CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment;
24d9fe69 78
4d438549 79ALTER TABLE person CHANGE COLUMN name name varchar(20) NOT NULL;
24d9fe69 80
06baeb21 81ALTER TABLE person CHANGE COLUMN age age integer(11) DEFAULT 18;
24d9fe69 82
06baeb21 83ALTER TABLE person CHANGE COLUMN iq iq integer(11) DEFAULT 0;
24d9fe69 84
4d438549 85ALTER TABLE person CHANGE COLUMN description physical_description text;
24d9fe69 86
4d438549 87ALTER TABLE person ADD UNIQUE INDEX unique_name (name);
24d9fe69 88
4d438549 89ALTER TABLE employee ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id);
24d9fe69 90
4d438549 91ALTER TABLE person ADD UNIQUE UC_person_id (person_id);
24d9fe69 92
4d438549 93ALTER TABLE person ADD UNIQUE UC_age_name (age, name);
24d9fe69 94
4d438549 95ALTER TABLE person ENGINE=InnoDB;
24d9fe69 96
4d438549 97ALTER TABLE deleted DROP FOREIGN KEY fk_fake;
24d9fe69 98
4d438549 99DROP TABLE deleted;
100
24d9fe69 101
4d438549 102COMMIT;
24d9fe69 103
4d438549 104## END OF DIFF
105
4d438549 106$out = SQL::Translator::Diff::schema_diff($source_schema, 'MySQL', $target_schema, 'MySQL',
107 { ignore_index_names => 1,
7467c458 108 ignore_constraint_names => 1,
1f5b2625 109 producer_args => { quote_table_names => 0 },
4d438549 110 });
111
112eq_or_diff($out, <<'## END OF DIFF', "Diff as expected");
24d9fe69 113-- Convert schema 'create1.yml' to 'create2.yml':;
4d438549 114
f9ed5d54 115BEGIN;
4d438549 116
117SET foreign_key_checks=0;
118
4d438549 119CREATE TABLE added (
120 id integer(11)
121);
122
4d438549 123SET foreign_key_checks=1;
124
4d438549 125ALTER TABLE employee DROP COLUMN job_title;
24d9fe69 126
46bf5655 127ALTER TABLE old_name RENAME TO new_name,
128 ADD COLUMN new_field integer;
24d9fe69 129
74ca32ce 130ALTER TABLE person DROP INDEX UC_age_name,
06baeb21 131 ADD COLUMN is_rock_star tinyint(4) DEFAULT 1,
4d438549 132 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
133 CHANGE COLUMN name name varchar(20) NOT NULL,
06baeb21 134 CHANGE COLUMN age age integer(11) DEFAULT 18,
135 CHANGE COLUMN iq iq integer(11) DEFAULT 0,
4d438549 136 CHANGE COLUMN description physical_description text,
137 ADD UNIQUE UC_person_id (person_id),
138 ADD UNIQUE UC_age_name (age, name),
139 ENGINE=InnoDB;
24d9fe69 140
4d438549 141ALTER TABLE deleted DROP FOREIGN KEY fk_fake;
24d9fe69 142
4d438549 143DROP TABLE deleted;
144
24d9fe69 145
4d438549 146COMMIT;
24d9fe69 147
4d438549 148## END OF DIFF
149
150
151# Test for sameness
152$out = SQL::Translator::Diff::schema_diff($source_schema, 'MySQL', $source_schema, 'MySQL' );
153
154eq_or_diff($out, <<'## END OF DIFF', "No differences found");
24d9fe69 155-- Convert schema 'create1.yml' to 'create1.yml':;
4d438549 156
24d9fe69 157-- No differences found;
4d438549 158
159## END OF DIFF
160
07d6e5f7 161{
162 my $t = SQL::Translator->new;
163 $t->parser( 'MySQL' )
164 or die $tr->error;
165 my $out = $t->translate( catfile($Bin, qw/data mysql create.sql/ ) )
166 or die $tr->error;
46bf5655 167
168 # Lets remove the renamed table so we dont have to change the SQL or other tests
169 $target_schema->drop_table('new_name');
07d6e5f7 170
171 my $schema = $t->schema;
172 unless ( $schema->name ) {
173 $schema->name( 'create.sql' );
174 }
175
176 # Now lets change the type of one of the 'integer' columns so that it
177 # matches what the mysql parser sees for '<col> interger'.
178 my $field = $target_schema->get_table('employee')->get_field('employee_id');
179 $field->data_type('integer');
180 $field->size(0);
1f5b2625 181 $out = SQL::Translator::Diff::schema_diff($schema, 'MySQL', $target_schema, 'MySQL', { producer_args => { quote_table_names => 0 } } );
07d6e5f7 182 eq_or_diff($out, <<'## END OF DIFF', "No differences found");
24d9fe69 183-- Convert schema 'create.sql' to 'create2.yml':;
07d6e5f7 184
f9ed5d54 185BEGIN;
07d6e5f7 186
187SET foreign_key_checks=0;
188
07d6e5f7 189CREATE TABLE added (
190 id integer(11)
191);
192
07d6e5f7 193SET foreign_key_checks=1;
194
07d6e5f7 195ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E,
196 DROP COLUMN job_title,
1c680eb9 197 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id);
24d9fe69 198
74ca32ce 199ALTER TABLE person DROP INDEX UC_age_name,
07d6e5f7 200 DROP INDEX u_name,
06baeb21 201 ADD COLUMN is_rock_star tinyint(4) DEFAULT 1,
07d6e5f7 202 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
203 CHANGE COLUMN name name varchar(20) NOT NULL,
06baeb21 204 CHANGE COLUMN age age integer(11) DEFAULT 18,
205 CHANGE COLUMN iq iq integer(11) DEFAULT 0,
07d6e5f7 206 CHANGE COLUMN description physical_description text,
207 ADD UNIQUE INDEX unique_name (name),
208 ADD UNIQUE UC_person_id (person_id),
209 ADD UNIQUE UC_age_name (age, name),
210 ENGINE=InnoDB;
24d9fe69 211
07d6e5f7 212DROP TABLE deleted;
213
24d9fe69 214
07d6e5f7 215COMMIT;
24d9fe69 216
07d6e5f7 217## END OF DIFF
218}
f9ed5d54 219
220# Test InnoDB stupidness. Have to drop constraints before re-adding them if
221# they are just alters.
222
223
224{
225 my $s1 = SQL::Translator::Schema->new;
226 my $s2 = SQL::Translator::Schema->new;
227
228 $s1->name('Schema 1');
229 $s2->name('Schema 2');
230
231 my $t1 = $s1->add_table($target_schema->get_table('employee'));
232 my $t2 = $s2->add_table(dclone($target_schema->get_table('employee')));
233
234
235 my ($c) = grep { $_->name eq 'FK5302D47D93FE702E_diff' } $t2->get_constraints;
236 $c->on_delete('CASCADE');
237
238 $t2->add_constraint(
239 name => 'new_constraint',
240 type => 'FOREIGN KEY',
241 fields => ['employee_id'],
242 reference_fields => ['fake'],
243 reference_table => 'patty',
244 );
245
246 $t2->add_field(
247 name => 'new',
248 data_type => 'int'
249 );
250
4104f82b 251 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
f9ed5d54 252
253 eq_or_diff($out, <<'## END OF DIFF', "Batch alter of constraints work for InnoDB");
24d9fe69 254-- Convert schema 'Schema 1' to 'Schema 2':;
f9ed5d54 255
256BEGIN;
257
258ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E_diff;
24d9fe69 259
f9ed5d54 260ALTER TABLE employee ADD COLUMN new integer,
261 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id) ON DELETE CASCADE,
262 ADD CONSTRAINT new_constraint FOREIGN KEY (employee_id) REFERENCES patty (fake);
263
24d9fe69 264
f9ed5d54 265COMMIT;
24d9fe69 266
f9ed5d54 267## END OF DIFF
268}
4104f82b 269
270{
271 # Test other things about renaming tables to - namely that renames
272 # constraints are still formated right.
273
274 my $s1 = SQL::Translator::Schema->new;
275 my $s2 = SQL::Translator::Schema->new;
276
277 $s1->name('Schema 3');
278 $s2->name('Schema 4');
279
280 my $t1 = $s1->add_table(dclone($target_schema->get_table('employee')));
281 my $t2 = dclone($target_schema->get_table('employee'));
282 $t2->name('fnord');
283 $t2->extra(renamed_from => 'employee');
284 $s2->add_table($t2);
285
286
287 $t1->add_constraint(
288 name => 'bar_fk',
289 type => 'FOREIGN KEY',
290 fields => ['employee_id'],
291 reference_fields => ['id'],
292 reference_table => 'bar',
293 );
294 $t2->add_constraint(
295 name => 'foo_fk',
296 type => 'FOREIGN KEY',
297 fields => ['employee_id'],
298 reference_fields => ['id'],
299 reference_table => 'foo',
300 );
301
302 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
303 eq_or_diff($out, <<'## END OF DIFF', "Alter/drop constraints works with rename table");
24d9fe69 304-- Convert schema 'Schema 3' to 'Schema 4':;
4104f82b 305
306BEGIN;
307
308ALTER TABLE employee RENAME TO fnord,
309 DROP FOREIGN KEY bar_fk,
310 ADD CONSTRAINT foo_fk FOREIGN KEY (employee_id) REFERENCES foo (id);
311
24d9fe69 312
4104f82b 313COMMIT;
24d9fe69 314
4104f82b 315## END OF DIFF
7467c458 316
317 # Test quoting works too.
318 $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL',
1f5b2625 319 { producer_args => { quote_table_names => '`' } }
7467c458 320 );
321 eq_or_diff($out, <<'## END OF DIFF', "Quoting can be turned on");
24d9fe69 322-- Convert schema 'Schema 3' to 'Schema 4':;
7467c458 323
324BEGIN;
325
326ALTER TABLE `employee` RENAME TO `fnord`,
327 DROP FOREIGN KEY bar_fk,
328 ADD CONSTRAINT foo_fk FOREIGN KEY (employee_id) REFERENCES `foo` (id);
329
24d9fe69 330
7467c458 331COMMIT;
24d9fe69 332
7467c458 333## END OF DIFF
4104f82b 334}