alter_drop_constraint drop constraint, not index
[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,
196 DROP COLUMN job_title,
1c680eb9 197 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id);
24d9fe69 198
ae95e48e 199ALTER TABLE person DROP CONSTRAINT UC_age_name,
07d6e5f7 200 DROP INDEX u_name,
ad071409 201 ADD COLUMN is_rock_star tinyint(4) NULL DEFAULT 1,
3ab19c1b 202 ADD COLUMN value double(8, 2) NULL DEFAULT 0.00,
07d6e5f7 203 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
204 CHANGE COLUMN name name varchar(20) NOT NULL,
ad071409 205 CHANGE COLUMN age age integer(11) NULL DEFAULT 18,
206 CHANGE COLUMN iq iq integer(11) NULL DEFAULT 0,
207 CHANGE COLUMN description physical_description text NULL,
07d6e5f7 208 ADD UNIQUE INDEX unique_name (name),
209 ADD UNIQUE UC_person_id (person_id),
210 ADD UNIQUE UC_age_name (age, name),
211 ENGINE=InnoDB;
24d9fe69 212
07d6e5f7 213DROP TABLE deleted;
214
24d9fe69 215
07d6e5f7 216COMMIT;
24d9fe69 217
07d6e5f7 218## END OF DIFF
219}
f9ed5d54 220
221# Test InnoDB stupidness. Have to drop constraints before re-adding them if
222# they are just alters.
223
224
225{
226 my $s1 = SQL::Translator::Schema->new;
227 my $s2 = SQL::Translator::Schema->new;
228
229 $s1->name('Schema 1');
230 $s2->name('Schema 2');
231
232 my $t1 = $s1->add_table($target_schema->get_table('employee'));
233 my $t2 = $s2->add_table(dclone($target_schema->get_table('employee')));
234
235
236 my ($c) = grep { $_->name eq 'FK5302D47D93FE702E_diff' } $t2->get_constraints;
237 $c->on_delete('CASCADE');
238
239 $t2->add_constraint(
240 name => 'new_constraint',
241 type => 'FOREIGN KEY',
242 fields => ['employee_id'],
243 reference_fields => ['fake'],
244 reference_table => 'patty',
245 );
246
247 $t2->add_field(
248 name => 'new',
249 data_type => 'int'
250 );
251
4104f82b 252 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
f9ed5d54 253
bebf0aab 254 eq_or_diff($out, <<'## END OF DIFF', "Batch alter of constraints work for InnoDB", { context => 1 });
24d9fe69 255-- Convert schema 'Schema 1' to 'Schema 2':;
f9ed5d54 256
257BEGIN;
258
259ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E_diff;
24d9fe69 260
ad071409 261ALTER TABLE employee ADD COLUMN new integer NULL,
f9ed5d54 262 ADD CONSTRAINT FK5302D47D93FE702E_diff FOREIGN KEY (employee_id) REFERENCES person (person_id) ON DELETE CASCADE,
263 ADD CONSTRAINT new_constraint FOREIGN KEY (employee_id) REFERENCES patty (fake);
264
24d9fe69 265
f9ed5d54 266COMMIT;
24d9fe69 267
f9ed5d54 268## END OF DIFF
269}
4104f82b 270
271{
aee4b66e 272 # Test other things about renaming tables to - namely that renames
4104f82b 273 # constraints are still formated right.
274
275 my $s1 = SQL::Translator::Schema->new;
276 my $s2 = SQL::Translator::Schema->new;
277
278 $s1->name('Schema 3');
279 $s2->name('Schema 4');
280
281 my $t1 = $s1->add_table(dclone($target_schema->get_table('employee')));
237e4855 282 $s1->add_table(dclone($source_schema->get_table('deleted')));
4104f82b 283 my $t2 = dclone($target_schema->get_table('employee'));
284 $t2->name('fnord');
285 $t2->extra(renamed_from => 'employee');
286 $s2->add_table($t2);
287
288
289 $t1->add_constraint(
290 name => 'bar_fk',
291 type => 'FOREIGN KEY',
292 fields => ['employee_id'],
293 reference_fields => ['id'],
294 reference_table => 'bar',
295 );
296 $t2->add_constraint(
297 name => 'foo_fk',
298 type => 'FOREIGN KEY',
299 fields => ['employee_id'],
300 reference_fields => ['id'],
301 reference_table => 'foo',
302 );
303
304 my $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL' );
bebf0aab 305 eq_or_diff($out, <<'## END OF DIFF', "Alter/drop constraints works with rename table", { context => 1 });
24d9fe69 306-- Convert schema 'Schema 3' to 'Schema 4':;
4104f82b 307
308BEGIN;
309
310ALTER TABLE employee RENAME TO fnord,
311 DROP FOREIGN KEY bar_fk,
312 ADD CONSTRAINT foo_fk FOREIGN KEY (employee_id) REFERENCES foo (id);
313
237e4855 314ALTER TABLE deleted DROP FOREIGN KEY fk_fake;
315
316DROP TABLE deleted;
317
24d9fe69 318
4104f82b 319COMMIT;
24d9fe69 320
4104f82b 321## END OF DIFF
7467c458 322
323 # Test quoting works too.
aee4b66e 324 $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL',
5e48784e 325 { producer_args => { quote_identifiers => 1 } }
7467c458 326 );
bebf0aab 327 eq_or_diff($out, <<'## END OF DIFF', "Quoting can be turned on", { context => 1 });
24d9fe69 328-- Convert schema 'Schema 3' to 'Schema 4':;
7467c458 329
330BEGIN;
331
332ALTER TABLE `employee` RENAME TO `fnord`,
5e48784e 333 DROP FOREIGN KEY `bar_fk`,
334 ADD CONSTRAINT `foo_fk` FOREIGN KEY (`employee_id`) REFERENCES `foo` (`id`);
7467c458 335
237e4855 336ALTER TABLE `deleted` DROP FOREIGN KEY `fk_fake`;
337
338DROP TABLE `deleted`;
339
24d9fe69 340
7467c458 341COMMIT;
24d9fe69 342
7467c458 343## END OF DIFF
4104f82b 344}