Release commit for 1.62
[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
55fa8147 22my ( $source_schema, $target_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;
aee4b66e 28
4d438549 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
aee4b66e 37my @out = SQL::Translator::Diff::schema_diff(
38 $source_schema, 'MySQL',
4863ba22 39 $target_schema, 'MySQL',
aee4b66e 40 {
41 no_batch_alters => 1,
5e48784e 42 producer_args => { quote_identifiers => 0 }
aee4b66e 43 }
4863ba22 44);
45
46ok( @out, 'Got a list' );
47
48my $out = join('', @out);
49
bebf0aab 50eq_or_diff($out, <<'## END OF DIFF', "Diff as expected", { context => 1 });
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 (
ad071409 58 id integer(11) NULL
4d438549 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
ae95e48e 67ALTER TABLE person DROP CONSTRAINT 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
ad071409 73ALTER TABLE new_name ADD COLUMN new_field integer NULL;
24d9fe69 74
ad071409 75ALTER TABLE person ADD COLUMN is_rock_star tinyint(4) NULL 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
ad071409 81ALTER TABLE person CHANGE COLUMN age age integer(11) NULL DEFAULT 18;
24d9fe69 82
ad071409 83ALTER TABLE person CHANGE COLUMN iq iq integer(11) NULL DEFAULT 0;
24d9fe69 84
ad071409 85ALTER TABLE person CHANGE COLUMN description physical_description text NULL;
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,
5e48784e 109 producer_args => { quote_identifiers => 0 },
4d438549 110 });
111
bebf0aab 112eq_or_diff($out, <<'## END OF DIFF', "Diff as expected", { context => 1 });
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 (
ad071409 120 id integer(11) NULL
4d438549 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,
ad071409 128 ADD COLUMN new_field integer NULL;
24d9fe69 129
ae95e48e 130ALTER TABLE person DROP CONSTRAINT UC_age_name,
ad071409 131 ADD COLUMN is_rock_star tinyint(4) NULL 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,
ad071409 134 CHANGE COLUMN age age integer(11) NULL DEFAULT 18,
135 CHANGE COLUMN iq iq integer(11) NULL DEFAULT 0,
136 CHANGE COLUMN description physical_description text NULL,
4d438549 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
bebf0aab 154eq_or_diff($out, <<'## END OF DIFF', "No differences found", { context => 1 });
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');
aee4b66e 170
07d6e5f7 171 my $schema = $t->schema;
172 unless ( $schema->name ) {
173 $schema->name( 'create.sql' );
174 }
175
aee4b66e 176 # Now lets change the type of one of the 'integer' columns so that it
07d6e5f7 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);
5e48784e 181 $out = SQL::Translator::Diff::schema_diff($schema, 'MySQL', $target_schema, 'MySQL', { producer_args => { quote_identifiers => 0 } } );
bebf0aab 182 eq_or_diff($out, <<'## END OF DIFF', "No differences found", { context => 1 });
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 (
ad071409 190 id integer(11) NULL
07d6e5f7 191);
192
07d6e5f7 193SET foreign_key_checks=1;
194
07d6e5f7 195ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E,
51fe887d 196 DROP CONSTRAINT demo_constraint,
07d6e5f7 197 DROP COLUMN job_title,
1c680eb9 198 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id);
24d9fe69 199
ae95e48e 200ALTER TABLE person DROP CONSTRAINT UC_age_name,
07d6e5f7 201 DROP INDEX u_name,
ad071409 202 ADD COLUMN is_rock_star tinyint(4) NULL DEFAULT 1,
3ab19c1b 203 ADD COLUMN value double(8, 2) NULL DEFAULT 0.00,
07d6e5f7 204 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
205 CHANGE COLUMN name name varchar(20) NOT NULL,
ad071409 206 CHANGE COLUMN age age integer(11) NULL DEFAULT 18,
207 CHANGE COLUMN iq iq integer(11) NULL DEFAULT 0,
208 CHANGE COLUMN description physical_description text NULL,
07d6e5f7 209 ADD UNIQUE INDEX unique_name (name),
210 ADD UNIQUE UC_person_id (person_id),
211 ADD UNIQUE UC_age_name (age, name),
212 ENGINE=InnoDB;
24d9fe69 213
07d6e5f7 214DROP TABLE deleted;
215
24d9fe69 216
07d6e5f7 217COMMIT;
24d9fe69 218
07d6e5f7 219## END OF DIFF
220}
f9ed5d54 221
222# Test InnoDB stupidness. Have to drop constraints before re-adding them if
223# they are just alters.
224
225
226{
227 my $s1 = SQL::Translator::Schema->new;
228 my $s2 = SQL::Translator::Schema->new;
229
230 $s1->name('Schema 1');
231 $s2->name('Schema 2');
232
233 my $t1 = $s1->add_table($target_schema->get_table('employee'));
234 my $t2 = $s2->add_table(dclone($target_schema->get_table('employee')));
235
236
237 my ($c) = grep { $_->name eq 'FK5302D47D93FE702E_diff' } $t2->get_constraints;
238 $c->on_delete('CASCADE');
239
240 $t2->add_constraint(
241 name => 'new_constraint',
242 type => 'FOREIGN KEY',
243 fields => ['employee_id'],
244 reference_fields => ['fake'],
245 reference_table => 'patty',
246 );
247
248 $t2->add_field(
249 name => 'new',
250 data_type => 'int'
251 );
252
4104f82b 253 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
f9ed5d54 254
bebf0aab 255 eq_or_diff($out, <<'## END OF DIFF', "Batch alter of constraints work for InnoDB", { context => 1 });
24d9fe69 256-- Convert schema 'Schema 1' to 'Schema 2':;
f9ed5d54 257
258BEGIN;
259
260ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E_diff;
24d9fe69 261
ad071409 262ALTER TABLE employee ADD COLUMN new integer NULL,
f9ed5d54 263 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id) ON DELETE CASCADE,
264 ADD CONSTRAINT new_constraint FOREIGN KEY (employee_id) REFERENCES patty (fake);
265
24d9fe69 266
f9ed5d54 267COMMIT;
24d9fe69 268
f9ed5d54 269## END OF DIFF
270}
4104f82b 271
272{
aee4b66e 273 # Test other things about renaming tables to - namely that renames
4104f82b 274 # constraints are still formated right.
275
276 my $s1 = SQL::Translator::Schema->new;
277 my $s2 = SQL::Translator::Schema->new;
278
279 $s1->name('Schema 3');
280 $s2->name('Schema 4');
281
282 my $t1 = $s1->add_table(dclone($target_schema->get_table('employee')));
237e4855 283 $s1->add_table(dclone($source_schema->get_table('deleted')));
4104f82b 284 my $t2 = dclone($target_schema->get_table('employee'));
285 $t2->name('fnord');
286 $t2->extra(renamed_from => 'employee');
287 $s2->add_table($t2);
288
289
290 $t1->add_constraint(
291 name => 'bar_fk',
292 type => 'FOREIGN KEY',
293 fields => ['employee_id'],
294 reference_fields => ['id'],
295 reference_table => 'bar',
296 );
297 $t2->add_constraint(
298 name => 'foo_fk',
299 type => 'FOREIGN KEY',
300 fields => ['employee_id'],
301 reference_fields => ['id'],
302 reference_table => 'foo',
303 );
304
305 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
bebf0aab 306 eq_or_diff($out, <<'## END OF DIFF', "Alter/drop constraints works with rename table", { context => 1 });
24d9fe69 307-- Convert schema 'Schema 3' to 'Schema 4':;
4104f82b 308
309BEGIN;
310
311ALTER TABLE employee RENAME TO fnord,
312 DROP FOREIGN KEY bar_fk,
313 ADD CONSTRAINT foo_fk FOREIGN KEY (employee_id) REFERENCES foo (id);
314
237e4855 315ALTER TABLE deleted DROP FOREIGN KEY fk_fake;
316
317DROP TABLE deleted;
318
24d9fe69 319
4104f82b 320COMMIT;
24d9fe69 321
4104f82b 322## END OF DIFF
7467c458 323
324 # Test quoting works too.
aee4b66e 325 $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL',
5e48784e 326 { producer_args => { quote_identifiers => 1 } }
7467c458 327 );
bebf0aab 328 eq_or_diff($out, <<'## END OF DIFF', "Quoting can be turned on", { context => 1 });
24d9fe69 329-- Convert schema 'Schema 3' to 'Schema 4':;
7467c458 330
331BEGIN;
332
333ALTER TABLE `employee` RENAME TO `fnord`,
5e48784e 334 DROP FOREIGN KEY `bar_fk`,
335 ADD CONSTRAINT `foo_fk` FOREIGN KEY (`employee_id`) REFERENCES `foo` (`id`);
7467c458 336
237e4855 337ALTER TABLE `deleted` DROP FOREIGN KEY `fk_fake`;
338
339DROP TABLE `deleted`;
340
24d9fe69 341
7467c458 342COMMIT;
24d9fe69 343
7467c458 344## END OF DIFF
4104f82b 345}