fraiseql_db/wire_pool.rs
1//! Connection pool for fraiseql-wire clients.
2//!
3//! fraiseql-wire's `FraiseClient` consumes itself on query execution,
4//! so we implement a simple connection factory pattern instead of traditional pooling.
5
6use std::sync::Arc;
7
8use fraiseql_error::{FraiseQLError, Result};
9
10/// Connection factory for fraiseql-wire clients.
11///
12/// Since `FraiseClient::query()` consumes the client, we store the connection string
13/// and create new clients on demand rather than pooling connections.
14#[derive(Debug, Clone)]
15pub struct WireClientFactory {
16 connection_string: Arc<String>,
17}
18
19impl WireClientFactory {
20 /// Create a new client factory.
21 ///
22 /// # Arguments
23 ///
24 /// * `connection_string` - PostgreSQL connection string (e.g., "postgres://localhost/mydb")
25 ///
26 /// # Example
27 ///
28 /// ```ignore
29 /// use fraiseql_core::db::wire_pool::WireClientFactory;
30 ///
31 /// let factory = WireClientFactory::new("postgres://localhost/fraiseql");
32 /// ```
33 #[must_use]
34 pub fn new(connection_string: impl Into<String>) -> Self {
35 Self {
36 connection_string: Arc::new(connection_string.into()),
37 }
38 }
39
40 /// Create a new fraiseql-wire client.
41 ///
42 /// This method creates a fresh connection each time it's called.
43 /// The connection is closed when the client is dropped after query execution.
44 ///
45 /// # Returns
46 ///
47 /// A new `FraiseClient` ready for query execution.
48 ///
49 /// # Errors
50 ///
51 /// Returns `FraiseQLError::ConnectionPool` if connection fails.
52 ///
53 /// # Example
54 ///
55 /// ```ignore
56 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
57 /// use fraiseql_core::db::wire_pool::WireClientFactory;
58 ///
59 /// let factory = WireClientFactory::new("postgres://localhost/fraiseql");
60 /// let client = factory.create_client().await?;
61 /// # Ok(())
62 /// # }
63 /// ```
64 pub async fn create_client(&self) -> Result<fraiseql_wire::FraiseClient> {
65 fraiseql_wire::FraiseClient::connect(&self.connection_string)
66 .await
67 .map_err(|e| FraiseQLError::ConnectionPool {
68 message: format!("Failed to create fraiseql-wire client: {e}"),
69 })
70 }
71
72 /// Get the connection string.
73 #[must_use]
74 pub fn connection_string(&self) -> &str {
75 &self.connection_string
76 }
77}
78
79#[cfg(test)]
80mod tests;