diff --git a/crates/storage/src/migrations.rs b/crates/storage/src/migrations.rs index 8d4c5b2..cd01292 100644 --- a/crates/storage/src/migrations.rs +++ b/crates/storage/src/migrations.rs @@ -110,6 +110,40 @@ const MIGRATIONS: &[(i64, &str, &str)] = &[ "#), ]; +/// Split SQL into individual statements, respecting BEGIN...END trigger blocks. +fn split_statements(sql: &str) -> Vec { + let mut result = Vec::new(); + let mut current = String::new(); + let mut depth: i32 = 0; + let upper = sql.to_ascii_uppercase(); + let ub = upper.as_bytes(); + let ob = sql.as_bytes(); + let n = ob.len(); + let mut i = 0; + while i < n { + let prev_alpha = i > 0 && ob[i - 1].is_ascii_alphanumeric(); + if !prev_alpha && ub[i..].starts_with(b"BEGIN") { + let next_alpha = i + 5 < n && ob[i + 5].is_ascii_alphanumeric(); + if !next_alpha { depth += 1; } + } + if !prev_alpha && ub[i..].starts_with(b"END") { + let next_alpha = i + 3 < n && ob[i + 3].is_ascii_alphanumeric(); + if !next_alpha && depth > 0 { depth -= 1; } + } + if ob[i] == b';' && depth == 0 { + let stmt = current.trim().to_string(); + if !stmt.is_empty() { result.push(stmt); } + current = String::new(); + } else { + current.push(ob[i] as char); + } + i += 1; + } + let stmt = current.trim().to_string(); + if !stmt.is_empty() { result.push(stmt); } + result +} + /// Ensure the schema_version table exists and run any pending migrations. pub async fn run_migrations(pool: &SqlitePool) -> Result<()> { sqlx::query( @@ -132,12 +166,9 @@ pub async fn run_migrations(pool: &SqlitePool) -> Result<()> { if *version > current { log::info!("Running migration {}: {}", version, description); - let statements: Vec<&str> = sql.split(';') - .map(|s| s.trim()) - .filter(|s| !s.is_empty()) - .collect(); + let statements = split_statements(sql); - for statement in statements { + for statement in &statements { sqlx::query(statement) .execute(pool) .await diff --git a/crates/transcription/src/lib.rs b/crates/transcription/src/lib.rs index b43b365..8c297fd 100644 --- a/crates/transcription/src/lib.rs +++ b/crates/transcription/src/lib.rs @@ -6,6 +6,7 @@ pub use concurrency::run_inference; pub use local_engine::{ load_parakeet, load_whisper, LocalEngine, TimedTranscript, }; +pub use transcribe_rs::SpeechModel; pub use model_manager::{ download, is_downloaded, list_downloaded, model_dir, models_dir, }; diff --git a/src-tauri/src/commands/models.rs b/src-tauri/src/commands/models.rs index ddee05f..4121aeb 100644 --- a/src-tauri/src/commands/models.rs +++ b/src-tauri/src/commands/models.rs @@ -72,7 +72,7 @@ fn model_capability( } } -fn load_model_from_disk(model_id: &ModelId) -> Result { +fn load_model_from_disk(model_id: &ModelId) -> Result, String> { let entry = model_registry::find_model(model_id) .ok_or_else(|| format!("Unknown model: {model_id}"))?;