Skip to main content

modo/db/
mod.rs

1//! # modo::db
2//!
3//! Lightweight libsql (SQLite) database layer with typed row mapping,
4//! composable query building, filtering, and pagination.
5//!
6//! ## Core types
7//!
8//! | Type | Purpose |
9//! |------|---------|
10//! | [`Database`] | Clone-able, `Arc`-wrapped single-connection handle |
11//! | [`Config`] | YAML-deserializable database configuration with PRAGMA defaults |
12//! | [`ManagedDatabase`] | Wrapper for graceful shutdown via `modo::run!` |
13//! | [`DatabasePool`] | Multi-database pool with lazy shard opening for tenant isolation |
14//! | [`PoolConfig`] | Configuration for database sharding (`base_path`, `lock_shards`) |
15//! | [`ManagedDatabasePool`] | Wrapper for graceful pool shutdown via `modo::run!` |
16//!
17//! ## Factory functions
18//!
19//! | Function | Purpose |
20//! |----------|---------|
21//! | [`managed`] | Wraps a [`Database`] into a [`ManagedDatabase`] |
22//! | [`managed_pool`] | Wraps a [`DatabasePool`] into a [`ManagedDatabasePool`] |
23//!
24//! ## Connection & querying
25//!
26//! | Item | Purpose |
27//! |------|---------|
28//! | [`connect`] | Open a database, apply PRAGMAs, optionally run migrations |
29//! | [`migrate`] | Run `*.sql` migrations from a directory with checksum tracking |
30//! | [`ConnExt`] | Low-level `query_raw`/`execute_raw` trait for `Connection` and `Transaction` |
31//! | [`ConnQueryExt`] | High-level `query_one`/`query_all`/`query_optional` + `_map` variants (blanket impl on `ConnExt`) |
32//! | [`SelectBuilder`] | Composable query builder combining filters, sorting, and pagination |
33//!
34//! ## Row mapping
35//!
36//! | Item | Purpose |
37//! |------|---------|
38//! | [`FromRow`] | Trait for converting a `libsql::Row` into a Rust struct |
39//! | [`FromValue`] | Trait for converting a `libsql::Value` into a concrete Rust type |
40//! | [`ColumnMap`] | Column name to index lookup for name-based row access |
41//!
42//! ## Filtering & pagination
43//!
44//! | Item | Purpose |
45//! |------|---------|
46//! | [`Filter`] | Raw parsed filter from query string (axum extractor) |
47//! | [`FilterSchema`] | Declares allowed filter and sort fields for an endpoint |
48//! | [`ValidatedFilter`] | Schema-validated filter safe for SQL generation |
49//! | [`FieldType`] | Column type enum for filter value validation |
50//! | [`PageRequest`] | Offset-based pagination extractor (`?page=N&per_page=N`) |
51//! | [`Page`] | Offset-based page response with total/has_next/has_prev |
52//! | [`CursorRequest`] | Cursor-based pagination extractor (`?after=<cursor>&per_page=N`) |
53//! | [`CursorPage`] | Cursor-based page response with next_cursor/has_more |
54//! | [`PaginationConfig`] | Configurable defaults and limits for pagination extractors |
55//!
56//! ## Configuration enums
57//!
58//! | Enum | Purpose |
59//! |------|---------|
60//! | [`JournalMode`] | SQLite journal mode (WAL, Delete, Truncate, Memory, Off) |
61//! | [`SynchronousMode`] | SQLite synchronous mode (Off, Normal, Full, Extra) |
62//! | [`TempStore`] | SQLite temp store location (Default, File, Memory) |
63//!
64//! ## Maintenance
65//!
66//! | Item | Purpose |
67//! |------|---------|
68//! | [`DbHealth`] | Page-level health metrics from PRAGMA introspection |
69//! | [`VacuumOptions`] | Configuration for [`run_vacuum`] (threshold, dry_run) |
70//! | [`VacuumResult`] | Before/after health snapshots with timing |
71//! | [`run_vacuum`] | VACUUM with threshold guard and health snapshots |
72//! | [`vacuum_if_needed`] | Shorthand for `run_vacuum` with threshold only |
73//! | [`vacuum_handler`] | Cron handler factory for scheduled maintenance |
74//!
75//! ## Re-exports
76//!
77//! The [`libsql`] crate is re-exported for direct access to low-level types
78//! such as `libsql::params!`, `libsql::Value`, `libsql::Connection`, and
79//! `libsql::Transaction`.
80//!
81//! ## Quick start
82//!
83//! ```rust,ignore
84//! use modo::db::{self, ConnExt, ConnQueryExt};
85//!
86//! // Connect with defaults (data/app.db, WAL mode, FK on)
87//! let db = db::connect(&db::Config::default()).await?;
88//!
89//! // Use query helpers via ConnQueryExt
90//! let user: User = db.conn().query_one(
91//!     "SELECT id, name FROM users WHERE id = ?1",
92//!     libsql::params!["user_abc"],
93//! ).await?;
94//!
95//! // Or use the SelectBuilder for filtered, paginated queries
96//! let page = db.conn()
97//!     .select("SELECT id, name FROM users")
98//!     .filter(validated_filter)
99//!     .order_by("\"created_at\" DESC")
100//!     .page::<User>(page_request)
101//!     .await?;
102//! ```
103
104mod error;
105
106mod config;
107pub use config::{Config, JournalMode, PoolConfig, SynchronousMode, TempStore};
108
109mod database;
110pub use database::Database;
111
112mod connect;
113pub use connect::connect;
114
115mod from_row;
116pub use from_row::{ColumnMap, FromRow, FromValue};
117
118mod conn;
119pub use conn::{ConnExt, ConnQueryExt};
120
121mod managed;
122pub use managed::{ManagedDatabase, managed};
123
124mod pool;
125pub use pool::{DatabasePool, ManagedDatabasePool, managed_pool};
126
127mod migrate;
128pub use migrate::migrate;
129
130mod page;
131pub use page::{CursorPage, CursorRequest, Page, PageRequest, PaginationConfig};
132
133mod filter;
134pub use filter::{FieldType, Filter, FilterSchema, ValidatedFilter};
135
136mod select;
137pub use select::SelectBuilder;
138
139mod maintenance;
140pub use maintenance::{
141    DbHealth, VacuumOptions, VacuumResult, run_vacuum, vacuum_handler, vacuum_if_needed,
142};
143
144// Re-export libsql for direct access
145pub use libsql;