refactor(core): Rename GiError to LoreError and add search infrastructure
Mechanical rename of GiError -> LoreError across the core module to match the project's rebranding from gitlab-inbox to gitlore/lore. Updates the error enum name, all From impls, and the Result type alias. Additionally introduces: - New error variants for embedding pipeline: OllamaUnavailable, OllamaModelNotFound, EmbeddingFailed, EmbeddingsNotBuilt. Each includes actionable suggestions (e.g., "ollama serve", "ollama pull nomic-embed-text") to guide users through recovery. - New error codes 14-16 for programmatic handling of Ollama failures. - Savepoint-based migration execution in db.rs: each migration now runs inside a SQLite SAVEPOINT so a failed migration rolls back cleanly without corrupting the schema_version tracking. Previously a partial migration could leave the database in an inconsistent state. - core::backoff module: exponential backoff with jitter utility for retry loops in the embedding pipeline and discussion queues. - core::project module: helper for resolving project IDs and paths from the local database, used by the document regenerator and search filters. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ use std::fs;
|
||||
use std::path::Path;
|
||||
use tracing::{debug, info};
|
||||
|
||||
use super::error::{GiError, Result};
|
||||
use super::error::{LoreError, Result};
|
||||
|
||||
/// Embedded migrations - compiled into the binary.
|
||||
const MIGRATIONS: &[(&str, &str)] = &[
|
||||
@@ -27,6 +27,18 @@ const MIGRATIONS: &[(&str, &str)] = &[
|
||||
"006",
|
||||
include_str!("../../migrations/006_merge_requests.sql"),
|
||||
),
|
||||
(
|
||||
"007",
|
||||
include_str!("../../migrations/007_documents.sql"),
|
||||
),
|
||||
(
|
||||
"008",
|
||||
include_str!("../../migrations/008_fts5.sql"),
|
||||
),
|
||||
(
|
||||
"009",
|
||||
include_str!("../../migrations/009_embeddings.sql"),
|
||||
),
|
||||
];
|
||||
|
||||
/// Create a database connection with production-grade pragmas.
|
||||
@@ -88,13 +100,36 @@ pub fn run_migrations(conn: &Connection) -> Result<()> {
|
||||
continue;
|
||||
}
|
||||
|
||||
conn.execute_batch(sql)
|
||||
.map_err(|e| GiError::MigrationFailed {
|
||||
// Wrap each migration in a transaction to prevent partial application.
|
||||
// If the migration SQL already contains BEGIN/COMMIT, execute_batch handles
|
||||
// it, but wrapping in a savepoint ensures atomicity for those that don't.
|
||||
let savepoint_name = format!("migration_{}", version);
|
||||
conn.execute_batch(&format!("SAVEPOINT {}", savepoint_name))
|
||||
.map_err(|e| LoreError::MigrationFailed {
|
||||
version,
|
||||
message: e.to_string(),
|
||||
message: format!("Failed to create savepoint: {}", e),
|
||||
source: Some(e),
|
||||
})?;
|
||||
|
||||
match conn.execute_batch(sql) {
|
||||
Ok(()) => {
|
||||
conn.execute_batch(&format!("RELEASE {}", savepoint_name))
|
||||
.map_err(|e| LoreError::MigrationFailed {
|
||||
version,
|
||||
message: format!("Failed to release savepoint: {}", e),
|
||||
source: Some(e),
|
||||
})?;
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = conn.execute_batch(&format!("ROLLBACK TO {}", savepoint_name));
|
||||
return Err(LoreError::MigrationFailed {
|
||||
version,
|
||||
message: e.to_string(),
|
||||
source: Some(e),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
info!(version, "Migration applied");
|
||||
}
|
||||
|
||||
@@ -146,7 +181,7 @@ pub fn run_migrations_from_dir(conn: &Connection, migrations_dir: &Path) -> Resu
|
||||
let sql = fs::read_to_string(entry.path())?;
|
||||
|
||||
conn.execute_batch(&sql)
|
||||
.map_err(|e| GiError::MigrationFailed {
|
||||
.map_err(|e| LoreError::MigrationFailed {
|
||||
version,
|
||||
message: e.to_string(),
|
||||
source: Some(e),
|
||||
|
||||
Reference in New Issue
Block a user