Skip to main content

systemprompt_database/services/postgres/
ext.rs

1//! Typed-row extension methods over [`PostgresProvider`].
2//!
3//! Part of the documented sqlx allowlist: the SQL is supplied dynamically
4//! through [`QuerySelector`], so compile-time verification is impossible.
5//!
6//! Copyright (c) systemprompt.io — Business Source License 1.1.
7//! See <https://systemprompt.io> for licensing details.
8
9use crate::error::DatabaseResult;
10
11use super::PostgresProvider;
12use super::conversion::bind_params;
13use crate::models::{FromDatabaseRow, QuerySelector, ToDbValue};
14use crate::services::provider::DatabaseProviderExt;
15
16impl DatabaseProviderExt for PostgresProvider {
17    async fn fetch_typed_optional<T: FromDatabaseRow>(
18        &self,
19        query: &dyn QuerySelector,
20        params: &[&dyn ToDbValue],
21    ) -> DatabaseResult<Option<T>> {
22        let sql = query.select_query();
23        let query_obj = sqlx::query(sqlx::AssertSqlSafe(sql));
24        let query_obj = bind_params(query_obj, params);
25
26        let row = query_obj.fetch_optional(self.pool()).await?;
27
28        match row {
29            Some(r) => Ok(Some(T::from_postgres_row(&r)?)),
30            None => Ok(None),
31        }
32    }
33
34    async fn fetch_typed_one<T: FromDatabaseRow>(
35        &self,
36        query: &dyn QuerySelector,
37        params: &[&dyn ToDbValue],
38    ) -> DatabaseResult<T> {
39        let sql = query.select_query();
40        let query_obj = sqlx::query(sqlx::AssertSqlSafe(sql));
41        let query_obj = bind_params(query_obj, params);
42
43        let row = query_obj.fetch_one(self.pool()).await?;
44
45        T::from_postgres_row(&row)
46    }
47
48    async fn fetch_typed_all<T: FromDatabaseRow>(
49        &self,
50        query: &dyn QuerySelector,
51        params: &[&dyn ToDbValue],
52    ) -> DatabaseResult<Vec<T>> {
53        let sql = query.select_query();
54        let query_obj = sqlx::query(sqlx::AssertSqlSafe(sql));
55        let query_obj = bind_params(query_obj, params);
56
57        let rows = query_obj.fetch_all(self.pool()).await?;
58
59        rows.iter().map(|r| T::from_postgres_row(r)).collect()
60    }
61}