waypoint_core/lib.rs
1//! Lightweight, Flyway-compatible PostgreSQL migration library.
2//!
3//! # Quick Start
4//!
5//! ```rust,no_run
6//! use waypoint_core::config::WaypointConfig;
7//! use waypoint_core::Waypoint;
8//!
9//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
10//! let config = WaypointConfig::load(None, None)?;
11//! let wp = Waypoint::new(config).await?;
12//! let report = wp.migrate(None).await?;
13//! println!("Applied {} migrations", report.migrations_applied);
14//! # Ok(())
15//! # }
16//! ```
17//!
18//! # Architecture
19//!
20//! - [`config`] — Configuration loading (TOML, env vars, CLI overrides)
21//! - [`migration`] — Migration file parsing and scanning
22//! - [`db`] — Database connections, TLS, advisory locks
23//! - [`history`] — Schema history table operations
24//! - [`commands`] — Individual command implementations (migrate, info, validate, repair, baseline, clean)
25//! - [`checksum`] — CRC32 checksums (Flyway-compatible)
26//! - [`placeholder`] — `${key}` placeholder replacement in SQL
27//! - [`hooks`] — SQL callback hooks (before/after migrate)
28//! - [`error`] — Error types
29
30pub mod checksum;
31pub mod commands;
32pub mod config;
33pub mod db;
34pub mod error;
35pub mod history;
36pub mod hooks;
37pub mod migration;
38pub mod placeholder;
39
40use config::WaypointConfig;
41use error::Result;
42use tokio_postgres::Client;
43
44pub use commands::info::{MigrationInfo, MigrationState};
45pub use commands::migrate::MigrateReport;
46pub use commands::repair::RepairReport;
47pub use commands::validate::ValidateReport;
48pub use config::CliOverrides;
49
50/// Main entry point for the Waypoint library.
51///
52/// Create a `Waypoint` instance with a config and use its methods to
53/// run migration commands programmatically.
54pub struct Waypoint {
55 pub config: WaypointConfig,
56 client: Client,
57}
58
59impl Waypoint {
60 /// Create a new Waypoint instance, connecting to the database.
61 ///
62 /// If `connect_retries` is configured, retries with exponential backoff.
63 pub async fn new(config: WaypointConfig) -> Result<Self> {
64 let conn_string = config.connection_string()?;
65 let client = db::connect_with_config(
66 &conn_string,
67 &config.database.ssl_mode,
68 config.database.connect_retries,
69 config.database.connect_timeout_secs,
70 config.database.statement_timeout_secs,
71 )
72 .await?;
73 Ok(Self { config, client })
74 }
75
76 /// Create a new Waypoint instance with an existing database client.
77 pub fn with_client(config: WaypointConfig, client: Client) -> Self {
78 Self { config, client }
79 }
80
81 /// Apply pending migrations.
82 pub async fn migrate(&self, target_version: Option<&str>) -> Result<MigrateReport> {
83 commands::migrate::execute(&self.client, &self.config, target_version).await
84 }
85
86 /// Show migration status information.
87 pub async fn info(&self) -> Result<Vec<MigrationInfo>> {
88 commands::info::execute(&self.client, &self.config).await
89 }
90
91 /// Validate applied migrations against local files.
92 pub async fn validate(&self) -> Result<ValidateReport> {
93 commands::validate::execute(&self.client, &self.config).await
94 }
95
96 /// Repair the schema history table.
97 pub async fn repair(&self) -> Result<RepairReport> {
98 commands::repair::execute(&self.client, &self.config).await
99 }
100
101 /// Baseline an existing database.
102 pub async fn baseline(&self, version: Option<&str>, description: Option<&str>) -> Result<()> {
103 commands::baseline::execute(&self.client, &self.config, version, description).await
104 }
105
106 /// Drop all objects in managed schemas.
107 pub async fn clean(&self, allow_clean: bool) -> Result<Vec<String>> {
108 commands::clean::execute(&self.client, &self.config, allow_clean).await
109 }
110}