agent-book-translate 0.1.7

A powerful LLM-driven agentic EPUB book translator with robust progress monitoring and recovery
Documentation
use crate::agent::client::parse_translation_content;
use crate::db::checkpoint::open_checkpoint_db;
use crate::error::Result;
use rusqlite::params;
use std::path::Path;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MigrationResult {
    pub scanned: usize,
    pub repaired: usize,
}

pub fn migrate_checkpoint_db(db_path: &Path) -> Result<MigrationResult> {
    let conn = open_checkpoint_db(db_path)?;
    let mut updates = Vec::new();
    let mut scanned = 0;

    {
        let mut stmt = conn.prepare(
            "SELECT chapter_id, chunk_index, translated_text FROM chunk_progress WHERE state = 'completed'"
        )?;

        let mut rows = stmt.query([])?;
        while let Some(row) = rows.next()? {
            scanned += 1;
            let chapter_id: String = row.get(0)?;
            let chunk_index: i64 = row.get(1)?;
            let translated_text: Option<String> = row.get(2)?;

            if let Some(raw) = translated_text
                && let Ok(normalized) = parse_translation_content(&raw)
                && normalized != raw
            {
                updates.push((chapter_id, chunk_index, normalized));
            }
        }
    }

    let mut repaired = 0;
    for (chapter_id, chunk_index, normalized) in updates {
        conn.execute(
            "UPDATE chunk_progress SET translated_text = ?1 WHERE chapter_id = ?2 AND chunk_index = ?3",
            params![normalized, chapter_id, chunk_index],
        )?;
        repaired += 1;
    }

    Ok(MigrationResult { scanned, repaired })
}