repo/sqlite: implement methods
- get list - get one - insert - remove
This commit is contained in:
parent
78cbc633c4
commit
a6cb3c7804
4 changed files with 102 additions and 27 deletions
|
@ -5,20 +5,22 @@ CREATE TABLE _tas_info (
|
|||
CREATE TABLE tasks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
project TEXT NULL,
|
||||
link TEXT NULL,
|
||||
dir_path TEXT NULL,
|
||||
project TEXT ,
|
||||
link TEXT ,
|
||||
dir_path TEXT ,
|
||||
|
||||
current BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
created_at DATETIME NOT NULL DEFAULT datetime('now'),
|
||||
finished_at DATETIME NULL
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
finished_at DATETIME
|
||||
);
|
||||
|
||||
CREATE VIEW active_tasks AS (
|
||||
SELECT t.*
|
||||
FROM tasks AS t
|
||||
WHERE t.finished_at IS NULL
|
||||
ORDER BY t.created_at
|
||||
);
|
||||
CREATE VIEW active_tasks
|
||||
AS
|
||||
SELECT
|
||||
t.*,
|
||||
row_number() OVER (ORDER BY t.created_at) AS idx
|
||||
FROM tasks AS t
|
||||
WHERE t.finished_at IS NULL
|
||||
ORDER BY t.created_at
|
||||
;
|
||||
|
|
|
@ -5,19 +5,22 @@ CREATE TABLE _tas_info (
|
|||
CREATE TABLE tasks (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
project TEXT NULL,
|
||||
link TEXT NULL,
|
||||
dir_path TEXT NULL,
|
||||
project TEXT ,
|
||||
link TEXT ,
|
||||
dir_path TEXT ,
|
||||
|
||||
current BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
created_at DATETIME NOT NULL DEFAULT datetime('now'),
|
||||
finished_at DATETIME NULL
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
finished_at DATETIME
|
||||
);
|
||||
|
||||
CREATE VIEW active_tasks AS (
|
||||
SELECT t.*
|
||||
FROM tasks AS t
|
||||
WHERE t.finished_at IS NULL
|
||||
ORDER BY t.created_at
|
||||
);
|
||||
CREATE VIEW active_tasks
|
||||
AS
|
||||
SELECT
|
||||
t.*,
|
||||
row_number() OVER (ORDER BY t.created_at) AS idx
|
||||
FROM tasks AS t
|
||||
WHERE t.finished_at IS NULL
|
||||
ORDER BY t.created_at
|
||||
;
|
||||
|
|
|
@ -28,6 +28,7 @@ pub enum Error {
|
|||
NotFound,
|
||||
InvalidData,
|
||||
InsertData,
|
||||
RemoveData,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
|
@ -39,6 +40,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::RemoveData => f.write_str("Cannot remove data"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use rusqlite::Connection;
|
||||
use rusqlite::{Connection, OptionalExtension};
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::domain;
|
||||
|
@ -17,6 +17,8 @@ struct Task {
|
|||
|
||||
created_at: time::OffsetDateTime,
|
||||
finished_at: Option<time::OffsetDateTime>,
|
||||
|
||||
idx: i64,
|
||||
}
|
||||
|
||||
impl From<Task> for domain::Task {
|
||||
|
@ -43,6 +45,7 @@ impl<'r> TryFrom<&'r rusqlite::Row<'_>> for Task {
|
|||
current: row.get("current")?,
|
||||
created_at: row.get("created_at")?,
|
||||
finished_at: row.get("finished_at")?,
|
||||
idx: row.get("idx")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -57,17 +60,53 @@ impl SqliteRepo {
|
|||
pub fn new(xdg_dirs: BaseDirectories) -> Result<Self, Error> {
|
||||
let file_path = xdg_dirs.get_data_file(SCHEMA_FILE);
|
||||
let conn = Connection::open(file_path).map_err(|_| Error::Connect)?;
|
||||
|
||||
/*
|
||||
conn.execute_batch(&format!(
|
||||
"BEGIN; {} COMMIT;",
|
||||
include_str!("../../database/schema.sql")
|
||||
))
|
||||
.map_err(|err| match err {
|
||||
rusqlite::Error::SqlInputError { .. } => panic!("{}", err),
|
||||
_ => err,
|
||||
})
|
||||
.ok();
|
||||
*/
|
||||
|
||||
Ok(Self { conn })
|
||||
}
|
||||
}
|
||||
|
||||
impl Repository for SqliteRepo {
|
||||
fn get_current_task_opt(&self) -> Result<Option<domain::CurrentTaskInfo>, Error> {
|
||||
todo!()
|
||||
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.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> {
|
||||
todo!()
|
||||
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_tasks(&self) -> Result<Vec<domain::Task>, Error> {
|
||||
|
@ -87,11 +126,40 @@ impl Repository for SqliteRepo {
|
|||
}
|
||||
|
||||
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
let task = self.get_task_opt(id)?.ok_or(Error::NotFound)?;
|
||||
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("DELETE FROM tasks WHERE id = ?")
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
stmt.execute([&(id as i64)])
|
||||
.map_err(|_| Error::RemoveData)?;
|
||||
|
||||
Ok(task)
|
||||
}
|
||||
|
||||
fn insert_task(&self, insert_data: super::InsertTaskData) -> Result<domain::Task, Error> {
|
||||
todo!()
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare(
|
||||
"INSERT INTO tasks (name, project, link, dir_path)
|
||||
VALUES (?1, ?2, ?3, ?4)",
|
||||
)
|
||||
.map_err(|_| Error::PrepareQuery)?;
|
||||
|
||||
let id = stmt
|
||||
.insert((
|
||||
&insert_data.name,
|
||||
&insert_data.project,
|
||||
&insert_data.link,
|
||||
&insert_data
|
||||
.dir_path
|
||||
.and_then(|p| p.into_os_string().into_string().ok()),
|
||||
))
|
||||
.map_err(|_| Error::InsertData)?;
|
||||
|
||||
self.get_task_opt(id as usize)?.ok_or(Error::NotFound)
|
||||
}
|
||||
|
||||
fn update_task(
|
||||
|
|
Loading…
Reference in a new issue