REFACTOR: Dry'ing out the insert_new_note feature.
Since both `insert_page` and `insert_note` need to insert a note, having that code twice in the same block was annoying, especially since discovering that my oh-so-clever use of `include_str!` precludes me from using the `query!` macros, which want the strings included *before* doing analysis. All that wrestling with the Transaction type turned out to be much simpler when I was able to just devolve it into an Executor.
This commit is contained in:
parent
75809d821d
commit
1565fef001
|
@ -12,9 +12,9 @@ mod tests {
|
|||
|
||||
async fn fresh_inmemory_database() -> NoteStore {
|
||||
let storagepool = NoteStore::new("sqlite://:memory:").await;
|
||||
assert!(storagepool.is_ok(), "{:?}", storagepool);
|
||||
assert!(storagepool.is_ok(), "{:?}", storagepool);
|
||||
let storagepool = storagepool.unwrap();
|
||||
let reset = storagepool.reset_database().await;
|
||||
let reset = storagepool.reset_database().await;
|
||||
assert!(reset.is_ok(), "{:?}", reset);
|
||||
storagepool
|
||||
}
|
||||
|
@ -45,29 +45,29 @@ mod tests {
|
|||
|
||||
#[tokio::test(threaded_scheduler)]
|
||||
async fn can_save_a_note() {
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let note_id = storagepool.insert_note("noteid", "notecontent", "note").await;
|
||||
assert!(note_id.is_ok(), "{:?}", note_id);
|
||||
let note_id = note_id.unwrap();
|
||||
assert!(note_id > 0);
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let note_id = storagepool.insert_note("noteid", "notecontent", "note").await;
|
||||
assert!(note_id.is_ok(), "{:?}", note_id);
|
||||
let note_id = note_id.unwrap();
|
||||
assert!(note_id > 0);
|
||||
|
||||
let foundnote = storagepool.fetch_raw_note("noteid").await;
|
||||
assert!(foundnote.is_ok(), "{:?}", foundnote);
|
||||
let foundnote = foundnote.unwrap();
|
||||
assert_eq!(foundnote.content, "notecontent");
|
||||
assert_eq!(foundnote.notetype, "note");
|
||||
}
|
||||
let foundnote = storagepool.fetch_raw_note("noteid").await;
|
||||
assert!(foundnote.is_ok(), "{:?}", foundnote);
|
||||
let foundnote = foundnote.unwrap();
|
||||
assert_eq!(foundnote.content, "notecontent");
|
||||
assert_eq!(foundnote.notetype, "note");
|
||||
}
|
||||
|
||||
#[tokio::test(threaded_scheduler)]
|
||||
async fn can_save_a_page() {
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let page_id = storagepool.insert_page("pageid", "Test page").await;
|
||||
assert!(page_id.is_ok(), "{:?}", page_id);
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let page_id = storagepool.insert_page("pageid", "Test page").await;
|
||||
assert!(page_id.is_ok(), "{:?}", page_id);
|
||||
|
||||
let page = storagepool.fetch_raw_page("pageid").await;
|
||||
assert!(page.is_ok(), "{:?}", page);
|
||||
let page = page.unwrap();
|
||||
assert_eq!(page.title, "Test page");
|
||||
assert!(page.note_id > 0);
|
||||
}
|
||||
let page = storagepool.fetch_raw_page("pageid").await;
|
||||
assert!(page.is_ok(), "{:?}", page);
|
||||
let page = page.unwrap();
|
||||
assert_eq!(page.title, "Test page");
|
||||
assert!(page.note_id > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::errors::NoteStoreError;
|
||||
use crate::structs::{RawNote, RawPage};
|
||||
use friendly_id;
|
||||
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.
|
||||
|
@ -13,6 +14,24 @@ 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?;
|
||||
|
@ -37,47 +56,34 @@ impl NoteStore {
|
|||
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> {
|
||||
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())
|
||||
}
|
||||
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_note_sql = include_str!("sql/insert_one_note.sql");
|
||||
let insert_one_page_sql = include_str!("sql/insert_one_page.sql");
|
||||
// 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 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 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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue