From 34d8c1a903dc7f926291118c5286f399ffdc9f57 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 20 Jan 2025 10:32:20 +0100 Subject: [PATCH] Make offline upgrade more flexible --- crates/meilitool/src/upgrade/mod.rs | 49 +++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/crates/meilitool/src/upgrade/mod.rs b/crates/meilitool/src/upgrade/mod.rs index 47ca2cbd9..51cb5f454 100644 --- a/crates/meilitool/src/upgrade/mod.rs +++ b/crates/meilitool/src/upgrade/mod.rs @@ -20,6 +20,34 @@ pub struct OfflineUpgrade { impl OfflineUpgrade { pub fn upgrade(self) -> anyhow::Result<()> { + // Adding a version? + // + // 1. Update the LAST_SUPPORTED_UPGRADE_FROM_VERSION and LAST_SUPPORTED_UPGRADE_TO_VERSION. + // 2. Add new version to the upgrade list if necessary + // 3. Use `no_upgrade` as index for versions that are compatible. + + if self.current_version == self.target_version { + println!("Database is already at the target version. Exiting."); + return Ok(()); + } + + if self.current_version > self.target_version { + bail!( + "Cannot downgrade from {}.{}.{} to {}.{}.{}. Downgrade not supported", + self.current_version.0, + self.current_version.1, + self.current_version.2, + self.target_version.0, + self.target_version.1, + self.target_version.2 + ); + } + + const FIRST_SUPPORTED_UPGRADE_FROM_VERSION: &str = "1.9.0"; + const LAST_SUPPORTED_UPGRADE_FROM_VERSION: &str = "1.12.5"; + const FIRST_SUPPORTED_UPGRADE_TO_VERSION: &str = "1.10.0"; + const LAST_SUPPORTED_UPGRADE_TO_VERSION: &str = "1.12.5"; + let upgrade_list = [ ( v1_9_to_v1_10 as fn(&Path, &str, &str, &str) -> Result<(), anyhow::Error>, @@ -32,6 +60,8 @@ impl OfflineUpgrade { (v1_12_to_v1_12_3, "1", "12", "3"), ]; + let no_upgrade: usize = upgrade_list.len(); + let (current_major, current_minor, current_patch) = &self.current_version; let start_at = match ( @@ -43,8 +73,11 @@ impl OfflineUpgrade { ("1", "10", _) => 1, ("1", "11", _) => 2, ("1", "12", x) if x == "0" || x == "1" || x == "2" => 3, + ("1", "12", x) if x == "3" || x == "4" || x == "5" => no_upgrade, _ => { - bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from v1.9 and v1.10") + bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from versions in range [{}-{}]", + FIRST_SUPPORTED_UPGRADE_FROM_VERSION, + LAST_SUPPORTED_UPGRADE_FROM_VERSION); } }; @@ -54,17 +87,27 @@ impl OfflineUpgrade { ("1", "10", _) => 0, ("1", "11", _) => 1, ("1", "12", x) if x == "0" || x == "1" || x == "2" => 2, - ("1", "12", "3") => 3, + ("1", "12", x) if x == "3" || x == "4" || x == "5" => 3, (major, _, _) if major.starts_with('v') => { bail!("Target version must not starts with a `v`. Instead of writing `v1.9.0` write `1.9.0` for example.") } _ => { - bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to v1.10 and v1.11") + bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to versions in range [{}-{}]", + FIRST_SUPPORTED_UPGRADE_TO_VERSION, + LAST_SUPPORTED_UPGRADE_TO_VERSION); } }; println!("Starting the upgrade from {current_major}.{current_minor}.{current_patch} to {target_major}.{target_minor}.{target_patch}"); + if start_at == no_upgrade { + println!("No upgrade operation to perform, writing VERSION file"); + create_version_file(&self.db_path, target_major, target_minor, target_patch) + .context("while writing VERSION file after the upgrade")?; + println!("Success"); + return Ok(()); + } + #[allow(clippy::needless_range_loop)] for index in start_at..=ends_at { let (func, major, minor, patch) = upgrade_list[index];