feat: v1.0.5, auto repair table keys
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -997,7 +997,7 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "local-mini-kms"
|
name = "local-mini-kms"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes-gcm-stream",
|
"aes-gcm-stream",
|
||||||
"aes-kw",
|
"aes-kw",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "local-mini-kms"
|
name = "local-mini-kms"
|
||||||
version = "1.0.4"
|
version = "1.0.5"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
79
src/db.rs
79
src/db.rs
@@ -24,24 +24,73 @@ pub fn open_db(db: &str) -> XResult<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_db(conn: &Connection) -> XResult<bool> {
|
pub fn init_db(conn: &Connection) -> XResult<bool> {
|
||||||
let mut stmt = conn.prepare(
|
if let Ok(false) = check_table_keys(conn) {
|
||||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='keys'")?;
|
repair_table_keys(conn)?;
|
||||||
let mut rows = stmt.query(())?;
|
|
||||||
if rows.next()?.is_some() {
|
|
||||||
log::info!("Table keys exists, skip init");
|
|
||||||
return Ok(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = conn.execute(r##"
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repair_table_keys(conn: &Connection) -> XResult<()> {
|
||||||
|
let field_names = list_table_fields(conn, "keys")?;
|
||||||
|
let field_names = field_names.iter().map(|n| n.as_str()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !field_names.contains(&"comment") {
|
||||||
|
log::info!("Repair table keys, add column comment");
|
||||||
|
let _ = conn.execute("ALTER TABLE keys ADD COLUMN comment TEXT", ())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list_table_fields(conn: &Connection, table: &str) -> XResult<Vec<String>> {
|
||||||
|
let mut stmt_query_fields = conn.prepare(&format!("pragma table_info({})", table))?;
|
||||||
|
let mut rows_query_field = stmt_query_fields.query(())?;
|
||||||
|
|
||||||
|
let mut field_names = vec![];
|
||||||
|
let mut next_query_field_opt = rows_query_field.next()?;
|
||||||
|
while let Some(next_query_field) = next_query_field_opt {
|
||||||
|
// cid|name|type|notnull|dflt_value|pk
|
||||||
|
// ^ ^ ^ ^ ^ ^
|
||||||
|
// | | | | | [5] - Is column PK
|
||||||
|
// | | | | [4] Column default value
|
||||||
|
// | | | [3] Is column not null
|
||||||
|
// | | [2] Column type
|
||||||
|
// | [1] Column name
|
||||||
|
// [0] Column index
|
||||||
|
let field_name: String = next_query_field.get(1)?;
|
||||||
|
field_names.push(field_name.to_lowercase());
|
||||||
|
next_query_field_opt = rows_query_field.next()?;
|
||||||
|
}
|
||||||
|
log::trace!("Table {} fields: {:?}", table, field_names);
|
||||||
|
Ok(field_names)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_table_keys(conn: &Connection) -> XResult<bool> {
|
||||||
|
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_none() {
|
||||||
|
log::info!("Create table keys");
|
||||||
|
create_table_keys(conn)?;
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_table_keys(conn: &Connection) -> XResult<()> {
|
||||||
|
let _ = conn.execute(
|
||||||
|
r##"
|
||||||
CREATE TABLE keys (
|
CREATE TABLE keys (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
value TEXT,
|
value TEXT,
|
||||||
comment TEXT
|
comment TEXT
|
||||||
)
|
)"##,
|
||||||
"##, ())?;
|
(),
|
||||||
log::info!("Table keys created");
|
)?;
|
||||||
Ok(true)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> {
|
pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> {
|
||||||
@@ -49,7 +98,11 @@ pub fn insert_key(conn: &Connection, key: &Key) -> XResult<()> {
|
|||||||
log::debug!("insert key name={}", &key.name);
|
log::debug!("insert key name={}", &key.name);
|
||||||
let _ = conn.execute(
|
let _ = conn.execute(
|
||||||
"INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)",
|
"INSERT INTO keys (name, value, comment) VALUES (?1, ?2, ?3)",
|
||||||
(&key.name, &key.encrypted_key, key.comment.as_ref().unwrap_or(&default_comment)),
|
(
|
||||||
|
&key.name,
|
||||||
|
&key.encrypted_key,
|
||||||
|
key.comment.as_ref().unwrap_or(&default_comment),
|
||||||
|
),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -90,4 +143,4 @@ pub fn find_key(conn: &Connection, name: &str) -> XResult<Option<Key>> {
|
|||||||
}
|
}
|
||||||
Some(Err(e)) => simple_error!("Find key failed: {}", e),
|
Some(Err(e)) => simple_error!("Find key failed: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user