diff --git a/Cargo.lock b/Cargo.lock index 9e298b22..1f3bb42b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,7 @@ dependencies = [ "chewing", "clap", "clap_mangen", + "env_logger", ] [[package]] diff --git a/src/dictionary/sqlite.rs b/src/dictionary/sqlite.rs index afdbf3a6..7f272686 100644 --- a/src/dictionary/sqlite.rs +++ b/src/dictionary/sqlite.rs @@ -5,6 +5,7 @@ use std::{ str, }; +use log::debug; use rusqlite::{Connection, Error as RusqliteError, OpenFlags, OptionalExtension, params}; use super::{ @@ -50,11 +51,26 @@ pub enum SqliteDictionaryError { impl Display for SqliteDictionaryError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "sqlite error") + match self { + SqliteDictionaryError::SqliteError { source: _ } => { + write!(f, "failed to perform sqlite operation") + } + SqliteDictionaryError::MissingTable { table } => { + write!(f, "sqlite {table} does not exist") + } + SqliteDictionaryError::ReadOnly => write!(f, "sqlite file is readonly"), + } } } -impl Error for SqliteDictionaryError {} +impl Error for SqliteDictionaryError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + SqliteDictionaryError::SqliteError { source } => Some(source), + _ => None, + } + } +} impl From for SqliteDictionaryError { fn from(value: RusqliteError) -> Self { @@ -75,11 +91,16 @@ impl SqliteDictionary { /// TODO: doc pub fn open>(path: P) -> Result { let path = path.as_ref().to_path_buf(); + debug!("open sqlite dictionary at {path:?}"); let mut conn = Connection::open(&path)?; + debug!("initialize dictionary tables"); Self::initialize_tables(&conn)?; + debug!("migrate from userphrase_v1"); Self::migrate_from_userphrase_v1(&mut conn)?; + debug!("ensure tables exist"); Self::ensure_tables(&conn)?; let info = Self::read_info_v1(&conn)?; + debug!("read dictionary info {info:?}"); Ok(SqliteDictionary { conn, @@ -179,16 +200,19 @@ impl SqliteDictionary { } fn migrate_from_userphrase_v1(conn: &mut Connection) -> Result<(), SqliteDictionaryError> { + debug!("query has_userphrase_v1"); let has_userphrase_v1: bool = conn.query_row( "SELECT EXISTS (SELECT 1 FROM sqlite_master WHERE type='table' AND name='userphrase_v1')", [], |row| row.get(0) )?; + debug!("query migrated"); let migrated: bool = conn.query_row( "SELECT EXISTS (SELECT 1 FROM migration_v1 WHERE name='migrate_from_userphrase_v1')", [], |row| row.get(0), )?; + debug!("has_userphrase_v1={has_userphrase_v1} migrated={migrated}"); if !has_userphrase_v1 || migrated { // Don't need to migrate conn.execute( @@ -233,13 +257,13 @@ impl SqliteDictionary { userphrases.push(( syllables, row.get(0)?, - row.get(1)?, - row.get(2)?, - row.get(3)?, + row.get(1).unwrap_or(0), + row.get(2).unwrap_or(0), + row.get(3).unwrap_or(0), )); } } - + debug!("{} phrases loaded", userphrases.len()); let tx = conn.transaction()?; { for item in userphrases { diff --git a/tools/Cargo.toml b/tools/Cargo.toml index 893b7e3f..cb7d4b2c 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -9,6 +9,7 @@ edition = "2024" anyhow = "1.0.0" chewing = { version = "0.11.0", path = ".." } clap = { version = "4.4.18", features = ["derive"] } +env_logger.workspace = true [dependencies.clap_mangen] version = "0.2.12" diff --git a/tools/src/main.rs b/tools/src/main.rs index d7fbace1..e0b0ed5b 100644 --- a/tools/src/main.rs +++ b/tools/src/main.rs @@ -7,6 +7,7 @@ mod info; mod init_database; fn main() -> Result<()> { + env_logger::init(); #[cfg(feature = "mangen")] { use clap::CommandFactory;