feat: add error handling to catalog persist function

This commit is contained in:
2025-10-04 07:03:08 +02:00
parent 5a9b1a97ab
commit 5ec86bac7f
4 changed files with 41 additions and 18 deletions

View File

@@ -26,33 +26,50 @@ const INSERT_ATTRIBUTE_STATEMENT_TEMPLATE: &str = r#"
VALUES (?1, ?2, ?3); VALUES (?1, ?2, ?3);
"#; "#;
fn write_attribute(attribute: &Attribute, entity: &Entity, transaction: &rusqlite::Transaction) { fn write_attribute(
attribute: &Attribute,
entity: &Entity,
transaction: &rusqlite::Transaction,
) -> result::Result<(), FailedTo> {
let column = column(&attribute.value); let column = column(&attribute.value);
let attribute_values = (&attribute.id, &entity.id, &attribute.value.to_string()); let attribute_values = (&attribute.id, &entity.id, &attribute.value.to_string());
let insert_attribute_statement = let insert_attribute_statement =
INSERT_ATTRIBUTE_STATEMENT_TEMPLATE.replace("{column}", column); INSERT_ATTRIBUTE_STATEMENT_TEMPLATE.replace("{column}", column);
let _ = transaction.execute(&insert_attribute_statement, attribute_values); transaction
.execute(&insert_attribute_statement, attribute_values)
.map_err(|_| FailedTo::ExecuteSQLiteStatement)?;
Ok(())
} }
fn write_entity(entity: &Entity, transaction: &rusqlite::Transaction) { fn write_entity(entity: &Entity, transaction: &rusqlite::Transaction) -> Result<(), FailedTo> {
let entity_id = [&entity.id]; let entity_id = [&entity.id];
let entity_values = (&entity.id, &entity.class, entity.ref_date); let entity_values = (&entity.id, &entity.class, entity.ref_date);
let _ = transaction.execute(DELETE_ENTITY_STATEMENT, entity_id); transaction
let _ = transaction.execute(INSERT_ENTITY_STATEMENT, entity_values); .execute(DELETE_ENTITY_STATEMENT, entity_id)
for (_key, attribute) in entity.attributes.iter() { .map_err(|_| FailedTo::ExecuteSQLiteStatement)?;
write_attribute(attribute, entity, transaction); transaction
.execute(INSERT_ENTITY_STATEMENT, entity_values)
.map_err(|_| FailedTo::ExecuteSQLiteStatement)?;
for attribute in entity.attributes.values() {
write_attribute(attribute, entity, transaction)?;
} }
Ok(())
} }
pub fn run(path: &path::Path, catalog: &Catalog) { pub fn run(path: &path::Path, catalog: &Catalog) -> result::Result<(), FailedTo> {
let mut connection = Connection::open(path).unwrap(); let mut connection = Connection::open(path).map_err(|_| FailedTo::OpenSQLiteConnection)?;
let transaction = connection.transaction().unwrap(); let transaction = connection
for (_key, entity) in catalog .transaction()
.map_err(|_| FailedTo::BeginSQLiteTransaction)?;
for entity in catalog
.items .items
.iter() .values()
.filter(|item| item.1.state == EntityState::New) .filter(|item| item.state == EntityState::New)
{ {
write_entity(entity, &transaction); write_entity(entity, &transaction)?;
} }
let _ = transaction.commit(); transaction
.commit()
.map_err(|_| FailedTo::CommitSQLiteTransaction)?;
Ok(())
} }

View File

@@ -139,9 +139,10 @@ impl O {
} }
/// Persists the current state of the catalog to the database. /// Persists the current state of the catalog to the database.
pub fn persist(&self) { pub fn persist(&self) -> result::Result<(), FailedTo> {
let path = path::Path::new(&self.path); let path = path::Path::new(&self.path);
sqlite::persist::catalog(path, self); sqlite::persist::catalog(path, self).map_err(|_| FailedTo::PersistCatalog)?;
Ok(())
} }
/// Loads an entity by its ID from the database into the catalog. /// Loads an entity by its ID from the database into the catalog.

View File

@@ -1,6 +1,10 @@
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)] #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
pub enum E { pub enum E {
BeginSQLiteTransaction,
CommitSQLiteTransaction,
ExecuteSQLiteBatch, ExecuteSQLiteBatch,
ExecuteSQLiteStatement,
InitDatabase, InitDatabase,
OpenSQLiteConnection, OpenSQLiteConnection,
PersistCatalog,
} }

View File

@@ -129,6 +129,7 @@ mod tests {
catalog.insert_many(operations); catalog.insert_many(operations);
catalog.insert_many(categories); catalog.insert_many(categories);
catalog.insert_many(relations); catalog.insert_many(relations);
catalog.persist(); let result = catalog.persist();
assert!(result.is_ok());
} }
} }