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
//! PostgreSQL storage adapter for codlet (RFC-034).
//!
//! ## Atomicity
//!
//! Code claim and form-token consume use a conditional `UPDATE … WHERE … AND
//! <guard>` with `rows_affected()`. Under PostgreSQL's default `READ
//! COMMITTED` isolation level, the UPDATE acquires a row-level lock on the
//! matched row. Concurrent transactions targeting the same row serialise:
//! exactly one commits with `rows_affected() == 1`; the rest see `0`.
//!
//! This is equivalent to SQLite's serialised write mode and D1's per-row
//! locking. No `SERIALIZABLE` isolation or `FOR UPDATE` pre-lock is needed.
//!
//! ## Why no `RETURNING` clause
//!
//! RFC-034 §7 explicitly rejects `RETURNING`: the `CodeStore` trait is
//! designed around `classify_claim(rows_affected())`. Adding `RETURNING`
//! would require a different code path for no security gain — the conditional
//! WHERE clause already provides the single-winner guarantee.
pub use PostgresCodeStore;
pub use PostgresSessionStore;
pub use PostgresFormTokenStore;
/// PostgreSQL storage adapter for codlet (RFC-034).
///
/// Wraps a [`sqlx::PgPool`]. Clone is cheap — the pool is reference-counted.
///
/// Implements [`codlet_core::store::code::CodeStore`],
/// [`codlet_core::store::session::SessionStore`],
/// [`codlet_core::store::token::FormTokenStore`], and
/// [`codlet_core::admin::CodeAdminStore`].
/// Run codlet's PostgreSQL migrations against `pool` (RFC-034 §9).
///
/// Applies `migrations/0002_postgres.sql` statement by statement. Uses
/// `IF NOT EXISTS` throughout — safe to call on every startup.
///
/// # Errors
///
/// Returns [`sqlx::Error`] if any statement fails.
pub async