Skip to main content

spawn_db/commands/migration/
build.rs

1use crate::commands::{Command, Outcome, TelemetryDescribe, TelemetryInfo};
2use crate::config::Config;
3use crate::migrator::Migrator;
4use crate::store::get_migration_fs_status;
5use crate::variables::Variables;
6use anyhow::Result;
7
8pub struct BuildMigration {
9    pub migration: String,
10    pub pinned: bool,
11    pub variables: Option<Variables>,
12}
13
14impl TelemetryDescribe for BuildMigration {
15    fn telemetry(&self) -> TelemetryInfo {
16        TelemetryInfo::new("migration build").with_properties(vec![
17            ("opt_pinned", self.pinned.to_string()),
18            ("has_variables", self.variables.is_some().to_string()),
19        ])
20    }
21}
22
23impl Command for BuildMigration {
24    async fn execute(&self, config: &Config) -> Result<Outcome> {
25        let mgrtr = Migrator::new(config, &self.migration, self.pinned);
26
27        // Check if lock file exists when not using --pinned
28        let pinned_warn = if !self.pinned {
29            let fs_status =
30                get_migration_fs_status(config.operator(), &config.pather(), &self.migration)
31                    .await?;
32            fs_status.has_lock_toml
33        } else {
34            false
35        };
36
37        match mgrtr.generate_streaming(self.variables.clone()).await {
38            Ok(gen) => {
39                let mut buffer = Vec::new();
40                gen.render_to_writer(&mut buffer)
41                    .map_err(std::io::Error::other)?;
42                let content = String::from_utf8(buffer)?;
43
44                Ok(Outcome::BuiltMigration {
45                    content,
46                    pinned_warn,
47                })
48            }
49            Err(e) => Err(e),
50        }
51    }
52}