Skip to main content

systemprompt_database/services/
provider.rs

1//! Trait abstractions over a database backend.
2//!
3//! [`DatabaseProvider`] is dyn-safe (callers hold `Arc<dyn DatabaseProvider>`)
4//! and uses `#[async_trait]`. [`DatabaseProviderExt`] is generic, never used
5//! through a trait object, and uses native `async fn`.
6
7use crate::error::DatabaseResult;
8use crate::models::{
9    DatabaseInfo, DatabaseTransaction, DbValue, FromDatabaseRow, JsonRow, QueryResult,
10    QuerySelector, ToDbValue,
11};
12use async_trait::async_trait;
13use std::sync::Arc;
14
15#[async_trait]
16pub trait DatabaseProvider: Send + Sync + std::fmt::Debug {
17    fn get_postgres_pool(&self) -> Option<Arc<sqlx::PgPool>> {
18        None
19    }
20
21    fn is_postgres(&self) -> bool {
22        true
23    }
24
25    async fn execute(
26        &self,
27        query: &dyn QuerySelector,
28        params: &[&dyn ToDbValue],
29    ) -> DatabaseResult<u64>;
30
31    async fn execute_raw(&self, sql: &str) -> DatabaseResult<()>;
32
33    async fn fetch_all(
34        &self,
35        query: &dyn QuerySelector,
36        params: &[&dyn ToDbValue],
37    ) -> DatabaseResult<Vec<JsonRow>>;
38
39    async fn fetch_one(
40        &self,
41        query: &dyn QuerySelector,
42        params: &[&dyn ToDbValue],
43    ) -> DatabaseResult<JsonRow>;
44
45    async fn fetch_optional(
46        &self,
47        query: &dyn QuerySelector,
48        params: &[&dyn ToDbValue],
49    ) -> DatabaseResult<Option<JsonRow>>;
50
51    async fn fetch_scalar_value(
52        &self,
53        query: &dyn QuerySelector,
54        params: &[&dyn ToDbValue],
55    ) -> DatabaseResult<DbValue>;
56
57    async fn begin_transaction(&self) -> DatabaseResult<Box<dyn DatabaseTransaction>>;
58
59    async fn get_database_info(&self) -> DatabaseResult<DatabaseInfo>;
60
61    async fn test_connection(&self) -> DatabaseResult<()>;
62
63    async fn execute_batch(&self, sql: &str) -> DatabaseResult<()>;
64
65    async fn query_raw(&self, query: &dyn QuerySelector) -> DatabaseResult<QueryResult>;
66
67    async fn query_raw_with(
68        &self,
69        query: &dyn QuerySelector,
70        params: Vec<serde_json::Value>,
71    ) -> DatabaseResult<QueryResult>;
72}
73
74#[allow(async_fn_in_trait)]
75pub trait DatabaseProviderExt {
76    async fn fetch_typed_optional<T: FromDatabaseRow>(
77        &self,
78        query: &dyn QuerySelector,
79        params: &[&dyn ToDbValue],
80    ) -> DatabaseResult<Option<T>>;
81
82    async fn fetch_typed_one<T: FromDatabaseRow>(
83        &self,
84        query: &dyn QuerySelector,
85        params: &[&dyn ToDbValue],
86    ) -> DatabaseResult<T>;
87
88    async fn fetch_typed_all<T: FromDatabaseRow>(
89        &self,
90        query: &dyn QuerySelector,
91        params: &[&dyn ToDbValue],
92    ) -> DatabaseResult<Vec<T>>;
93}