[wip] store api overhaul

This commit is contained in:
Riley Apeldoorn 2024-04-23 00:52:39 +02:00
parent 523e9a7479
commit c26b6cdb04
5 changed files with 1070 additions and 25 deletions

View file

@ -30,7 +30,7 @@ pub fn create_post(db: &Store, author: Key, content: impl ToString) -> store::Re
content: Some(content.to_string()), content: Some(content.to_string()),
summary: None, summary: None,
})?; })?;
tx.insert_arrow((author, key), AuthorOf)?; tx.insert_arrow::<AuthorOf>((author, key))?;
Ok(key) Ok(key)
}) })
} }
@ -131,7 +131,7 @@ pub mod fr {
pub fn create(db: &Store, requester: Key, target: Key) -> store::Result<()> { pub fn create(db: &Store, requester: Key, target: Key) -> store::Result<()> {
db.transaction(|tx| { db.transaction(|tx| {
tx.insert_arrow((requester, target), FollowRequested)?; tx.insert_arrow::<FollowRequested>((requester, target))?;
OK OK
}) })
} }
@ -139,7 +139,7 @@ pub mod fr {
pub fn accept(db: &Store, requester: Key, target: Key) -> store::Result<()> { pub fn accept(db: &Store, requester: Key, target: Key) -> store::Result<()> {
db.transaction(|tx| { db.transaction(|tx| {
tx.remove_arrow::<FollowRequested>((requester, target))?; tx.remove_arrow::<FollowRequested>((requester, target))?;
tx.insert_arrow((requester, target), Follows)?; tx.insert_arrow::<Follows>((requester, target))?;
OK OK
}) })
} }

View file

@ -44,7 +44,8 @@ pub mod multi {
} }
/// A directed edge between two vertices. /// A directed edge between two vertices.
pub trait Arrow: Encode + Decode { pub trait Arrow {
type Label: Encode + Decode = ();
const SPACE: (Space, Space); const SPACE: (Space, Space);
} }
@ -55,7 +56,6 @@ pub enum Direction {
} }
/// The node this arrow points away from is the "author" of the node the arrow points to. /// The node this arrow points away from is the "author" of the node the arrow points to.
#[derive(Encode, Decode)]
pub struct AuthorOf; pub struct AuthorOf;
impl Arrow for AuthorOf { impl Arrow for AuthorOf {
@ -63,7 +63,6 @@ impl Arrow for AuthorOf {
} }
/// The origin of this arrow has follow requested the target. /// The origin of this arrow has follow requested the target.
#[derive(Encode, Decode)]
pub struct FollowRequested; pub struct FollowRequested;
impl Arrow for FollowRequested { impl Arrow for FollowRequested {
@ -71,7 +70,6 @@ impl Arrow for FollowRequested {
} }
/// The origin "follows" the target. /// The origin "follows" the target.
#[derive(Encode, Decode)]
pub struct Follows; pub struct Follows;
impl Arrow for Follows { impl Arrow for Follows {

File diff suppressed because it is too large Load diff

View file

@ -203,7 +203,7 @@ impl Transaction<'_> {
impl Transaction<'_> { impl Transaction<'_> {
/// Find an arrow of type `A` with the given `tail` and `head`. /// Find an arrow of type `A` with the given `tail` and `head`.
pub fn lookup_arrow<A>(&self, (tail, head): (Key, Key)) -> Result<Option<A>> pub fn lookup_arrow<A>(&self, (tail, head): (Key, Key)) -> Result<Option<A::Label>>
where where
A: Arrow, A: Arrow,
{ {
@ -214,14 +214,14 @@ impl Transaction<'_> {
Err(err) => Err(err), Err(err) => Err(err),
} }
} }
/// Create a new arrow of type `A` and associate the label with it. /// Create a simple arrow of type `A`.
/// ///
/// # Errors /// # Errors
/// ///
/// - `Error::Undefined` if either key is not registered /// - `Error::Undefined` if either key is not registered
pub fn insert_arrow<A>(&self, (tail, head): (Key, Key), label: A) -> Result<()> pub fn insert_arrow<A>(&self, (tail, head): (Key, Key)) -> Result<()>
where where
A: Arrow, A: Arrow<Label = ()>,
{ {
if !self.is_registered(tail)? { if !self.is_registered(tail)? {
return Err(Error::Undefined { key: tail }); return Err(Error::Undefined { key: tail });
@ -230,9 +230,8 @@ impl Transaction<'_> {
return Err(Error::Undefined { key: head }); return Err(Error::Undefined { key: head });
} }
let (l, r) = A::SPACE; let (l, r) = A::SPACE;
let label = encode(label)?; self.with(l).set(tail.fuse(head), b"")?;
self.with(l).set(tail.fuse(head), &label)?; self.with(r).set(head.fuse(tail), b"")?;
self.with(r).set(head.fuse(tail), &label)?;
OK OK
} }
/// Delete an arrow from the data store. /// Delete an arrow from the data store.
@ -252,21 +251,27 @@ impl Transaction<'_> {
self.with(A::SPACE.0).has(tail.fuse(head)) self.with(A::SPACE.0).has(tail.fuse(head))
} }
/// Get all arrows of type `A` "pointing at" `key`. /// Get all arrows of type `A` "pointing at" `key`.
pub fn list_incoming<A>(&self, key: impl Keylike) -> impl Iterator<Item = Result<(Key, A)>> + '_ pub fn list_incoming<A>(
&self,
key: impl Keylike,
) -> impl Iterator<Item = Result<(Key, A::Label)>> + '_
where where
A: Arrow, A: Arrow,
{ {
self.list_arrows_where(Direction::Incoming, key) self.list_arrows_where::<A>(Direction::Incoming, key)
} }
/// Get all arrows of type `A` "pointing away from" `key`. /// Get all arrows of type `A` "pointing away from" `key`.
pub fn list_outgoing<A>(&self, key: impl Keylike) -> impl Iterator<Item = Result<(Key, A)>> + '_ pub fn list_outgoing<A>(
&self,
key: impl Keylike,
) -> impl Iterator<Item = Result<(Key, A::Label)>> + '_
where where
A: Arrow, A: Arrow,
{ {
self.list_arrows_where(Direction::Outgoing, key) self.list_arrows_where::<A>(Direction::Outgoing, key)
} }
/// Get all arrows of type `A`. /// Get all arrows of type `A`.
pub fn list_arrows<A>(&self) -> impl Iterator<Item = Result<(Key, A, Key)>> + '_ pub fn list_arrows<A>(&self) -> impl Iterator<Item = Result<(Key, A::Label, Key)>> + '_
where where
A: Arrow, A: Arrow,
{ {
@ -280,7 +285,7 @@ impl Transaction<'_> {
&self, &self,
direction: Direction, direction: Direction,
key: impl Keylike, key: impl Keylike,
) -> impl Iterator<Item = Result<(Key, A)>> + '_ ) -> impl Iterator<Item = Result<(Key, A::Label)>> + '_
where where
A: Arrow, A: Arrow,
{ {

View file

@ -34,7 +34,7 @@ fn with_test_arrow(f: impl Fn(Key, Key, &Transaction<'_>, usize) -> Result<()>)
tx.create_vertex(target, TEST_TAG)?; tx.create_vertex(target, TEST_TAG)?;
tx.create_vertex(origin, TEST_TAG)?; tx.create_vertex(origin, TEST_TAG)?;
tx.insert_arrow((origin, target), TestArrow)?; tx.insert_arrow::<TestArrow>((origin, target))?;
let l: Vec<String> = tx let l: Vec<String> = tx
.with("test-arrow/l") .with("test-arrow/l")
@ -126,7 +126,7 @@ fn fanout() -> Result<()> {
tx.create_vertex(origin, TEST_TAG)?; tx.create_vertex(origin, TEST_TAG)?;
for t in targets { for t in targets {
tx.create_vertex(t, TEST_TAG)?; tx.create_vertex(t, TEST_TAG)?;
tx.insert_arrow((origin, t), TestArrow)?; tx.insert_arrow::<TestArrow>((origin, t))?;
} }
let oo: Vec<_> = tx.list_outgoing::<TestArrow>(origin).keys().try_collect()?; let oo: Vec<_> = tx.list_outgoing::<TestArrow>(origin).keys().try_collect()?;
@ -154,7 +154,7 @@ fn fanin() -> Result<()> {
tx.create_vertex(target, TEST_TAG)?; tx.create_vertex(target, TEST_TAG)?;
for o in origins { for o in origins {
tx.create_vertex(o, TEST_TAG)?; tx.create_vertex(o, TEST_TAG)?;
tx.insert_arrow((o, target), TestArrow)?; tx.insert_arrow::<TestArrow>((o, target))?;
} }
let ti: Vec<_> = tx.list_incoming::<TestArrow>(target).keys().try_collect()?; let ti: Vec<_> = tx.list_incoming::<TestArrow>(target).keys().try_collect()?;
@ -185,7 +185,7 @@ fn distinct_many_to_many() -> Result<()> {
for o in origins { for o in origins {
tx.create_vertex(o, TEST_TAG)?; tx.create_vertex(o, TEST_TAG)?;
for t in targets { for t in targets {
tx.insert_arrow((o, t), TestArrow)?; tx.insert_arrow::<TestArrow>((o, t))?;
} }
} }