use std::path::Path;
use rusqlite::Connection;
use super::SnapshotTuiRow;
use super::consts::UblxDbStatements;
use super::core::open_for_snapshot_tui_read;
pub fn load_lens_names_from_conn(conn: &Connection) -> Result<Vec<String>, anyhow::Error> {
let mut stmt = conn.prepare(UblxDbStatements::SELECT_LENS_NAMES)?;
let names: Vec<String> = stmt
.query_map([], |row| row.get::<_, String>(0))?
.collect::<Result<Vec<_>, _>>()?;
Ok(names)
}
pub fn load_lens_names(db_path: &Path) -> Result<Vec<String>, anyhow::Error> {
if !db_path.exists() {
return Ok(Vec::new());
}
let conn = open_for_snapshot_tui_read(db_path)?;
load_lens_names_from_conn(&conn)
}
pub fn load_lens_paths(
db_path: &Path,
lens_name: &str,
) -> Result<Vec<SnapshotTuiRow>, anyhow::Error> {
if !db_path.exists() {
return Ok(Vec::new());
}
let conn = open_for_snapshot_tui_read(db_path)?;
let lens_id: i64 = match conn.query_row(
UblxDbStatements::SELECT_LENS_ID_BY_NAME,
[lens_name],
|row| row.get(0),
) {
Ok(id) => id,
Err(rusqlite::Error::QueryReturnedNoRows) => return Ok(Vec::new()),
Err(e) => return Err(e.into()),
};
let mut stmt = conn.prepare(UblxDbStatements::SELECT_LENS_ROWS_FOR_TUI)?;
let rows = stmt.query_map([lens_id], |row| {
let size: i64 = row.get(2)?;
Ok((
row.get::<_, String>(0)?,
row.get::<_, String>(1)?,
size.max(0).cast_unsigned(),
))
})?;
rows.collect::<Result<Vec<_>, _>>().map_err(Into::into)
}
pub fn create_lens(db_path: &Path, name: &str) -> Result<i64, anyhow::Error> {
let conn = Connection::open(db_path)?;
conn.execute(UblxDbStatements::INSERT_LENS, [name])?;
Ok(conn.last_insert_rowid())
}
fn get_or_create_path_id(conn: &Connection, path: &str) -> Result<i64, anyhow::Error> {
conn.execute(UblxDbStatements::INSERT_PATH, [path])?;
let id: i64 = conn.query_row(UblxDbStatements::SELECT_PATH_ID_BY_PATH, [path], |row| {
row.get(0)
})?;
Ok(id)
}
pub fn add_path_to_lens(
db_path: &Path,
lens_name: &str,
path: &str,
position: i64,
) -> Result<(), anyhow::Error> {
let conn = Connection::open(db_path)?;
let lens_id: i64 = conn.query_row(
UblxDbStatements::SELECT_LENS_ID_BY_NAME,
[lens_name],
|row| row.get(0),
)?;
let path_id = get_or_create_path_id(&conn, path)?;
conn.execute(
UblxDbStatements::INSERT_LENS_PATH,
[lens_id, path_id, position],
)?;
Ok(())
}
pub fn remove_path_from_lens(
db_path: &Path,
lens_name: &str,
path: &str,
) -> Result<(), anyhow::Error> {
if !db_path.exists() {
return Ok(());
}
let conn = Connection::open(db_path)?;
conn.execute(UblxDbStatements::DELETE_LENS_PATH_ROW, (lens_name, path))?;
Ok(())
}
pub fn rename_lens(db_path: &Path, old_name: &str, new_name: &str) -> Result<(), anyhow::Error> {
if new_name.trim().is_empty() {
return Err(anyhow::anyhow!("lens name cannot be empty"));
}
let conn = Connection::open(db_path)?;
let changed = conn.execute(UblxDbStatements::UPDATE_LENS_NAME, (old_name, new_name))?;
if changed == 0 {
return Err(anyhow::anyhow!("lens not found: {old_name}"));
}
Ok(())
}
pub fn delete_lens(db_path: &Path, lens_name: &str) -> Result<(), anyhow::Error> {
if !db_path.exists() {
return Ok(());
}
let conn = Connection::open(db_path)?;
conn.execute(UblxDbStatements::DELETE_LENS, [lens_name])?;
Ok(())
}
pub fn rename_path_string(db_path: &Path, old: &str, new: &str) -> Result<(), anyhow::Error> {
if !db_path.exists() {
return Ok(());
}
let conn = Connection::open(db_path)?;
conn.execute(UblxDbStatements::UPDATE_PATH_STRING, (new, old))?;
Ok(())
}
pub fn delete_path_row(db_path: &Path, path: &str) -> Result<(), anyhow::Error> {
if !db_path.exists() {
return Ok(());
}
let conn = Connection::open(db_path)?;
conn.execute(UblxDbStatements::DELETE_PATH_ROW, [path])?;
Ok(())
}