DOC Rustfmt works.

TEST Added test to reassure myself that Arc copies of the storage pool
     are working as planned.
This commit is contained in:
Elf M. Sternberg 2020-09-29 08:08:30 -07:00
parent 71dfc479d8
commit 884822a230
3 changed files with 64 additions and 51 deletions

15
server/nm-store/Makefile Normal file
View File

@ -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

View File

@ -2,36 +2,43 @@ mod errors;
mod store; mod store;
mod structs; mod structs;
pub use crate::store::NoteStore;
pub use crate::errors::NoteStoreError; pub use crate::errors::NoteStoreError;
pub use crate::store::NoteStore;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use tokio; use tokio;
async fn fresh_inmemory_database() -> NoteStore { async fn fresh_inmemory_database() -> NoteStore {
let storagepool = NoteStore::new("sqlite://:memory:").await; let storagepool = NoteStore::new("sqlite://:memory:").await;
assert!(storagepool.is_ok()); assert!(storagepool.is_ok());
let storagepool = storagepool.unwrap(); let storagepool = storagepool.unwrap();
assert!(storagepool.reset_database().await.is_ok()); assert!(storagepool.reset_database().await.is_ok());
storagepool storagepool
} }
#[tokio::test(threaded_scheduler)] #[tokio::test(threaded_scheduler)]
async fn fetching_unfound_page_works() { async fn fetching_unfound_page_works() {
let storagepool = fresh_inmemory_database().await; let storagepool = fresh_inmemory_database().await;
let unfoundpage = storagepool.fetch_page("nonexistent-page").await; let unfoundpage = storagepool.fetch_page("nonexistent-page").await;
assert!(unfoundpage.is_err()); assert!(unfoundpage.is_err());
} }
#[tokio::test(threaded_scheduler)] #[tokio::test(threaded_scheduler)]
async fn fetching_unfound_note_works() { async fn fetching_unfound_note_works() {
let storagepool = fresh_inmemory_database().await; let storagepool = fresh_inmemory_database().await;
let unfoundnote = storagepool.fetch_note("nonexistent-note").await; let unfoundnote = storagepool.fetch_note("nonexistent-note").await;
assert!(unfoundnote.is_err()); 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());
}
} }

View File

@ -1,8 +1,8 @@
use crate::errors::NoteStoreError;
use crate::structs::{RawNote, RawPage};
use sqlx; use sqlx;
use sqlx::sqlite::SqlitePool; use sqlx::sqlite::SqlitePool;
use std::sync::Arc; use std::sync::Arc;
use crate::errors::NoteStoreError;
use crate::structs::{RawPage, RawNote};
/// A handle to our Sqlite database. /// A handle to our Sqlite database.
#[derive(Clone)] #[derive(Clone)]
@ -12,35 +12,26 @@ type NoteResult<T> = core::result::Result<T, NoteStoreError>;
type SqlResult<T> = sqlx::Result<T>; type SqlResult<T> = sqlx::Result<T>;
impl NoteStore { impl NoteStore {
pub async fn new(url: &str) -> NoteResult<Self> { pub async fn new(url: &str) -> NoteResult<Self> {
let pool = SqlitePool::connect(url).await?; let pool = SqlitePool::connect(url).await?;
Ok(NoteStore(Arc::new(pool))) Ok(NoteStore(Arc::new(pool)))
} }
/// This will erase all the data in the database. Only use this /// This will erase all the data in the database. Only use this
/// if you're sure that's what you want. /// if you're sure that's what you want.
pub async fn reset_database(&self) -> NoteResult<()> { pub async fn reset_database(&self) -> NoteResult<()> {
let initialize_sql = include_str!("sql/initialize_database.sql"); let initialize_sql = include_str!("sql/initialize_database.sql");
sqlx::query(initialize_sql) sqlx::query(initialize_sql).execute(&*self.0).await?;
.execute(&*self.0) Ok(())
.await?; }
Ok(())
}
pub async fn fetch_page(&self, id: &str) -> SqlResult<RawPage> { pub async fn fetch_page(&self, id: &str) -> SqlResult<RawPage> {
let select_one_page_sql = include_str!("sql/select_one_page.sql"); let select_one_page_sql = include_str!("sql/select_one_page.sql");
sqlx::query_as(select_one_page_sql) sqlx::query_as(select_one_page_sql).bind(&id).fetch_one(&*self.0).await
.bind(&id) }
.fetch_one(&*self.0)
.await
}
pub async fn fetch_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 fetch_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
}
} }