Added peer families to StateDB
. Relates to #5
This commit is contained in:
parent
4b00cef7e7
commit
a8a8d2968b
7 changed files with 193 additions and 8 deletions
20
ubisync-lib/src/types/family.rs
Normal file
20
ubisync-lib/src/types/family.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{FamilyId, PeerId};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub struct Family {
|
||||
pub id: FamilyId,
|
||||
pub name: Option<String>,
|
||||
pub members: Vec<PeerId>,
|
||||
}
|
||||
|
||||
impl Family {
|
||||
pub fn new(id: FamilyId, name: Option<String>, members: Vec<PeerId>) -> Self {
|
||||
Family {
|
||||
id,
|
||||
name,
|
||||
members,
|
||||
}
|
||||
}
|
||||
}
|
11
ubisync-lib/src/types/family_id.rs
Normal file
11
ubisync-lib/src/types/family_id.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default, Ord, PartialOrd, PartialEq, Eq, Hash)]
|
||||
pub struct FamilyId(Uuid);
|
||||
|
||||
impl FamilyId {
|
||||
pub fn new() -> Self {
|
||||
FamilyId { 0: Uuid::new_v4() }
|
||||
}
|
||||
}
|
|
@ -10,6 +10,12 @@ pub use element_id::ElementId;
|
|||
mod element;
|
||||
pub use element::Element;
|
||||
|
||||
mod family_id;
|
||||
pub use family_id::FamilyId;
|
||||
|
||||
mod family;
|
||||
pub use family::Family;
|
||||
|
||||
mod message_id;
|
||||
pub use message_id::MessageId;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::bail;
|
|||
use i2p::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct PeerId {
|
||||
i2p_addr: I2pSocketAddr,
|
||||
}
|
||||
|
|
|
@ -2,18 +2,20 @@ use bonsaidb::core::schema::Schema;
|
|||
|
||||
use apps::DbApp;
|
||||
use elements::DbElement;
|
||||
use peer_families::DbPeerFamily;
|
||||
use peers::DbPeer;
|
||||
use pot_memberships::DbPotMembership;
|
||||
use pots::DbPot;
|
||||
|
||||
mod apps;
|
||||
mod elements;
|
||||
mod peer_families;
|
||||
mod peers;
|
||||
mod pot_memberships;
|
||||
mod pots;
|
||||
|
||||
#[derive(Schema, Debug)]
|
||||
#[schema(name = "ubisync", collections = [DbElement, DbPotMembership, DbApp, DbPot, DbPeer])]
|
||||
#[schema(name = "ubisync", collections = [DbElement, DbPotMembership, DbApp, DbPot, DbPeer, DbPeerFamily])]
|
||||
pub struct UbisyncSchema;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
144
ubisync/src/state/database/collections/peer_families.rs
Normal file
144
ubisync/src/state/database/collections/peer_families.rs
Normal file
|
@ -0,0 +1,144 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use anyhow::{anyhow, Error};
|
||||
use bonsaidb::core::schema::{Collection, SerializedCollection};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ubisync_lib::types::{Family, FamilyId, PeerId};
|
||||
|
||||
use crate::state::database::{as_key::AsKey, StateDB};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Collection, PartialEq, Clone)]
|
||||
#[collection(name = "peer-families", views = [])]
|
||||
pub(super) struct DbPeerFamily {
|
||||
#[natural_id]
|
||||
pub(super) id: AsKey<FamilyId>,
|
||||
pub(super) name: Option<String>,
|
||||
pub(super) members: HashSet<PeerId>,
|
||||
}
|
||||
|
||||
impl From<DbPeerFamily> for Family {
|
||||
fn from(value: DbPeerFamily) -> Self {
|
||||
Family {
|
||||
id: (*value.id).clone(),
|
||||
name: value.name,
|
||||
members: value.members.iter().map(|p| p.clone()).collect_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StateDB {
|
||||
pub fn add_peer_family(
|
||||
&self,
|
||||
id: FamilyId,
|
||||
name: Option<String>,
|
||||
initial_members: Vec<PeerId>,
|
||||
) -> anyhow::Result<()> {
|
||||
DbPeerFamily::push(
|
||||
DbPeerFamily {
|
||||
id: AsKey::new(id),
|
||||
name,
|
||||
members: HashSet::from_iter(initial_members),
|
||||
},
|
||||
&self.db,
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
pub fn add_peer_to_family(&self, peer: PeerId, family: FamilyId) -> anyhow::Result<()> {
|
||||
DbPeerFamily::get(&AsKey::new(family), &self.db)
|
||||
.map_err(|e| anyhow!(e))?
|
||||
.ok_or(Error::msg("Could not find peer family"))?
|
||||
.modify(&self.db, |doc| {
|
||||
doc.contents.members.insert(peer.clone());
|
||||
})
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
pub fn set_peer_family_name(
|
||||
&self,
|
||||
family: FamilyId,
|
||||
name: Option<String>,
|
||||
) -> anyhow::Result<()> {
|
||||
DbPeerFamily::get(&AsKey::new(family), &self.db)
|
||||
.map_err(|e| anyhow!(e))?
|
||||
.ok_or(Error::msg("Could not find peer family"))?
|
||||
.modify(&self.db, |doc| {
|
||||
doc.contents.name = name.clone();
|
||||
})
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
pub fn get_peer_family(&self, id: FamilyId) -> anyhow::Result<Option<Family>> {
|
||||
DbPeerFamily::get(&AsKey::new(id), &self.db)
|
||||
.map(|doc_opt| doc_opt.map(|doc| doc.contents.into()))
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ubisync_lib::types::{Family, FamilyId, PeerId};
|
||||
|
||||
use crate::state::database::StateDB;
|
||||
|
||||
#[test]
|
||||
fn add_get() {
|
||||
let db = StateDB::init(None);
|
||||
let family_id = FamilyId::new();
|
||||
let peer_id = PeerId::default();
|
||||
|
||||
db.add_peer_family(
|
||||
family_id.clone(),
|
||||
Some("My family name".to_string()),
|
||||
vec![peer_id.clone()],
|
||||
)
|
||||
.unwrap();
|
||||
let retrieved_family = db.get_peer_family(family_id.clone()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
retrieved_family,
|
||||
Some(Family::new(
|
||||
family_id,
|
||||
Some("My family name".to_string()),
|
||||
vec![peer_id]
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_name() {
|
||||
let db = StateDB::init(None);
|
||||
let family_id = FamilyId::new();
|
||||
let peer_id = PeerId::default();
|
||||
|
||||
db.add_peer_family(
|
||||
family_id.clone(),
|
||||
Some("My family name".to_string()),
|
||||
vec![peer_id.clone()],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
db.get_peer_family(family_id.clone()).unwrap(),
|
||||
Some(Family::new(
|
||||
family_id.clone(),
|
||||
Some("My family name".to_string()),
|
||||
vec![peer_id.clone()]
|
||||
))
|
||||
);
|
||||
|
||||
db.set_peer_family_name(family_id.clone(), Some("New family name".to_string()))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
db.get_peer_family(family_id.clone()).unwrap(),
|
||||
Some(Family::new(
|
||||
family_id,
|
||||
Some("New family name".to_string()),
|
||||
vec![peer_id]
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,7 @@ use anyhow::{anyhow, Error};
|
|||
use bonsaidb::core::schema::{Collection, SerializedCollection};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ubisync_lib::{
|
||||
peer::Peer,
|
||||
types::{self, PeerId},
|
||||
};
|
||||
use ubisync_lib::{peer::Peer, types::PeerId};
|
||||
|
||||
use crate::state::database::{as_key::AsKey, StateDB};
|
||||
|
||||
|
@ -13,7 +10,7 @@ use crate::state::database::{as_key::AsKey, StateDB};
|
|||
#[collection(name = "peers", views = [])]
|
||||
pub(super) struct DbPeer {
|
||||
#[natural_id]
|
||||
pub(super) id: AsKey<types::PeerId>,
|
||||
pub(super) id: AsKey<PeerId>,
|
||||
pub(super) name: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -45,7 +42,12 @@ impl StateDB {
|
|||
pub fn get_all_peers(&self) -> anyhow::Result<Vec<Peer>> {
|
||||
DbPeer::all(&self.db)
|
||||
.query()
|
||||
.map(|peers| peers.iter().map(|p| p.contents.clone().into()).collect_vec())
|
||||
.map(|peers| {
|
||||
peers
|
||||
.iter()
|
||||
.map(|p| p.contents.clone().into())
|
||||
.collect_vec()
|
||||
})
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue