mod common; #[cfg(all(test, feature = "sqlx-postgres"))] mod inner { use crate::common::migrator::default::*; use sea_orm::{ConnectOptions, ConnectionTrait, Database, DbBackend, Statement, error::DbErr}; use sea_orm_migration::prelude::*; #[tokio::test] async fn test_fresh_with_extension() -> Result<(), DbErr> { let url = &std::env::var("DATABASE_URL").expect("Environment variable 'DATABASE_URL' not set"); let db_name = "test_fresh_with_extension"; let db_connect = |url: String| async { let connect_options = ConnectOptions::new(url).to_owned(); Database::connect(connect_options).await }; let db = db_connect(url.to_owned()).await?; if !matches!(db.get_database_backend(), DbBackend::Postgres) { return Ok(()); } db.execute_unprepared(&format!(r#"DROP DATABASE IF EXISTS "{db_name}""#)) .await?; db.execute_unprepared(&format!(r#"CREATE DATABASE "{db_name}""#)) .await?; let url = format!("{url}/{db_name}"); let db = db_connect(url).await?; // Create the extension, a custom type, and dependent objects. db.execute_unprepared("CREATE EXTENSION IF NOT EXISTS citext") .await?; db.execute_unprepared("CREATE TYPE \"UserFruit\" AS ENUM ('Apple', 'Banana')") .await?; db.execute_unprepared(r#"CREATE DOMAIN "UserFruitDomain" AS "UserFruit""#) .await?; db.execute_unprepared( r#"CREATE FUNCTION format_user_fruit("UserFruit") RETURNS text LANGUAGE SQL AS $$ SELECT $1::text $$"#, ) .await?; // Run the fresh migration Migrator::fresh(&db).await?; // Check that the custom type and its dependent objects were dropped, // and the extension's type was not. let citext_exists: Option = db .query_one_raw(Statement::from_string( DbBackend::Postgres, r#"SELECT 1 as "value" FROM pg_type WHERE typname = 'citext'"#.to_owned(), )) .await? .map(|row| row.try_get("", "value").unwrap()); assert_eq!(citext_exists, Some(1), "the citext type should still exist"); let user_fruit_exists: Option = db .query_one_raw(Statement::from_string( DbBackend::Postgres, r#"SELECT 1 as "value" FROM pg_type WHERE typname = 'UserFruit'"#.to_owned(), )) .await? .map(|row| row.try_get("", "value").unwrap()); assert_eq!( user_fruit_exists, None, "the UserFruit type should have been dropped" ); let user_fruit_domain_exists: Option = db .query_one_raw(Statement::from_string( DbBackend::Postgres, r#"SELECT 1 as "value" FROM pg_type WHERE typname = 'UserFruitDomain'"#.to_owned(), )) .await? .map(|row| row.try_get("", "value").unwrap()); assert_eq!( user_fruit_domain_exists, None, "the dependent UserFruitDomain type should have been dropped" ); let format_user_fruit_exists: Option = db .query_one_raw(Statement::from_string( DbBackend::Postgres, r#"SELECT 1 as "value" FROM pg_proc WHERE proname = 'format_user_fruit'"# .to_owned(), )) .await? .map(|row| row.try_get("", "value").unwrap()); assert_eq!( format_user_fruit_exists, None, "the dependent format_user_fruit function should have been dropped" ); Ok(()) } }