diff --git a/_sql/artcraft_migrations/20250708000000_create_tasks_table.sql b/_sql/artcraft_migrations/20250708000000_create_tasks_table.sql index 923811688e..830b46617f 100644 --- a/_sql/artcraft_migrations/20250708000000_create_tasks_table.sql +++ b/_sql/artcraft_migrations/20250708000000_create_tasks_table.sql @@ -1,7 +1,14 @@ -- noinspection SqlDialectInspectionForFile +-- +-- NB: This version needs to be bumped even if just adding or changing comments! +-- Failure to do so will cause Windows to segfault at start. (This is horrible!) +-- +-- NB: `app_state_dir.rs` contains the file version number. +-- -- Migration history: -- tasks_v1.sqlite - initial version -- tasks_v2.sqlite - added model_type (nullable) +-- tasks_v3.sqlite - added frontend_caller, comments CREATE TABLE tasks ( -- Task auto-incrementing primary key. diff --git a/crates/desktop/artcraft/src/core/state/data_dir/app_state_dir.rs b/crates/desktop/artcraft/src/core/state/data_dir/app_state_dir.rs index 0af3d3f7d4..ef39db2d44 100644 --- a/crates/desktop/artcraft/src/core/state/data_dir/app_state_dir.rs +++ b/crates/desktop/artcraft/src/core/state/data_dir/app_state_dir.rs @@ -22,7 +22,9 @@ impl DataSubdir for AppStateDir{ impl AppStateDir { pub fn get_tasks_sqlite_database_path(&self) -> PathBuf { - self.path.join("tasks_v2.sqlite") + // NB: This must be incremented on any change to the database schema (including comments). + // The database houses ephemeral content and will be migrated automatically. + self.path.join("tasks_v3.sqlite") } pub fn get_window_size_config_file(&self) -> PathBuf { diff --git a/crates/schema/database/sqlite_tasks/src/connection.rs b/crates/schema/database/sqlite_tasks/src/connection.rs index 7a7884f1a8..23f7d25a34 100644 --- a/crates/schema/database/sqlite_tasks/src/connection.rs +++ b/crates/schema/database/sqlite_tasks/src/connection.rs @@ -12,17 +12,27 @@ pub struct TaskDbConnection { impl TaskDbConnection { pub async fn connect_and_migrate>(database_file: P) -> AnyhowResult { - match run_migrations(&database_file).await { - Ok(pool) => return Ok(Self { pool }), - Err(err) => { - error!("Error running SQLite migrations: {:?}", err); + { + match run_migrations(&database_file).await { + Ok(pool) => return Ok(Self { pool }), + Err(err) => { + error!("Error running SQLite migrations: {:?}", err); + } } - } - info!("Deleting and recreating SQLite database at {:?}", database_file.as_ref()); + info!("Deleting and recreating SQLite database at {:?}", database_file.as_ref()); - if let Err(err) = std::fs::remove_file(&database_file) { - error!("Error deleting SQLite database file: {:?}", err); + if let Err(err) = std::fs::remove_file(&database_file) { + error!("Error deleting SQLite database file: {:?}", err); + } + + // NB: Scope change here is an attempt to drop the open file connection for Windows. + // On Windows, we've observed that the file might still be open, preventing deletion: + // [2025-08-08][06:42:29][sqlite_tasks::connection][INFO] Deleting and recreating SQLite + // database at "C:\Users\User\Artcraft\state\tasks_v2.sqlite" + // [2025-08-08][06:42:29][sqlite_tasks::connection][ERROR] Error deleting SQLite database + // file: Os { code: 32, kind: Uncategorized, message: "The process cannot access the file + // because it is being used by another process." } } let pool = run_migrations(database_file).await?;