1use async_trait::async_trait;
19use serde::{Deserialize, Serialize};
20
21use crate::diff::SchemaDiff;
22use crate::errors::Result;
23use crate::snapshot::SchemaSnapshot;
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct MigrationPlan {
31 pub steps: Vec<MigrationStep>,
33
34 pub estimated_duration_secs: f64,
36
37 pub requires_downtime: bool,
39
40 pub warnings: Vec<String>,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46pub struct MigrationStep {
47 pub step_number: usize,
49
50 pub operation: MigrationOperation,
52
53 pub description: String,
55
56 pub reversible: bool,
58
59 pub dependencies: Vec<usize>,
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
65#[serde(tag = "type")]
66pub enum MigrationOperation {
67 CreateTable {
69 table_name: String,
70 columns: Vec<ColumnDefinition>,
71 primary_key: Option<PrimaryKeyDefinition>,
72 indexes: Vec<IndexDefinition>,
73 },
74
75 DropTable {
77 table_name: String,
78 },
79
80 AddColumn {
82 table_name: String,
83 column: ColumnDefinition,
84 },
85
86 DropColumn {
88 table_name: String,
89 column_name: String,
90 },
91
92 ModifyColumn {
94 table_name: String,
95 column_name: String,
96 changes: ColumnChanges,
97 },
98
99 AddForeignKey {
101 table_name: String,
102 constraint: ForeignKeyDefinition,
103 },
104
105 DropForeignKey {
107 table_name: String,
108 constraint_name: String,
109 },
110
111 AddUniqueConstraint {
113 table_name: String,
114 constraint: UniqueConstraintDefinition,
115 },
116
117 DropUniqueConstraint {
119 table_name: String,
120 constraint_name: String,
121 },
122
123 CreateIndex {
125 table_name: String,
126 index: IndexDefinition,
127 },
128
129 DropIndex {
131 table_name: String,
132 index_name: String,
133 },
134
135 AddCheckConstraint {
137 table_name: String,
138 constraint: CheckConstraintDefinition,
139 },
140
141 DropCheckConstraint {
143 table_name: String,
144 constraint_name: String,
145 },
146
147 CreateView {
149 view_name: String,
150 definition: String,
151 },
152
153 DropView {
155 view_name: String,
156 },
157
158 ModifyView {
160 view_name: String,
161 new_definition: String,
162 },
163
164 CreateFunction {
166 function_name: String,
167 signature: String,
168 body: String,
169 return_type: String,
170 },
171
172 DropFunction {
174 function_name: String,
175 signature: String,
176 },
177
178 CreateType {
180 type_name: String,
181 kind: String,
182 definition: String,
183 },
184
185 DropType {
187 type_name: String,
188 },
189}
190
191#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
193pub struct ColumnDefinition {
194 pub name: String,
195 pub data_type: String,
196 pub nullable: bool,
197 pub default_value: Option<String>,
198 pub auto_increment: bool,
199}
200
201#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
203pub struct PrimaryKeyDefinition {
204 pub name: String,
205 pub columns: Vec<String>,
206}
207
208#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
210pub struct ForeignKeyDefinition {
211 pub name: String,
212 pub columns: Vec<String>,
213 pub referenced_table: String,
214 pub referenced_columns: Vec<String>,
215 pub on_delete: Option<String>,
216 pub on_update: Option<String>,
217}
218
219#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
221pub struct UniqueConstraintDefinition {
222 pub name: String,
223 pub columns: Vec<String>,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
228pub struct IndexDefinition {
229 pub name: String,
230 pub columns: Vec<String>,
231 pub unique: bool,
232 pub index_type: Option<String>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
237pub struct CheckConstraintDefinition {
238 pub name: String,
239 pub expression: String,
240}
241
242#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
244pub struct ColumnChanges {
245 pub data_type: Option<TypeChange>,
246 pub nullable: Option<bool>,
247 pub default_value: Option<DefaultChange>,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
252pub struct TypeChange {
253 pub old_type: String,
254 pub new_type: String,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
259pub struct DefaultChange {
260 pub old_default: Option<String>,
261 pub new_default: Option<String>,
262}
263
264#[async_trait]
272pub trait Planner: Send + Sync {
273 async fn create_plan(
285 &self,
286 current: &SchemaSnapshot,
287 target: &SchemaSnapshot,
288 diff: &SchemaDiff,
289 ) -> Result<MigrationPlan>;
290
291 async fn validate_plan(&self, plan: &MigrationPlan) -> Result<()>;
298}
299