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
//! # entelix-graphmemory-pg
//!
//! Concrete [`entelix_memory::GraphMemory`] implementation backed by
//! Postgres (no extension required) — typed nodes + typed,
//! timestamped edges keyed by `entelix_memory::Namespace`.
//!
//! Companion to the trait-only [`entelix_memory`] crate:
//! sqlx specifics live here so users who plug their own
//! `GraphMemory` pay nothing in compile time.
//!
//! ## One-call setup
//!
//! ```ignore
//! use entelix_graphmemory_pg::PgGraphMemory;
//!
//! let graph = PgGraphMemory::<String, String>::builder()
//! .with_connection_string("postgres://localhost/entelix")
//! .build()
//! .await?;
//! ```
//!
//! ## Multi-tenancy
//!
//! Two-table design (`graph_nodes` + `graph_edges`) with composite
//! `(namespace_key, id)` primary keys. Every read / write rides a
//! `WHERE namespace_key = $1` anchor — invariant 11 / F2 demand
//! structural tenant isolation, and the composite PK doubles as
//! the B-tree index that anchor relies on.
//!
//! Defense-in-depth via Postgres row-level security (analogous to
//!'s treatment of the `entelix-persistence` tables) is
//! reserved for a follow-up slice — operators that need it today
//! enable it externally with a policy that consults
//! `current_setting('entelix.tenant_id', true)` against the
//! `tenant_id` segment encoded in `namespace_key`.
//!
//! ## Schema-as-code escape hatch
//!
//! Operators that own the schema externally (DBA-managed, IaC,
//! migration pipeline) call [`PgGraphMemoryBuilder::with_auto_migrate`]
//! with `false` — the builder skips table / index creation,
//! trusting the operator to have stamped them.
// `Postgres` rides through doc strings as a vendor name. Crate-
// internal `pub(crate)` items inside private modules are the
// canonical helper pattern.
pub use ;
pub use ;