Skip to main content

sofie_db/migrate/
fresh.rs

1use sofie_core::{Error, Result, SqlValue};
2
3use super::{Migrations, Schema};
4use crate::{Step, query_values};
5
6impl Schema<'_> {
7    /// Schemas no migration made are left alone; without schemas, every table goes.
8    pub async fn fresh(self, modules: &[Migrations]) -> Result<()> {
9        let drops = match self.db.driver().dialect().drop_every_table() {
10            Some(statements) => self.table_drops(statements).await?,
11            None => self.schema_drops(modules),
12        };
13        self.db.transaction(drops).await?;
14        self.migrate(modules).await
15    }
16
17    fn schema_drops(self, modules: &[Migrations]) -> Vec<Step> {
18        let dialect = self.db.driver().dialect();
19        let framework = dialect.framework_migrations();
20        std::iter::once(&framework)
21            .chain(modules)
22            .map(|migrations| {
23                let schema = dialect.quote(migrations.module);
24                Step::Script(format!("DROP SCHEMA IF EXISTS {schema} CASCADE"))
25            })
26            .collect()
27    }
28
29    async fn table_drops(self, statements: &str) -> Result<Vec<Step>> {
30        query_values(self.db.driver(), statements, &[])
31            .await?
32            .into_iter()
33            .map(|row| match <[SqlValue; 1]>::try_from(row) {
34                Ok([SqlValue::Text(statement)]) => Ok(Step::Script(statement)),
35                row => Err(Error::internal_message(format!(
36                    "the statements dropping every table came back as {row:?}"
37                ))),
38            })
39            .collect()
40    }
41}