@@ -59,15 +59,13 @@ impl DatabaseVersionChecker {
59
59
) ;
60
60
let connection = Connection :: open ( & self . sqlite_file_path ) ?;
61
61
let provider = DatabaseVersionProvider :: new ( & connection) ;
62
- provider. create_table_if_not_exists ( ) ?;
62
+ provider. create_table_if_not_exists ( & self . application_type ) ?;
63
63
let updater = DatabaseVersionUpdater :: new ( & connection) ;
64
64
let db_version = provider
65
65
. get_application_version ( & self . application_type ) ?
66
- . unwrap_or_else ( || DatabaseVersion {
67
- version : 0 ,
68
- application_type : self . application_type . clone ( ) ,
69
- updated_at : Local :: now ( ) . naive_local ( ) ,
70
- } ) ;
66
+ . unwrap ( ) ; // At least a record exists.
67
+
68
+ // if no migration registered then we are at version 0.
71
69
let migration_version = self . migrations . iter ( ) . map ( |m| m. version ) . max ( ) . unwrap_or ( 0 ) ;
72
70
73
71
match migration_version. cmp ( & db_version. version ) {
@@ -176,17 +174,15 @@ mod tests {
176
174
let version = provider
177
175
. get_application_version ( & ApplicationNodeType :: Aggregator )
178
176
. unwrap ( )
179
- . unwrap_or_else ( || DatabaseVersion {
180
- application_type : ApplicationNodeType :: Aggregator ,
181
- version : 0 ,
182
- updated_at : Local :: now ( ) . naive_local ( ) ,
183
- } ) ;
177
+ . unwrap ( ) ;
184
178
185
179
assert_eq ! ( db_version, version. version) ;
186
180
}
187
181
188
182
fn create_sqlite_file ( name : & str ) -> PathBuf {
189
- let filepath = std:: env:: temp_dir ( ) . join ( name) ;
183
+ let dirpath = std:: env:: temp_dir ( ) . join ( "mithril_test_database" ) ;
184
+ std:: fs:: create_dir_all ( & dirpath) . unwrap ( ) ;
185
+ let filepath = dirpath. join ( name) ;
190
186
191
187
if filepath. exists ( ) {
192
188
std:: fs:: remove_file ( filepath. as_path ( ) ) . unwrap ( ) ;
@@ -214,7 +210,7 @@ mod tests {
214
210
215
211
#[ test]
216
212
fn test_upgrade_with_migration ( ) {
217
- let filepath = create_sqlite_file ( "test_1 .sqlite3" ) ;
213
+ let filepath = create_sqlite_file ( "test_upgrade_with_migration .sqlite3" ) ;
218
214
let mut db_checker = DatabaseVersionChecker :: new (
219
215
slog_scope:: logger ( ) ,
220
216
ApplicationNodeType :: Aggregator ,
@@ -273,7 +269,7 @@ mod tests {
273
269
274
270
#[ test]
275
271
fn starting_with_migration ( ) {
276
- let filepath = create_sqlite_file ( "test_2 .sqlite3" ) ;
272
+ let filepath = create_sqlite_file ( "starting_with_migration .sqlite3" ) ;
277
273
let mut db_checker = DatabaseVersionChecker :: new (
278
274
slog_scope:: logger ( ) ,
279
275
ApplicationNodeType :: Aggregator ,
@@ -292,21 +288,66 @@ mod tests {
292
288
}
293
289
294
290
#[ test]
291
+ /// This test case ensure that when multiple migrations are played and one fails:
292
+ /// * previous migrations are ok and the database version is updated
293
+ /// * further migrations are not played.
295
294
fn test_failing_migration ( ) {
296
- let filepath = create_sqlite_file ( "test_3 .sqlite3" ) ;
295
+ let filepath = create_sqlite_file ( "test_failing_migration .sqlite3" ) ;
297
296
let mut db_checker = DatabaseVersionChecker :: new (
298
297
slog_scope:: logger ( ) ,
299
298
ApplicationNodeType :: Aggregator ,
300
299
filepath. clone ( ) ,
301
300
) ;
302
301
// Table whatever does not exist, this should fail with error.
303
- let alterations = "alter table whatever add column thing_content text; update whatever set thing_content = 'some content' " ;
302
+ let alterations = "create table whatever (thing_id integer); insert into whatever (thing_id) values (1), (2), (3), (4); " ;
304
303
let migration = SqlMigration {
305
304
version : 1 ,
306
305
alterations : alterations. to_string ( ) ,
307
306
} ;
308
307
db_checker. add_migration ( migration) ;
308
+ let alterations = "alter table wrong add column thing_content text; update whatever set thing_content = 'some content'" ;
309
+ let migration = SqlMigration {
310
+ version : 2 ,
311
+ alterations : alterations. to_string ( ) ,
312
+ } ;
313
+ db_checker. add_migration ( migration) ;
314
+ let alterations = "alter table whatever add column thing_content text; update whatever set thing_content = 'some content'" ;
315
+ let migration = SqlMigration {
316
+ version : 3 ,
317
+ alterations : alterations. to_string ( ) ,
318
+ } ;
319
+ db_checker. add_migration ( migration) ;
309
320
db_checker. apply ( ) . unwrap_err ( ) ;
310
- check_database_version ( & filepath, 0 ) ;
321
+ check_database_version ( & filepath, 1 ) ;
322
+ }
323
+
324
+ #[ test]
325
+ fn test_fail_downgrading ( ) {
326
+ let filepath = create_sqlite_file ( "test_fail_downgrading.sqlite3" ) ;
327
+ let mut db_checker = DatabaseVersionChecker :: new (
328
+ slog_scope:: logger ( ) ,
329
+ ApplicationNodeType :: Aggregator ,
330
+ filepath. clone ( ) ,
331
+ ) ;
332
+ let alterations = "create table whatever (thing_id integer); insert into whatever (thing_id) values (1), (2), (3), (4);" ;
333
+ let migration = SqlMigration {
334
+ version : 1 ,
335
+ alterations : alterations. to_string ( ) ,
336
+ } ;
337
+ db_checker. add_migration ( migration) ;
338
+ db_checker. apply ( ) . unwrap ( ) ;
339
+ check_database_version ( & filepath, 1 ) ;
340
+
341
+ // re instanciate a new checker with no migration registered (version 0).
342
+ let db_checker = DatabaseVersionChecker :: new (
343
+ slog_scope:: logger ( ) ,
344
+ ApplicationNodeType :: Aggregator ,
345
+ filepath. clone ( ) ,
346
+ ) ;
347
+ assert ! (
348
+ db_checker. apply( ) . is_err( ) ,
349
+ "using an old version with an up to date database should fail"
350
+ ) ;
351
+ check_database_version ( & filepath, 1 ) ;
311
352
}
312
353
}
0 commit comments