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