// SPDX-FileCopyrightText: 2023 Aravinth Manivannan // // SPDX-License-Identifier: AGPL-3.0-or-later use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; use sqlx::PgPool; #[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)] pub struct JobState { pub name: String, } impl JobState { pub fn new(name: String) -> Self { Self { name } } } lazy_static! { pub static ref JOB_STATE_CREATE: JobState = JobState::new("job.state.create".into()); pub static ref JOB_STATE_FINISH: JobState = JobState::new("job.state.finish".into()); pub static ref JOB_STATE_RUNNING: JobState = JobState::new("job.state.running".into()); pub static ref JOB_STATES: [&'static JobState; 3] = [&*JOB_STATE_CREATE, &*JOB_STATE_FINISH, &*JOB_STATE_RUNNING]; } async fn job_state_exists( db: &PgPool, job_state: &JobState, ) -> sqlx::error::Result { let res = sqlx::query!( "SELECT EXISTS (SELECT 1 from survey_mcaptcha_upload_job_states WHERE name = $1)", job_state.name, ) .fetch_one(db) .await?; let mut resp = false; if let Some(x) = res.exists { resp = x; } Ok(resp) } async fn create_job_states(db: &PgPool) -> sqlx::error::Result<()> { for j in &*JOB_STATES { if !job_state_exists(db, j).await? { sqlx::query!( "INSERT INTO survey_mcaptcha_upload_job_states (name) VALUES ($1) ON CONFLICT (name) DO NOTHING;", j.name ) .execute(db) .await?; } } Ok(()) } pub async fn migrate_db(db: &PgPool) -> sqlx::error::Result<()> { sqlx::migrate!("./migrations/").run(db).await?; create_job_states(db).await?; Ok(()) } #[cfg(test)] mod tests { use super::*; #[actix_rt::test] async fn test_mcaptcha_job_states_exist() { // can't use crate::tests::get_test_data because this module is used by // ./src/tests-migrate.rs too, which doesn't load tests module let settings = crate::settings::Settings::new().unwrap(); let db = sqlx::postgres::PgPoolOptions::new() .max_connections(2) .connect(&settings.database.url) .await .expect("Unable to form database pool"); migrate_db(&db).await.unwrap(); for e in (*JOB_STATES).iter() { println!("checking job state {}", e.name); assert!(job_state_exists(&db, e).await.unwrap()); } } }