diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-03-19 02:42:02 +0100 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-03-19 02:42:02 +0100 |
| commit | 6df299c87ba8faab75626d04392f874ec642c8dc (patch) | |
| tree | 64744ae2dea2c726d72589ce290e88679e60c564 /crates/rocie-server/src/storage/migrate/mod.rs | |
| parent | chore(rocie-client): Re-generate the client api (diff) | |
| download | server-6df299c87ba8faab75626d04392f874ec642c8dc.zip | |
feat(rocie-server): Provide default units (and other changes)
Diffstat (limited to 'crates/rocie-server/src/storage/migrate/mod.rs')
| -rw-r--r-- | crates/rocie-server/src/storage/migrate/mod.rs | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/crates/rocie-server/src/storage/migrate/mod.rs b/crates/rocie-server/src/storage/migrate/mod.rs index ae0732b..5c81580 100644 --- a/crates/rocie-server/src/storage/migrate/mod.rs +++ b/crates/rocie-server/src/storage/migrate/mod.rs @@ -7,10 +7,15 @@ use chrono::TimeDelta; use log::{debug, info}; use sqlx::{Sqlite, SqlitePool, Transaction, query}; -use crate::app::App; +use crate::{ + app::App, + storage::sql::{config::Config, get::config}, +}; + +mod defaults; macro_rules! make_upgrade { - ($app:expr, $old_version:expr, $new_version:expr, $sql_name:expr) => { + ($app:expr, $old_version:expr, $new_version:expr, $sql_name:expr) => {{ let mut tx = $app .db .begin() @@ -57,8 +62,8 @@ macro_rules! make_upgrade { new_version: $new_version, })?; - Ok(()) - }; + Ok::<_, update::Error>(()) + }}; } #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] @@ -135,11 +140,12 @@ impl DbVersion { /// /// Each update is atomic, so if this function fails you are still guaranteed to have a /// database at version `get_version`. - #[allow(clippy::too_many_lines)] async fn update(self, app: &App) -> Result<(), update::Error> { match self { Self::Empty => { - make_upgrade! {app, Self::Empty, Self::One, "./sql/0->1.sql"} + make_upgrade! {app, Self::Empty, Self::One, "./sql/0->1.sql"}?; + + Ok(()) } // This is the current_version @@ -158,7 +164,10 @@ impl Display for DbVersion { } } pub(crate) mod update { - use crate::storage::migrate::{DbVersion, db_version_set, get_db_version}; + use crate::storage::{ + migrate::{DbVersion, db_version_set, defaults, get_db_version}, + sql::get::config, + }; #[derive(thiserror::Error, Debug)] pub(crate) enum Error { @@ -182,6 +191,11 @@ pub(crate) mod update { #[error("Failed to commit the update transaction: {0}")] TxnCommit(sqlx::Error), + #[error("Failed to access the rocie config: {0}")] + ConfigGet(#[from] config::get::Error), + #[error("Failed to add defaults to the database: {0}")] + AddDefaults(#[from] defaults::apply_defaults::Error), + #[error("Failed to perform the next chained update (to ver {new_version}): {err}")] NextUpdate { err: Box<Self>, @@ -197,6 +211,12 @@ pub(crate) mod db_version_parse { } } +async fn should_use_defaults(app: &App) -> Result<bool, config::get::Error> { + let config = Config::get(app).await?; + + Ok(config.should_use_defaults) +} + /// Returns the current data as UNIX time stamp. pub(crate) fn get_current_date() -> i64 { let start = SystemTime::now(); @@ -238,7 +258,7 @@ pub(crate) async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion, get_d ) .fetch_optional(pool) .await - .map_err(|err| get_db_version::Error::VersionTableExistance(err))?; + .map_err(get_db_version::Error::VersionTableExistance)?; if let Some(output) = query { assert_eq!(output.result, 1); @@ -261,7 +281,7 @@ pub(crate) async fn get_version_db(pool: &SqlitePool) -> Result<DbVersion, get_d ) .fetch_one(pool) .await - .map_err(|err| get_db_version::Error::VersionNumberFetch(err))?; + .map_err(get_db_version::Error::VersionNumberFetch)?; Ok(DbVersion::from_db( current_version.number, @@ -288,6 +308,26 @@ pub(crate) mod get_db_version { pub(crate) async fn migrate_db(app: &App) -> Result<(), migrate_db::Error> { let current_version = get_version(app).await?; + if app.db_version_at_start.get().is_none() { + app.db_version_at_start + .set(current_version) + .expect("the cell to be unititialized, we checked"); + } + + if app.db_version_at_start.get() == Some(&DbVersion::Empty) { + // We cannot run this code in the normal update function, because for the empty db, there + // is no way to know if we want defaults. + // + // So we need to add the defaults later, which is achieved by another call to `migrate_db` + // in provision. + // + // That is kinda hacky, but I don't see a way around it. + // For defaults added in version Two and onward, the default mechanism should just work. + if should_use_defaults(app).await? { + defaults::add_defaults_0_to_1(app).await?; + } + } + if current_version == CURRENT_VERSION { return Ok(()); } @@ -300,7 +340,12 @@ pub(crate) async fn migrate_db(app: &App) -> Result<(), migrate_db::Error> { } pub(crate) mod migrate_db { - use crate::storage::migrate::{get_db_version, update}; + use actix_web::ResponseError; + + use crate::storage::{ + migrate::{defaults, get_db_version, update}, + sql::get::config, + }; #[derive(thiserror::Error, Debug)] pub(crate) enum Error { @@ -309,5 +354,12 @@ pub(crate) mod migrate_db { #[error("Failed to update the database: {0}")] Upadate(#[from] update::Error), + + #[error("Failed to access the rocie config: {0}")] + ConfigGet(#[from] config::get::Error), + #[error("Failed to add defaults to the database: {0}")] + AddDefaults(#[from] defaults::apply_defaults::Error), } + + impl ResponseError for Error {} } |
