1use std::fmt;
2
3use bon::bon;
4use sqlparser::ast::{CreateDomain, CreateIndex};
5use thiserror::Error;
6
7use crate::{
8 ast::{
9 AlterTable, AlterTableOperation, AlterType, AlterTypeOperation, CreateExtension,
10 CreateTable, CreateType, Statement,
11 },
12 dialect::{Generic, PostgreSQL, SQLite},
13 sealed::Sealed,
14};
15
16pub mod generic;
17
18#[derive(Error, Debug)]
19pub struct MigrateError {
20 kind: MigrateErrorKind,
21 statement_a: Option<Box<Statement>>,
22 statement_b: Option<Box<Statement>>,
23}
24
25impl fmt::Display for MigrateError {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 write!(
28 f,
29 "Oops, we couldn't migrate that: {reason}",
30 reason = self.kind
31 )?;
32 if let Some(statement_a) = &self.statement_a {
33 write!(f, "\n\nSubject:\n{statement_a}")?;
34 }
35 if let Some(statement_b) = &self.statement_b {
36 write!(f, "\n\nMigration:\n{statement_b}")?;
37 }
38 Ok(())
39 }
40}
41
42#[bon]
43impl MigrateError {
44 #[builder]
45 fn new(
46 kind: MigrateErrorKind,
47 statement_a: Option<Statement>,
48 statement_b: Option<Statement>,
49 ) -> Self {
50 Self {
51 kind,
52 statement_a: statement_a.map(Box::new),
53 statement_b: statement_b.map(Box::new),
54 }
55 }
56}
57
58#[derive(Error, Debug)]
59#[non_exhaustive]
60enum MigrateErrorKind {
61 #[error("ALTER TABLE operation \"{0}\" not yet supported")]
62 AlterTableOpNotImplemented(Box<AlterTableOperation>),
63 #[error("invalid ALTER TYPE operation \"{0}\"")]
64 AlterTypeInvalidOp(Box<AlterTypeOperation>),
65 #[error("not yet supported")]
66 NotImplemented,
67}
68
69type Result<T, E = MigrateError> = std::result::Result<T, E>;
70
71pub trait TreeMigrator: StatementMigrator + Sealed {
72 fn migrate_tree(&self, a: Vec<Statement>, b: &[Statement]) -> Result<Vec<Statement>> {
73 generic::tree::migrate_tree(self, a, b)
74 }
75
76 fn match_and_migrate_create_table(
77 &self,
78 sa: &Statement,
79 a: &CreateTable,
80 b: &[Statement],
81 ) -> Result<Vec<Statement>> {
82 generic::tree::match_and_migrate_create_table(self, sa, a, b)
83 }
84
85 fn match_and_migrate_create_index(
86 &self,
87 sa: &Statement,
88 a: &CreateIndex,
89 b: &[Statement],
90 ) -> Result<Vec<Statement>> {
91 generic::tree::match_and_migrate_create_index(self, sa, a, b)
92 }
93
94 fn match_and_migrate_create_type(
95 &self,
96 sa: &Statement,
97 a: &CreateType,
98 b: &[Statement],
99 ) -> Result<Vec<Statement>> {
100 generic::tree::match_and_migrate_create_type(self, sa, a, b)
101 }
102
103 fn match_and_migrate_create_extension(
104 &self,
105 sa: &Statement,
106 a: &CreateExtension,
107 b: &[Statement],
108 ) -> Result<Vec<Statement>> {
109 generic::tree::match_and_migrate_create_extension(self, sa, a, b)
110 }
111
112 fn match_and_migrate_create_domain(
113 &self,
114 sa: &Statement,
115 a: &CreateDomain,
116 b: &[Statement],
117 ) -> Result<Vec<Statement>> {
118 generic::tree::match_and_migrate_create_domain(self, sa, a, b)
119 }
120}
121
122impl TreeMigrator for Generic {}
123
124impl TreeMigrator for PostgreSQL {}
125
126impl TreeMigrator for SQLite {}
127
128pub trait StatementMigrator: fmt::Debug + Default + Clone + Sized + Sealed {
129 fn migrate(&self, a: &Statement, b: &Statement) -> Result<Vec<Statement>> {
130 generic::statement::migrate(self, a, b)
131 }
132
133 fn migrate_create_table(&self, a: &CreateTable, sb: &Statement) -> Result<Vec<Statement>> {
134 generic::statement::migrate_create_table(self, a, sb)
135 }
136
137 fn migrate_alter_table(&self, a: &CreateTable, b: &AlterTable) -> Result<Vec<Statement>> {
138 generic::statement::migrate_alter_table(self, a, b)
139 }
140
141 fn migrate_create_index(&self, a: &CreateIndex, sb: &Statement) -> Result<Vec<Statement>> {
142 generic::statement::migrate_create_index(self, a, sb)
143 }
144
145 fn migrate_create_type(&self, a: &CreateType, sb: &Statement) -> Result<Vec<Statement>> {
146 generic::statement::migrate_create_type(self, a, sb)
147 }
148
149 fn migrate_alter_type(&self, a: &CreateType, b: &AlterType) -> Result<Vec<Statement>> {
150 generic::statement::migrate_alter_type(self, a, b)
151 }
152
153 fn migrate_create_extension(
154 &self,
155 a: &CreateExtension,
156 sb: &Statement,
157 ) -> Result<Vec<Statement>> {
158 generic::statement::migrate_create_extension(self, a, sb)
159 }
160
161 fn migrate_create_domain(&self, a: &CreateDomain, sb: &Statement) -> Result<Vec<Statement>> {
162 generic::statement::migrate_create_domain(self, a, sb)
163 }
164}
165
166impl StatementMigrator for Generic {}
167
168impl StatementMigrator for PostgreSQL {}
169
170impl StatementMigrator for SQLite {}