fix migration system, better errors
This commit is contained in:
parent
92451ef268
commit
3ebfbf3342
@ -43,13 +43,15 @@ pub enum Error {
|
|||||||
/// Returned when current version cannot be read or guessed.
|
/// Returned when current version cannot be read or guessed.
|
||||||
UnknownDatabaseVersion,
|
UnknownDatabaseVersion,
|
||||||
/// Migration does not support existing pruning algorithm.
|
/// Migration does not support existing pruning algorithm.
|
||||||
UnsuportedPruningMethod,
|
UnsupportedPruningMethod,
|
||||||
/// Existing DB is newer than the known one.
|
/// Existing DB is newer than the known one.
|
||||||
FutureDBVersion,
|
FutureDBVersion,
|
||||||
/// Migration is not possible.
|
/// Migration is not possible.
|
||||||
MigrationImpossible,
|
MigrationImpossible,
|
||||||
/// Migration unexpectadly failed.
|
/// Migration unexpectadly failed.
|
||||||
MigrationFailed,
|
MigrationFailed,
|
||||||
|
/// Internal migration error.
|
||||||
|
Internal(MigrationError),
|
||||||
/// Migration was completed succesfully,
|
/// Migration was completed succesfully,
|
||||||
/// but there was a problem with io.
|
/// but there was a problem with io.
|
||||||
Io(IoError),
|
Io(IoError),
|
||||||
@ -59,10 +61,11 @@ impl Display for Error {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||||
let out = match *self {
|
let out = match *self {
|
||||||
Error::UnknownDatabaseVersion => "Current database version cannot be read".into(),
|
Error::UnknownDatabaseVersion => "Current database version cannot be read".into(),
|
||||||
Error::UnsuportedPruningMethod => "Unsupported pruning method for database migration. Delete DB and resync.".into(),
|
Error::UnsupportedPruningMethod => "Unsupported pruning method for database migration. Delete DB and resync.".into(),
|
||||||
Error::FutureDBVersion => "Database was created with newer client version. Upgrade your client or delete DB and resync.".into(),
|
Error::FutureDBVersion => "Database was created with newer client version. Upgrade your client or delete DB and resync.".into(),
|
||||||
Error::MigrationImpossible => format!("Database migration to version {} is not possible.", CURRENT_VERSION),
|
Error::MigrationImpossible => format!("Database migration to version {} is not possible.", CURRENT_VERSION),
|
||||||
Error::MigrationFailed => "Database migration unexpectedly failed".into(),
|
Error::MigrationFailed => "Database migration unexpectedly failed".into(),
|
||||||
|
Error::Internal(ref err) => format!("{}", err),
|
||||||
Error::Io(ref err) => format!("Unexpected io error on DB migration: {}.", err),
|
Error::Io(ref err) => format!("Unexpected io error on DB migration: {}.", err),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,7 +83,7 @@ impl From<MigrationError> for Error {
|
|||||||
fn from(err: MigrationError) -> Self {
|
fn from(err: MigrationError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
MigrationError::Io(e) => Error::Io(e),
|
MigrationError::Io(e) => Error::Io(e),
|
||||||
_ => Error::MigrationFailed,
|
_ => Error::Internal(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +323,7 @@ mod legacy {
|
|||||||
let res = match pruning {
|
let res = match pruning {
|
||||||
Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()),
|
Algorithm::Archive => manager.add_migration(migrations::state::ArchiveV7::default()),
|
||||||
Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()),
|
Algorithm::OverlayRecent => manager.add_migration(migrations::state::OverlayRecentV7::default()),
|
||||||
_ => return Err(Error::UnsuportedPruningMethod),
|
_ => return Err(Error::UnsupportedPruningMethod),
|
||||||
};
|
};
|
||||||
|
|
||||||
try!(res.map_err(|_| Error::MigrationImpossible));
|
try!(res.map_err(|_| Error::MigrationImpossible));
|
||||||
|
@ -20,6 +20,7 @@ mod tests;
|
|||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fmt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use ::kvdb::{CompactionProfile, Database, DatabaseConfig, DBTransaction};
|
use ::kvdb::{CompactionProfile, Database, DatabaseConfig, DBTransaction};
|
||||||
@ -96,6 +97,17 @@ pub enum Error {
|
|||||||
Custom(String),
|
Custom(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match *self {
|
||||||
|
Error::CannotAddMigration => write!(f, "Cannot add migration"),
|
||||||
|
Error::MigrationImpossible => write!(f, "Migration impossible"),
|
||||||
|
Error::Io(ref err) => write!(f, "{}", err),
|
||||||
|
Error::Custom(ref err) => write!(f, "{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<::std::io::Error> for Error {
|
impl From<::std::io::Error> for Error {
|
||||||
fn from(e: ::std::io::Error) -> Self {
|
fn from(e: ::std::io::Error) -> Self {
|
||||||
Error::Io(e)
|
Error::Io(e)
|
||||||
@ -104,6 +116,8 @@ impl From<::std::io::Error> for Error {
|
|||||||
|
|
||||||
/// A generalized migration from the given db to a destination db.
|
/// A generalized migration from the given db to a destination db.
|
||||||
pub trait Migration: 'static {
|
pub trait Migration: 'static {
|
||||||
|
/// Number of columns in the database before the migration.
|
||||||
|
fn pre_columns(&self) -> Option<u32> { self.columns() }
|
||||||
/// Number of columns in database after the migration.
|
/// Number of columns in database after the migration.
|
||||||
fn columns(&self) -> Option<u32>;
|
fn columns(&self) -> Option<u32>;
|
||||||
/// Version of the database after the migration.
|
/// Version of the database after the migration.
|
||||||
@ -195,6 +209,7 @@ impl Manager {
|
|||||||
Some(last) => migration.version() > last.version(),
|
Some(last) => migration.version() > last.version(),
|
||||||
None => true,
|
None => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
match is_new {
|
match is_new {
|
||||||
true => Ok(self.migrations.push(Box::new(migration))),
|
true => Ok(self.migrations.push(Box::new(migration))),
|
||||||
false => Err(Error::CannotAddMigration),
|
false => Err(Error::CannotAddMigration),
|
||||||
@ -205,9 +220,11 @@ impl Manager {
|
|||||||
/// and producing a path where the final migration lives.
|
/// and producing a path where the final migration lives.
|
||||||
pub fn execute(&mut self, old_path: &Path, version: u32) -> Result<PathBuf, Error> {
|
pub fn execute(&mut self, old_path: &Path, version: u32) -> Result<PathBuf, Error> {
|
||||||
let config = self.config.clone();
|
let config = self.config.clone();
|
||||||
let columns = self.no_of_columns_at(version);
|
|
||||||
let migrations = self.migrations_from(version);
|
let migrations = self.migrations_from(version);
|
||||||
if migrations.is_empty() { return Err(Error::MigrationImpossible) };
|
if migrations.is_empty() { return Err(Error::MigrationImpossible) };
|
||||||
|
|
||||||
|
let columns = migrations.iter().find(|m| m.version() == version).and_then(|m| m.pre_columns());
|
||||||
|
|
||||||
let mut db_config = DatabaseConfig {
|
let mut db_config = DatabaseConfig {
|
||||||
max_open_files: 64,
|
max_open_files: 64,
|
||||||
cache_size: None,
|
cache_size: None,
|
||||||
@ -267,14 +284,6 @@ impl Manager {
|
|||||||
fn migrations_from(&mut self, version: u32) -> Vec<&mut Box<Migration>> {
|
fn migrations_from(&mut self, version: u32) -> Vec<&mut Box<Migration>> {
|
||||||
self.migrations.iter_mut().filter(|m| m.version() > version).collect()
|
self.migrations.iter_mut().filter(|m| m.version() > version).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_of_columns_at(&self, version: u32) -> Option<u32> {
|
|
||||||
let migration = self.migrations.iter().find(|m| m.version() == version);
|
|
||||||
match migration {
|
|
||||||
Some(m) => m.columns(),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a dot every `max` ticks
|
/// Prints a dot every `max` ticks
|
||||||
|
Loading…
Reference in New Issue
Block a user