From 33566845307d05487d40a2307b970fb0acef24a7 Mon Sep 17 00:00:00 2001 From: fluo10 Date: Sun, 22 Jun 2025 11:29:44 +0900 Subject: [PATCH] Add TestDefault trait --- lazy-supplements-core/src/cache/entity/mod.rs | 6 +- .../src/cache/entity/multi_address.rs | 5 +- .../src/cache/entity/peer.rs | 5 +- lazy-supplements-core/src/config/storage.rs | 24 ++-- lazy-supplements-core/src/data/entity/node.rs | 5 +- .../src/data/entity/record_deletion.rs | 5 +- lazy-supplements-core/src/global/config.rs | 17 ++- .../src/global/database_connection.rs | 40 ++++-- lazy-supplements-core/src/global/mod.rs | 72 +++++------ lazy-supplements-core/src/global/peers.rs | 13 +- lazy-supplements-core/src/p2p/mod.rs | 22 ++-- lazy-supplements-core/src/tests.rs | 8 ++ .../src/config/desktop.rs | 77 ------------ lazy-supplements-desktop/src/config/unix.rs | 2 +- lazy-supplements-desktop/src/global.rs | 114 +++++++++++++++++- 15 files changed, 241 insertions(+), 174 deletions(-) delete mode 100644 lazy-supplements-desktop/src/config/desktop.rs diff --git a/lazy-supplements-core/src/cache/entity/mod.rs b/lazy-supplements-core/src/cache/entity/mod.rs index a091d9a..a75f9bf 100644 --- a/lazy-supplements-core/src/cache/entity/mod.rs +++ b/lazy-supplements-core/src/cache/entity/mod.rs @@ -2,13 +2,15 @@ mod multi_address; mod peer; pub use multi_address::{ - ActiveModel as MultiAddressActiveModel, + ActiveModel as ActiveMultiAddressModel, + Column as MultiAddressColumn, Model as MultiAddressModel, Entity as MultiAddressEntity, }; pub use peer::{ - ActiveModel as PeerActiveModel, + ActiveModel as ActivePeerModel, + Column as PeerColumn, Model as PeerModel, Entity as PeerEntity, }; \ No newline at end of file diff --git a/lazy-supplements-core/src/cache/entity/multi_address.rs b/lazy-supplements-core/src/cache/entity/multi_address.rs index d4ac871..8eff6d6 100644 --- a/lazy-supplements-core/src/cache/entity/multi_address.rs +++ b/lazy-supplements-core/src/cache/entity/multi_address.rs @@ -41,14 +41,15 @@ impl ActiveModel { #[cfg(test)] mod tests { + use crate::global::get_or_init_test_cache_database; + use super::*; use libp2p::identity; - use crate::global::GLOBAL; #[tokio::test] async fn check_insert_node() { - let db = crate::global::get_or_init_temporary_main_database().await; + let db = get_or_init_test_cache_database().await; ActiveModel{ peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()), diff --git a/lazy-supplements-core/src/cache/entity/peer.rs b/lazy-supplements-core/src/cache/entity/peer.rs index 22ff686..cd3aeee 100644 --- a/lazy-supplements-core/src/cache/entity/peer.rs +++ b/lazy-supplements-core/src/cache/entity/peer.rs @@ -37,14 +37,15 @@ impl ActiveModel { #[cfg(test)] mod tests { + use crate::global::get_or_init_test_cache_database; + use super::*; use libp2p::identity; - use crate::global::GLOBAL; #[tokio::test] async fn check_insert_node() { - let db = crate::global::get_or_init_temporary_main_database().await; + let db = get_or_init_test_cache_database().await; ActiveModel{ peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()), diff --git a/lazy-supplements-core/src/config/storage.rs b/lazy-supplements-core/src/config/storage.rs index 64041d7..b3cbebe 100644 --- a/lazy-supplements-core/src/config/storage.rs +++ b/lazy-supplements-core/src/config/storage.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; #[cfg(feature="desktop")] use clap::Args; -use crate::config::{ConfigError, PartialConfig}; +use crate::{config::{ConfigError, PartialConfig}}; use libp2p::mdns::Config; use serde::{Deserialize, Serialize}; @@ -10,14 +10,7 @@ static DATA_DATABASE_NAME: &str = "data.sqlite"; static CACHE_DATABASE_NAME: &str = "cache.sqlite"; #[cfg(any(test, feature="test"))] -static TEST_DATA_DATABASE_PATH: std::sync::LazyLock = std::sync::LazyLock::new(|| { - let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path(); - temp_path.disable_cleanup(true); - println!("{}", temp_path.as_os_str().to_str().unwrap()); - temp_path -}); - - +use crate::tests::{GlobalTestDefault, TestDefault}; #[derive(Debug)] pub struct StorageConfig { @@ -26,11 +19,6 @@ pub struct StorageConfig { } impl StorageConfig { - #[cfg(any(test, feature="test"))] - pub fn new_test() -> Self { - let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path().keep().unwrap(); - Self { data_directory: temp_path.clone(), cache_directory: temp_path } - } pub fn get_data_database_path(&self) -> PathBuf{ self.data_directory.join(DATA_DATABASE_NAME) } @@ -39,6 +27,14 @@ impl StorageConfig { } } +#[cfg(any(test, feature="test"))] +impl TestDefault for StorageConfig { + fn test_default() -> Self { + let temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path().keep().unwrap(); + Self { data_directory: temp_path.clone(), cache_directory: temp_path } + } +} + impl TryFrom for StorageConfig { type Error = ConfigError; diff --git a/lazy-supplements-core/src/data/entity/node.rs b/lazy-supplements-core/src/data/entity/node.rs index 34a20c8..d932c8e 100644 --- a/lazy-supplements-core/src/data/entity/node.rs +++ b/lazy-supplements-core/src/data/entity/node.rs @@ -42,14 +42,15 @@ impl ActiveModel { #[cfg(test)] mod tests { + use crate::global::get_or_init_test_data_database; + use super::*; use libp2p::identity; - use crate::global::GLOBAL; #[tokio::test] async fn check_insert_node() { - let db = crate::global::get_or_init_temporary_main_database().await; + let db = get_or_init_test_data_database().await; ActiveModel{ peer_id: Set(identity::Keypair::generate_ed25519().public().to_peer_id().to_string()), diff --git a/lazy-supplements-core/src/data/entity/record_deletion.rs b/lazy-supplements-core/src/data/entity/record_deletion.rs index 3454a49..5084f44 100644 --- a/lazy-supplements-core/src/data/entity/record_deletion.rs +++ b/lazy-supplements-core/src/data/entity/record_deletion.rs @@ -35,14 +35,15 @@ impl ActiveModel { #[cfg(test)] mod tests { + use crate::global::get_or_init_test_data_database; + use super::*; use uuid::{Timestamp, Uuid}; - use crate::global::get_or_init_temporary_main_database; #[tokio::test] async fn check_insert_record_deletion() { - let db = get_or_init_temporary_main_database().await; + let db = get_or_init_test_data_database().await; assert!(ActiveModel{ table_name: Set("test_table".to_string()), diff --git a/lazy-supplements-core/src/global/config.rs b/lazy-supplements-core/src/global/config.rs index e27c402..4cf5916 100644 --- a/lazy-supplements-core/src/global/config.rs +++ b/lazy-supplements-core/src/global/config.rs @@ -1,6 +1,15 @@ -use crate::{config::StorageConfig, error::Error, global::SimpleGlobal}; -use tokio::sync::OnceCell; -use uuid::fmt::Simple; +use crate::{config::{P2pConfig, StorageConfig}, error::Error, global::GlobalConstant}; -pub static STORAGE_CONFIG: SimpleGlobal = SimpleGlobal::const_new(); +pub static STORAGE_CONFIG: GlobalConstant = GlobalConstant::const_new(stringify!(STORAGE_CONFIG)); +pub static P2P_CONFIG: GlobalConstant = GlobalConstant::const_new(stringify!(P2P_CONFIG)); +#[cfg(test)] +mod tests { + use crate::global::{config::P2P_CONFIG, STORAGE_CONFIG}; + + #[test] + fn test_global_constant_names() { + assert_eq!(STORAGE_CONFIG.name, stringify!(STORAGE_CONFIG)); + assert_eq!(P2P_CONFIG.name, stringify!(P2P_CONFIG)); + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/database_connection.rs b/lazy-supplements-core/src/global/database_connection.rs index 902bf41..6ee4a37 100644 --- a/lazy-supplements-core/src/global/database_connection.rs +++ b/lazy-supplements-core/src/global/database_connection.rs @@ -5,35 +5,51 @@ use sea_orm_migration::MigratorTrait; use crate::error::Error; use tokio::sync::OnceCell; -static DATA_DATABASE_CONNECTION: GlobalDatabaseConnection = GlobalDatabaseConnection::const_new(); -static CACHE_DATABASE_CONNECTION: GlobalDatabaseConnection = GlobalDatabaseConnection::const_new(); +pub static DATA_DATABASE_CONNECTION: GlobalDatabaseConnection = GlobalDatabaseConnection::const_new(stringify!(DATA_DATABASE_CONNECTION)); +pub static CACHE_DATABASE_CONNECTION: GlobalDatabaseConnection = GlobalDatabaseConnection::const_new(stringify!(CACHE_DATABASE_CONNECTION)); -struct GlobalDatabaseConnection { +pub struct GlobalDatabaseConnection { + name: &'static str, inner: OnceCell } impl GlobalDatabaseConnection { - pub const fn const_new() -> Self { + pub const fn const_new(name: &'static str) -> Self { Self { + name: name, inner: OnceCell::const_new() } } - pub fn get(&'static self) -> Option<&'static DatabaseConnection> { - self.inner.get() + pub fn get(&'static self) -> &'static DatabaseConnection { + self.inner.get().expect(&format!("{} is uninitialized!", self.name)) } - pub fn get_and_unwrap(&'static self) -> &'static DatabaseConnection { - self.get().expect(&format!("{} is uninitialized!", &stringify!(self))) - } - pub async fn get_or_try_init(&'static self, path: T, _: U) -> Result<&'static DatabaseConnection, Error> + pub async fn get_or_init(&'static self, path: T, _: U) -> &'static DatabaseConnection where T: AsRef, U: MigratorTrait { let url = "sqlite://".to_string() + path.as_ref().to_str().unwrap() + "?mode=rwc"; - Ok(self.inner.get_or_try_init(|| async { + self.inner.get_or_try_init(|| async { let db = Database::connect(&url).await?; U::up(&db, None).await?; Ok::(db) - }).await?) + }).await.expect(&format!("Fail to initialize {}!", self.name)) } } + +#[cfg(test)] +pub use tests::*; + + +#[cfg(test)] +mod tests { + use super::*; + use crate::{cache::migration::CacheMigrator, data::migration::DataMigrator, global::STORAGE_CONFIG, tests::GlobalTestDefault}; + + pub async fn get_or_init_test_data_database() -> &'static DatabaseConnection{ + DATA_DATABASE_CONNECTION.get_or_init(STORAGE_CONFIG.get_or_init_test_default().await.get_data_database_path(), DataMigrator).await + } + pub async fn get_or_init_test_cache_database() -> &'static DatabaseConnection{ + CACHE_DATABASE_CONNECTION.get_or_init(STORAGE_CONFIG.get_or_init_test_default().await.get_cache_database_path(), CacheMigrator).await + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/mod.rs b/lazy-supplements-core/src/global/mod.rs index 7fb5c3c..7cff42b 100644 --- a/lazy-supplements-core/src/global/mod.rs +++ b/lazy-supplements-core/src/global/mod.rs @@ -1,14 +1,16 @@ use std::{any::type_name, collections::HashMap, net::{IpAddr, Ipv4Addr}, path::{Path, PathBuf}, sync::LazyLock}; -use crate::{config::{P2pConfig, PartialP2pConfig, StorageConfig}, error::Error}; +use crate::{config::{P2pConfig, PartialP2pConfig, StorageConfig}, error::Error }; +#[cfg(any(test, feature="test"))] +use crate::tests::{GlobalTestDefault, TestDefault}; use futures::StreamExt; use libp2p::{swarm::SwarmEvent, Multiaddr, PeerId}; use sea_orm::{prelude::*, Database}; use sea_orm_migration::MigratorTrait; -use tokio::sync::{OnceCell, RwLock}; +use tokio::sync::{OnceCell, RwLock, RwLockReadGuard, RwLockWriteGuard}; mod peers; -pub use peers::GlobalPeers; +pub use peers::PEERS; mod config; pub use config::STORAGE_CONFIG; mod database_connection; @@ -37,13 +39,17 @@ fn uninitialized_message(var: T) -> String { format!("{} is uninitialized!", &stringify!(var)) } -struct SimpleGlobal { +pub struct GlobalConstant { + pub name: &'static str, inner: OnceCell } -impl SimpleGlobal { - pub const fn const_new() -> Self { - Self{inner: OnceCell::const_new()} +impl GlobalConstant { + pub const fn const_new(name: &'static str ) -> Self { + Self{ + name: name, + inner: OnceCell::const_new() + } } pub async fn get_or_init(&'static self, source: T) -> &'static T { self.inner.get_or_init(|| async { @@ -58,46 +64,40 @@ impl SimpleGlobal { } } +#[cfg(any(test, feature="test"))] +impl GlobalTestDefault for GlobalConstant +where + T: TestDefault + 'static +{ + async fn get_or_init_test_default(&'static self) -> &'static T { + self.get_or_init(T::test_default()).await + } +} + struct GlobalRwLock { + pub name: &'static str, inner: OnceCell> } impl GlobalRwLock { - pub const fn const_new() -> Self { - Self{inner: OnceCell::const_new()} + pub const fn const_new(name: &'static str) -> Self { + Self{ + name: name, + inner: OnceCell::const_new() + } } - async fn write(&'static self) -> tokio::sync::RwLockWriteGuard<'_ ,T> { - self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).write().await + pub fn get(&'static self) -> &'static RwLock { + self.inner.get().expect(&format!("{} is uninitialized", self.name)) } - async fn read(&'static self) -> RwLockReadGuard<'_, T> { - self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).read().await - + pub async fn write(&'static self) -> RwLockWriteGuard<'_ ,T> { + self.get().write().await + } + pub async fn read(&'static self) -> RwLockReadGuard<'_, T> { + self.get().read().await } -} - -#[cfg(test)] -pub struct TestGlobal { - pub storage_config: &'static StorageConfig, - pub data_database_connection: &'static DatabaseConnection, - pub cache_database_connection: &'static DatabaseConnection, } #[cfg(test)] mod tests { - use crate::{cache::migration::CacheMigrator, data::migration::DataMigrator}; - use super::*; - static TEST_DATA_DIRECTORY: LazyLock = todo!(); - static TEST_DATA_DATABASE_PATH: LazyLock = todo!(); - static TEST_CACHE_DIRECTORY: LazyLock = todo!(); - static TEST_CACHE_DATABASE_PATH: LazyLock = todo!(); - static TEST_STORAGE_CONFIG: LazyLock = todo!(); - - pub async fn get_or_try_init_test() -> TestGlobal { - TestGlobal { - storage_config: get_or_init_storage_config(StorageConfig{data_directory: TEST_DATA_DIRECTORY.clone(), cache_directory: TEST_CACHE_DIRECTORY.clone()}).await, - data_database_connection: get_or_try_init_data_database_connection(&*TEST_DATA_DATABASE_PATH, DataMigrator ).await.unwrap(), - cache_database_connection: get_or_try_init_cache_database_connection(&*TEST_CACHE_DATABASE_PATH, CacheMigrator).await.unwrap(), - } - } } diff --git a/lazy-supplements-core/src/global/peers.rs b/lazy-supplements-core/src/global/peers.rs index 7affc74..b08f3a2 100644 --- a/lazy-supplements-core/src/global/peers.rs +++ b/lazy-supplements-core/src/global/peers.rs @@ -5,14 +5,7 @@ use tokio::sync::{OnceCell, RwLock, RwLockReadGuard}; use crate::cache::entity::PeerModel; -static UNINITIALIZED_MESSAGE: &str = "Global peer set uninitialized!"; -pub trait GlobalPeers { - fn get_peers_once_cell(&'static self) -> &OnceCell>>; - async fn write_peers(&'static self) -> tokio::sync::RwLockWriteGuard<'_ ,HashSet> { - self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).write().await - } - async fn read_peers(&'static self) -> RwLockReadGuard<'_, HashSet> { - self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).read().await +use super::GlobalRwLock; + +pub static PEERS: GlobalRwLock> = GlobalRwLock::const_new(stringify!(PEERS)); - } -} \ No newline at end of file diff --git a/lazy-supplements-core/src/p2p/mod.rs b/lazy-supplements-core/src/p2p/mod.rs index af42f06..24bccac 100644 --- a/lazy-supplements-core/src/p2p/mod.rs +++ b/lazy-supplements-core/src/p2p/mod.rs @@ -1,6 +1,7 @@ use libp2p::{ identity::Keypair, mdns, ping, swarm}; +use sea_orm::{ActiveModelTrait, ActiveValue::Set, ColumnTrait, EntityTrait, QueryFilter}; -use crate::{error::Error, global::GlobalPeers}; +use crate::{cache::entity::{ActivePeerModel, PeerColumn, PeerEntity}, error::Error, global::{CACHE_DATABASE_CONNECTION, PEERS}}; #[derive(swarm::NetworkBehaviour)] #[behaviour(to_swarm = "Event")] @@ -29,20 +30,23 @@ pub enum Event { } impl Event { - pub async fn run(self, global: &T) - where - T: GlobalPeers + pub async fn run(&self) { match self { Self::Mdns(x) => { match x { mdns::Event::Discovered(e) => { - for peer in e { - global.write_peers().await; - peers.insert(peer.0, peer.1); + for peer in e.iter() { + match PeerEntity::find().filter(PeerColumn::PeerId.contains(&peer.0.to_string())).one(CACHE_DATABASE_CONNECTION.get()).await { + Ok(_) => {} + Err(_) => { + ActivePeerModel{ + peer_id: Set(peer.0.to_string()), + ..ActivePeerModel::new() + }.insert(CACHE_DATABASE_CONNECTION.get()).await; + } + } } - let peers = global.read_peers().await; - println!("Peers: {peers:?}"); }, _ => {}, } diff --git a/lazy-supplements-core/src/tests.rs b/lazy-supplements-core/src/tests.rs index 9f76e44..e8dd1e5 100644 --- a/lazy-supplements-core/src/tests.rs +++ b/lazy-supplements-core/src/tests.rs @@ -20,6 +20,14 @@ pub static TEST_DATABASE_PATH: std::sync::LazyLock = std::sync::LazyLoc TEST_DIR_PATH.join("lazy-supplements.sqlite") }); +pub trait TestDefault { + fn test_default() -> Self; +} + +pub trait GlobalTestDefault { + async fn get_or_init_test_default(&'static self) -> &'static T; +} + pub fn test_cbor_serialize_deserialize(src: T) where T: DeserializeOwned + Serialize + PartialEq + std::fmt::Debug { diff --git a/lazy-supplements-desktop/src/config/desktop.rs b/lazy-supplements-desktop/src/config/desktop.rs deleted file mode 100644 index 8d065ba..0000000 --- a/lazy-supplements-desktop/src/config/desktop.rs +++ /dev/null @@ -1,77 +0,0 @@ -use std::path::PathBuf; - -use clap::Args; -use lazy_supplements_core::config::{ConfigError, PartialConfig}; -use libp2p::mdns::Config; -use serde::{Deserialize, Serialize}; - -pub struct DesktopConfig { - pub data_directory: PathBuf, - pub data_database: PathBuf, - pub cache_directory: PathBuf, - pub cache_database: PathBuf, -} - -impl TryFrom for DesktopConfig { - type Error = ConfigError; - - fn try_from(value: PartialDesktopConfig) -> Result { - Ok(Self { - data_directory: value.data_directory.ok_or(ConfigError::MissingConfig("data_directory".to_string()))?, - data_database: value.data_database.ok_or(ConfigError::MissingConfig("data_database".to_string()))?, - cache_directory: value.cache_directory.ok_or(ConfigError::MissingConfig("cache_directory".to_string()))?, - cache_database: value.cache_database.ok_or(ConfigError::MissingConfig("cache_database".to_string()))?, - }) - } -} - -#[derive(Args, Clone, Debug, Deserialize, Serialize)] -pub struct PartialDesktopConfig { - #[arg(long)] - pub data_directory: Option, - #[arg(long)] - pub data_database: Option, - #[arg(long)] - pub cache_directory: Option, - #[arg(long)] - pub cache_database: Option, -} - -impl From for PartialDesktopConfig { - fn from(config: DesktopConfig) -> PartialDesktopConfig { - Self { - data_database: Some(config.data_database), - data_directory: Some(config.data_directory), - cache_database: Some(config.cache_database), - cache_directory: Some(config.cache_directory), - } - } -} - -impl PartialConfig for PartialDesktopConfig { - fn empty() -> Self { - Self{ - data_database: None, - cache_database: None, - data_directory: None, - cache_directory: None, - } - } - fn default() -> Self { - todo!() - } - fn merge(&mut self, other: Self) { - if let Some(x) = other.data_directory { - self.data_directory = Some(x); - } - if let Some(x) = other.data_database { - self.data_database = Some(x); - } - if let Some(x) = other.cache_directory { - self.cache_directory = Some(x); - } - if let Some(x) = other.cache_database { - self.cache_database = Some(x); - } - } -} \ No newline at end of file diff --git a/lazy-supplements-desktop/src/config/unix.rs b/lazy-supplements-desktop/src/config/unix.rs index 3ff4af3..35dcafe 100644 --- a/lazy-supplements-desktop/src/config/unix.rs +++ b/lazy-supplements-desktop/src/config/unix.rs @@ -33,7 +33,7 @@ impl From for PartialUnixConfig { } } -impl PartialConfig for PartialUnixConfig { +impl PartialConfig for PartialUnixConfig { fn empty() -> Self { Self { socket_path: None } } diff --git a/lazy-supplements-desktop/src/global.rs b/lazy-supplements-desktop/src/global.rs index b5024b5..d5c1269 100644 --- a/lazy-supplements-desktop/src/global.rs +++ b/lazy-supplements-desktop/src/global.rs @@ -35,4 +35,116 @@ pub static DEFAULT_PARTIAL_CORE_CONFIG: LazyLock = LazyLock:: listen_ips: Some(DEFAULT_LISTEN_IPS.to_vec()), port: Some(0), } -}); \ No newline at end of file +}); + +pub struct Global { + pub p2p_config: OnceCell, + pub main_database: OnceCell, + pub cache_database: OnceCell, + pub peers: OnceCell>>, +} + +impl Global { + pub fn get_p2p_config(&self) -> Option<&P2pConfig> { + self.p2p_config.get() + } + pub async fn get_or_init_p2p_config(&self, config: P2pConfig) -> &P2pConfig { + self.p2p_config.get_or_init(|| async {config}).await + } + pub async fn get_or_init_peers(&self) -> &RwLock> { + self.peers.get_or_init(|| async { + RwLock::new(HashMap::new()) + }).await + } + pub async fn read_peers(&self) -> tokio::sync::RwLockReadGuard<'_, HashMap>{ + self.get_or_init_peers().await.read().await + } + pub async fn write_peers(&self) -> tokio::sync::RwLockWriteGuard<'_, HashMap>{ + self.get_or_init_peers().await.write().await + } + pub async fn launch_swarm(&self) -> Result<(), Error> { + let mut swarm = self.get_p2p_config().unwrap().clone().try_into_swarm().await?; + loop{ + let swarm_event = swarm.select_next_some().await; + tokio::spawn(async move{ + match swarm_event { + SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), + SwarmEvent::Behaviour(event) => { + println!("{event:?}"); + event.run().await; + }, + _ => {} + } + }); + } + } +} + +impl GlobalDatabase for Global { + fn get_main_database(&self) -> Option<&DatabaseConnection> { + self.main_database.get() + } + async fn get_or_try_init_main_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> + where + T: AsRef, + U: MigratorTrait, + { + let url = "sqlite://".to_string() + path.as_ref().to_str().unwrap() + "?mode=rwc"; + + Ok(self.main_database.get_or_try_init(|| async { + let db = Database::connect(&url).await?; + U::up(&db, None).await?; + Ok::(db) + }).await?) + } + fn get_cache_database(&self) -> Option<&DatabaseConnection> { + self.cache_database.get() + } + async fn get_or_try_init_cache_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> + where + T: AsRef, + U: MigratorTrait, + { + let url = "sqlite://".to_string() + path.as_ref().to_str().unwrap() + "?mode=rwc"; + + Ok(self.cache_database.get_or_try_init(|| async { + let db = Database::connect(&url).await?; + U::up(&db, None).await?; + Ok::(db) + }).await?) + } + +} + + +#[cfg(test)] +pub use tests::{get_or_init_temporary_main_database, get_or_init_temporary_cache_database}; +#[cfg(test)] +pub mod tests { + use std::sync::LazyLock; + + use sea_orm_migration::MigratorTrait; + + use crate::{global::GLOBAL, cache::migration::CacheMigrator, data::migration::MainMigrator}; + + use super::*; + + pub async fn get_or_init_temporary_main_database() -> &'static DatabaseConnection { + GLOBAL.get_or_try_init_temporary_main_database(MainMigrator).await.unwrap() + } + pub async fn get_or_init_temporary_cache_database() -> &'static DatabaseConnection { + GLOBAL.get_or_try_init_temporary_cache_database(CacheMigrator).await.unwrap() + } + + #[tokio::test] + async fn connect_main_database () { + let db = get_or_init_temporary_main_database().await; + assert!(db.ping().await.is_ok()); + } + + #[tokio::test] + async fn connect_cache_database () { + let db = get_or_init_temporary_cache_database().await; + assert!(db.ping().await.is_ok()); + } +} \ No newline at end of file