Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I5cf55cc4cb558c3f9f764c71224e87176a6a6964
84 lines
2 KiB
Rust
84 lines
2 KiB
Rust
use sqlx::PgPool;
|
|
use uuid::Uuid;
|
|
|
|
use crate::{
|
|
error::{CiError, Result},
|
|
models::BuildStatus,
|
|
};
|
|
|
|
/// Check if a derivation path is in the failed paths cache.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns error if database query fails.
|
|
pub async fn is_cached_failure(pool: &PgPool, drv_path: &str) -> Result<bool> {
|
|
let row: Option<(bool,)> =
|
|
sqlx::query_as("SELECT true FROM failed_paths_cache WHERE drv_path = $1")
|
|
.bind(drv_path)
|
|
.fetch_optional(pool)
|
|
.await
|
|
.map_err(CiError::Database)?;
|
|
|
|
Ok(row.is_some())
|
|
}
|
|
|
|
/// Insert a failed derivation path into the cache.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns error if database insert fails.
|
|
pub async fn insert(
|
|
pool: &PgPool,
|
|
drv_path: &str,
|
|
failure_status: BuildStatus,
|
|
source_build_id: Uuid,
|
|
) -> Result<()> {
|
|
let status_str = failure_status.to_string();
|
|
sqlx::query(
|
|
"INSERT INTO failed_paths_cache (drv_path, source_build_id, \
|
|
failure_status, failed_at) VALUES ($1, $2, $3, NOW()) ON CONFLICT \
|
|
(drv_path) DO UPDATE SET source_build_id = $2, failure_status = $3, \
|
|
failed_at = NOW()",
|
|
)
|
|
.bind(drv_path)
|
|
.bind(source_build_id)
|
|
.bind(&status_str)
|
|
.execute(pool)
|
|
.await
|
|
.map_err(CiError::Database)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Remove a derivation path from the failed paths cache.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns error if database delete fails.
|
|
pub async fn invalidate(pool: &PgPool, drv_path: &str) -> Result<()> {
|
|
sqlx::query("DELETE FROM failed_paths_cache WHERE drv_path = $1")
|
|
.bind(drv_path)
|
|
.execute(pool)
|
|
.await
|
|
.map_err(CiError::Database)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Remove expired entries from the failed paths cache.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// Returns error if database delete fails.
|
|
pub async fn cleanup_expired(pool: &PgPool, ttl_seconds: u64) -> Result<u64> {
|
|
let result = sqlx::query(
|
|
"DELETE FROM failed_paths_cache WHERE failed_at < NOW() - \
|
|
make_interval(secs => $1)",
|
|
)
|
|
.bind(ttl_seconds as f64)
|
|
.execute(pool)
|
|
.await
|
|
.map_err(CiError::Database)?;
|
|
|
|
Ok(result.rows_affected())
|
|
}
|