ironflow_ops_postgres/admin/
health.rs1use async_trait::async_trait;
4use ironflow_core::error::OperationError;
5use ironflow_core::operation::{Operation, OperationContext, TypedOperation};
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use sqlx::PgPool;
9
10use crate::helpers::{pg_error, to_value};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct HealthCheckOutput {
15 pub healthy: bool,
17}
18
19pub struct HealthCheck {
33 pool: PgPool,
34}
35
36impl HealthCheck {
37 pub fn new(pool: PgPool) -> Self {
39 Self { pool }
40 }
41
42 pub async fn run(&self, _ctx: &OperationContext) -> Result<HealthCheckOutput, OperationError> {
48 sqlx::query("SELECT 1")
49 .fetch_one(&self.pool)
50 .await
51 .map_err(pg_error)?;
52 Ok(HealthCheckOutput { healthy: true })
53 }
54}
55
56#[async_trait]
57impl Operation for HealthCheck {
58 fn kind(&self) -> &str {
59 "postgres"
60 }
61 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
62 to_value(&self.run(ctx).await?)
63 }
64}
65
66impl TypedOperation for HealthCheck {
67 type Output = HealthCheckOutput;
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[tokio::test]
75 async fn kind() {
76 let pool = PgPool::connect_lazy("postgres://localhost/test").unwrap();
77 let op = HealthCheck::new(pool);
78 assert_eq!(op.kind(), "postgres");
79 }
80}