repo/sqlite: implement rest methods
This commit is contained in:
parent
a6cb3c7804
commit
62ad59ab76
4 changed files with 126 additions and 45 deletions
|
@ -15,7 +15,7 @@
|
|||
//!
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub type TaskId = usize;
|
||||
pub type TaskIdx = usize;
|
||||
|
||||
pub struct Task {
|
||||
pub name: String,
|
||||
|
|
10
src/repo.rs
10
src/repo.rs
|
@ -28,6 +28,7 @@ pub enum Error {
|
|||
NotFound,
|
||||
InvalidData,
|
||||
InsertData,
|
||||
UpdateData,
|
||||
RemoveData,
|
||||
}
|
||||
|
||||
|
@ -40,6 +41,7 @@ impl std::fmt::Display for Error {
|
|||
Error::NotFound => f.write_str("Cannot find data"),
|
||||
Error::InvalidData => f.write_str("Invalid data format"),
|
||||
Error::InsertData => f.write_str("Cannot insert data"),
|
||||
Error::UpdateData => f.write_str("Cannot update data"),
|
||||
Error::RemoveData => f.write_str("Cannot remove data"),
|
||||
}
|
||||
}
|
||||
|
@ -65,21 +67,21 @@ pub struct UpdateTaskData {
|
|||
pub trait Repository {
|
||||
fn get_current_task_opt(&self) -> Result<Option<domain::CurrentTaskInfo>, Error>;
|
||||
|
||||
fn get_task_opt(&self, id: domain::TaskId) -> Result<Option<domain::Task>, Error>;
|
||||
fn get_task_opt(&self, id: domain::TaskIdx) -> Result<Option<domain::Task>, Error>;
|
||||
|
||||
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error>;
|
||||
|
||||
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error>;
|
||||
fn remove_task(&self, id: domain::TaskIdx) -> Result<domain::Task, Error>;
|
||||
|
||||
fn update_task(
|
||||
&self,
|
||||
id: domain::TaskId,
|
||||
id: domain::TaskIdx,
|
||||
update_data: UpdateTaskData,
|
||||
) -> Result<domain::Task, Error>;
|
||||
|
||||
fn insert_task(&self, insert_data: InsertTaskData) -> Result<domain::Task, Error>;
|
||||
|
||||
fn start_task(&self, id: domain::TaskId) -> Result<domain::Task, Error>;
|
||||
fn start_task(&self, id: domain::TaskIdx) -> Result<domain::Task, Error>;
|
||||
|
||||
fn stop_task(&self) -> Result<domain::Task, Error>;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ impl Repository for FsRepo {
|
|||
.map(|cur_task| cur_task.map(From::from))
|
||||
}
|
||||
|
||||
fn get_task_opt(&self, id: domain::TaskId) -> Result<Option<domain::Task>, Error> {
|
||||
fn get_task_opt(&self, id: domain::TaskIdx) -> Result<Option<domain::Task>, Error> {
|
||||
let tasks = self.get_tasks_impl()?;
|
||||
if id == 0 || id > tasks.len() {
|
||||
return Err(Error::NotFound);
|
||||
|
@ -93,7 +93,7 @@ impl Repository for FsRepo {
|
|||
.map(|tasks| tasks.into_iter().map(Task::into).collect())
|
||||
}
|
||||
|
||||
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||
fn remove_task(&self, id: domain::TaskIdx) -> Result<domain::Task, Error> {
|
||||
let mut tasks = self.get_tasks_impl()?;
|
||||
if id == 0 || id > tasks.len() {
|
||||
return Err(Error::NotFound);
|
||||
|
@ -107,7 +107,7 @@ impl Repository for FsRepo {
|
|||
|
||||
fn update_task(
|
||||
&self,
|
||||
id: domain::TaskId,
|
||||
id: domain::TaskIdx,
|
||||
update_data: UpdateTaskData,
|
||||
) -> Result<domain::Task, Error> {
|
||||
let mut tasks = self.get_tasks_impl()?;
|
||||
|
@ -161,7 +161,7 @@ impl Repository for FsRepo {
|
|||
Ok(new_task.into())
|
||||
}
|
||||
|
||||
fn start_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||
fn start_task(&self, id: domain::TaskIdx) -> Result<domain::Task, Error> {
|
||||
let tasks = self.get_tasks_impl()?;
|
||||
if id == 0 || id > tasks.len() {
|
||||
return Err(Error::NotFound);
|
||||
|
|
|
@ -12,12 +12,11 @@ struct Task {
|
|||
project: Option<String>,
|
||||
link: Option<String>,
|
||||
dir_path: Option<String>,
|
||||
|
||||
/*
|
||||
current: bool,
|
||||
|
||||
created_at: time::OffsetDateTime,
|
||||
finished_at: Option<time::OffsetDateTime>,
|
||||
|
||||
*/
|
||||
idx: i64,
|
||||
}
|
||||
|
||||
|
@ -42,9 +41,11 @@ impl<'r> TryFrom<&'r rusqlite::Row<'_>> for Task {
|
|||
project: row.get("project")?,
|
||||
link: row.get("link")?,
|
||||
dir_path: row.get("dir_path")?,
|
||||
/*
|
||||
current: row.get("current")?,
|
||||
created_at: row.get("created_at")?,
|
||||
finished_at: row.get("finished_at")?,
|
||||
*/
|
||||
idx: row.get("idx")?,
|
||||
})
|
||||
}
|
||||
|
@ -79,34 +80,16 @@ impl SqliteRepo {
|
|||
|
||||
impl Repository for SqliteRepo {
|
||||
fn get_current_task_opt(&self) -> Result<Option<domain::CurrentTaskInfo>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT * FROM active_tasks WHERE current IS true")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
let db_task = self.get_current_task_opt_impl()?;
|
||||
|
||||
let row = stmt
|
||||
.query_row([], |row| Task::try_from(row))
|
||||
.optional()
|
||||
.map_err(|_| Error::QueryData)?;
|
||||
|
||||
Ok(row.map(|db_task| domain::CurrentTaskInfo {
|
||||
Ok(db_task.map(|db_task| domain::CurrentTaskInfo {
|
||||
task_idx: db_task.idx as usize,
|
||||
task: db_task.into(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn get_task_opt(&self, id: domain::TaskId) -> Result<Option<domain::Task>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT * FROM active_tasks WHERE idx = ?")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
let row = stmt
|
||||
.query_row([id as i64], |row| Task::try_from(row))
|
||||
.optional()
|
||||
.map_err(|_| Error::QueryData)?;
|
||||
|
||||
Ok(row.map(From::from))
|
||||
fn get_task_opt(&self, id: domain::TaskIdx) -> Result<Option<domain::Task>, Error> {
|
||||
self.get_task_opt_impl(id).map(|t| t.map(From::from))
|
||||
}
|
||||
|
||||
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error> {
|
||||
|
@ -125,18 +108,18 @@ impl Repository for SqliteRepo {
|
|||
.map_err(|_| Error::InvalidData)
|
||||
}
|
||||
|
||||
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||
let task = self.get_task_opt(id)?.ok_or(Error::NotFound)?;
|
||||
fn remove_task(&self, idx: domain::TaskIdx) -> Result<domain::Task, Error> {
|
||||
let db_task = self.get_task_opt_impl(idx)?.ok_or(Error::NotFound)?;
|
||||
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("DELETE FROM tasks WHERE id = ?")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
stmt.execute([&(id as i64)])
|
||||
stmt.execute([&(db_task.id)])
|
||||
.map_err(|_| Error::RemoveData)?;
|
||||
|
||||
Ok(task)
|
||||
Ok(db_task.into())
|
||||
}
|
||||
|
||||
fn insert_task(&self, insert_data: super::InsertTaskData) -> Result<domain::Task, Error> {
|
||||
|
@ -159,26 +142,122 @@ impl Repository for SqliteRepo {
|
|||
))
|
||||
.map_err(|_| Error::InsertData)?;
|
||||
|
||||
self.get_task_opt(id as usize)?.ok_or(Error::NotFound)
|
||||
dbg!(id);
|
||||
|
||||
self.get_task_by_id_impl(id).map(From::from)
|
||||
}
|
||||
|
||||
fn update_task(
|
||||
&self,
|
||||
id: domain::TaskId,
|
||||
idx: domain::TaskIdx,
|
||||
update_data: super::UpdateTaskData,
|
||||
) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
let task = self.get_task_opt_impl(idx)?.ok_or(Error::NotFound)?;
|
||||
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare(
|
||||
"UPDATE tasks
|
||||
SET name = ?1,
|
||||
project = ?2,
|
||||
link = ?3,
|
||||
dir_path = ?4
|
||||
WHERE id = ?5
|
||||
",
|
||||
)
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
stmt.execute((
|
||||
&update_data.name.unwrap_or(task.name),
|
||||
&update_data.project.unwrap_or(task.project),
|
||||
&update_data.link.unwrap_or(task.link),
|
||||
&update_data
|
||||
.dir_path
|
||||
.unwrap_or(task.dir_path.map(PathBuf::from))
|
||||
.and_then(|p| p.into_os_string().into_string().ok()),
|
||||
&task.id,
|
||||
))
|
||||
.map_err(|_| Error::UpdateData)?;
|
||||
|
||||
self.get_task_opt(idx)?.ok_or(Error::NotFound)
|
||||
}
|
||||
|
||||
fn start_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
fn start_task(&self, idx: domain::TaskIdx) -> Result<domain::Task, Error> {
|
||||
let db_task = self.get_task_opt_impl(idx)?.ok_or(Error::NotFound)?;
|
||||
|
||||
self.conn
|
||||
.execute(
|
||||
"UPDATE tasks SET current = true WHERE id = ?1",
|
||||
[&db_task.id],
|
||||
)
|
||||
.map_err(|_| Error::UpdateData)?;
|
||||
|
||||
Ok(db_task.into())
|
||||
}
|
||||
|
||||
fn stop_task(&self) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
let db_task = self.get_current_task_opt_impl()?.ok_or(Error::NotFound)?;
|
||||
|
||||
self.conn
|
||||
.execute(
|
||||
"UPDATE tasks SET current = false WHERE id = ?1",
|
||||
[&db_task.id],
|
||||
)
|
||||
.map_err(|_| Error::UpdateData)?;
|
||||
|
||||
Ok(db_task.into())
|
||||
}
|
||||
|
||||
fn finish_task(&self) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
let db_task = self.get_current_task_opt_impl()?.ok_or(Error::NotFound)?;
|
||||
|
||||
self.conn
|
||||
.execute(
|
||||
"UPDATE tasks
|
||||
SET current = false,
|
||||
finished_at = CURRENT_TIMESTAMP
|
||||
WHERE id = ?1",
|
||||
[&db_task.id],
|
||||
)
|
||||
.map_err(|_| Error::UpdateData)?;
|
||||
|
||||
Ok(db_task.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl SqliteRepo {
|
||||
fn get_task_by_id_impl(&self, id: i64) -> Result<Task, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT * FROM active_tasks WHERE id = ?")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
stmt.query_row([id], |row| Task::try_from(row))
|
||||
.map_err(|_| Error::QueryData)
|
||||
}
|
||||
|
||||
fn get_task_opt_impl(&self, idx: domain::TaskIdx) -> Result<Option<Task>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT * FROM active_tasks WHERE idx = ?")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
stmt.query_row([idx as i64], |row| Task::try_from(row))
|
||||
.optional()
|
||||
.map_err(|_| Error::QueryData)
|
||||
}
|
||||
|
||||
fn get_current_task_opt_impl(&self) -> Result<Option<Task>, Error> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("SELECT * FROM active_tasks WHERE current IS true")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
let row = stmt
|
||||
.query_row([], |row| Task::try_from(row))
|
||||
.optional()
|
||||
.map_err(|_| Error::QueryData)?;
|
||||
|
||||
Ok(row)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue