Compare commits

..

No commits in common. "83d5858a458f7273cd1f9a835e36f8c5001cc546" and "9337b98ad3c4b10a89ed2db9cc336e36230ae75c" have entirely different histories.

8 changed files with 57 additions and 113 deletions

View File

@ -1,2 +0,0 @@
[ ] Add RelationshipKind to Notes passed out
[ ] Add KastenKind to Backreferences passed out

View File

@ -6,8 +6,7 @@ mod structs;
pub use crate::errors::NoteStoreError;
pub use crate::store::NoteStore;
pub use crate::structs::{Note, NoteKind, NoteRelationship, KastenRelationship};
pub use crate::structs::{Note, NoteKind};
#[cfg(test)]
mod tests {
@ -82,22 +81,22 @@ mod tests {
// <- 2 <- 4
let note1 = make_new_note("1");
let note1_id = storagepool.add_note(&note1, &root.id, Some(0)).await;
let note1_id = storagepool.add_note(&note1, &root.id, 0).await;
assert!(note1_id.is_ok(), "{:?}", note1_id);
let note1_id = note1_id.unwrap();
let note2 = make_new_note("2");
let note2_id = storagepool.add_note(&note2, &root.id, Some(0)).await;
let note2_id = storagepool.add_note(&note2, &root.id, 0).await;
assert!(note2_id.is_ok(), "{:?}", note2_id);
let note2_id = note2_id.unwrap();
let note3 = make_new_note("3");
let note3_id = storagepool.add_note(&note3, &note1_id, Some(0)).await;
let note3_id = storagepool.add_note(&note3, &note1_id, 0).await;
assert!(note3_id.is_ok(), "{:?}", note3_id);
let _note3_id = note3_id.unwrap();
let note4 = make_new_note("4");
let note4_id = storagepool.add_note(&note4, &note2_id, Some(0)).await;
let note4_id = storagepool.add_note(&note4, &note2_id, 0).await;
assert!(note4_id.is_ok(), "{:?}", note4_id);
let _note4_id = note4_id.unwrap();

View File

@ -16,7 +16,7 @@ CREATE TABLE notes (
CREATE INDEX note_ids ON notes (id);
CREATE TABLE favorites (
id TEXT NOT NULL UNIQUE,
id TEXT NOT NULL,
location INTEGER NOT NULL,
FOREIGN KEY (id) REFERENCES notes (id) ON DELETE CASCADE
);
@ -32,9 +32,7 @@ CREATE TABLE note_relationships (
kind TEXT NOT NULL,
-- If either note disappears, we want all the edges to disappear as well.
FOREIGN KEY (note_id) REFERENCES notes (id) ON DELETE CASCADE,
FOREIGN KEY (parent_id) REFERENCES notes (id) ON DELETE CASCADE,
UNIQUE (note_id, parent_id),
CHECK (note_id <> parent_id)
FOREIGN KEY (parent_id) REFERENCES notes (id) ON DELETE CASCADE
);
-- This table represents the graph of data relating notes to kastens.
@ -45,8 +43,6 @@ CREATE TABLE note_kasten_relationships (
kind TEXT NOT NULL,
-- If either note disappears, we want all the edges to disappear as well.
FOREIGN KEY (note_id) REFERENCES notes (id) ON DELETE CASCADE,
FOREIGN KEY (kasten_id) REFERENCES notes (id) ON DELETE CASCADE,
UNIQUE (note_id, kasten_id),
CHECK (note_id <> kasten_id)
FOREIGN KEY (kasten_id) REFERENCES notes (id) ON DELETE CASCADE
);

View File

@ -137,7 +137,7 @@ impl NoteStore {
Ok((vec![Note::from(zettlekasten)], vec![]))
}
pub async fn add_note(&self, note: &NewNote, parent_id: &str, location: Option<i64>) -> NoteResult<String> {
pub async fn add_note(&self, note: &NewNote, parent_id: &str, location: i64) -> NoteResult<String> {
self.insert_note(
note,
&ParentId(parent_id.to_string()),
@ -229,16 +229,14 @@ impl NoteStore {
&self,
note: &NewNote,
parent_id: &ParentId,
location: Option<i64>,
location: i64,
kind: RelationshipKind,
) -> NoteResult<String> {
if let Some(location) = location {
if location < 0 {
return Err(NoteStoreError::InvalidNoteStructure(
"Add note: A negative location is not valid.".to_string(),
"Add note: A negative position is not valid.".to_string(),
));
}
}
if parent_id.is_empty() {
return Err(NoteStoreError::InvalidNoteStructure(
@ -261,14 +259,10 @@ impl NoteStore {
let references = build_references(&note.content);
let mut tx = self.0.begin().await?;
let location = {
let max_child = assert_max_child_location_for_note(&mut tx, parent_id).await? + 1;
if let Some(location) = location {
cmp::min(max_child, location)
} else {
max_child
}
};
let location = cmp::min(
assert_max_child_location_for_note(&mut tx, parent_id).await? + 1,
location,
);
let note_id = NoteId(note.id.clone());
insert_note(&mut tx, &note).await?;

View File

@ -198,7 +198,7 @@ pub(crate) struct NoteRelationshipRow {
}
#[derive(Clone, Debug)]
pub struct NoteRelationship {
pub(crate) struct NoteRelationship {
pub parent_id: String,
pub note_id: String,
pub location: i64,
@ -224,7 +224,7 @@ pub(crate) struct KastenRelationshipRow {
}
#[derive(Clone, Debug)]
pub struct KastenRelationship {
pub(crate) struct KastenRelationship {
pub note_id: String,
pub kasten_id: String,
pub kind: KastenRelationshipKind,

View File

@ -13,41 +13,28 @@ mod make_tree;
mod structs;
use nm_store::{NoteStore, NoteStoreError, NewNote};
use crate::structs::{Page, Note};
use crate::make_tree::{make_note_tree, make_backreferences};
use crate::structs::Page;
use crate::make_tree::make_tree;
#[derive(Debug)]
pub struct Notesmachine(pub(crate) NoteStore);
type Result<T> = core::result::Result<T, NoteStoreError>;
pub fn make_page(foundtree: &Note, backreferences: Vec<Vec<Note>>) -> Page {
Page {
slug: foundtree.id,
title: foundtree.content,
creation_date: foundtree.creation_date,
updated_date: foundtree.updated_date,
lastview_date: foundtree.lastview_date,
deleted_date: foundtree.deleted_date,
notes: foundtree.children,
backreferences: backreferences
}
}
impl Notesmachine {
pub async fn new(url: &str) -> Result<Self> {
let notestore = NoteStore::new(url).await?;
Ok(Notesmachine(notestore))
}
pub async fn get_page_via_slug(&self, slug: &str) -> Result<Page> {
let (rawtree, rawbackreferences) = self.0.get_kasten_by_slug(slug).await?;
Ok(make_page(&make_note_tree(&rawtree), make_backreferences(&rawbackreferences)))
pub async fn get_box_via_slug(&self, slug: &str) -> Result<Page> {
let (rawpage, rawnotes) = self.0.get_page_by_slug(slug).await?;
Ok(make_tree(&rawpage, &rawnotes))
}
pub async fn get_page(&self, title: &str) -> Result<Page> {
let (rawtree, rawbackreferences) = self.0.get_kasten_by_title(title).await?;
Ok(make_page(&make_note_tree(&rawtree), make_backreferences(&rawbackreferences)))
pub async fn get_box(&self, title: &str) -> Result<Page> {
let (rawpage, rawnotes) = self.0.get_page_by_title(title).await?;
Ok(make_tree(&rawpage, &rawnotes))
}
// TODO:

View File

@ -1,12 +1,8 @@
use crate::structs::{Note, Page};
use nm_store::NoteKind;
use nm_store::{RawNote, RawPage};
fn make_note_tree_from(rawnotes: &[nm_store::Note], root_id: &str) -> Note {
let the_note = {
let foundroots: Vec<&nm_store::Note> = rawnotes.iter().filter(|note| note.id == root_id).collect();
debug_assert!(foundroots.len() == 1);
foundroots.iter().next().unwrap().clone()
};
fn make_note_tree(rawnotes: &[RawNote], root: i64) -> Note {
let the_note = rawnotes.iter().find(|note| note.id == root).unwrap().clone();
// The special case of the root node must be filtered out here to
// prevent the first pass from smashing the stack in an infinite
@ -15,61 +11,35 @@ fn make_note_tree_from(rawnotes: &[nm_store::Note], root_id: &str) -> Note {
// are faster.
let mut children = rawnotes
.iter()
.filter(|note| note.parent_id.is_some() && note.parent_id.unwrap() == root_id && note.id != the_note.id)
.map(|note| make_note_tree_from(rawnotes, &note.id))
.filter(|note| note.parent_id == root && note.id != root)
.map(|note| make_note_tree(rawnotes, note.id))
.collect::<Vec<Note>>();
children.sort_unstable_by(|a, b| a.location.cmp(&b.location));
children.sort_unstable_by(|a, b| a.position.cmp(&b.position));
Note {
id: the_note.id,
parent_id: the_note.parent_id,
uuid: the_note.uuid,
parent_uuid: the_note.parent_uuid,
content: the_note.content,
kind: the_note.kind.to_string(),
location: the_note.location,
notetype: the_note.notetype,
position: the_note.position,
creation_date: the_note.creation_date,
updated_date: the_note.updated_date,
lastview_date: the_note.updated_date,
deleted_date: the_note.deleted_date,
children: children,
}
}
pub(crate) fn make_note_tree(rawnotes: &[nm_store::Note]) -> Note {
let the_root = {
let foundroots: Vec<&nm_store::Note> = rawnotes.iter().filter(|note| note.kind == NoteKind::Kasten).collect();
debug_assert!(foundroots.len() == 1);
foundroots.iter().next().unwrap().clone()
};
make_note_tree_from(&rawnotes, &the_root.id)
}
fn add_child(rawnotes: &[nm_store::Note], acc: &mut Vec<Note>, note_id: &str) -> Vec<Note> {
let child = rawnotes
.iter()
.find(|note| note.parent_id.is_some() && note.parent_id.unwrap() == note_id);
if let Some(c) = child {
acc.push(Note {
id: c.id,
parent_id: Some(note_id.to_string()),
content: c.content,
kind: c.kind.to_string(),
location: c.location,
creation_date: c.creation_date,
updated_date: c.updated_date,
lastview_date: c.updated_date,
deleted_date: c.deleted_date,
children: vec![],
});
add_child(rawnotes, acc, &c.id)
} else {
acc.to_vec()
}
}
pub(crate) fn make_backreferences(rawnotes: &[nm_store::Note]) -> Vec<Vec<Note>> {
rawnotes
.iter()
.filter(|note| note.parent_id.is_none() && note.kind == NoteKind::Kasten)
.map(|root| add_child(rawnotes, &mut Vec::<Note>::new(), &root.id))
.collect()
pub(crate) fn make_tree(rawpage: &RawPage, rawnotes: &[RawNote]) -> Page {
let the_page = rawpage.clone();
Page {
slug: the_page.slug,
title: the_page.title,
creation_date: the_page.creation_date,
updated_date: the_page.updated_date,
lastview_date: the_page.updated_date,
deleted_date: the_page.deleted_date,
root_note: make_note_tree(rawnotes, rawpage.note_id),
}
}

View File

@ -3,11 +3,11 @@ use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Note {
pub id: String,
pub parent_id: Option<String>,
pub uuid: String,
pub parent_uuid: String,
pub content: String,
pub location: i64,
pub kind: String,
pub position: i64,
pub notetype: String,
pub creation_date: DateTime<Utc>,
pub updated_date: DateTime<Utc>,
pub lastview_date: DateTime<Utc>,
@ -15,6 +15,7 @@ pub struct Note {
pub children: Vec<Note>,
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Page {
pub slug: String,
pub title: String,
@ -22,6 +23,5 @@ pub struct Page {
pub updated_date: DateTime<Utc>,
pub lastview_date: DateTime<Utc>,
pub deleted_date: Option<DateTime<Utc>>,
pub notes: Vec<Note>,
pub backreferences: Vec<Vec<Note>>,
pub root_note: Note,
}