use rusqlite::{Connection, params}; use rust_util::{debugging, information, opt_result, simple_error, success, XResult}; pub const DEFAULT_MASTER_KEY_VERIFICATION_KEY: &str = "__master_verification_key"; pub struct Key { pub name: String, pub encrypted_key: String, pub comment: Option, } pub fn make_db_key_name(name: &str) -> String { format!("value:{}", name) } pub fn open_db(db: &str) -> XResult { let con = opt_result!(Connection::open(db), "Open sqlite db: {}, failed: {}", db); debugging!("Db auto commit: {}", con.is_autocommit()); Ok(con) } pub fn init_db(conn: &Connection) -> XResult { let mut stmt = conn.prepare( "SELECT name FROM sqlite_master WHERE type='table' AND name='keys'")?; let mut rows = stmt.query(())?; if rows.next()?.is_some() { information!("Table keys exists, skip init"); return Ok(false); } let _ = conn.execute(r##" CREATE TABLE keys ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, value TEXT, comment TEXT ) "##, ())?; success!("Table keys created"); Ok(true) } pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> { let default_comment = "".to_string(); let _ = conn.execute( "INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)", (&key.name, &key.encrypted_key, key.comment.as_ref().unwrap_or(&default_comment)), )?; Ok(()) } pub fn update_key(conn: &Connection, key: &Key) -> XResult<()> { if let Some(comment) = &key.comment { let _ = conn.execute( "UPDATE keys SET value = ?1, comment = ?2 WHERE name = ?3", (&key.encrypted_key, comment, &key.name), )?; } else { let _ = conn.execute( "UPDATE keys SET value = ?1 WHERE name = ?2", (&key.encrypted_key, &key.name), )?; } Ok(()) } pub fn find_key(conn: &Connection, name: &str) -> XResult> { let mut stmt = conn.prepare("SELECT id, name, value, comment FROM keys WHERE name = ?1")?; let mut key_iter = stmt.query_map(params![name], |row| { Ok(Key { name: row.get(1)?, encrypted_key: row.get(2)?, comment: row.get(3)?, }) })?; match key_iter.next() { None => Ok(None), Some(Ok(r)) => Ok(Some(r)), Some(Err(e)) => simple_error!("Find key failed: {}", e), } }