diff --git a/server/nm-store/Makefile b/server/nm-store/Makefile new file mode 100644 index 0000000..e0b2174 --- /dev/null +++ b/server/nm-store/Makefile @@ -0,0 +1,15 @@ +.PHONY: all +all: help + +.PHONY: help +help: + @M=$$(perl -ne 'm/((\w|-)*):.*##/ && print length($$1)."\n"' Makefile | \ + sort -nr | head -1) && \ + perl -ne "m/^((\w|-)*):.*##\s*(.*)/ && print(sprintf(\"%s: %s\t%s\n\", \$$1, \" \"x($$M-length(\$$1)), \$$3))" Makefile + +# This is necessary because I'm trying hard not to use +# any `nightly` features. But rustfmt is likely to be +# a `nightly-only` feature for a long time to come, so +# this is my hack. +fmt: ## Format the code, using the most modern version of rustfmt + rustup run nightly cargo fmt diff --git a/server/nm-store/src/lib.rs b/server/nm-store/src/lib.rs index 12ec374..27bb446 100644 --- a/server/nm-store/src/lib.rs +++ b/server/nm-store/src/lib.rs @@ -2,36 +2,43 @@ mod errors; mod store; mod structs; -pub use crate::store::NoteStore; pub use crate::errors::NoteStoreError; - +pub use crate::store::NoteStore; #[cfg(test)] mod tests { - use super::*; - use tokio; + use super::*; + use tokio; - async fn fresh_inmemory_database() -> NoteStore { - let storagepool = NoteStore::new("sqlite://:memory:").await; - assert!(storagepool.is_ok()); - let storagepool = storagepool.unwrap(); - assert!(storagepool.reset_database().await.is_ok()); - storagepool - } - - #[tokio::test(threaded_scheduler)] + async fn fresh_inmemory_database() -> NoteStore { + let storagepool = NoteStore::new("sqlite://:memory:").await; + assert!(storagepool.is_ok()); + let storagepool = storagepool.unwrap(); + assert!(storagepool.reset_database().await.is_ok()); + storagepool + } + + #[tokio::test(threaded_scheduler)] async fn fetching_unfound_page_works() { - let storagepool = fresh_inmemory_database().await; - let unfoundpage = storagepool.fetch_page("nonexistent-page").await; - assert!(unfoundpage.is_err()); + let storagepool = fresh_inmemory_database().await; + let unfoundpage = storagepool.fetch_page("nonexistent-page").await; + assert!(unfoundpage.is_err()); } - #[tokio::test(threaded_scheduler)] + #[tokio::test(threaded_scheduler)] async fn fetching_unfound_note_works() { - let storagepool = fresh_inmemory_database().await; - let unfoundnote = storagepool.fetch_note("nonexistent-note").await; - assert!(unfoundnote.is_err()); + let storagepool = fresh_inmemory_database().await; + let unfoundnote = storagepool.fetch_note("nonexistent-note").await; + assert!(unfoundnote.is_err()); } - + #[tokio::test(threaded_scheduler)] + async fn cloning_storagepool_is_ok() { + let storagepool = fresh_inmemory_database().await; + let storagepool2 = storagepool.clone(); + let unfoundnote = storagepool2.fetch_note("nonexistent-note").await; + assert!(unfoundnote.is_err()); + let unfoundnote = storagepool.fetch_note("nonexistent-note").await; + assert!(unfoundnote.is_err()); + } } diff --git a/server/nm-store/src/store.rs b/server/nm-store/src/store.rs index ceb880f..8d04324 100644 --- a/server/nm-store/src/store.rs +++ b/server/nm-store/src/store.rs @@ -1,8 +1,8 @@ +use crate::errors::NoteStoreError; +use crate::structs::{RawNote, RawPage}; use sqlx; use sqlx::sqlite::SqlitePool; use std::sync::Arc; -use crate::errors::NoteStoreError; -use crate::structs::{RawPage, RawNote}; /// A handle to our Sqlite database. #[derive(Clone)] @@ -12,35 +12,26 @@ 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))) - } + 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(()) - } + /// 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_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_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 fetch_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_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 + } }