Skip to main content

sql_orm_migrate/
operation.rs

1use crate::{ColumnSnapshot, ForeignKeySnapshot, IndexSnapshot, TableSnapshot};
2
3/// Ordered migration operations emitted by the diff engine.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum MigrationOperation {
6    CreateSchema(CreateSchema),
7    DropSchema(DropSchema),
8    CreateTable(CreateTable),
9    DropTable(DropTable),
10    RenameTable(RenameTable),
11    RenameColumn(RenameColumn),
12    AddColumn(AddColumn),
13    DropColumn(DropColumn),
14    AlterColumn(AlterColumn),
15    CreateIndex(CreateIndex),
16    DropIndex(DropIndex),
17    AddForeignKey(AddForeignKey),
18    DropForeignKey(DropForeignKey),
19}
20
21impl MigrationOperation {
22    pub fn schema_name(&self) -> &str {
23        match self {
24            Self::CreateSchema(operation) => &operation.schema_name,
25            Self::DropSchema(operation) => &operation.schema_name,
26            Self::CreateTable(operation) => &operation.schema_name,
27            Self::DropTable(operation) => &operation.schema_name,
28            Self::RenameTable(operation) => &operation.schema_name,
29            Self::RenameColumn(operation) => &operation.schema_name,
30            Self::AddColumn(operation) => &operation.schema_name,
31            Self::DropColumn(operation) => &operation.schema_name,
32            Self::AlterColumn(operation) => &operation.schema_name,
33            Self::CreateIndex(operation) => &operation.schema_name,
34            Self::DropIndex(operation) => &operation.schema_name,
35            Self::AddForeignKey(operation) => &operation.schema_name,
36            Self::DropForeignKey(operation) => &operation.schema_name,
37        }
38    }
39
40    pub fn table_name(&self) -> Option<&str> {
41        match self {
42            Self::CreateSchema(_) | Self::DropSchema(_) => None,
43            Self::CreateTable(operation) => Some(&operation.table.name),
44            Self::DropTable(operation) => Some(&operation.table_name),
45            Self::RenameTable(operation) => Some(&operation.next_table_name),
46            Self::RenameColumn(operation) => Some(&operation.table_name),
47            Self::AddColumn(operation) => Some(&operation.table_name),
48            Self::DropColumn(operation) => Some(&operation.table_name),
49            Self::AlterColumn(operation) => Some(&operation.table_name),
50            Self::CreateIndex(operation) => Some(&operation.table_name),
51            Self::DropIndex(operation) => Some(&operation.table_name),
52            Self::AddForeignKey(operation) => Some(&operation.table_name),
53            Self::DropForeignKey(operation) => Some(&operation.table_name),
54        }
55    }
56}
57
58/// Create a missing SQL Server schema.
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct CreateSchema {
61    pub schema_name: String,
62}
63
64impl CreateSchema {
65    pub fn new(schema_name: impl Into<String>) -> Self {
66        Self {
67            schema_name: schema_name.into(),
68        }
69    }
70}
71
72/// Drop a SQL Server schema that no longer exists in the model.
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub struct DropSchema {
75    pub schema_name: String,
76}
77
78impl DropSchema {
79    pub fn new(schema_name: impl Into<String>) -> Self {
80        Self {
81            schema_name: schema_name.into(),
82        }
83    }
84}
85
86/// Create a table from its full snapshot.
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct CreateTable {
89    pub schema_name: String,
90    pub table: TableSnapshot,
91}
92
93impl CreateTable {
94    pub fn new(schema_name: impl Into<String>, table: TableSnapshot) -> Self {
95        Self {
96            schema_name: schema_name.into(),
97            table,
98        }
99    }
100}
101
102/// Drop a table by schema and name.
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct DropTable {
105    pub schema_name: String,
106    pub table_name: String,
107}
108
109impl DropTable {
110    pub fn new(schema_name: impl Into<String>, table_name: impl Into<String>) -> Self {
111        Self {
112            schema_name: schema_name.into(),
113            table_name: table_name.into(),
114        }
115    }
116}
117
118/// Rename an existing table inside the same schema without recreating it.
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct RenameTable {
121    pub schema_name: String,
122    pub previous_table_name: String,
123    pub next_table_name: String,
124}
125
126impl RenameTable {
127    pub fn new(
128        schema_name: impl Into<String>,
129        previous_table_name: impl Into<String>,
130        next_table_name: impl Into<String>,
131    ) -> Self {
132        Self {
133            schema_name: schema_name.into(),
134            previous_table_name: previous_table_name.into(),
135            next_table_name: next_table_name.into(),
136        }
137    }
138}
139
140/// Rename an existing column in a table without recreating it.
141#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct RenameColumn {
143    pub schema_name: String,
144    pub table_name: String,
145    pub previous_column_name: String,
146    pub next_column_name: String,
147}
148
149impl RenameColumn {
150    pub fn new(
151        schema_name: impl Into<String>,
152        table_name: impl Into<String>,
153        previous_column_name: impl Into<String>,
154        next_column_name: impl Into<String>,
155    ) -> Self {
156        Self {
157            schema_name: schema_name.into(),
158            table_name: table_name.into(),
159            previous_column_name: previous_column_name.into(),
160            next_column_name: next_column_name.into(),
161        }
162    }
163}
164
165/// Add a new column to an existing table.
166#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct AddColumn {
168    pub schema_name: String,
169    pub table_name: String,
170    pub column: ColumnSnapshot,
171}
172
173impl AddColumn {
174    pub fn new(
175        schema_name: impl Into<String>,
176        table_name: impl Into<String>,
177        column: ColumnSnapshot,
178    ) -> Self {
179        Self {
180            schema_name: schema_name.into(),
181            table_name: table_name.into(),
182            column,
183        }
184    }
185}
186
187/// Drop an existing column from a table.
188#[derive(Debug, Clone, PartialEq, Eq)]
189pub struct DropColumn {
190    pub schema_name: String,
191    pub table_name: String,
192    pub column_name: String,
193}
194
195impl DropColumn {
196    pub fn new(
197        schema_name: impl Into<String>,
198        table_name: impl Into<String>,
199        column_name: impl Into<String>,
200    ) -> Self {
201        Self {
202            schema_name: schema_name.into(),
203            table_name: table_name.into(),
204            column_name: column_name.into(),
205        }
206    }
207}
208
209/// Alter an existing column by comparing the previous and desired snapshots.
210#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct AlterColumn {
212    pub schema_name: String,
213    pub table_name: String,
214    pub previous: ColumnSnapshot,
215    pub next: ColumnSnapshot,
216}
217
218impl AlterColumn {
219    pub fn new(
220        schema_name: impl Into<String>,
221        table_name: impl Into<String>,
222        previous: ColumnSnapshot,
223        next: ColumnSnapshot,
224    ) -> Self {
225        Self {
226            schema_name: schema_name.into(),
227            table_name: table_name.into(),
228            previous,
229            next,
230        }
231    }
232}
233
234/// Create a missing index on an existing table.
235#[derive(Debug, Clone, PartialEq, Eq)]
236pub struct CreateIndex {
237    pub schema_name: String,
238    pub table_name: String,
239    pub index: IndexSnapshot,
240}
241
242impl CreateIndex {
243    pub fn new(
244        schema_name: impl Into<String>,
245        table_name: impl Into<String>,
246        index: IndexSnapshot,
247    ) -> Self {
248        Self {
249            schema_name: schema_name.into(),
250            table_name: table_name.into(),
251            index,
252        }
253    }
254}
255
256/// Drop an index from an existing table.
257#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct DropIndex {
259    pub schema_name: String,
260    pub table_name: String,
261    pub index_name: String,
262}
263
264impl DropIndex {
265    pub fn new(
266        schema_name: impl Into<String>,
267        table_name: impl Into<String>,
268        index_name: impl Into<String>,
269    ) -> Self {
270        Self {
271            schema_name: schema_name.into(),
272            table_name: table_name.into(),
273            index_name: index_name.into(),
274        }
275    }
276}
277
278/// Add a foreign key to an existing table.
279#[derive(Debug, Clone, PartialEq, Eq)]
280pub struct AddForeignKey {
281    pub schema_name: String,
282    pub table_name: String,
283    pub foreign_key: ForeignKeySnapshot,
284}
285
286impl AddForeignKey {
287    pub fn new(
288        schema_name: impl Into<String>,
289        table_name: impl Into<String>,
290        foreign_key: ForeignKeySnapshot,
291    ) -> Self {
292        Self {
293            schema_name: schema_name.into(),
294            table_name: table_name.into(),
295            foreign_key,
296        }
297    }
298}
299
300/// Drop a foreign key from an existing table.
301#[derive(Debug, Clone, PartialEq, Eq)]
302pub struct DropForeignKey {
303    pub schema_name: String,
304    pub table_name: String,
305    pub foreign_key_name: String,
306}
307
308impl DropForeignKey {
309    pub fn new(
310        schema_name: impl Into<String>,
311        table_name: impl Into<String>,
312        foreign_key_name: impl Into<String>,
313    ) -> Self {
314        Self {
315            schema_name: schema_name.into(),
316            table_name: table_name.into(),
317            foreign_key_name: foreign_key_name.into(),
318        }
319    }
320}