survey/src/db.rs

92 lines
2.5 KiB
Rust

// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// 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<bool> {
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());
}
}
}