schema migrations implemented in a more convenient way
@@ -4,7 +4,7 @@ use crate::constants::{
SCHEMA_VERSION_STORAGE_KEY,
};
use chrono::{DateTime, Utc};
-use futures::future::{Either, LocalBoxFuture};
+use futures::future::LocalBoxFuture;
use futures::{future, Future, FutureExt, TryFutureExt};
use http::Request;
use serde::ser::SerializeStruct;
@@ -16,6 +16,7 @@ use url::Url;
pub enum EnvError {
StorageUnavailable,
StorageSchemaVersionDowngrade(usize, usize),
+ StorageSchemaVersionUpgrade(Box<EnvError>),
Fetch(String),
AddonTransport(String),
Serde(String),
@@ -29,6 +30,10 @@ impl EnvError {
"Downgrade storage schema version from {} to {} is not allowed.",
from, to
),
+ EnvError::StorageSchemaVersionUpgrade(source) => format!(
+ "Upgrade storage schema version failed. {}",
+ source.message()
+ ),
EnvError::Fetch(message) => format!("Failed to fetch: {}", message),
EnvError::AddonTransport(message) => format!("Addon protocol violation: {}", message),
EnvError::Serde(message) => format!("Serialization error: {}", message),
@@ -38,9 +43,10 @@ impl EnvError {
match &self {
EnvError::StorageUnavailable => 1,
EnvError::StorageSchemaVersionDowngrade(_, _) => 2,
- EnvError::Fetch(_) => 3,
- EnvError::AddonTransport(_) => 4,
- EnvError::Serde(_) => 5,
+ EnvError::StorageSchemaVersionUpgrade(_) => 3,
+ EnvError::Fetch(_) => 4,
+ EnvError::AddonTransport(_) => 5,
+ EnvError::Serde(_) => 6,
}
}
}
@@ -85,16 +91,34 @@ pub trait Env {
Self: Sized + 'static,
{
Self::get_storage::<usize>(SCHEMA_VERSION_STORAGE_KEY)
- .and_then(|schema_version| match schema_version {
- Some(schema_version) if schema_version > SCHEMA_VERSION => {
- Either::Left(future::err(EnvError::StorageSchemaVersionDowngrade(
+ .and_then(|schema_version| async move {
+ let mut schema_version = schema_version.unwrap_or_default();
+ if schema_version > SCHEMA_VERSION {
+ return Err(EnvError::StorageSchemaVersionDowngrade(
schema_version,
SCHEMA_VERSION,
- )))
- }
- None => Either::Right(migrate_storage_schema_v1::<Self>()),
- // TODO Some(1) => Either::Right(migrate_storage_schema_v2::<Self>()),
- _ => Either::Left(future::ok(())),
+ ));
+ };
+ if schema_version == 0 {
+ migrate_storage_schema_v1::<Self>()
+ .map_err(|error| EnvError::StorageSchemaVersionUpgrade(Box::new(error)))
+ .await?;
+ schema_version = 1;
+ };
+ // TODO v2
+ // if schema_version == 1 {
+ // migrate_storage_schema_v2::<Self>()
+ // .map_err(|error| EnvError::StorageSchemaVersionUpgrade(Box::new(error)))
+ // .await?;
+ // schema_version = 2;
+ // };
+ if schema_version != SCHEMA_VERSION {
+ panic!(
+ "Storage schema version must be upgraded from {} to {}",
+ schema_version, SCHEMA_VERSION
+ );
+ };
+ Ok(())
})
.boxed_local()
}
