Compare commits
No commits in common. "ebbe3d82d6adcd64e4b216fd5aaeed6021484759" and "33566845307d05487d40a2307b970fb0acef24a7" have entirely different histories.
ebbe3d82d6
...
3356684530
15 changed files with 153 additions and 352 deletions
|
@ -1,5 +1,13 @@
|
||||||
|
mod multi_address;
|
||||||
mod peer;
|
mod peer;
|
||||||
|
|
||||||
|
pub use multi_address::{
|
||||||
|
ActiveModel as ActiveMultiAddressModel,
|
||||||
|
Column as MultiAddressColumn,
|
||||||
|
Model as MultiAddressModel,
|
||||||
|
Entity as MultiAddressEntity,
|
||||||
|
};
|
||||||
|
|
||||||
pub use peer::{
|
pub use peer::{
|
||||||
ActiveModel as ActivePeerModel,
|
ActiveModel as ActivePeerModel,
|
||||||
Column as PeerColumn,
|
Column as PeerColumn,
|
||||||
|
|
61
lazy-supplements-core/src/cache/entity/multi_address.rs
vendored
Normal file
61
lazy-supplements-core/src/cache/entity/multi_address.rs
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use chrono::Local;
|
||||||
|
use sea_orm::entity::{
|
||||||
|
*,
|
||||||
|
prelude::*
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||||
|
#[sea_orm(table_name = "node")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: u32,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub created_at: DateTimeUtc,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub updated_at: DateTimeUtc,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub synced_at: Option<DateTimeUtc>,
|
||||||
|
#[sea_orm(indexed)]
|
||||||
|
pub peer_id: String,
|
||||||
|
#[sea_orm(column_type = "Text")]
|
||||||
|
pub note: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
|
impl ActiveModel {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||||
|
Self{
|
||||||
|
created_at: Set(timestamp),
|
||||||
|
updated_at: Set(timestamp),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::global::get_or_init_test_cache_database;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use libp2p::identity;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn check_insert_node() {
|
||||||
|
let db = get_or_init_test_cache_database().await;
|
||||||
|
|
||||||
|
ActiveModel{
|
||||||
|
peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()),
|
||||||
|
note: Set("test note".to_owned()),
|
||||||
|
..ActiveModel::new()
|
||||||
|
}.insert(db).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
lazy-supplements-core/src/cache/entity/peer.rs
vendored
51
lazy-supplements-core/src/cache/entity/peer.rs
vendored
|
@ -1,17 +1,13 @@
|
||||||
use std::str::FromStr;
|
use chrono::Local;
|
||||||
|
use sea_orm::entity::{
|
||||||
use chrono::{Days, Local};
|
*,
|
||||||
use libp2p::{multiaddr, Multiaddr, PeerId};
|
prelude::*
|
||||||
use sea_orm::{entity::{
|
};
|
||||||
prelude::*, *
|
|
||||||
}, sea_query};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::data::value::{MultiaddrValue, PeerIdValue};
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
#[sea_orm(table_name = "node")]
|
||||||
#[sea_orm(table_name = "peer")]
|
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key)]
|
#[sea_orm(primary_key)]
|
||||||
pub id: u32,
|
pub id: u32,
|
||||||
|
@ -20,28 +16,20 @@ pub struct Model {
|
||||||
#[sea_orm(indexed)]
|
#[sea_orm(indexed)]
|
||||||
pub updated_at: DateTimeUtc,
|
pub updated_at: DateTimeUtc,
|
||||||
#[sea_orm(indexed)]
|
#[sea_orm(indexed)]
|
||||||
pub expires_at: DateTimeUtc,
|
pub peer_id: String,
|
||||||
#[sea_orm(indexed)]
|
|
||||||
pub peer_id: PeerIdValue,
|
|
||||||
#[sea_orm(indexed)]
|
|
||||||
pub address: MultiaddrValue,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
pub enum Relation {}
|
pub enum Relation {}
|
||||||
|
|
||||||
impl ActiveModelBehavior for ActiveModel {}
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
impl ActiveModel {
|
impl ActiveModel {
|
||||||
pub fn new(peer_id: PeerId, multiaddr: Multiaddr) -> Self {
|
pub fn new() -> Self {
|
||||||
let timestamp: DateTimeUtc = Local::now().to_utc();
|
let timestamp: DateTimeUtc = Local::now().to_utc();
|
||||||
Self{
|
Self{
|
||||||
peer_id: Set(PeerIdValue::from(peer_id)),
|
|
||||||
address: Set(MultiaddrValue::from(multiaddr)),
|
|
||||||
created_at: Set(timestamp),
|
created_at: Set(timestamp),
|
||||||
updated_at: Set(timestamp),
|
updated_at: Set(timestamp),
|
||||||
expires_at: Set(timestamp.checked_add_days(Days::new(30)).unwrap()),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,25 +37,20 @@ impl ActiveModel {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::net::Ipv4Addr;
|
use crate::global::get_or_init_test_cache_database;
|
||||||
|
|
||||||
use crate::{cache::entity::peer, global::get_or_init_test_cache_database};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use libp2p::{identity::{self, Keypair}, swarm::handler::multi};
|
use libp2p::identity;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn insert() {
|
async fn check_insert_node() {
|
||||||
let db = get_or_init_test_cache_database().await;
|
let db = get_or_init_test_cache_database().await;
|
||||||
let peer_id = Keypair::generate_ed25519().public().to_peer_id();
|
|
||||||
let multiaddr = Multiaddr::empty()
|
ActiveModel{
|
||||||
.with(Ipv4Addr::new(127,0,0,1).into())
|
peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()),
|
||||||
.with(multiaddr::Protocol::Tcp(0));
|
..ActiveModel::new()
|
||||||
let inserted: Model = ActiveModel::new(peer_id.clone(), multiaddr.clone())
|
}.insert(db).await.unwrap();
|
||||||
.insert(db).await.unwrap();
|
|
||||||
assert_eq!(PeerId::from(inserted.peer_id), peer_id);
|
|
||||||
assert_eq!(Multiaddr::from(inserted.address), multiaddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -9,16 +9,18 @@ pub struct Migration;
|
||||||
impl MigrationTrait for Migration {
|
impl MigrationTrait for Migration {
|
||||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
Peer::up(manager).await?;
|
Peer::up(manager).await?;
|
||||||
|
Address::up(manager).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
Peer::down(manager).await?;
|
Peer::down(manager).await?;
|
||||||
|
Address::down(manager).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden, DeriveMigrationName)]
|
#[derive(DeriveIden)]
|
||||||
enum Peer {
|
enum Peer {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
|
@ -26,14 +28,9 @@ enum Peer {
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
UpdatedAt,
|
UpdatedAt,
|
||||||
ExpiresAt,
|
ExpiresAt,
|
||||||
Address,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IDX_PEER_ADDRESS: &str = "idx_peer_address";
|
|
||||||
static IDX_PEER_PEER_ID: &str = "idx_peer_peer_id";
|
static IDX_PEER_PEER_ID: &str = "idx_peer_peer_id";
|
||||||
static IDX_PEER_CREATED_AT: &str = "idx_peer_created_at";
|
|
||||||
static IDX_PEER_UPDATED_AT: &str = "idx_peer_updated_at";
|
|
||||||
static IDX_PEER_EXPIRES_AT: &str = "idx_peer_expires_at";
|
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl TableMigration for Peer {
|
impl TableMigration for Peer {
|
||||||
|
@ -43,11 +40,10 @@ impl TableMigration for Peer {
|
||||||
.table(Self::Table)
|
.table(Self::Table)
|
||||||
.if_not_exists()
|
.if_not_exists()
|
||||||
.col(pk_auto(Self::Id))
|
.col(pk_auto(Self::Id))
|
||||||
.col(string_len(Self::PeerId, 255))
|
|
||||||
.col(timestamp(Self::CreatedAt))
|
.col(timestamp(Self::CreatedAt))
|
||||||
.col(timestamp(Self::UpdatedAt))
|
.col(timestamp(Self::UpdatedAt))
|
||||||
.col(timestamp(Self::ExpiresAt))
|
.col(timestamp(Self::ExpiresAt))
|
||||||
.col(text_uniq(Self::Address))
|
.col(string_len_uniq(Self::PeerId, 255))
|
||||||
.to_owned()
|
.to_owned()
|
||||||
).await?;
|
).await?;
|
||||||
manager.create_index(
|
manager.create_index(
|
||||||
|
@ -57,32 +53,53 @@ impl TableMigration for Peer {
|
||||||
.col(Self::PeerId)
|
.col(Self::PeerId)
|
||||||
.to_owned()
|
.to_owned()
|
||||||
).await?;
|
).await?;
|
||||||
manager.create_index(
|
Ok(())
|
||||||
Index::create()
|
}
|
||||||
.name(IDX_PEER_ADDRESS)
|
async fn down<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr>{
|
||||||
|
manager.drop_table(Table::drop().table(Self::Table).to_owned()).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(DeriveIden, DeriveMigrationName)]
|
||||||
|
enum Address {
|
||||||
|
Table,
|
||||||
|
Id,
|
||||||
|
PeerId,
|
||||||
|
CreatedAt,
|
||||||
|
UpdatedAt,
|
||||||
|
ExpiresAt,
|
||||||
|
MultiAddress,
|
||||||
|
}
|
||||||
|
|
||||||
|
static IDX_ADDRESS_MULTIADDRESS: &str = "idx_address_multiaddress";
|
||||||
|
static FK_ADDRESS_PEER: &str = "fk_address_peer";
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl TableMigration for Address {
|
||||||
|
async fn up<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> {
|
||||||
|
manager.create_table(
|
||||||
|
Table::create()
|
||||||
.table(Self::Table)
|
.table(Self::Table)
|
||||||
.col(Self::Address)
|
.if_not_exists()
|
||||||
|
.col(pk_auto(Self::Id))
|
||||||
|
.col(integer(Self::PeerId))
|
||||||
|
.col(timestamp(Self::CreatedAt))
|
||||||
|
.col(timestamp(Self::UpdatedAt))
|
||||||
|
.col(timestamp(Self::ExpiresAt))
|
||||||
|
.col(text_uniq(Self::MultiAddress))
|
||||||
|
.foreign_key(
|
||||||
|
ForeignKey::create()
|
||||||
|
.name(FK_ADDRESS_PEER)
|
||||||
|
.from(Self::Table, Self::PeerId)
|
||||||
|
.to(Peer::Table, Peer::Id)
|
||||||
|
)
|
||||||
.to_owned()
|
.to_owned()
|
||||||
).await?;
|
).await?;
|
||||||
manager.create_index(
|
manager.create_index(
|
||||||
Index::create()
|
Index::create()
|
||||||
.name(IDX_PEER_CREATED_AT)
|
.name(IDX_ADDRESS_MULTIADDRESS)
|
||||||
.table(Self::Table)
|
.table(Self::Table)
|
||||||
.col(Self::CreatedAt)
|
.col(Self::MultiAddress)
|
||||||
.to_owned()
|
|
||||||
).await?;
|
|
||||||
manager.create_index(
|
|
||||||
Index::create()
|
|
||||||
.name(IDX_PEER_UPDATED_AT)
|
|
||||||
.table(Self::Table)
|
|
||||||
.col(Self::UpdatedAt)
|
|
||||||
.to_owned()
|
|
||||||
).await?;
|
|
||||||
manager.create_index(
|
|
||||||
Index::create()
|
|
||||||
.name(IDX_PEER_EXPIRES_AT)
|
|
||||||
.table(Self::Table)
|
|
||||||
.col(Self::ExpiresAt)
|
|
||||||
.to_owned()
|
.to_owned()
|
||||||
).await?;
|
).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -2,9 +2,6 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
#[cfg(feature="desktop")]
|
#[cfg(feature="desktop")]
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
|
|
||||||
#[cfg(any(test, feature="test"))]
|
|
||||||
use tempfile::tempdir;
|
|
||||||
use crate::{config::{ConfigError, PartialConfig}};
|
use crate::{config::{ConfigError, PartialConfig}};
|
||||||
use libp2p::mdns::Config;
|
use libp2p::mdns::Config;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -33,9 +30,8 @@ impl StorageConfig {
|
||||||
#[cfg(any(test, feature="test"))]
|
#[cfg(any(test, feature="test"))]
|
||||||
impl TestDefault for StorageConfig {
|
impl TestDefault for StorageConfig {
|
||||||
fn test_default() -> Self {
|
fn test_default() -> Self {
|
||||||
|
let temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path().keep().unwrap();
|
||||||
let temp_dir = tempdir().unwrap().keep();
|
Self { data_directory: temp_path.clone(), cache_directory: temp_path }
|
||||||
Self { data_directory: temp_dir.clone(), cache_directory: temp_dir }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
mod trusted_peer;
|
mod node;
|
||||||
mod record_deletion;
|
mod record_deletion;
|
||||||
|
|
||||||
pub use trusted_peer::{
|
pub use node::{
|
||||||
ActiveModel as TrustedPeerActiveModel,
|
ActiveModel as NodeActiveModel,
|
||||||
Column as TrustedPeerColumn,
|
Column as NodeColumn,
|
||||||
Entity as TrustedPeerEntity,
|
Entity as NodeEntity,
|
||||||
Model as TrustedPeerModel,
|
Model as NodeModel,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use record_deletion::{
|
pub use record_deletion::{
|
||||||
|
|
|
@ -5,11 +5,9 @@ use sea_orm::entity::{
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::data::value::PeerIdValue;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||||
#[sea_orm(table_name = "trusted_peer")]
|
#[sea_orm(table_name = "node")]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key, auto_increment = false)]
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
|
@ -20,10 +18,9 @@ pub struct Model {
|
||||||
#[sea_orm(indexed)]
|
#[sea_orm(indexed)]
|
||||||
pub synced_at: Option<DateTimeUtc>,
|
pub synced_at: Option<DateTimeUtc>,
|
||||||
#[sea_orm(indexed)]
|
#[sea_orm(indexed)]
|
||||||
pub peer_id: PeerIdValue,
|
pub peer_id: String,
|
||||||
#[sea_orm(column_type = "Text")]
|
#[sea_orm(column_type = "Text")]
|
||||||
pub note: String,
|
pub note: String,
|
||||||
pub is_prefered: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
#[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]
|
||||||
|
@ -49,14 +46,14 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use libp2p::{identity, PeerId};
|
use libp2p::identity;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn check_insert_node() {
|
async fn check_insert_node() {
|
||||||
let db = get_or_init_test_data_database().await;
|
let db = get_or_init_test_data_database().await;
|
||||||
|
|
||||||
ActiveModel{
|
ActiveModel{
|
||||||
peer_id: Set(PeerIdValue::from(PeerId::random())),
|
peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()),
|
||||||
note: Set("test note".to_owned()),
|
note: Set("test note".to_owned()),
|
||||||
..ActiveModel::new()
|
..ActiveModel::new()
|
||||||
}.insert(db).await.unwrap();
|
}.insert(db).await.unwrap();
|
|
@ -8,20 +8,20 @@ pub struct Migration;
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl MigrationTrait for Migration {
|
impl MigrationTrait for Migration {
|
||||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
TrustedPeer::up(manager).await?;
|
Node::up(manager).await?;
|
||||||
RecordDeletion::up(manager).await?;
|
RecordDeletion::up(manager).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||||
TrustedPeer::down(manager).await?;
|
Node::down(manager).await?;
|
||||||
RecordDeletion::down(manager).await?;
|
RecordDeletion::down(manager).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(DeriveIden)]
|
#[derive(DeriveIden)]
|
||||||
enum TrustedPeer {
|
enum Node {
|
||||||
Table,
|
Table,
|
||||||
Id,
|
Id,
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
|
@ -29,11 +29,10 @@ enum TrustedPeer {
|
||||||
SyncedAt,
|
SyncedAt,
|
||||||
PeerId,
|
PeerId,
|
||||||
Note,
|
Note,
|
||||||
IsPrefered,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl TableMigration for TrustedPeer {
|
impl TableMigration for Node {
|
||||||
async fn up<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> {
|
async fn up<'a>(manager: &'a SchemaManager<'a>) -> Result<(), DbErr> {
|
||||||
manager.create_table(
|
manager.create_table(
|
||||||
Table::create()
|
Table::create()
|
||||||
|
@ -45,7 +44,6 @@ impl TableMigration for TrustedPeer {
|
||||||
.col(timestamp_null(Self::SyncedAt))
|
.col(timestamp_null(Self::SyncedAt))
|
||||||
.col(string_len(Self::PeerId, 255))
|
.col(string_len(Self::PeerId, 255))
|
||||||
.col(text(Self::Note))
|
.col(text(Self::Note))
|
||||||
.col(boolean(Self::IsPrefered))
|
|
||||||
.to_owned()
|
.to_owned()
|
||||||
).await?;
|
).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
pub mod entity;
|
pub mod entity;
|
||||||
pub mod migration;
|
pub mod migration;
|
||||||
pub mod syncable;
|
|
||||||
pub mod value;
|
|
|
@ -1,64 +0,0 @@
|
||||||
use sea_orm::{*, prelude::*, query::*};
|
|
||||||
|
|
||||||
pub trait SyncableModel: ModelTrait<Entity = Self::SyncableEntity> {
|
|
||||||
type SyncableEntity: SyncableEntity<SyncableModel = Self>;
|
|
||||||
fn get_updated_at(&self) -> DateTimeUtc;
|
|
||||||
fn get_uuid(&self) -> Uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SyncableEntity: EntityTrait<
|
|
||||||
Model = Self::SyncableModel,
|
|
||||||
ActiveModel = Self::SyncableActiveModel,
|
|
||||||
Column = Self::SyncableColumn,
|
|
||||||
>{
|
|
||||||
type SyncableModel: SyncableModel<SyncableEntity = Self> + FromQueryResult;
|
|
||||||
type SyncableActiveModel: SyncableActiveModel<SyncableEntity= Self>;
|
|
||||||
type SyncableColumn: SyncableColumn;
|
|
||||||
|
|
||||||
async fn get_updated_after(date: DateTimeUtc, db: &DatabaseConnection) -> Result<Vec<<Self as EntityTrait>::Model>, SyncableError> {
|
|
||||||
let result: Vec<Self::SyncableModel> = <Self as EntityTrait>::find()
|
|
||||||
.filter(Self::SyncableColumn::updated_at().gte(date))
|
|
||||||
.all(db)
|
|
||||||
.await.unwrap();
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
fn apply_updated(models: Vec<<Self as EntityTrait>::Model>, db: &DatabaseConnection) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SyncableActiveModel: ActiveModelTrait<Entity = Self::SyncableEntity> {
|
|
||||||
|
|
||||||
type SyncableEntity: SyncableEntity<SyncableActiveModel = Self>;
|
|
||||||
fn get_uuid(&self) -> Option<Uuid>;
|
|
||||||
fn get_updated_at(&self) -> Option<DateTimeUtc>;
|
|
||||||
fn try_merge(&mut self, other: <Self::SyncableEntity as SyncableEntity>::SyncableModel) -> Result<(), SyncableError> {
|
|
||||||
if self.get_uuid().ok_or(SyncableError::MissingField("uuid"))? != other.get_uuid() {
|
|
||||||
return Err(SyncableError::MismatchUuid)
|
|
||||||
}
|
|
||||||
if self.get_updated_at().ok_or(SyncableError::MissingField("updated_at"))? < other.get_updated_at() {
|
|
||||||
for column in <<<Self as ActiveModelTrait>::Entity as EntityTrait>::Column as Iterable>::iter() {
|
|
||||||
self.take(column).set_if_not_equals(other.get(column));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SyncableColumn: ColumnTrait {
|
|
||||||
fn is_uuid(&self) -> bool;
|
|
||||||
fn is_updated_at(&self) -> bool;
|
|
||||||
fn updated_at() -> Self;
|
|
||||||
fn should_not_sync(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
pub enum SyncableError {
|
|
||||||
#[error("Invalid UUID")]
|
|
||||||
MismatchUuid,
|
|
||||||
#[error("mandatory field {0} is missing")]
|
|
||||||
MissingField(&'static str),
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
mod multiaddr;
|
|
||||||
mod peer_id;
|
|
||||||
|
|
||||||
pub use multiaddr::MultiaddrValue;
|
|
||||||
pub use peer_id::PeerIdValue;
|
|
|
@ -1,68 +0,0 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use libp2p::Multiaddr;
|
|
||||||
use sea_orm::{sea_query::ValueTypeErr, DbErr};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
|
||||||
pub struct MultiaddrValue(Multiaddr);
|
|
||||||
|
|
||||||
impl From<Multiaddr> for MultiaddrValue {
|
|
||||||
fn from(source: Multiaddr) -> Self {
|
|
||||||
Self(source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<MultiaddrValue> for Multiaddr {
|
|
||||||
fn from(source: MultiaddrValue) -> Self {
|
|
||||||
source.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<MultiaddrValue> for sea_orm::Value {
|
|
||||||
fn from(value: MultiaddrValue) -> Self {
|
|
||||||
Self::from(value.0.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::TryGetable for MultiaddrValue {
|
|
||||||
fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I)
|
|
||||||
-> std::result::Result<Self, sea_orm::TryGetError> {
|
|
||||||
match <String as sea_orm::TryGetable>::try_get_by(res, idx){
|
|
||||||
Ok(x) => match Multiaddr::from_str(&x) {
|
|
||||||
Ok(y) => Ok(Self(y)),
|
|
||||||
Err(_) => Err(DbErr::Type("Multiaddr".to_string()).into()),
|
|
||||||
},
|
|
||||||
Err(x) => Err(x),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::sea_query::ValueType for MultiaddrValue {
|
|
||||||
fn try_from(v: sea_orm::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {
|
|
||||||
match <String as sea_orm::sea_query::ValueType>::try_from(v) {
|
|
||||||
Ok(x) => match Multiaddr::from_str(&x) {
|
|
||||||
Ok(y) => Ok(Self(y)),
|
|
||||||
Err(_) => Err(ValueTypeErr{}),
|
|
||||||
},
|
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn type_name() -> std::string::String {
|
|
||||||
stringify!(MultiaddrValue).to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn array_type() -> sea_orm::sea_query::ArrayType {
|
|
||||||
sea_orm::sea_query::ArrayType::String
|
|
||||||
}
|
|
||||||
|
|
||||||
fn column_type() -> sea_orm::sea_query::ColumnType {
|
|
||||||
sea_orm::sea_query::ColumnType::Text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::sea_query::Nullable for MultiaddrValue {
|
|
||||||
fn null() -> sea_orm::Value {
|
|
||||||
<String as sea_orm::sea_query::Nullable>::null()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use libp2p::PeerId;
|
|
||||||
use sea_orm::{sea_query::ValueTypeErr, DbErr};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::error::Error;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct PeerIdValue(PeerId);
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for PeerIdValue {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de> {
|
|
||||||
Self::from_str(&String::deserialize(deserializer)?).or(Err(<D::Error as serde::de::Error>::custom("fail to parse PeerId")))
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for PeerIdValue {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer {
|
|
||||||
serializer.serialize_str(&self.0.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for PeerIdValue{
|
|
||||||
type Err = libp2p::identity::ParseError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
Ok(Self(PeerId::from_str(s)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for PeerIdValue {
|
|
||||||
fn to_string(&self) -> String {
|
|
||||||
self.0.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PeerId> for PeerIdValue {
|
|
||||||
fn from(source: PeerId) -> Self {
|
|
||||||
Self(source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<PeerIdValue> for PeerId {
|
|
||||||
fn from(source: PeerIdValue) -> Self {
|
|
||||||
source.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PeerIdValue> for sea_orm::Value {
|
|
||||||
fn from(value: PeerIdValue) -> Self {
|
|
||||||
Self::from(value.0.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::TryGetable for PeerIdValue {
|
|
||||||
fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I)
|
|
||||||
-> std::result::Result<Self, sea_orm::TryGetError> {
|
|
||||||
match <String as sea_orm::TryGetable>::try_get_by(res, idx){
|
|
||||||
Ok(x) => match PeerId::from_str(&x) {
|
|
||||||
Ok(y) => Ok(Self(y)),
|
|
||||||
Err(_) => Err(DbErr::Type("PeerId".to_string()).into()),
|
|
||||||
},
|
|
||||||
Err(x) => Err(x),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::sea_query::ValueType for PeerIdValue {
|
|
||||||
fn try_from(v: sea_orm::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {
|
|
||||||
match <String as sea_orm::sea_query::ValueType>::try_from(v) {
|
|
||||||
Ok(x) => match PeerId::from_str(&x) {
|
|
||||||
Ok(y) => Ok(Self(y)),
|
|
||||||
Err(_) => Err(ValueTypeErr{}),
|
|
||||||
},
|
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn type_name() -> std::string::String {
|
|
||||||
stringify!(PeerIdValue).to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn array_type() -> sea_orm::sea_query::ArrayType {
|
|
||||||
sea_orm::sea_query::ArrayType::String
|
|
||||||
}
|
|
||||||
|
|
||||||
fn column_type() -> sea_orm::sea_query::ColumnType {
|
|
||||||
sea_orm::sea_query::ColumnType::Text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl sea_orm::sea_query::Nullable for PeerIdValue {
|
|
||||||
fn null() -> sea_orm::Value {
|
|
||||||
<String as sea_orm::sea_query::Nullable>::null()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::tests::{test_cbor_serialize_deserialize, test_toml_serialize_deserialize};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
|
||||||
struct PeerIdValueWrapper {
|
|
||||||
content: PeerIdValue
|
|
||||||
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn test_serialize_deserialize() {
|
|
||||||
let peer_id= PeerIdValueWrapper{content: PeerIdValue::from(PeerId::random())};
|
|
||||||
let x = toml::to_string(&peer_id).unwrap();
|
|
||||||
assert_eq!(peer_id.content, toml::from_str::<PeerIdValueWrapper>(&x).unwrap().content)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,8 +40,10 @@ impl Event {
|
||||||
match PeerEntity::find().filter(PeerColumn::PeerId.contains(&peer.0.to_string())).one(CACHE_DATABASE_CONNECTION.get()).await {
|
match PeerEntity::find().filter(PeerColumn::PeerId.contains(&peer.0.to_string())).one(CACHE_DATABASE_CONNECTION.get()).await {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
ActivePeerModel::new(peer.0.clone(), peer.1.clone())
|
ActivePeerModel{
|
||||||
.insert(CACHE_DATABASE_CONNECTION.get()).await;
|
peer_id: Set(peer.0.to_string()),
|
||||||
|
..ActivePeerModel::new()
|
||||||
|
}.insert(CACHE_DATABASE_CONNECTION.get()).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use std::{path::PathBuf, sync::LazyLock};
|
use std::{path::PathBuf, sync::LazyLock};
|
||||||
|
|
||||||
use sea_orm::{sea_query::{FromValueTuple, IntoValueTuple, ValueType}, ActiveModelBehavior, ActiveModelTrait, ColumnTrait, Condition, DatabaseConnection, EntityTrait, IntoActiveModel, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, Value};
|
|
||||||
use sea_orm::QueryFilter;
|
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use crate::{ config::PartialConfig, message::Message};
|
use crate::{ config::PartialConfig, message::Message};
|
||||||
|
|
||||||
|
@ -45,4 +43,4 @@ where T: DeserializeOwned + Serialize + PartialEq + std::fmt::Debug
|
||||||
let buf = toml::to_string(&src).unwrap();
|
let buf = toml::to_string(&src).unwrap();
|
||||||
let dst: T = toml::from_str(&buf).unwrap();
|
let dst: T = toml::from_str(&buf).unwrap();
|
||||||
assert_eq!(src, dst);
|
assert_eq!(src, dst);
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue