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;
|
mod element;
|
||||||
pub use element::Element;
|
pub use element::Element;
|
||||||
|
|
||||||
|
mod family_id;
|
||||||
|
pub use family_id::FamilyId;
|
||||||
|
|
||||||
|
mod family;
|
||||||
|
pub use family::Family;
|
||||||
|
|
||||||
mod message_id;
|
mod message_id;
|
||||||
pub use message_id::MessageId;
|
pub use message_id::MessageId;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::bail;
|
||||||
use i2p::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
|
use i2p::net::{I2pAddr, I2pSocketAddr, ToI2pSocketAddrs};
|
||||||
use serde::{Deserialize, Serialize};
|
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 {
|
pub struct PeerId {
|
||||||
i2p_addr: I2pSocketAddr,
|
i2p_addr: I2pSocketAddr,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,20 @@ use bonsaidb::core::schema::Schema;
|
||||||
|
|
||||||
use apps::DbApp;
|
use apps::DbApp;
|
||||||
use elements::DbElement;
|
use elements::DbElement;
|
||||||
|
use peer_families::DbPeerFamily;
|
||||||
use peers::DbPeer;
|
use peers::DbPeer;
|
||||||
use pot_memberships::DbPotMembership;
|
use pot_memberships::DbPotMembership;
|
||||||
use pots::DbPot;
|
use pots::DbPot;
|
||||||
|
|
||||||
mod apps;
|
mod apps;
|
||||||
mod elements;
|
mod elements;
|
||||||
|
mod peer_families;
|
||||||
mod peers;
|
mod peers;
|
||||||
mod pot_memberships;
|
mod pot_memberships;
|
||||||
mod pots;
|
mod pots;
|
||||||
|
|
||||||
#[derive(Schema, Debug)]
|
#[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;
|
pub struct UbisyncSchema;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[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 bonsaidb::core::schema::{Collection, SerializedCollection};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ubisync_lib::{
|
use ubisync_lib::{peer::Peer, types::PeerId};
|
||||||
peer::Peer,
|
|
||||||
types::{self, PeerId},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::state::database::{as_key::AsKey, StateDB};
|
use crate::state::database::{as_key::AsKey, StateDB};
|
||||||
|
|
||||||
|
@ -13,7 +10,7 @@ use crate::state::database::{as_key::AsKey, StateDB};
|
||||||
#[collection(name = "peers", views = [])]
|
#[collection(name = "peers", views = [])]
|
||||||
pub(super) struct DbPeer {
|
pub(super) struct DbPeer {
|
||||||
#[natural_id]
|
#[natural_id]
|
||||||
pub(super) id: AsKey<types::PeerId>,
|
pub(super) id: AsKey<PeerId>,
|
||||||
pub(super) name: Option<String>,
|
pub(super) name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +42,12 @@ impl StateDB {
|
||||||
pub fn get_all_peers(&self) -> anyhow::Result<Vec<Peer>> {
|
pub fn get_all_peers(&self) -> anyhow::Result<Vec<Peer>> {
|
||||||
DbPeer::all(&self.db)
|
DbPeer::all(&self.db)
|
||||||
.query()
|
.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))
|
.map_err(|e| anyhow!(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue