use anyhow::Result;
use std::path::{Path, PathBuf};
use crate::catalog::Catalog;
use crate::db::connection::connect_with_retry_quiet;
use crate::db::sql_executor::{SqlExecutorConfig, discover_sql_files_ordered, execute_sql_file};
pub async fn import_from_directory(
dir: PathBuf,
shadow_url: &str,
roles_file: Option<&Path>,
objects: &crate::config::types::Objects,
) -> Result<Catalog> {
let sql_files = discover_sql_files_ordered(&dir)?;
tracing::debug!("Found {} SQL files. Executing in order...", sql_files.len());
let pool = connect_with_retry_quiet(shadow_url).await?;
crate::db::cleaner::clean_shadow_db(&pool, objects).await?;
if let Some(roles_path) = roles_file
&& roles_path.exists()
{
tracing::debug!("Applying roles from: {}", roles_path.display());
crate::schema_ops::apply_roles_file(&pool, roles_path).await?;
}
let executor_config = SqlExecutorConfig {
initialize_session: true,
verbose: false,
};
for file in &sql_files {
execute_sql_file(&pool, file, &executor_config).await?;
}
let catalog = Catalog::load_unfiltered(&pool).await?;
pool.close().await;
Ok(catalog)
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
#[test]
fn test_import_directory_basic_structure() {
let temp_dir = env::temp_dir().join("pgmt_test_import_directory");
let _ = std::fs::remove_dir_all(&temp_dir);
std::fs::create_dir_all(&temp_dir).unwrap();
std::fs::write(temp_dir.join("01_schema.sql"), "CREATE SCHEMA test;").unwrap();
std::fs::write(
temp_dir.join("02_tables.sql"),
"CREATE TABLE test.users (id SERIAL);",
)
.unwrap();
let files = discover_sql_files_ordered(&temp_dir).unwrap();
assert_eq!(files.len(), 2);
assert!(
files[0]
.file_name()
.unwrap()
.to_str()
.unwrap()
.starts_with("01_")
);
assert!(
files[1]
.file_name()
.unwrap()
.to_str()
.unwrap()
.starts_with("02_")
);
let _ = std::fs::remove_dir_all(&temp_dir);
}
}