Skip to main content

pgorm/
lib.rs

1//! # pgorm
2//!
3//! A lightweight Postgres-only ORM for Rust.
4//!
5//! ## Features
6//!
7//! - **SQL explicit**: SQL is a first-class citizen (use `query()` / `sql()`; `qb::query()` is an alias)
8//! - **Type-safe mapping**: Row → Struct via `FromRow` trait
9//! - **Minimal magic**: Traits and macros only for boilerplate reduction
10//! - **Transaction-friendly**: pass a transaction anywhere a `GenericClient` is expected
11//! - **Query monitoring**: Built-in support for timing, logging, and hooking SQL execution
12//! - **SQL checking**: Validate SQL against registered schemas and lint for common issues
13//! - **Migrations**: Optional SQL migrations via `refinery` (feature: `migrate`)
14//!
15//! ## SQL fallback (qb)
16//!
17//! The `qb` module is a thin wrapper around `query()` for running hand-written SQL:
18//!
19//! ```ignore
20//! use pgorm::qb;
21//!
22//! let users: Vec<User> = qb::query("SELECT * FROM users WHERE status = $1")
23//!     .bind("active")
24//!     .fetch_all_as(&client)
25//!     .await?;
26//! ```
27
28mod builder;
29pub mod changeset;
30mod client;
31mod condition;
32pub mod eager;
33mod error;
34mod ident;
35mod monitor;
36pub mod prelude;
37pub mod qb;
38mod row;
39mod sql;
40mod transaction;
41
42#[cfg(feature = "validate")]
43pub mod validate;
44
45// SQL migrations (via refinery)
46#[cfg(feature = "migrate")]
47pub mod migrate;
48
49pub use builder::{NullsOrder, OrderBy, OrderItem, Pagination, SortDir, WhereExpr};
50pub use changeset::{ValidationCode, ValidationError, ValidationErrors};
51pub use client::GenericClient;
52pub use condition::{Condition, Op};
53pub use eager::{BelongsToMap, HasManyMap, Loaded};
54pub use error::{OrmError, OrmResult};
55pub use ident::{Ident, IdentPart, IntoIdent};
56#[cfg(feature = "tracing")]
57pub use monitor::TracingSqlHook;
58pub use monitor::{
59    CompositeHook, CompositeMonitor, HookAction, InstrumentedClient, LoggingMonitor, MonitorConfig,
60    NoopMonitor, QueryContext, QueryHook, QueryMonitor, QueryResult, QueryStats, QueryType,
61    StatsMonitor,
62};
63pub use row::{FromRow, PgType, RowExt};
64pub use sql::{Query, Sql, query, sql};
65pub use tokio_postgres::types::Json;
66
67// Re-export refinery types for convenience
68#[cfg(feature = "migrate")]
69pub use migrate::{Migration, Report, Runner, Target, embed_migrations};
70
71#[cfg(feature = "pool")]
72mod pool;
73
74#[cfg(feature = "pool")]
75pub use client::PoolClient;
76
77#[cfg(feature = "pool")]
78pub use pool::{create_pool, create_pool_with_config};
79
80#[cfg(feature = "pool")]
81pub use pool::{create_pool_with_manager_config, create_pool_with_tls};
82
83#[cfg(feature = "derive")]
84pub use pgorm_derive::{FromRow, InsertModel, Model, QueryParams, UpdateModel, ViewModel};
85
86// SQL checking and linting
87mod check;
88
89// Checked client with auto-registration (lower-level)
90mod checked_client;
91
92// Unified PgClient (recommended)
93#[cfg(feature = "check")]
94mod pg_client;
95
96pub use check::{
97    ColumnMeta, SchemaIssue, SchemaIssueKind, SchemaIssueLevel, SchemaRegistry, TableMeta,
98    TableSchema,
99};
100
101// Re-export inventory for use by derive macros
102#[doc(hidden)]
103pub use inventory;
104
105// Re-export serde for derive-generated input structs.
106#[doc(hidden)]
107pub use serde;
108
109// Re-export CheckedClient and related types (lower-level API)
110#[doc(hidden)]
111pub use checked_client::ModelRegistration;
112
113#[cfg(feature = "check")]
114pub use checked_client::CheckedClient;
115
116// Re-export PgClient (recommended API)
117#[cfg(feature = "check")]
118pub use pg_client::{
119    CheckMode, DangerousDmlPolicy, ModelCheckResult, PgClient, PgClientConfig,
120    SelectWithoutLimitPolicy, SqlPolicy,
121};
122
123#[cfg(feature = "check")]
124pub use check::{
125    CheckClient,
126    CheckError,
127    CheckResult,
128    ColumnInfo,
129    // Lint types and functions
130    ColumnRef,
131    DbSchema,
132    LintIssue,
133    LintLevel,
134    LintResult,
135    ParseResult,
136    RelationKind,
137    SchemaCache,
138    SchemaCacheConfig,
139    SchemaCacheLoad,
140    SqlCheckIssue,
141    SqlCheckIssueKind,
142    SqlCheckLevel,
143    StatementKind,
144    TableInfo,
145    // Database schema check
146    check_sql,
147    check_sql_cached,
148    delete_has_where,
149    detect_statement_kind,
150    get_column_refs,
151    get_table_names,
152    is_valid_sql,
153    lint_select_many,
154    lint_sql,
155    // Schema introspection
156    load_schema_from_db,
157    select_has_limit,
158    select_has_star,
159    update_has_where,
160};
161
162// ─────────────────────────────────────────────────────────────────────────────
163// Write Graph Types (for multi-table writes)
164// ─────────────────────────────────────────────────────────────────────────────
165
166/// Trait for models with a primary key.
167///
168/// This trait is automatically implemented by `#[derive(Model)]` for structs
169/// with an `#[orm(id)]` field. It provides a way to access the primary key
170/// value without requiring field visibility.
171///
172/// # Example
173///
174/// ```ignore
175/// #[derive(Model)]
176/// #[orm(table = "orders")]
177/// struct Order {
178///     #[orm(id)]
179///     id: i64,
180///     user_id: i64,
181/// }
182///
183/// // ModelPk is automatically implemented:
184/// let order: Order = /* ... */;
185/// let pk: &i64 = order.pk();
186/// ```
187pub trait ModelPk {
188    /// The type of the primary key.
189    type Id: Clone + Send + Sync + 'static;
190
191    /// Returns a reference to the primary key value.
192    fn pk(&self) -> &Self::Id;
193}
194
195/// Report returned by `insert_graph_report` / `update_by_id_graph_report`.
196///
197/// Contains detailed information about each step in the write graph execution.
198#[derive(Debug, Clone)]
199pub struct WriteReport<R> {
200    /// Sum of affected rows across all steps.
201    pub affected: u64,
202    /// Per-step statistics (in execution order).
203    pub steps: ::std::vec::Vec<WriteStepReport>,
204    /// The root table's returning value (if the `_returning` or `_report` variant was called).
205    pub root: ::std::option::Option<R>,
206}
207
208/// Statistics for a single step in a write graph.
209#[derive(Debug, Clone)]
210pub struct WriteStepReport {
211    /// A tag identifying this step, e.g. `"graph:belongs_to:categories"`,
212    /// `"graph:root:orders"`, `"graph:has_many:order_items"`.
213    pub tag: &'static str,
214    /// Number of rows affected by this step.
215    pub affected: u64,
216}