sea_orm_migration/migrator/
with_self.rs1use super::{Migration, MigrationStatus, exec::*};
2use crate::{IntoSchemaManagerConnection, MigrationTrait, SchemaManager, seaql_migrations};
3use sea_orm::sea_query::IntoIden;
4use sea_orm::{ConnectionTrait, DbErr, DynIden};
5
6use tracing::info;
7
8#[async_trait::async_trait]
10pub trait MigratorTraitSelf: Sized + Send + Sync {
11 fn migrations(&self) -> Vec<Box<dyn MigrationTrait>>;
13
14 fn migration_table_name(&self) -> DynIden {
16 seaql_migrations::Entity.into_iden()
17 }
18
19 fn get_migration_files(&self) -> Vec<Migration> {
21 self.migrations()
22 .into_iter()
23 .map(|migration| Migration {
24 migration,
25 status: MigrationStatus::Pending,
26 })
27 .collect()
28 }
29
30 async fn get_migration_models<C>(&self, db: &C) -> Result<Vec<seaql_migrations::Model>, DbErr>
32 where
33 C: ConnectionTrait,
34 {
35 self.install(db).await?;
36 get_migration_models(db, self.migration_table_name()).await
37 }
38
39 async fn get_migration_with_status<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
41 where
42 C: ConnectionTrait,
43 {
44 self.install(db).await?;
45 get_migration_with_status(
46 self.get_migration_files(),
47 self.get_migration_models(db).await?,
48 )
49 }
50
51 async fn get_pending_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
53 where
54 C: ConnectionTrait,
55 {
56 self.install(db).await?;
57 Ok(self
58 .get_migration_with_status(db)
59 .await?
60 .into_iter()
61 .filter(|file| file.status == MigrationStatus::Pending)
62 .collect())
63 }
64
65 async fn get_applied_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
67 where
68 C: ConnectionTrait,
69 {
70 self.install(db).await?;
71 Ok(self
72 .get_migration_with_status(db)
73 .await?
74 .into_iter()
75 .filter(|file| file.status == MigrationStatus::Applied)
76 .collect())
77 }
78
79 async fn get_migration_with_status_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
86 where
87 C: ConnectionTrait,
88 {
89 get_migration_with_status(
90 self.get_migration_files(),
91 get_migration_models_read_only(db, self.migration_table_name()).await?,
92 )
93 }
94
95 async fn get_pending_migrations_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
100 where
101 C: ConnectionTrait,
102 {
103 Ok(self
104 .get_migration_with_status_read_only(db)
105 .await?
106 .into_iter()
107 .filter(|file| file.status == MigrationStatus::Pending)
108 .collect())
109 }
110
111 async fn get_applied_migrations_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
116 where
117 C: ConnectionTrait,
118 {
119 Ok(self
120 .get_migration_with_status_read_only(db)
121 .await?
122 .into_iter()
123 .filter(|file| file.status == MigrationStatus::Applied)
124 .collect())
125 }
126
127 async fn install<C>(&self, db: &C) -> Result<(), DbErr>
129 where
130 C: ConnectionTrait,
131 {
132 install(db, self.migration_table_name()).await
133 }
134
135 async fn status<C>(&self, db: &C) -> Result<(), DbErr>
137 where
138 C: ConnectionTrait,
139 {
140 self.install(db).await?;
141
142 info!("Checking migration status");
143
144 for Migration { migration, status } in self.get_migration_with_status(db).await? {
145 info!("Migration '{}'... {}", migration.name(), status);
146 }
147
148 Ok(())
149 }
150
151 async fn fresh<'c, C>(&self, db: C) -> Result<(), DbErr>
153 where
154 C: IntoSchemaManagerConnection<'c>,
155 {
156 let db = db.into_database_executor();
157 let manager = SchemaManager::new(db);
158 exec_fresh(self, &manager).await
159 }
160
161 async fn refresh<'c, C>(&self, db: C) -> Result<(), DbErr>
163 where
164 C: IntoSchemaManagerConnection<'c>,
165 {
166 let db = db.into_database_executor();
167 let manager = SchemaManager::new(db);
168 exec_down(self, &manager, None).await?;
169 exec_up(self, &manager, None).await
170 }
171
172 async fn reset<'c, C>(&self, db: C) -> Result<(), DbErr>
174 where
175 C: IntoSchemaManagerConnection<'c>,
176 {
177 let db = db.into_database_executor();
178 let manager = SchemaManager::new(db);
179 exec_down(self, &manager, None).await?;
180 uninstall(&manager, self.migration_table_name()).await
181 }
182
183 async fn uninstall<'c, C>(&self, db: C) -> Result<(), DbErr>
186 where
187 C: IntoSchemaManagerConnection<'c>,
188 {
189 let db = db.into_database_executor();
190 let manager = SchemaManager::new(db);
191 uninstall(&manager, self.migration_table_name()).await
192 }
193
194 async fn up<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>
196 where
197 C: IntoSchemaManagerConnection<'c>,
198 {
199 let db = db.into_database_executor();
200 let manager = SchemaManager::new(db);
201 exec_up(self, &manager, steps).await
202 }
203
204 async fn down<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>
206 where
207 C: IntoSchemaManagerConnection<'c>,
208 {
209 let db = db.into_database_executor();
210 let manager = SchemaManager::new(db);
211 exec_down(self, &manager, steps).await
212 }
213}
214
215#[async_trait::async_trait]
216impl<M> MigratorTraitSelf for M
217where
218 M: super::MigratorTrait + Sized + Send + Sync,
219{
220 fn migrations(&self) -> Vec<Box<dyn MigrationTrait>> {
221 M::migrations()
222 }
223
224 fn migration_table_name(&self) -> DynIden {
225 M::migration_table_name()
226 }
227
228 fn get_migration_files(&self) -> Vec<Migration> {
229 M::get_migration_files()
230 }
231
232 async fn get_migration_models<C>(&self, db: &C) -> Result<Vec<seaql_migrations::Model>, DbErr>
233 where
234 C: ConnectionTrait,
235 {
236 M::get_migration_models(db).await
237 }
238
239 async fn get_migration_with_status<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
240 where
241 C: ConnectionTrait,
242 {
243 M::get_migration_with_status(db).await
244 }
245
246 async fn get_pending_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
247 where
248 C: ConnectionTrait,
249 {
250 M::get_pending_migrations(db).await
251 }
252
253 async fn get_migration_with_status_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
254 where
255 C: ConnectionTrait,
256 {
257 M::get_migration_with_status_read_only(db).await
258 }
259
260 async fn get_pending_migrations_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
261 where
262 C: ConnectionTrait,
263 {
264 M::get_pending_migrations_read_only(db).await
265 }
266
267 async fn get_applied_migrations_read_only<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
268 where
269 C: ConnectionTrait,
270 {
271 M::get_applied_migrations_read_only(db).await
272 }
273
274 async fn get_applied_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>
275 where
276 C: ConnectionTrait,
277 {
278 M::get_applied_migrations(db).await
279 }
280
281 async fn install<C>(&self, db: &C) -> Result<(), DbErr>
282 where
283 C: ConnectionTrait,
284 {
285 M::install(db).await
286 }
287
288 async fn status<C>(&self, db: &C) -> Result<(), DbErr>
290 where
291 C: ConnectionTrait,
292 {
293 M::status(db).await
294 }
295
296 async fn fresh<'c, C>(&self, db: C) -> Result<(), DbErr>
297 where
298 C: IntoSchemaManagerConnection<'c>,
299 {
300 M::fresh(db).await
301 }
302
303 async fn refresh<'c, C>(&self, db: C) -> Result<(), DbErr>
304 where
305 C: IntoSchemaManagerConnection<'c>,
306 {
307 M::refresh(db).await
308 }
309
310 async fn reset<'c, C>(&self, db: C) -> Result<(), DbErr>
311 where
312 C: IntoSchemaManagerConnection<'c>,
313 {
314 M::reset(db).await
315 }
316
317 async fn uninstall<'c, C>(&self, db: C) -> Result<(), DbErr>
318 where
319 C: IntoSchemaManagerConnection<'c>,
320 {
321 M::uninstall(db).await
322 }
323
324 async fn up<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>
325 where
326 C: IntoSchemaManagerConnection<'c>,
327 {
328 M::up(db, steps).await
329 }
330
331 async fn down<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>
332 where
333 C: IntoSchemaManagerConnection<'c>,
334 {
335 M::down(db, steps).await
336 }
337}
338
339async fn exec_fresh<M>(migrator: &M, manager: &SchemaManager<'_>) -> Result<(), DbErr>
340where
341 M: MigratorTraitSelf,
342{
343 let db = manager.get_connection();
344
345 migrator.install(db).await?;
346
347 drop_everything(db).await?;
348
349 exec_up(migrator, manager, None).await
350}
351
352async fn exec_up<M>(
353 migrator: &M,
354 manager: &SchemaManager<'_>,
355 steps: Option<u32>,
356) -> Result<(), DbErr>
357where
358 M: MigratorTraitSelf,
359{
360 let db = manager.get_connection();
361
362 migrator.install(db).await?;
363
364 exec_up_with(
365 manager,
366 steps,
367 migrator.get_pending_migrations(db).await?,
368 migrator.migration_table_name(),
369 )
370 .await
371}
372
373async fn exec_down<M>(
374 migrator: &M,
375 manager: &SchemaManager<'_>,
376 steps: Option<u32>,
377) -> Result<(), DbErr>
378where
379 M: MigratorTraitSelf,
380{
381 let db = manager.get_connection();
382
383 migrator.install(db).await?;
384
385 exec_down_with(
386 manager,
387 steps,
388 migrator.get_applied_migrations(db).await?,
389 migrator.migration_table_name(),
390 )
391 .await
392}