Replace FS with Sqlite #20
6 changed files with 106 additions and 17 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -182,6 +182,15 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -274,6 +283,7 @@ dependencies = [
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -339,6 +349,7 @@ dependencies = [
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"time",
|
||||||
"xdg",
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -368,6 +379,24 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
|
@ -12,7 +12,8 @@ maintenance = { status = "experimental" }
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "3.2.16", default-features = false, features = ["derive", "std"] }
|
clap = { version = "3.2.16", default-features = false, features = ["derive", "std"] }
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
rusqlite = { version = "0.28.0", features = ["bundled", "time"] }
|
||||||
serde = { version = "1.0.142", features = ["derive"] }
|
serde = { version = "1.0.142", features = ["derive"] }
|
||||||
serde_json = "1.0.83"
|
serde_json = "1.0.83"
|
||||||
|
time = "0.3"
|
||||||
xdg = "2.4.1"
|
xdg = "2.4.1"
|
||||||
|
|
|
@ -5,9 +5,9 @@ CREATE TABLE _tas_info (
|
||||||
CREATE TABLE tasks (
|
CREATE TABLE tasks (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
group TEXT NULL,
|
project TEXT NULL,
|
||||||
link TEXT NULL,
|
link TEXT NULL,
|
||||||
path TEXT NULL,
|
dir_path TEXT NULL,
|
||||||
|
|
||||||
current BOOLEAN NOT NULL DEFAULT false,
|
current BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
|
||||||
|
@ -16,10 +16,9 @@ CREATE TABLE tasks (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE VIEW active_tasks AS (
|
CREATE VIEW active_tasks AS (
|
||||||
SELECT *
|
SELECT t.*
|
||||||
FROM tasks
|
FROM tasks AS t
|
||||||
WHERE finished_at IS NULL
|
WHERE t.finished_at IS NULL
|
||||||
ORDER BY created_at
|
ORDER BY t.created_at
|
||||||
);
|
);
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ CREATE TABLE _tas_info (
|
||||||
CREATE TABLE tasks (
|
CREATE TABLE tasks (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
group TEXT NULL,
|
project TEXT NULL,
|
||||||
link TEXT NULL,
|
link TEXT NULL,
|
||||||
path TEXT NULL,
|
dir_path TEXT NULL,
|
||||||
|
|
||||||
current BOOLEAN NOT NULL DEFAULT false,
|
current BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
|
||||||
|
@ -16,9 +16,8 @@ CREATE TABLE tasks (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE VIEW active_tasks AS (
|
CREATE VIEW active_tasks AS (
|
||||||
SELECT *
|
SELECT t.*
|
||||||
FROM tasks
|
FROM tasks AS t
|
||||||
WHERE finished_at IS NULL
|
WHERE t.finished_at IS NULL
|
||||||
ORDER BY created_at
|
ORDER BY t.created_at
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ use crate::domain;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Connect,
|
Connect,
|
||||||
|
PrepareQuery,
|
||||||
|
QueryData,
|
||||||
NotFound,
|
NotFound,
|
||||||
InvalidData,
|
InvalidData,
|
||||||
InsertData,
|
InsertData,
|
||||||
|
@ -31,6 +33,9 @@ pub enum Error {
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Error::Connect => f.write_str("Cannot connect to the repository"),
|
||||||
|
Error::PrepareQuery => f.write_str("Cannot prepare query"),
|
||||||
|
Error::QueryData => f.write_str("Cannot query data"),
|
||||||
Error::NotFound => f.write_str("Cannot find data"),
|
Error::NotFound => f.write_str("Cannot find data"),
|
||||||
Error::InvalidData => f.write_str("Invalid data format"),
|
Error::InvalidData => f.write_str("Invalid data format"),
|
||||||
Error::InsertData => f.write_str("Cannot insert data"),
|
Error::InsertData => f.write_str("Cannot insert data"),
|
||||||
|
|
|
@ -1,9 +1,52 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use xdg::BaseDirectories;
|
use xdg::BaseDirectories;
|
||||||
|
|
||||||
use crate::domain;
|
use crate::domain;
|
||||||
use crate::repo::{Error, Repository};
|
use crate::repo::{Error, Repository};
|
||||||
|
|
||||||
|
struct Task {
|
||||||
|
id: i64,
|
||||||
|
name: String,
|
||||||
|
project: Option<String>,
|
||||||
|
link: Option<String>,
|
||||||
|
dir_path: Option<String>,
|
||||||
|
|
||||||
|
current: bool,
|
||||||
|
|
||||||
|
created_at: time::OffsetDateTime,
|
||||||
|
finished_at: Option<time::OffsetDateTime>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Task> for domain::Task {
|
||||||
|
fn from(repo: Task) -> Self {
|
||||||
|
Self {
|
||||||
|
name: repo.name,
|
||||||
|
project: repo.project,
|
||||||
|
link: repo.link,
|
||||||
|
dir_path: repo.dir_path.map(PathBuf::from),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r> TryFrom<&'r rusqlite::Row<'_>> for Task {
|
||||||
|
type Error = rusqlite::Error;
|
||||||
|
|
||||||
|
fn try_from(row: &'r rusqlite::Row<'_>) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self {
|
||||||
|
id: row.get("id")?,
|
||||||
|
name: row.get("name")?,
|
||||||
|
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")?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const SCHEMA_FILE: &str = "schema.sql";
|
const SCHEMA_FILE: &str = "schema.sql";
|
||||||
|
|
||||||
pub struct SqliteRepo {
|
pub struct SqliteRepo {
|
||||||
|
@ -28,8 +71,21 @@ impl Repository for SqliteRepo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error> {
|
fn get_tasks(&self) -> Result<Vec<domain::Task>, Error> {
|
||||||
todo!()
|
let mut stmt = self
|
||||||
|
.conn
|
||||||
|
.prepare("SELECT * FROM active_tasks")
|
||||||
|
.map_err(|_| Error::PrepareQuery)?;
|
||||||
|
|
||||||
|
let rows = stmt
|
||||||
|
.query_map([], |row| Task::try_from(row))
|
||||||
|
.map_err(|_| Error::QueryData)?;
|
||||||
|
|
||||||
|
rows.into_iter()
|
||||||
|
.map(|db_task| db_task.map(From::from).map_err(|_| Error::QueryData))
|
||||||
|
.collect::<Result<Vec<_>, Error>>()
|
||||||
|
.map_err(|_| Error::InvalidData)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
fn remove_task(&self, id: domain::TaskId) -> Result<domain::Task, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue