hoard/src/db.rs

98 lines
2.6 KiB
Rust
Raw Normal View History

2024-03-10 04:52:50 +01:00
use jobdispatcher::{JobDispatcher, JobOrder};
2024-03-07 16:18:47 +01:00
use rusqlite::Connection;
2024-03-10 04:52:50 +01:00
use std::sync::{mpsc::Receiver, Arc};
2024-03-07 16:18:47 +01:00
2024-03-10 04:52:50 +01:00
pub struct DatabaseBackend {
pub file: String,
pub conn: Connection,
pub dispatcher: Arc<JobDispatcher<Query, Out>>,
pub recv: Receiver<JobOrder<Query, Out>>,
2024-03-07 16:18:47 +01:00
}
2024-03-10 04:52:50 +01:00
impl DatabaseBackend {
2024-03-07 16:18:47 +01:00
pub fn new(file: &str) -> Self {
2024-03-10 04:52:50 +01:00
let (dispatcher, recv) = jobdispatcher::JobDispatcher::<Query, Out>::new();
2024-03-07 16:18:47 +01:00
let conn = Connection::open(file).unwrap();
2024-03-10 04:52:50 +01:00
2024-03-07 16:18:47 +01:00
conn.execute(
"CREATE TABLE IF NOT EXISTS urls (
id INTEGER PRIMARY KEY,
url TEXT NOT NULL,
timestamp TEXT NOT NULL
)",
[],
)
.unwrap();
2024-03-10 04:52:50 +01:00
let dispatcher = Arc::new(dispatcher);
2024-03-07 16:18:47 +01:00
Self {
file: file.to_string(),
2024-03-10 04:52:50 +01:00
conn,
dispatcher,
recv,
2024-03-07 16:18:47 +01:00
}
}
2024-03-10 04:52:50 +01:00
pub fn take_db(&self) -> Database {
Database::new(self.dispatcher.clone())
}
pub fn run(&self) {
while let Ok(job) = self.recv.recv() {
match job.param {
Query::InsertUrl(ref url) => {
let timestamp = chrono::Local::now().to_rfc3339();
self.conn
.execute(
"INSERT INTO urls (url, timestamp) VALUES (?, ?)",
[url, &timestamp],
)
.unwrap();
job.done(Out::Ok);
}
Query::CheckForUrl(ref url) => {
let conn = Connection::open(&self.file).unwrap();
let mut stmt = conn
.prepare("SELECT COUNT(*) FROM urls WHERE url = ?")
.unwrap();
let count: i64 = stmt.query_row([url], |row| row.get(0)).unwrap();
job.done(Out::Bool(count > 0));
}
}
}
}
}
pub enum Query {
InsertUrl(String),
CheckForUrl(String),
}
pub enum Out {
Ok,
Bool(bool),
// Rows(Vec<String>),
}
#[derive(Clone)]
pub struct Database {
conn: Arc<JobDispatcher<Query, Out>>,
}
impl Database {
pub fn new(conn: Arc<JobDispatcher<Query, Out>>) -> Self {
Self { conn }
2024-03-07 16:18:47 +01:00
}
2024-03-10 04:52:50 +01:00
pub fn insert_url(&self, url: &str) {
self.conn.send(Query::InsertUrl(url.to_string()));
}
pub fn check_for_url(&self, url: &str) -> bool {
match self.conn.send(Query::CheckForUrl(url.to_string())) {
Out::Ok => false,
Out::Bool(b) => b,
}
2024-03-07 16:18:47 +01:00
}
}