148 lines
4.3 KiB
Rust

use crate::api;
use crate::core;
use crate::repositories;
use diesel::{
r2d2::{ConnectionManager, Pool},
PgConnection,
};
///
pub struct Synchronizer {
pool: Pool<ConnectionManager<PgConnection>>,
api_config: core::config::ApiConfig,
synchronization_history_repository: repositories::synchronization_history::repository::Repository,
vendor_repository: repositories::vendor::repository::Repository,
game_repository: repositories::game::repository::Repository,
game_api: api::game::api::Api,
}
impl std::fmt::Debug for Synchronizer {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("Synchronizer of api.kgon.identity").finish()
}
}
impl std::clone::Clone for Synchronizer {
fn clone(&self) -> Self {
Self {
pool: self.pool.clone(),
api_config: self.api_config.clone(),
synchronization_history_repository:
repositories::synchronization_history::repository::Repository::new(),
vendor_repository: repositories::vendor::repository::Repository::new(),
game_repository: repositories::game::repository::Repository::new(),
game_api: api::game::api::Api::new(self.api_config.clone()),
}
}
}
impl Synchronizer {
///
pub fn new(
pool: Pool<ConnectionManager<PgConnection>>,
api_config: core::config::ApiConfig,
) -> Synchronizer {
Synchronizer {
pool,
api_config: api_config.clone(),
synchronization_history_repository:
repositories::synchronization_history::repository::Repository::new(),
vendor_repository: repositories::vendor::repository::Repository::new(),
game_repository: repositories::game::repository::Repository::new(),
game_api: api::game::api::Api::new(api_config),
}
}
pub async fn games(&self) -> Result<(), Box<dyn std::error::Error>> {
let start_at = (chrono::Utc::now()).timestamp();
if let Err(e) = async {
let conn = self.pool.get().expect("conn");
let vendors = self
.vendor_repository
.select_all(
&conn,
&repositories::vendor::models::FindAll {
pagination: None,
sorts: None,
search: None,
},
)
.expect("vendor select_all");
let mut upsert_games: Vec<repositories::game::models::UpsertGame> = vec![];
for v in vendors {
let req = api::game::models::ListGamesRequest {
vendor_key: v.key.clone(),
};
let res = self.game_api.list_games(req).await?;
for g in res.games {
match upsert_games.iter().find(|v| v.id.eq(&g.id)) {
Some(d) => {
println!("id is duplicated. e: {:?}, n: {:?}", d, g);
continue;
}
None => {}
};
upsert_games.push(repositories::game::models::UpsertGame {
id: g.id,
parent_id: v.id,
key: g.key.clone(),
names: serde_json::to_string(&g.names).expect("names"),
platform: g.platform.clone(),
category: g.category.clone(),
game_type: g.game_type.clone(),
image: g.image,
});
}
}
let _affected = self
.game_repository
.upserts(&conn, upsert_games)
.expect("game upsert");
self
.synchronization_history_repository
.insert(
&conn,
&repositories::synchronization_history::models::NewSynchronizationHistory {
item: repositories::synchronization::models::ITEM_GAMES.to_string(),
start_at,
complete_at: (chrono::Utc::now()).timestamp(),
code: 0,
message: None,
data: None,
},
)
.expect("synchronization_history insert");
Ok::<(), api::core::models::Error>(())
}
.await
{
let conn = self.pool.get().expect("conn");
self
.synchronization_history_repository
.insert(
&conn,
&repositories::synchronization_history::models::NewSynchronizationHistory {
item: repositories::synchronization::models::ITEM_GAMES.to_string(),
start_at,
complete_at: (chrono::Utc::now()).timestamp(),
code: e.code,
message: e.msg,
data: None,
},
)
.expect("synchronization_history insert");
}
Ok(())
}
}