Adjust view production for stupid mysql
[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
4d438549 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
4d438549 81ALTER TABLE person CHANGE COLUMN age age integer(11) DEFAULT '18';
24d9fe69 82
4d438549 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,
4d438549 131 ADD COLUMN is_rock_star tinyint(4) DEFAULT '1',
132 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
133 CHANGE COLUMN name name varchar(20) NOT NULL,
134 CHANGE COLUMN age age integer(11) DEFAULT '18',
135 CHANGE COLUMN iq iq integer(11) DEFAULT '0',
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,
201 ADD COLUMN is_rock_star tinyint(4) DEFAULT '1',
202 CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment,
203 CHANGE COLUMN name name varchar(20) NOT NULL,
204 CHANGE COLUMN age age integer(11) DEFAULT '18',
205 CHANGE COLUMN iq iq integer(11) DEFAULT '0',
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}