103 lines
2.6 KiB
Rust
103 lines
2.6 KiB
Rust
use crate::Result;
|
|
|
|
use anyhow::anyhow;
|
|
use sqlx::{self, ConnectOptions, SqliteConnection};
|
|
use sqlx::sqlite::SqliteConnectOptions;
|
|
|
|
pub(crate) type Id = i64;
|
|
|
|
#[derive(sqlx::FromRow)]
|
|
pub struct Bookmark {
|
|
#[sqlx(rename="rowid")]
|
|
pub id: Id,
|
|
pub link: String,
|
|
pub comment: String,
|
|
}
|
|
|
|
impl Bookmark {
|
|
pub fn new(link: String, comment: String) -> Self {
|
|
Bookmark { id: 0, link, comment }
|
|
}
|
|
}
|
|
|
|
pub struct Store {
|
|
conn: SqliteConnection,
|
|
table: &'static str,
|
|
}
|
|
|
|
impl Store {
|
|
pub async fn new(location: &str, is_reading_list: bool) -> Result<Self> {
|
|
let conn = location.parse::<SqliteConnectOptions>()?
|
|
.connect().await?;
|
|
let table = {
|
|
if is_reading_list { "reading_list" } else { "bookmarks" }
|
|
};
|
|
let mut result = Self { conn, table };
|
|
result.create_tables().await?;
|
|
Ok(result)
|
|
}
|
|
|
|
pub async fn list(&mut self) -> Result<Vec<Bookmark>> {
|
|
let query = format!(
|
|
"SELECT rowid, link, comment
|
|
FROM {}
|
|
ORDER BY timestamp",
|
|
self.table
|
|
);
|
|
Ok(sqlx::query_as(&query)
|
|
.fetch_all(&mut self.conn)
|
|
.await?)
|
|
}
|
|
|
|
pub async fn add(&mut self, bookmark: Bookmark) -> Result<()> {
|
|
let query = format!(
|
|
"INSERT INTO {} VALUES
|
|
($1, $2, unixepoch('now'))",
|
|
self.table
|
|
);
|
|
sqlx::query(&query)
|
|
.bind(bookmark.link)
|
|
.bind(bookmark.comment)
|
|
.execute(&mut self.conn).await?;
|
|
Ok(())
|
|
}
|
|
|
|
|
|
pub async fn get(&mut self, id: Id)
|
|
-> Result<Bookmark> {
|
|
let query = format!(
|
|
"SELECT rowid, link, comment
|
|
FROM {}
|
|
WHERE rowid = $1",
|
|
self.table
|
|
);
|
|
let result = sqlx::query_as(&query)
|
|
.bind(id)
|
|
.fetch_optional(&mut self.conn)
|
|
.await?
|
|
.ok_or(anyhow!("Could not find a bookmark with that ID!"))?;
|
|
Ok(result)
|
|
}
|
|
|
|
pub async fn rm(&mut self, id: Id) -> Result<()> {
|
|
let query = format!(
|
|
"DELETE FROM {}
|
|
WHERE rowid = $1",
|
|
self.table
|
|
);
|
|
sqlx::query(&query).bind(id).execute(&mut self.conn).await?;
|
|
Ok(())
|
|
}
|
|
|
|
async fn create_tables(&mut self) -> Result<()> {
|
|
for table in ["bookmarks", "reading_list"] {
|
|
let query = format!(
|
|
"CREATE TABLE IF NOT EXISTS {}
|
|
(link TEXT, comment TEXT, timestamp DATETIME)",
|
|
table
|
|
);
|
|
sqlx::query(&query).execute(&mut self.conn).await?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|