@@ -21,7 +21,7 @@ use std::path::{Path, PathBuf};
21
21
use std:: sync:: Arc ;
22
22
use std:: { fs, io, error} ;
23
23
24
- use log:: { info, trace} ;
24
+ use log:: { info, trace, warn } ;
25
25
use kvdb:: DBTransaction ;
26
26
use kvdb_rocksdb:: { CompactionProfile , Database , DatabaseConfig } ;
27
27
@@ -97,10 +97,12 @@ pub trait Migration {
97
97
/// Whether this migration alters any existing columns.
98
98
/// if not, then column families will simply be added and `migrate` will never be called.
99
99
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 }
100
102
/// Version of the database after the migration.
101
103
fn version ( & self ) -> u32 ;
102
104
/// 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 < ( ) > ;
104
106
}
105
107
106
108
/// A simple migration over key-value pairs of a single column.
@@ -123,8 +125,15 @@ impl<T: SimpleMigration> Migration for T {
123
125
124
126
fn version ( & self ) -> u32 { SimpleMigration :: version ( self ) }
125
127
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 < ( ) > {
127
129
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
+ } ;
128
137
let mut batch = Batch :: new ( config, col) ;
129
138
130
139
for ( key, value) in source. iter ( col) {
@@ -156,7 +165,7 @@ impl Migration for ChangeColumns {
156
165
fn columns ( & self ) -> u32 { self . post_columns }
157
166
fn alters_existing ( & self ) -> bool { false }
158
167
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 < ( ) > {
160
169
Ok ( ( ) )
161
170
}
162
171
}
@@ -170,10 +179,11 @@ pub struct VacuumAccountsBloom {
170
179
impl Migration for VacuumAccountsBloom {
171
180
fn pre_columns ( & self ) -> u32 { self . columns }
172
181
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 }
174
184
fn version ( & self ) -> u32 { self . version }
175
185
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 < ( ) > {
177
187
if col != self . column_to_vacuum {
178
188
return Ok ( ( ) )
179
189
}
@@ -300,7 +310,7 @@ impl Manager {
300
310
let mut new_db = Database :: open ( & db_config, temp_path_str) ?;
301
311
302
312
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) ?
304
314
}
305
315
306
316
// next iteration, we will migrate from this db into the other temp.
@@ -309,6 +319,11 @@ impl Manager {
309
319
310
320
// remove the other temporary migration database.
311
321
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
+ }
312
327
} else {
313
328
// migrations which simply add or remove column families.
314
329
// we can do this in-place.
@@ -322,6 +337,8 @@ impl Manager {
322
337
}
323
338
}
324
339
}
340
+ // If `temp_path` is different from `old_path` we will shuffle database
341
+ // directories and delete the old paths.
325
342
Ok ( temp_path)
326
343
}
327
344
0 commit comments