Skip to main content

entelix_graphmemory_pg/
lib.rs

1//! # entelix-graphmemory-pg
2//!
3//! Concrete [`entelix_memory::GraphMemory`] implementation backed by
4//! Postgres (no extension required) — typed nodes + typed,
5//! timestamped edges keyed by `entelix_memory::Namespace`.
6//!
7//! Companion to the trait-only [`entelix_memory`] crate:
8//! sqlx specifics live here so users who plug their own
9//! `GraphMemory` pay nothing in compile time.
10//!
11//! ## One-call setup
12//!
13//! ```ignore
14//! use entelix_graphmemory_pg::PgGraphMemory;
15//!
16//! let graph = PgGraphMemory::<String, String>::builder()
17//!     .with_connection_string("postgres://localhost/entelix")
18//!     .build()
19//!     .await?;
20//! ```
21//!
22//! ## Multi-tenancy
23//!
24//! Two-table design (`graph_nodes` + `graph_edges`) with composite
25//! `(namespace_key, id)` primary keys. Every read / write rides a
26//! `WHERE namespace_key = $1` anchor — invariant 11 / F2 demand
27//! structural tenant isolation, and the composite PK doubles as
28//! the B-tree index that anchor relies on.
29//!
30//! Defense-in-depth via Postgres row-level security (analogous to
31//!'s treatment of the `entelix-persistence` tables) is
32//! reserved for a follow-up slice — operators that need it today
33//! enable it externally with a policy that consults
34//! `current_setting('entelix.tenant_id', true)` against the
35//! `tenant_id` segment encoded in `namespace_key`.
36//!
37//! ## Schema-as-code escape hatch
38//!
39//! Operators that own the schema externally (DBA-managed, IaC,
40//! migration pipeline) call [`PgGraphMemoryBuilder::with_auto_migrate`]
41//! with `false` — the builder skips table / index creation,
42//! trusting the operator to have stamped them.
43
44#![cfg_attr(docsrs, feature(doc_cfg))]
45#![doc(html_root_url = "https://docs.rs/entelix-graphmemory-pg/0.5.3")]
46#![deny(missing_docs)]
47// `Postgres` rides through doc strings as a vendor name. Crate-
48// internal `pub(crate)` items inside private modules are the
49// canonical helper pattern.
50#![allow(
51    clippy::doc_markdown,
52    clippy::redundant_pub_crate,
53    clippy::missing_const_for_fn,
54    clippy::expect_used,
55    // Three CREATE INDEX statements bind to `create_from_idx` /
56    // `create_to_idx` / `create_ts_idx` — mirrors the SQL pattern;
57    // the lint flags the deliberate parallel naming as confusable.
58    clippy::similar_names
59)]
60
61mod error;
62mod migration;
63mod store;
64mod tenant;
65
66pub use error::{PgGraphMemoryError, PgGraphMemoryResult};
67pub use store::{PgGraphMemory, PgGraphMemoryBuilder};