Commit | Line | Data |
c0329273 |
1 | BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) } |
cb551b07 |
2 | use DBIx::Class::Optional::Dependencies -skip_all_without => qw(deploy test_rdbms_mysql); |
3 | |
c9d2e0a2 |
4 | use strict; |
5 | use warnings; |
68de9438 |
6 | |
c9d2e0a2 |
7 | use Test::More; |
d7a58a29 |
8 | use Test::Warn; |
9 | use Test::Exception; |
10 | |
4bea1fe7 |
11 | use Time::HiRes qw/time sleep/; |
12 | |
8d6b1478 |
13 | use DBICTest; |
e48635f7 |
14 | use DBIx::Class::_Util qw( sigwarn_silencer mkdir_p ); |
15 | use DBICTest::Util 'rm_rf'; |
4bea1fe7 |
16 | |
cb551b07 |
17 | my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_MYSQL_${_}" } qw/DSN USER PASS/}; |
c9d2e0a2 |
18 | |
8d6b1478 |
19 | # this is just to grab a lock |
20 | { |
21 | my $s = DBICTest::Schema->connect($dsn, $user, $pass); |
22 | } |
23 | |
eed5492f |
24 | # in case it came from the env |
25 | $ENV{DBIC_NO_VERSION_CHECK} = 0; |
26 | |
652d9b76 |
27 | # FIXME - work around RT#113965 in combination with -T on older perls: |
28 | # the non-deparsing XS portion of D::D gets confused by some of the IO |
29 | # handles trapped in the debug object of DBIC. What a mess. |
30 | $Data::Dumper::Deparse = 1; |
31 | |
b9ae34d3 |
32 | use_ok('DBICVersion_v1'); |
b9ae34d3 |
33 | |
b4b1e91c |
34 | my $version_table_name = 'dbix_class_schema_versions'; |
35 | my $old_table_name = 'SchemaVersions'; |
36 | |
e48635f7 |
37 | my $ddl_dir = "t/var/versioning_ddl-$$"; |
38 | mkdir_p $ddl_dir unless -d $ddl_dir; |
b9ae34d3 |
39 | |
1475105d |
40 | my $fn = { |
e48635f7 |
41 | v1 => "$ddl_dir/DBICVersion-Schema-1.0-MySQL.sql", |
42 | v2 => "$ddl_dir/DBICVersion-Schema-2.0-MySQL.sql", |
43 | v3 => "$ddl_dir/DBICVersion-Schema-3.0-MySQL.sql", |
44 | trans_v12 => "$ddl_dir/DBICVersion-Schema-1.0-2.0-MySQL.sql", |
45 | trans_v23 => "$ddl_dir/DBICVersion-Schema-2.0-3.0-MySQL.sql", |
1475105d |
46 | }; |
47 | |
d2bc7045 |
48 | my $schema_v1 = DBICVersion::Schema->connect($dsn, $user, $pass, { ignore_version => 1 }); |
49 | eval { $schema_v1->storage->dbh->do('drop table ' . $version_table_name) }; |
50 | eval { $schema_v1->storage->dbh->do('drop table ' . $old_table_name) }; |
c9d2e0a2 |
51 | |
d2bc7045 |
52 | is($schema_v1->ddl_filename('MySQL', '1.0', $ddl_dir), $fn->{v1}, 'Filename creation working'); |
1475105d |
53 | unlink( $fn->{v1} ) if ( -e $fn->{v1} ); |
d2bc7045 |
54 | $schema_v1->create_ddl_dir('MySQL', undef, $ddl_dir); |
c9d2e0a2 |
55 | |
1475105d |
56 | ok(-f $fn->{v1}, 'Created DDL file'); |
d2bc7045 |
57 | $schema_v1->deploy({ add_drop_table => 1 }); |
c9d2e0a2 |
58 | |
d2bc7045 |
59 | my $tvrs = $schema_v1->{vschema}->resultset('Table'); |
60 | is($schema_v1->_source_exists($tvrs), 1, 'Created schema from DDL file'); |
c9d2e0a2 |
61 | |
1475105d |
62 | # loading a new module defining a new version of the same table |
63 | DBICVersion::Schema->_unregister_source ('Table'); |
7eb9a6f1 |
64 | use_ok('DBICVersion_v2'); |
1475105d |
65 | |
d2bc7045 |
66 | my $schema_v2 = DBICVersion::Schema->connect($dsn, $user, $pass, { ignore_version => 1 }); |
f925f7cb |
67 | { |
1475105d |
68 | unlink($fn->{v2}); |
d2bc7045 |
69 | unlink($fn->{trans_v12}); |
f925f7cb |
70 | |
d2bc7045 |
71 | is($schema_v2->get_db_version(), '1.0', 'get_db_version ok'); |
72 | is($schema_v2->schema_version, '2.0', 'schema version ok'); |
73 | $schema_v2->create_ddl_dir('MySQL', '2.0', $ddl_dir, '1.0'); |
74 | ok(-f $fn->{trans_v12}, 'Created DDL file'); |
1475105d |
75 | |
d7a58a29 |
76 | warnings_like ( |
d40a22fc |
77 | sub { $schema_v2->upgrade() }, |
d7a58a29 |
78 | qr/DB version .+? is lower than the schema version/, |
79 | 'Warn before upgrade', |
80 | ); |
1475105d |
81 | |
d2bc7045 |
82 | is($schema_v2->get_db_version(), '2.0', 'db version number upgraded'); |
f925f7cb |
83 | |
d7a58a29 |
84 | lives_ok ( sub { |
d2bc7045 |
85 | $schema_v2->storage->dbh->do('select NewVersionName from TestVersion'); |
d7a58a29 |
86 | }, 'new column created' ); |
87 | |
88 | warnings_exist ( |
d40a22fc |
89 | sub { $schema_v2->create_ddl_dir('MySQL', '2.0', $ddl_dir, '1.0') }, |
d7a58a29 |
90 | [ |
475713af |
91 | qr/Overwriting existing DDL file - \Q$fn->{v2}\E/, |
92 | qr/Overwriting existing diff file - \Q$fn->{trans_v12}\E/, |
d7a58a29 |
93 | ], |
94 | 'An overwrite warning generated for both the DDL and the diff', |
95 | ); |
f925f7cb |
96 | } |
b4b1e91c |
97 | |
98 | { |
99 | my $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass); |
d7a58a29 |
100 | lives_ok (sub { |
b4b1e91c |
101 | $schema_version->storage->dbh->do('select * from ' . $version_table_name); |
d7a58a29 |
102 | }, 'version table exists'); |
b4b1e91c |
103 | |
d7a58a29 |
104 | lives_ok (sub { |
b4b1e91c |
105 | $schema_version->storage->dbh->do("DROP TABLE IF EXISTS $old_table_name"); |
86456031 |
106 | $schema_version->storage->dbh->do("RENAME TABLE $version_table_name TO $old_table_name"); |
d7a58a29 |
107 | }, 'versions table renamed to old style table'); |
b4b1e91c |
108 | |
109 | $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass); |
110 | is($schema_version->get_db_version, '2.0', 'transition from old table name to new okay'); |
111 | |
d7a58a29 |
112 | dies_ok (sub { |
b4b1e91c |
113 | $schema_version->storage->dbh->do('select * from ' . $old_table_name); |
d7a58a29 |
114 | }, 'old version table gone'); |
b4b1e91c |
115 | |
116 | } |
f81b9157 |
117 | |
d2bc7045 |
118 | # repeat the v1->v2 process for v2->v3 before testing v1->v3 |
119 | DBICVersion::Schema->_unregister_source ('Table'); |
7eb9a6f1 |
120 | use_ok('DBICVersion_v3'); |
d2bc7045 |
121 | |
122 | my $schema_v3 = DBICVersion::Schema->connect($dsn, $user, $pass, { ignore_version => 1 }); |
123 | { |
124 | unlink($fn->{v3}); |
125 | unlink($fn->{trans_v23}); |
126 | |
127 | is($schema_v3->get_db_version(), '2.0', 'get_db_version 2.0 ok'); |
128 | is($schema_v3->schema_version, '3.0', 'schema version 3.0 ok'); |
129 | $schema_v3->create_ddl_dir('MySQL', '3.0', $ddl_dir, '2.0'); |
130 | ok(-f $fn->{trans_v23}, 'Created DDL 2.0 -> 3.0 file'); |
131 | |
b9ae34d3 |
132 | warnings_exist ( |
133 | sub { $schema_v3->upgrade() }, |
134 | qr/DB version .+? is lower than the schema version/, |
135 | 'Warn before upgrade', |
136 | ); |
d2bc7045 |
137 | |
138 | is($schema_v3->get_db_version(), '3.0', 'db version number upgraded'); |
139 | |
b9ae34d3 |
140 | lives_ok ( sub { |
d2bc7045 |
141 | $schema_v3->storage->dbh->do('select ExtraColumn from TestVersion'); |
b9ae34d3 |
142 | }, 'new column created'); |
d2bc7045 |
143 | } |
144 | |
145 | # now put the v1 schema back again |
146 | { |
147 | # drop all the tables... |
148 | eval { $schema_v1->storage->dbh->do('drop table ' . $version_table_name) }; |
149 | eval { $schema_v1->storage->dbh->do('drop table ' . $old_table_name) }; |
150 | eval { $schema_v1->storage->dbh->do('drop table TestVersion') }; |
151 | |
152 | { |
153 | local $DBICVersion::Schema::VERSION = '1.0'; |
154 | $schema_v1->deploy; |
155 | } |
156 | is($schema_v1->get_db_version(), '1.0', 'get_db_version 1.0 ok'); |
157 | } |
158 | |
b9ae34d3 |
159 | # attempt v1 -> v3 upgrade |
d2bc7045 |
160 | { |
052a832c |
161 | local $SIG{__WARN__} = sigwarn_silencer( qr/Attempting upgrade\.$/ ); |
7eb9a6f1 |
162 | $schema_v3->upgrade(); |
d2bc7045 |
163 | is($schema_v3->get_db_version(), '3.0', 'db version number upgraded'); |
164 | } |
165 | |
b703fec7 |
166 | # Now, try a v1 -> v3 upgrade with a file that has comments strategically placed in it. |
167 | # First put the v1 schema back again... |
168 | { |
169 | # drop all the tables... |
170 | eval { $schema_v1->storage->dbh->do('drop table ' . $version_table_name) }; |
171 | eval { $schema_v1->storage->dbh->do('drop table ' . $old_table_name) }; |
172 | eval { $schema_v1->storage->dbh->do('drop table TestVersion') }; |
173 | |
174 | { |
175 | local $DBICVersion::Schema::VERSION = '1.0'; |
176 | $schema_v1->deploy; |
177 | } |
178 | is($schema_v1->get_db_version(), '1.0', 'get_db_version 1.0 ok'); |
179 | } |
180 | |
181 | # add a "harmless" comment before one of the statements. |
f3ec358e |
182 | { |
183 | my ($perl) = $^X =~ /(.+)/; |
184 | local $ENV{PATH}; |
185 | system( qq($perl -pi.bak -e "s/ALTER/-- this is a comment\nALTER/" $fn->{trans_v23}) ); |
186 | } |
b703fec7 |
187 | |
188 | # Then attempt v1 -> v3 upgrade |
189 | { |
052a832c |
190 | local $SIG{__WARN__} = sigwarn_silencer( qr/Attempting upgrade\.$/ ); |
b703fec7 |
191 | $schema_v3->upgrade(); |
192 | is($schema_v3->get_db_version(), '3.0', 'db version number upgraded to 3.0'); |
193 | |
194 | # make sure that the column added after the comment is actually added. |
195 | lives_ok ( sub { |
196 | $schema_v3->storage->dbh->do('select ExtraColumn from TestVersion'); |
197 | }, 'new column created'); |
198 | } |
199 | |
200 | |
f81b9157 |
201 | # check behaviour of DBIC_NO_VERSION_CHECK env var and ignore_version connect attr |
202 | { |
203 | my $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass); |
204 | eval { |
d0dfedc2 |
205 | $schema_version->storage->dbh->do("DELETE from $version_table_name"); |
f81b9157 |
206 | }; |
207 | |
d0dfedc2 |
208 | |
d7a58a29 |
209 | warnings_like ( sub { |
210 | $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass); |
211 | }, qr/Your DB is currently unversioned/, 'warning detected without env var or attr' ); |
f81b9157 |
212 | |
d7a58a29 |
213 | warnings_like ( sub { |
214 | $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass, { ignore_version => 1 }); |
215 | }, [], 'warning not detected with attr set'); |
d0dfedc2 |
216 | |
f81b9157 |
217 | |
1475105d |
218 | local $ENV{DBIC_NO_VERSION_CHECK} = 1; |
d7a58a29 |
219 | warnings_like ( sub { |
220 | $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass); |
221 | }, [], 'warning not detected with env var set'); |
f81b9157 |
222 | |
d7a58a29 |
223 | warnings_like ( sub { |
224 | $schema_version = DBICVersion::Schema->connect($dsn, $user, $pass, { ignore_version => 0 }); |
225 | }, qr/Your DB is currently unversioned/, 'warning detected without env var or attr'); |
f81b9157 |
226 | } |
1475105d |
227 | |
228 | # attempt a deploy/upgrade cycle within one second |
7eb9a6f1 |
229 | { |
d2bc7045 |
230 | eval { $schema_v2->storage->dbh->do('drop table ' . $version_table_name) }; |
231 | eval { $schema_v2->storage->dbh->do('drop table ' . $old_table_name) }; |
232 | eval { $schema_v2->storage->dbh->do('drop table TestVersion') }; |
1475105d |
233 | |
234 | # this attempts to sleep until the turn of the second |
235 | my $t = time(); |
236 | sleep (int ($t) + 1 - $t); |
7eb9a6f1 |
237 | note ('Fast deploy/upgrade start: ', time() ); |
1475105d |
238 | |
239 | { |
d2bc7045 |
240 | local $DBICVersion::Schema::VERSION = '2.0'; |
241 | $schema_v2->deploy; |
1475105d |
242 | } |
1475105d |
243 | |
052a832c |
244 | local $SIG{__WARN__} = sigwarn_silencer( qr/Attempting upgrade\.$/ ); |
245 | |
d2bc7045 |
246 | $schema_v2->upgrade(); |
1475105d |
247 | |
d2bc7045 |
248 | is($schema_v2->get_db_version(), '3.0', 'Fast deploy/upgrade'); |
e9fbbbf4 |
249 | }; |
1475105d |
250 | |
8012b15c |
251 | # Check that it Schema::Versioned deals with new/all forms of connect arguments. |
252 | { |
253 | my $get_db_version_run = 0; |
254 | |
255 | no warnings qw/once redefine/; |
256 | local *DBIx::Class::Schema::Versioned::get_db_version = sub { |
257 | $get_db_version_run = 1; |
258 | return $_[0]->schema_version; |
259 | }; |
260 | |
261 | # Make sure the env var isn't whats triggering it |
262 | local $ENV{DBIC_NO_VERSION_CHECK} = 0; |
263 | |
264 | DBICVersion::Schema->connect({ |
265 | dsn => $dsn, |
8273e845 |
266 | user => $user, |
8012b15c |
267 | pass => $pass, |
268 | ignore_version => 1 |
269 | }); |
8273e845 |
270 | |
8012b15c |
271 | ok($get_db_version_run == 0, "attributes pulled from hashref connect_info"); |
272 | $get_db_version_run = 0; |
273 | |
274 | DBICVersion::Schema->connect( $dsn, $user, $pass, { ignore_version => 1 } ); |
275 | ok($get_db_version_run == 0, "attributes pulled from list connect_info"); |
276 | } |
277 | |
81023d83 |
278 | # at this point we have v1, v2 and v3 still connected |
279 | # make sure they are the only connections and everything else is gone |
280 | is |
281 | scalar( grep |
282 | { defined $_ and $_->{Active} } |
283 | map |
284 | { @{$_->{ChildHandles}} } |
285 | values %{ { DBI->installed_drivers } } |
286 | ), 3, "Expected number of connections at end of script" |
287 | ; |
288 | |
e7dcdf69 |
289 | # Test custom HandleError setting on an in-memory instance |
290 | { |
291 | my $custom_handler = sub { die $_[0] }; |
292 | |
293 | # try to setup a custom error handle without unsafe set -- should |
294 | # fail, same behavior as regular Schema |
295 | throws_ok { |
296 | DBICVersion::Schema->connect( 'dbi:SQLite::memory:', undef, undef, { |
297 | HandleError => $custom_handler, |
298 | ignore_version => 1, |
299 | })->deploy; |
300 | } |
301 | qr/Refusing clobbering of \{HandleError\} installed on externally supplied DBI handle/, |
302 | 'HandleError with unsafe not set causes an exception' |
303 | ; |
304 | |
305 | # now try it with unsafe set -- should work (see RT #113741) |
306 | my $s = DBICVersion::Schema->connect( 'dbi:SQLite::memory:', undef, undef, { |
307 | unsafe => 1, |
308 | HandleError => $custom_handler, |
309 | ignore_version => 1, |
310 | }); |
311 | |
312 | $s->deploy; |
313 | |
314 | is $s->storage->dbh->{HandleError}, $custom_handler, 'Handler properly set on main schema'; |
315 | is $s->{vschema}->storage->dbh->{HandleError}, $custom_handler, 'Handler properly set on version subschema'; |
316 | } |
317 | |
8d6b1478 |
318 | END { |
e48635f7 |
319 | rm_rf $ddl_dir unless $ENV{DBICTEST_KEEP_VERSIONING_DDL}; |
1475105d |
320 | } |
7f6f5b69 |
321 | |
322 | done_testing; |