1pub mod advisor;
45pub mod checksum;
46pub mod commands;
47pub mod config;
48pub mod db;
49pub mod dependency;
50pub mod dialect;
51pub mod directive;
52pub mod engines;
53pub mod error;
54pub mod guard;
55pub mod history;
56pub mod hooks;
57pub mod migration;
58pub mod multi;
59pub mod placeholder;
60pub mod preflight;
61pub mod reversal;
62pub mod safety;
63pub mod schema;
64pub mod sql_parser;
65
66use std::path::PathBuf;
67
68use config::WaypointConfig;
69use db::DbClient;
70use error::Result;
71
72#[cfg(feature = "postgres")]
73use tokio_postgres::Client;
74
75pub use advisor::AdvisorReport;
76pub use commands::changelog::ChangelogReport;
77pub use commands::check_conflicts::ConflictReport;
78pub use commands::diff::DiffReport;
79pub use commands::drift::DriftReport;
80pub use commands::explain::ExplainReport;
81pub use commands::info::{MigrationInfo, MigrationState};
82pub use commands::lint::LintReport;
83pub use commands::migrate::MigrateReport;
84pub use commands::repair::RepairReport;
85pub use commands::safety::SafetyCommandReport;
86pub use commands::simulate::SimulationReport;
87pub use commands::snapshot::{RestoreReport, SnapshotReport};
88pub use commands::undo::{UndoReport, UndoTarget};
89pub use commands::validate::ValidateReport;
90pub use config::CliOverrides;
91pub use dialect::{DatabaseDialect, DialectKind};
92pub use multi::MultiWaypoint;
93pub use preflight::PreflightReport;
94pub use safety::SafetyReport;
95
96pub struct Waypoint {
101 pub config: WaypointConfig,
102 client: DbClient,
103}
104
105impl Waypoint {
106 pub async fn new(config: WaypointConfig) -> Result<Self> {
112 let conn_string = config.connection_string()?;
113 let client = db::connect_for_url(&conn_string, &config).await?;
114 Ok(Self { config, client })
115 }
116
117 #[cfg(feature = "postgres")]
122 pub fn with_client(config: WaypointConfig, client: Client) -> Self {
123 Self {
124 config,
125 client: DbClient::with_postgres(client),
126 }
127 }
128
129 pub fn with_db_client(config: WaypointConfig, client: DbClient) -> Self {
131 Self { config, client }
132 }
133
134 pub fn client(&self) -> &DbClient {
136 &self.client
137 }
138
139 #[cfg(feature = "postgres")]
145 pub fn postgres_client(&self) -> Result<&Client> {
146 self.client.as_postgres()
147 }
148
149 pub async fn migrate(&self, target_version: Option<&str>) -> Result<MigrateReport> {
151 self.migrate_with_options(target_version, false).await
152 }
153
154 pub async fn migrate_with_options(
158 &self,
159 target_version: Option<&str>,
160 force: bool,
161 ) -> Result<MigrateReport> {
162 match self.client.dialect_kind() {
163 #[cfg(feature = "postgres")]
164 DialectKind::Postgres => {
165 commands::migrate::execute_with_options(
166 self.client.as_postgres()?,
167 &self.config,
168 target_version,
169 force,
170 )
171 .await
172 }
173 #[cfg(not(feature = "postgres"))]
174 DialectKind::Postgres => Err(error::WaypointError::ConfigError(
175 "PostgreSQL support is not compiled in (enable the `postgres` feature)".into(),
176 )),
177 #[cfg(feature = "mysql")]
178 DialectKind::Mysql => {
179 commands::migrate::execute_mysql_with_options(
180 &self.client,
181 &self.config,
182 target_version,
183 force,
184 )
185 .await
186 }
187 #[cfg(not(feature = "mysql"))]
188 DialectKind::Mysql => Err(error::WaypointError::ConfigError(
189 "MySQL support is not compiled in (enable the `mysql` feature)".into(),
190 )),
191 }
192 }
193
194 pub async fn info(&self) -> Result<Vec<MigrationInfo>> {
196 commands::info::execute_db(&self.client, &self.config).await
197 }
198
199 pub async fn validate(&self) -> Result<ValidateReport> {
201 commands::validate::execute_db(&self.client, &self.config).await
202 }
203
204 pub async fn repair(&self) -> Result<RepairReport> {
206 commands::repair::execute_db(&self.client, &self.config).await
207 }
208
209 pub async fn baseline(&self, version: Option<&str>, description: Option<&str>) -> Result<()> {
211 commands::baseline::execute_db(&self.client, &self.config, version, description).await
212 }
213
214 pub async fn undo(&self, target: UndoTarget) -> Result<UndoReport> {
216 commands::undo::execute_db(&self.client, &self.config, target).await
217 }
218
219 pub async fn clean(&self, allow_clean: bool) -> Result<Vec<String>> {
221 commands::clean::execute_db(&self.client, &self.config, allow_clean).await
222 }
223
224 pub fn lint(locations: &[PathBuf], disabled_rules: &[String]) -> Result<LintReport> {
226 commands::lint::execute(locations, disabled_rules)
227 }
228
229 pub fn changelog(
231 locations: &[PathBuf],
232 from: Option<&str>,
233 to: Option<&str>,
234 ) -> Result<ChangelogReport> {
235 commands::changelog::execute(locations, from, to)
236 }
237
238 pub async fn diff(&self, target: commands::diff::DiffTarget) -> Result<DiffReport> {
240 commands::diff::execute_db(&self.client, &self.config, target).await
241 }
242
243 pub async fn drift(&self) -> Result<DriftReport> {
245 commands::drift::execute_db(&self.client, &self.config).await
246 }
247
248 pub async fn snapshot(
250 &self,
251 snapshot_config: &commands::snapshot::SnapshotConfig,
252 ) -> Result<SnapshotReport> {
253 commands::snapshot::execute_snapshot_db(&self.client, &self.config, snapshot_config).await
254 }
255
256 pub async fn restore(
258 &self,
259 snapshot_config: &commands::snapshot::SnapshotConfig,
260 snapshot_id: &str,
261 ) -> Result<RestoreReport> {
262 commands::snapshot::execute_restore_db(
263 &self.client,
264 &self.config,
265 snapshot_config,
266 snapshot_id,
267 )
268 .await
269 }
270
271 pub async fn explain(&self) -> Result<ExplainReport> {
273 commands::explain::execute_db(&self.client, &self.config).await
274 }
275
276 pub async fn preflight(&self) -> Result<PreflightReport> {
278 preflight::run_preflight_db(&self.client, &self.config.preflight).await
279 }
280
281 pub fn check_conflicts(locations: &[PathBuf], base_branch: &str) -> Result<ConflictReport> {
283 commands::check_conflicts::execute(locations, base_branch)
284 }
285
286 pub async fn safety(&self) -> Result<SafetyCommandReport> {
288 commands::safety::execute_db(&self.client, &self.config).await
289 }
290
291 pub async fn advise(&self) -> Result<AdvisorReport> {
293 commands::advisor::execute_db(&self.client, &self.config).await
294 }
295
296 pub async fn simulate(&self) -> Result<SimulationReport> {
298 commands::simulate::execute_db(&self.client, &self.config).await
299 }
300}