use crate::db::Pool;
use crate::db::database::interact_err;
use anyhow::{Context, Result};
use rusqlite::params;
#[derive(Clone)]
pub struct RecentPathsRepository {
pool: Pool,
}
impl RecentPathsRepository {
pub fn new(pool: Pool) -> Self {
Self { pool }
}
pub async fn record(&self, working_directory: &str, path: &str) -> Result<()> {
let wd = working_directory.to_string();
let p = path.to_string();
self.pool
.get()
.await
.context("Failed to get connection")?
.interact(move |conn| {
conn.execute(
"INSERT INTO recent_paths (working_directory, path, last_accessed) \
VALUES (?1, ?2, strftime('%s', 'now')) \
ON CONFLICT(working_directory, path) DO UPDATE \
SET last_accessed = strftime('%s', 'now')",
params![wd, p],
)
})
.await
.map_err(interact_err)?
.context("Failed to record recent path")?;
Ok(())
}
pub async fn top_for_dir(&self, working_directory: &str, limit: usize) -> Result<Vec<String>> {
let wd = working_directory.to_string();
let limit = limit as i64;
self.pool
.get()
.await
.context("Failed to get connection")?
.interact(move |conn| {
let mut stmt = conn.prepare_cached(
"SELECT path FROM recent_paths \
WHERE working_directory = ?1 \
ORDER BY last_accessed DESC \
LIMIT ?2",
)?;
let rows = stmt.query_map(params![wd, limit], |row| row.get::<_, String>(0))?;
rows.collect::<std::result::Result<Vec<_>, _>>()
})
.await
.map_err(interact_err)?
.context("Failed to query recent paths")
}
}