181 lines
5.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 = 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<repositories::game::models::UpsertGame> = 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(())
}
}