1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use cratePgPool;
/// Trait for providing database pools with read/write routing.
///
/// Implementations can provide separate read and write pools for load distribution,
/// or use a single pool for both operations.
///
/// # Thread Safety
///
/// Implementations must be `Clone`, `Send`, and `Sync` to work with async Rust
/// and be shared across tasks.
///
/// # When to Use Each Method
///
/// ## `.read()` - For Read Operations
///
/// Use for queries that:
/// - Don't modify data (SELECT without FOR UPDATE)
/// - Can tolerate slight staleness (eventual consistency)
/// - Benefit from load distribution
///
/// Examples: user listings, analytics, dashboards, search
///
/// ## `.write()` - For Write Operations
///
/// Use for operations that:
/// - Modify data (INSERT, UPDATE, DELETE)
/// - Require transactions
/// - Need locking reads (SELECT FOR UPDATE)
/// - Require read-after-write consistency
///
/// Examples: creating records, updates, deletes, transactions
///
/// # Example Implementation
///
/// ```
/// use sqlx_pool_registry::sqlx::{self, PgPool};
/// use sqlx_pool_registry::PoolProvider;
///
/// #[derive(Clone)]
/// struct MyPools {
/// primary: PgPool,
/// replica: Option<PgPool>,
/// }
///
/// impl PoolProvider for MyPools {
/// fn read(&self) -> &PgPool {
/// self.replica.as_ref().unwrap_or(&self.primary)
/// }
///
/// fn write(&self) -> &PgPool {
/// &self.primary
/// }
/// }
/// ```
/// Implement PoolProvider for PgPool for backward compatibility.
///
/// This allows existing code using `PgPool` directly to work with generic
/// code that accepts `impl PoolProvider` without any changes.
///
/// # Example
///
/// ```rust,no_run
/// use sqlx_pool_registry::sqlx::{self, PgPool};
/// use sqlx_pool_registry::PoolProvider;
///
/// async fn query_user<P: PoolProvider>(pools: &P, id: i64) -> Result<String, sqlx::Error> {
/// sqlx::query_scalar("SELECT name FROM users WHERE id = $1")
/// .bind(id)
/// .fetch_one(pools.read())
/// .await
/// }
///
/// # async fn example() -> Result<(), sqlx::Error> {
/// let pool = PgPool::connect("postgresql://localhost/db").await?;
///
/// // Works with PgPool directly
/// let name = query_user(&pool, 1).await?;
/// # Ok(())
/// # }
/// ```