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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
//! §Fase 37.x.j (D1) — `StoreConn`: connection-pinned executor wrapper.
//!
//! The Connection-Pinned Flow Execution Contract pins ONE physical
//! Postgres connection per axonstore for the entire flow lifetime,
//! so a transaction-mode pooler (Supabase Supavisor `:6543`, PgBouncer
//! `pool_mode=transaction`, Neon, RDS Proxy) cannot swap the backend
//! between two queries that should observe each other's prepared
//! statements.
//!
//! The contract requires every `PostgresStoreBackend` operation
//! (`query`, `insert`, `mutate`, `purge`, `ping`) to be able to execute
//! against EITHER the pool (legacy, pre-37.x.j) OR a pinned
//! [`sqlx::pool::PoolConnection<sqlx::Postgres>`] held on
//! `ExecContext`/`DispatchCtx`. The naive sqlx-idiomatic path
//! (taking an `executor: E where E: sqlx::Executor<'_, Database = Postgres>`
//! generic parameter) consumes the executor by-value on `.fetch_all` /
//! `.execute` / `.begin`, which collides with the backend's
//! cache-HIT-fall-through-to-MISS-on-schema-drift logic: after a HIT
//! attempt consumes the executor, the MISS path has no executor left.
//!
//! [`StoreConn`] resolves this with an explicit two-variant enum that
//! re-borrows on every operation. Each method dispatches by variant
//! and produces a fresh executor reference from the underlying handle
//! — so the caller can run a cache-HIT `fetch_all` + on schema-drift
//! fall through to a `begin()` + introspect-in-tx + retry, all against
//! the SAME `StoreConn` borrow without ever consuming it.
//!
//! # Design choice (C′ per Fase 37.x.j.1 ratification 2026-05-20)
//!
//! The sqlx-idiomatic generic `E: Executor` pattern (option C) was
//! considered and rejected because it cannot survive the cache
//! fall-through. Option (A) overlay (parallel `_pinned` methods) was
//! considered and rejected for API duplication. Option (C′) — this
//! file — is the pragmatic middle: a small, internal wrapper type
//! that owns the dispatch decision and lets each method consume a
//! single `&mut StoreConn` for its whole body.
//!
//! `StoreConn` is **not** a sqlx primitive. It does not appear in
//! adopter-facing axon code. It is a runtime-internal helper that
//! exists solely to satisfy the D1 pinning contract.
use PoolConnection;
use ;
use Connection;
use ;
/// §Fase 37.x.j (D1) — A connection-source for `PostgresStoreBackend`
/// operations.
///
/// Two variants:
///
/// - [`StoreConn::Pool`] — wraps a borrow of the backend's connection
/// pool; every operation acquires a fresh sqlx logical connection
/// per call. This is the v1.38.5 (and earlier) legacy behavior;
/// backwards-compat path D5.
///
/// - [`StoreConn::Pinned`] — wraps a mutable borrow of a single
/// `PoolConnection<Postgres>` already acquired (by `acquire_pin`
/// on the backend) and held by the calling [`ExecContext`] or
/// [`DispatchCtx`]. Every operation runs against this exact
/// physical Postgres backend connection, so a transaction-mode
/// pooler cannot swap mid-flow.
///
/// The wrapper is `'a`-scoped — the borrow lifetime matches the
/// lifetime of the pool reference or the pinned connection. The
/// caller passes `&mut StoreConn<'_>` into each backend method, which
/// can then re-borrow on each query without consuming the wrapper.
///
/// # Re-borrow discipline
///
/// `sqlx`'s `Executor` trait consumes by value on every operation.
/// `StoreConn` resolves this by NOT exposing the underlying handle —
/// instead, it provides three operations (`fetch_all`, `execute`,
/// `begin`) that each internally re-borrow the wrapped pool/conn,
/// freshly producing an `&PgPool` or `&mut PgConnection` (via
/// `&mut **pinned`) per call. The wrapper itself stays usable across
/// successive operations.
///
/// # The `begin()` method returns a `Transaction` (not a StoreConn)
///
/// Once inside a `Transaction`, the connection is automatically pinned
/// for the transaction's duration — sqlx's `Transaction` borrows the
/// connection mutably for its lifetime. The cache-MISS path of every
/// backend op uses this property: it begins a transaction on the
/// `StoreConn`, runs introspection + the operation queries against
/// the transaction, then commits. While the transaction is alive, no
/// other code can use the `StoreConn` (the borrow is exclusive), so
/// no foreign pool acquire can interleave a connection swap.