use std::sync::LazyLock;
#[cfg(feature = "db-sqlite")]
pub const SCHEMA_SQL: &str = include_str!("../../migrations/sqlite/schema.sqlite.sql");
#[cfg(feature = "db-postgres")]
pub const SCHEMA_SQL: &str = include_str!("../../migrations/postgres/schema.postgres.sql");
#[cfg(feature = "db-mysql")]
pub const SCHEMA_SQL: &str = include_str!("../../migrations/mysql/schema.mysql.sql");
fn parse_create_table_names(sql: &str) -> Vec<String> {
let mut names = Vec::new();
let mut pos = 0;
while let Some(idx) = sql[pos..].find("CREATE TABLE") {
let start = pos + idx + "CREATE TABLE".len();
let rest = sql[start..].trim_start();
let rest = rest.strip_prefix("IF NOT EXISTS ").unwrap_or(rest);
let end = rest.find([' ', '(', '\n']).unwrap_or(rest.len());
if end > 0 {
names.push(rest[..end].to_string());
}
pos = start + 1;
}
names
}
pub static SCHEMA_TABLES: LazyLock<Vec<String>> = LazyLock::new(|| {
let mut tables = parse_create_table_names(SCHEMA_SQL);
if !tables.iter().any(|t| t == "_migrations") {
tables.push("_migrations".to_string());
}
tables
});
static PROTECTED: std::sync::OnceLock<Vec<String>> = std::sync::OnceLock::new();
pub fn set_protected_tables(live_tables: Vec<String>, ct_tables: &[String]) {
let ct_set: std::collections::HashSet<&str> = ct_tables.iter().map(|s| s.as_str()).collect();
let protected: Vec<String> = live_tables
.into_iter()
.filter(|t| !ct_set.contains(t.as_str()))
.collect();
let _ = PROTECTED.set(protected);
}
pub fn get_protected_tables() -> Vec<String> {
PROTECTED
.get()
.cloned()
.unwrap_or_else(|| SCHEMA_TABLES.clone())
}