90 lines
2.8 KiB
Rust
90 lines
2.8 KiB
Rust
use crate::errors::NoteStoreError;
|
|
use crate::structs::{RawNote, RawPage};
|
|
use chrono;
|
|
use friendly_id;
|
|
use sqlx;
|
|
use sqlx::sqlite::SqlitePool;
|
|
use sqlx::{sqlite::Sqlite, Executor};
|
|
use std::sync::Arc;
|
|
|
|
/// A handle to our Sqlite database.
|
|
#[derive(Clone, Debug)]
|
|
pub struct NoteStore(Arc<SqlitePool>);
|
|
|
|
type NoteResult<T> = core::result::Result<T, NoteStoreError>;
|
|
type SqlResult<T> = sqlx::Result<T>;
|
|
|
|
async fn insert_note<'e, E>(executor: E, id: &str, content: &str, notetype: &str) -> SqlResult<i64>
|
|
where
|
|
E: 'e + Executor<'e, Database = Sqlite>,
|
|
{
|
|
let insert_one_note_sql = include_str!("sql/insert_one_note.sql");
|
|
let now = chrono::Utc::now();
|
|
Ok(sqlx::query(insert_one_note_sql)
|
|
.bind(&id)
|
|
.bind(&content)
|
|
.bind(¬etype)
|
|
.bind(&now)
|
|
.bind(&now)
|
|
.bind(&now)
|
|
.execute(executor)
|
|
.await?
|
|
.last_insert_rowid())
|
|
}
|
|
|
|
impl NoteStore {
|
|
pub async fn new(url: &str) -> NoteResult<Self> {
|
|
let pool = SqlitePool::connect(url).await?;
|
|
Ok(NoteStore(Arc::new(pool)))
|
|
}
|
|
|
|
/// This will erase all the data in the database. Only use this
|
|
/// if you're sure that's what you want.
|
|
pub async fn reset_database(&self) -> NoteResult<()> {
|
|
let initialize_sql = include_str!("sql/initialize_database.sql");
|
|
sqlx::query(initialize_sql).execute(&*self.0).await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn fetch_raw_page(&self, id: &str) -> SqlResult<RawPage> {
|
|
let select_one_page_sql = include_str!("sql/select_one_page.sql");
|
|
sqlx::query_as(select_one_page_sql).bind(&id).fetch_one(&*self.0).await
|
|
}
|
|
|
|
pub async fn fetch_raw_note(&self, id: &str) -> SqlResult<RawNote> {
|
|
let select_one_note_sql = include_str!("sql/select_one_note.sql");
|
|
sqlx::query_as(select_one_note_sql).bind(&id).fetch_one(&*self.0).await
|
|
}
|
|
|
|
pub async fn insert_note(&self, id: &str, content: &str, notetype: &str) -> SqlResult<i64> {
|
|
insert_note(&*self.0, id, content, notetype).await
|
|
}
|
|
|
|
// TODO: We're returning the raw page with the raw note id, note
|
|
// the friendly ID. Is there a disconnect there? It's making me
|
|
// furiously to think.
|
|
pub async fn insert_page(&self, id: &str, title: &str) -> SqlResult<i64> {
|
|
let insert_one_page_sql = include_str!("sql/insert_one_page.sql");
|
|
let new_note_id = friendly_id::create();
|
|
let now = chrono::Utc::now();
|
|
|
|
let mut tx = self.0.begin().await?;
|
|
|
|
let note_id = insert_note(&mut tx, &new_note_id, &"", &"page").await?;
|
|
|
|
let page_id = sqlx::query(insert_one_page_sql)
|
|
.bind(&id)
|
|
.bind(&title)
|
|
.bind(¬e_id)
|
|
.bind(&now)
|
|
.bind(&now)
|
|
.bind(&now)
|
|
.execute(&mut tx)
|
|
.await?
|
|
.last_insert_rowid();
|
|
|
|
tx.commit().await?;
|
|
Ok(page_id)
|
|
}
|
|
}
|