use crate::api; use crate::core; use crate::repositories; use diesel::{ r2d2::{ConnectionManager, Pool}, PgConnection, }; /// pub struct Synchronizer { pool: Pool>, 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>, 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> { let start_at = (chrono::Utc::now()).timestamp(); if let Err(e) = async { let conn = match self.pool.get() { Ok(c) => c, Err(e) => { return Err(api::core::models::Error { code: -1, msg: Some(format!("pool.get error: {}", e)), }); } }; let vendors = match self.vendor_repository.select_all( &conn, &repositories::vendor::models::FindAll { pagination: None, sorts: None, search: None, }, ) { Ok(v) => v, Err(e) => { return Err(api::core::models::Error { code: -1, msg: Some(format!("vendor_repository.select_all error: {}", e)), }); } }; let mut upsert_games: Vec = vec![]; for v in vendors { let req = api::game::models::ListGamesRequest { vendor_key: v.key.clone(), }; let res = match self.game_api.list_games(req).await { Ok(v) => v, Err(e) => { return Err(api::core::models::Error { code: -1, msg: Some(format!("game_api.list_games error: {:?}", e)), }); } }; for g in res.games { match upsert_games.iter().find(|v| v.id.eq(&g.id)) { Some(d) => { return Err(api::core::models::Error { code: -1, msg: Some(format!("id is duplicated. e: {:?}, n: {:?}", d, g)), }); } 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 = match self.game_repository.upserts(&conn, upsert_games) { Ok(c) => c, Err(e) => { return Err(api::core::models::Error { code: -1, msg: Some(format!("game_repository.upserts error: {}", e)), }); } }; if let Err(e) = 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, }, ) { println!("synchronization_history.insert error: {}", e); }; Ok::<(), api::core::models::Error>(()) } .await { let conn = match self.pool.get() { Ok(c) => c, Err(e) => { println!("pool.get error: {}", e); return Ok(()); } }; if let Err(e) = 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, }, ) { println!("synchronization_history.insert error: {}", e); }; } Ok(()) } }