use crate::errors::NoteStoreError; use crate::structs::{RawNote, RawPage}; use friendly_id; use chrono; use sqlx; use sqlx::sqlite::SqlitePool; use std::sync::Arc; /// A handle to our Sqlite database. #[derive(Clone, Debug)] pub struct NoteStore(Arc); type NoteResult = core::result::Result; type SqlResult = sqlx::Result; impl NoteStore { pub async fn new(url: &str) -> NoteResult { 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 { 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 { 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 { 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(&*self.0).await? .last_insert_rowid()) } // 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 { let insert_one_note_sql = include_str!("sql/insert_one_note.sql"); 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 = sqlx::query(insert_one_note_sql) .bind(&new_note_id) .bind(&"") .bind(&"page") .bind(&now).bind(&now).bind(&now) .execute(&mut tx).await? .last_insert_rowid(); 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) } }