ironflow_ops_postgres/schema/
databases.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, Row};
9
10use crate::helpers::{pg_error, to_value};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ListDatabasesOutput {
15 pub databases: Vec<String>,
17}
18
19pub struct ListDatabases {
33 pool: PgPool,
34}
35
36impl ListDatabases {
37 pub fn new(pool: PgPool) -> Self {
39 Self { pool }
40 }
41
42 pub async fn run(
48 &self,
49 _ctx: &OperationContext,
50 ) -> Result<ListDatabasesOutput, OperationError> {
51 let rows = sqlx::query(
52 "SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname",
53 )
54 .fetch_all(&self.pool)
55 .await
56 .map_err(pg_error)?;
57 let databases = rows
58 .iter()
59 .map(|r| r.try_get::<String, _>("datname").map_err(pg_error))
60 .collect::<Result<Vec<_>, _>>()?;
61 Ok(ListDatabasesOutput { databases })
62 }
63}
64
65#[async_trait]
66impl Operation for ListDatabases {
67 fn kind(&self) -> &str {
68 "postgres"
69 }
70 async fn execute(&self, ctx: &OperationContext) -> Result<Value, OperationError> {
71 to_value(&self.run(ctx).await?)
72 }
73}
74
75impl TypedOperation for ListDatabases {
76 type Output = ListDatabasesOutput;
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[tokio::test]
84 async fn kind() {
85 let pool = PgPool::connect_lazy("postgres://localhost/test").unwrap();
86 let op = ListDatabases::new(pool);
87 assert_eq!(op.kind(), "postgres");
88 }
89}