@@ -21,7 +21,7 @@ use std::path::{Path, PathBuf};
2121use std:: sync:: Arc ;
2222use std:: { fs, io, error} ;
2323
24- use log:: { info, trace} ;
24+ use log:: { info, trace, warn } ;
2525use kvdb:: DBTransaction ;
2626use kvdb_rocksdb:: { CompactionProfile , Database , DatabaseConfig } ;
2727
@@ -97,10 +97,12 @@ pub trait Migration {
9797 /// Whether this migration alters any existing columns.
9898 /// if not, then column families will simply be added and `migrate` will never be called.
9999 fn alters_existing ( & self ) -> bool { true }
100+ /// Whether this migration deletes data in any of the existing columns.
101+ fn deletes_existing ( & self ) -> bool { false }
100102 /// Version of the database after the migration.
101103 fn version ( & self ) -> u32 ;
102104 /// Migrate a source to a destination.
103- fn migrate ( & mut self , source : Arc < Database > , config : & Config , destination : & mut Database , col : u32 ) -> io:: Result < ( ) > ;
105+ fn migrate ( & mut self , source : Arc < Database > , config : & Config , destination : Option < & mut Database > , col : u32 ) -> io:: Result < ( ) > ;
104106}
105107
106108/// A simple migration over key-value pairs of a single column.
@@ -123,8 +125,15 @@ impl<T: SimpleMigration> Migration for T {
123125
124126 fn version ( & self ) -> u32 { SimpleMigration :: version ( self ) }
125127
126- fn migrate ( & mut self , source : Arc < Database > , config : & Config , dest : & mut Database , col : u32 ) -> io:: Result < ( ) > {
128+ fn migrate ( & mut self , source : Arc < Database > , config : & Config , dest : Option < & mut Database > , col : u32 ) -> io:: Result < ( ) > {
127129 let migration_needed = col == SimpleMigration :: migrated_column_index ( self ) ;
130+ let dest = match dest {
131+ None => {
132+ warn ! ( target: "migration" , "No destination db provided. No changes made." ) ;
133+ return Ok ( ( ) ) ;
134+ }
135+ Some ( dest) => dest,
136+ } ;
128137 let mut batch = Batch :: new ( config, col) ;
129138
130139 for ( key, value) in source. iter ( col) {
@@ -156,7 +165,7 @@ impl Migration for ChangeColumns {
156165 fn columns ( & self ) -> u32 { self . post_columns }
157166 fn alters_existing ( & self ) -> bool { false }
158167 fn version ( & self ) -> u32 { self . version }
159- fn migrate ( & mut self , _: Arc < Database > , _: & Config , _: & mut Database , _: u32 ) -> io:: Result < ( ) > {
168+ fn migrate ( & mut self , _: Arc < Database > , _: & Config , _: Option < & mut Database > , _: u32 ) -> io:: Result < ( ) > {
160169 Ok ( ( ) )
161170 }
162171}
@@ -170,10 +179,11 @@ pub struct VacuumAccountsBloom {
170179impl Migration for VacuumAccountsBloom {
171180 fn pre_columns ( & self ) -> u32 { self . columns }
172181 fn columns ( & self ) -> u32 { self . columns }
173- fn alters_existing ( & self ) -> bool { true }
182+ fn alters_existing ( & self ) -> bool { false }
183+ fn deletes_existing ( & self ) -> bool { true }
174184 fn version ( & self ) -> u32 { self . version }
175185
176- fn migrate ( & mut self , db : Arc < Database > , _config : & Config , _dest : & mut Database , col : u32 ) -> io:: Result < ( ) > {
186+ fn migrate ( & mut self , db : Arc < Database > , _config : & Config , _dest : Option < & mut Database > , col : u32 ) -> io:: Result < ( ) > {
177187 if col != self . column_to_vacuum {
178188 return Ok ( ( ) )
179189 }
@@ -300,7 +310,7 @@ impl Manager {
300310 let mut new_db = Database :: open ( & db_config, temp_path_str) ?;
301311
302312 for col in 0 ..current_columns {
303- migration. migrate ( cur_db. clone ( ) , & config, & mut new_db, col) ?
313+ migration. migrate ( cur_db. clone ( ) , & config, Some ( & mut new_db) , col) ?
304314 }
305315
306316 // next iteration, we will migrate from this db into the other temp.
@@ -309,6 +319,11 @@ impl Manager {
309319
310320 // remove the other temporary migration database.
311321 let _ = fs:: remove_dir_all ( temp_idx. path ( & db_root) ) ;
322+ } else if migration. deletes_existing ( ) {
323+ // Migration deletes data in an existing column.
324+ for col in 0 ..db_config. columns {
325+ migration. migrate ( cur_db. clone ( ) , & config, None , col) ?
326+ }
312327 } else {
313328 // migrations which simply add or remove column families.
314329 // we can do this in-place.
@@ -322,6 +337,8 @@ impl Manager {
322337 }
323338 }
324339 }
340+ // If `temp_path` is different from `old_path` we will shuffle database
341+ // directories and delete the old paths.
325342 Ok ( temp_path)
326343 }
327344
0 commit comments