1use anyhow::{Result, anyhow};
2use tracing::info;
3
4use crate::{SchemaMigrationReport, SchemaMismatchWriteError, SchemaVersion, StorageManager};
5
6#[derive(Debug, Clone)]
7pub enum StartupSchemaGuard {
8 UpToDate,
9 Migrated(SchemaMigrationReport),
10}
11
12pub async fn guard_daemon_startup_schema(
13 db_path: &str,
14 auto_migrate: bool,
15) -> Result<StartupSchemaGuard> {
16 let storage = StorageManager::new_lance_only(db_path).await?;
17
18 match storage.require_current_schema_for_writes().await {
19 Ok(()) => Ok(StartupSchemaGuard::UpToDate),
20 Err(error) => {
21 let Some(schema_error) = error.downcast_ref::<SchemaMismatchWriteError>() else {
22 return Err(error);
23 };
24 let db_path = schema_error.db_path().to_string();
25
26 if !auto_migrate {
27 return Err(anyhow!(
28 "ERROR: binary requires schema v4, table is v3-pre.\n\
29 Run 'rust-memex migrate-schema --db-path {db_path}' before starting daemon.\n\
30 Or pass --auto-migrate to migrate at startup."
31 ));
32 }
33
34 let message = "migrating schema v3-pre -> v4 at startup";
35 info!("{message}");
36 eprintln!("INFO: {message}");
37 let report =
38 StorageManager::migrate_lance_schema(&db_path, SchemaVersion::current(), false)
39 .await?;
40 Ok(StartupSchemaGuard::Migrated(report))
41 }
42 }
43}