spring_sqlx_migration_plugin/
lib.rs

1use serde::Deserialize;
2use spring::async_trait;
3use spring::config::{ConfigRegistry, Configurable};
4use spring::plugin::ComponentRegistry;
5use spring::tracing::{error, info};
6use spring::{app::AppBuilder, plugin::Plugin};
7use spring_sqlx::{ConnectPool, SqlxPlugin};
8use sqlx::migrate::Migrator;
9
10pub struct SqlxMigrationPlugin;
11
12#[async_trait]
13impl Plugin for SqlxMigrationPlugin {
14    async fn build(&self, app: &mut AppBuilder) {
15        let Ok(SqlxMigrationConfig { migration_folder }) = app.get_config::<SqlxMigrationConfig>() else {
16            error!("SqlxMigrationPlugin require the migration_folder config");
17            return;
18        };
19
20        let pool = app.get_component::<ConnectPool>().expect("sqlx connect pool not exists");
21
22        let Ok(migration_path) = std::path::absolute(migration_folder) else {
23            error!("Folder not found");
24            return;
25        };
26
27        let Ok(migrator) = Migrator::new(migration_path).await else {
28            error!("SQLX Migration plugin load failed");
29            return;
30        };
31
32        let count = migrator.iter().count();
33        info!("Migrations to run: {count}");
34
35        migrator.iter().for_each(|migration| {
36            let description = migration.description.clone();
37            let version = migration.version;
38            info!("{description} {version}");
39        });
40
41        if let Err(error) = migrator.run(&pool).await {
42            error!("Something goes wrong executing the migrations!");
43            error!("{error:#}")
44        }
45
46    }
47
48    fn dependencies(&self) -> Vec<&str> {
49        vec![std::any::type_name::<SqlxPlugin>()]
50    }
51}
52
53#[derive(Debug, Configurable, Deserialize)]
54#[config_prefix = "sqlx-migration"]
55pub struct SqlxMigrationConfig {
56    migration_folder: String,
57}