FEAT: Can save a new page. Automagically includes its root note.
This commit is contained in:
parent
6bc8b0e911
commit
75809d821d
|
@ -11,6 +11,7 @@ readme = "./README.org"
|
|||
|
||||
|
||||
[dependencies]
|
||||
friendly_id = "0.3.0"
|
||||
thiserror = "1.0.20"
|
||||
tokio = { version = "0.2.22", features = ["rt-threaded", "blocking"] }
|
||||
serde = { version = "1.0.116", features = ["derive"] }
|
||||
|
|
|
@ -12,23 +12,24 @@ mod tests {
|
|||
|
||||
async fn fresh_inmemory_database() -> NoteStore {
|
||||
let storagepool = NoteStore::new("sqlite://:memory:").await;
|
||||
assert!(storagepool.is_ok());
|
||||
assert!(storagepool.is_ok(), "{:?}", storagepool);
|
||||
let storagepool = storagepool.unwrap();
|
||||
assert!(storagepool.reset_database().await.is_ok());
|
||||
let reset = storagepool.reset_database().await;
|
||||
assert!(reset.is_ok(), "{:?}", reset);
|
||||
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;
|
||||
let unfoundpage = storagepool.fetch_raw_page("nonexistent-page").await;
|
||||
assert!(unfoundpage.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test(threaded_scheduler)]
|
||||
async fn fetching_unfound_note_works() {
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let unfoundnote = storagepool.fetch_note("nonexistent-note").await;
|
||||
let unfoundnote = storagepool.fetch_raw_note("nonexistent-note").await;
|
||||
assert!(unfoundnote.is_err());
|
||||
}
|
||||
|
||||
|
@ -36,9 +37,9 @@ mod tests {
|
|||
async fn cloning_storagepool_is_ok() {
|
||||
let storagepool = fresh_inmemory_database().await;
|
||||
let storagepool2 = storagepool.clone();
|
||||
let unfoundnote = storagepool2.fetch_note("nonexistent-note").await;
|
||||
let unfoundnote = storagepool2.fetch_raw_note("nonexistent-note").await;
|
||||
assert!(unfoundnote.is_err());
|
||||
let unfoundnote = storagepool.fetch_note("nonexistent-note").await;
|
||||
let unfoundnote = storagepool.fetch_raw_note("nonexistent-note").await;
|
||||
assert!(unfoundnote.is_err());
|
||||
}
|
||||
|
||||
|
@ -46,16 +47,27 @@ mod tests {
|
|||
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(), format!("note is not ok: {:?}", note_id));
|
||||
assert!(note_id.is_ok(), "{:?}", note_id);
|
||||
let note_id = note_id.unwrap();
|
||||
assert!(note_id > 0);
|
||||
|
||||
let foundnote = storagepool.fetch_note("noteid").await;
|
||||
assert!(foundnote.is_ok(), format!("foundnote is not ok: {:?}", foundnote));
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
INSERT INTO pages (
|
||||
slug,
|
||||
title,
|
||||
note_id,
|
||||
creation_date,
|
||||
updated_date,
|
||||
lastview_date)
|
||||
VALUES (?, ?, ?, ?, ?, ?);
|
|
@ -1 +1 @@
|
|||
SELECT id, title, slug, note_id FROM pages WHERE slug=?;
|
||||
SELECT id, title, slug, note_id, creation_date, updated_date, lastview_date, deleted_date FROM pages WHERE slug=?;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
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)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NoteStore(Arc<SqlitePool>);
|
||||
|
||||
type NoteResult<T> = core::result::Result<T, NoteStoreError>;
|
||||
|
@ -26,12 +27,12 @@ impl NoteStore {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn fetch_page(&self, id: &str) -> SqlResult<RawPage> {
|
||||
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_note(&self, id: &str) -> SqlResult<RawNote> {
|
||||
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
|
||||
}
|
||||
|
@ -43,10 +44,40 @@ impl NoteStore {
|
|||
.bind(&id)
|
||||
.bind(&content)
|
||||
.bind(¬etype)
|
||||
.bind(&now)
|
||||
.bind(&now)
|
||||
.bind(&now)
|
||||
.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<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");
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue