what2watch/src/import_utils.rs

107 lines
3.3 KiB
Rust

use julid::Julid;
use sqlx::{query_scalar, SqliteConnection, SqlitePool};
use crate::{Credit, Star, User, Watch};
//-************************************************************************
// the omega user is the system ID, but has no actual power in the app
//-************************************************************************
const OMEGA_ID: Julid = Julid::omega();
//-************************************************************************
// utility functions for building CLI tools, currently just for benchmarking
//-************************************************************************
pub async fn insert_watch(watch: Watch, db: &mut SqliteConnection) -> Julid {
let q = "insert into watches (kind, title, length, release_date, added_by, metadata_url) values (?, ?, ?, ?, ?, ?) returning id";
sqlx::query_scalar(q)
.bind(watch.kind)
.bind(watch.title)
.bind(watch.length)
.bind(watch.release_date)
.bind(watch.added_by)
.bind(watch.metadata_url)
.fetch_one(db)
.await
.unwrap()
}
pub async fn insert_star(star: &Star, db: &mut SqliteConnection) -> Julid {
let q = "insert into stars (name, metadata_url, born, died) values (?, ?, ?, ?) returning id";
sqlx::query_scalar(q)
.bind(&star.name)
.bind(&star.metadata_url)
.bind(&star.born)
.bind(&star.died)
.fetch_one(db)
.await
.unwrap()
}
pub async fn insert_credit(credit: &Credit, db: &mut SqliteConnection) {
let q = "insert into credits (star, watch, credit) values (?, ?, ?)";
sqlx::query(q)
.bind(credit.star)
.bind(credit.watch)
.bind(credit.credit.as_deref())
.execute(db)
.await
.map(|_| ())
.or_else(|e| match e {
sqlx::Error::Database(ref db) => {
let exit = db.code().unwrap_or_default().parse().unwrap_or(0u32);
// https://www.sqlite.org/rescode.html codes for unique constraint violations:
if exit == 2067 || exit == 1555 {
Ok(())
} else {
Err(e)
}
}
_ => Err(e),
})
.unwrap();
}
pub async fn ensure_omega(db_pool: &SqlitePool) -> Julid {
if !check_omega_exists(db_pool).await {
User::omega().try_insert(db_pool).await.unwrap();
}
OMEGA_ID
}
async fn check_omega_exists(db_pool: &SqlitePool) -> bool {
const USER_EXISTS_QUERY: &str = "select count(*) from users where id = $1";
let count = query_scalar(USER_EXISTS_QUERY)
.bind(OMEGA_ID)
.fetch_one(db_pool)
.await
.unwrap_or(0);
count > 0
}
//-************************************************************************
//tests
//-************************************************************************
#[cfg(test)]
mod test {
use tokio::runtime::Runtime;
use super::*;
#[test]
fn ensure_omega_user() {
let p = crate::db::get_db_pool();
let rt = Runtime::new().unwrap();
rt.block_on(async {
dbg!("checking omega");
assert!(!check_omega_exists(&p).await);
dbg!("no omega");
ensure_omega(&p).await;
});
dbg!("maybe omega");
assert!(rt.block_on(check_omega_exists(&p)));
}
}