use rusqlite::params;
use uuid::Uuid;
use super::{
ProjectId, Vault,
error::{DbError, map_rusqlite_error, not_found_or},
};
#[derive(Debug, Clone)]
pub struct Project {
pub id: ProjectId,
pub name: String,
pub created_at: i64,
pub updated_at: i64,
}
impl Vault {
pub fn ensure_project(&self, id: &ProjectId, name: &str) -> Result<(), DbError> {
self.conn
.execute(
"INSERT OR IGNORE INTO projects (id, name) VALUES (?1, ?2)",
params![id.as_str(), name],
)
.map_err(map_rusqlite_error)?;
Ok(())
}
pub fn create_project(&self, name: &str) -> Result<ProjectId, DbError> {
let id = Uuid::new_v4().to_string();
self.conn
.execute(
"INSERT INTO projects (id, name) VALUES (?1, ?2)",
params![id, name],
)
.map_err(map_rusqlite_error)?;
Ok(ProjectId(id))
}
pub fn get_project(&self, id: &ProjectId) -> Result<Project, DbError> {
self.conn
.query_row(
"SELECT id, name, created_at, updated_at
FROM projects
WHERE id = ?1",
params![id.as_str()],
row_to_project,
)
.map_err(not_found_or)
}
pub fn get_project_by_name(&self, name: &str) -> Result<Project, DbError> {
self.conn
.query_row(
"SELECT id, name, created_at, updated_at
FROM projects
WHERE name = ?1
ORDER BY created_at ASC
LIMIT 1",
params![name],
row_to_project,
)
.map_err(not_found_or)
}
pub fn list_projects(&self) -> Result<Vec<Project>, DbError> {
let mut stmt = self
.conn
.prepare(
"SELECT id, name, created_at, updated_at
FROM projects
ORDER BY created_at ASC",
)
.map_err(map_rusqlite_error)?;
let rows = stmt
.query_map([], row_to_project)
.map_err(map_rusqlite_error)?;
rows.map(|r| r.map_err(map_rusqlite_error))
.collect::<Result<Vec<Project>, DbError>>()
}
pub fn delete_project(&self, id: &ProjectId) -> Result<(), DbError> {
let changed = self
.conn
.execute("DELETE FROM projects WHERE id = ?1", params![id.as_str()])
.map_err(map_rusqlite_error)?;
if changed == 0 {
return Err(DbError::NotFound);
}
Ok(())
}
}
fn row_to_project(row: &rusqlite::Row<'_>) -> rusqlite::Result<Project> {
Ok(Project {
id: ProjectId(row.get(0)?),
name: row.get(1)?,
created_at: row.get(2)?,
updated_at: row.get(3)?,
})
}