use std::collections::HashMap;
use sqlparser::ast::{CreateTrigger, DropTrigger, TriggerEvent, TriggerObject, TriggerPeriod};
use super::StatementLocation;
use super::names::{find_table, object_leaf_name};
use crate::schema::Table;
pub(super) fn has_before_insert_trigger(tables: &[Table]) -> Vec<bool> {
tables
.iter()
.map(|table| !table.before_insert_triggers.is_empty())
.collect()
}
pub(super) fn record_lost_triggers(
tables: &[Table],
triggered: &[bool],
source_removed: &mut HashMap<(String, Option<String>), StatementLocation>,
here: &StatementLocation,
) {
for (table, had) in tables.iter().zip(triggered) {
if *had && table.before_insert_triggers.is_empty() {
source_removed.insert((table.module_name.clone(), None), here.clone());
}
}
}
pub(super) fn record_trigger(tables: &mut [Table], trigger: &CreateTrigger) {
let Some(index) = find_table(tables, &trigger.table_name) else {
return;
};
let table = &mut tables[index];
let name = object_leaf_name(&trigger.name);
table.before_insert_triggers.retain(|other| *other != name);
let before_insert = trigger.period == TriggerPeriod::Before
&& trigger.trigger_object == TriggerObject::Row
&& trigger.events.contains(&TriggerEvent::Insert);
if before_insert {
table.before_insert_triggers.push(name);
}
}
pub(super) fn forget_trigger(tables: &mut [Table], trigger: &DropTrigger) {
let name = object_leaf_name(&trigger.trigger_name);
let only = trigger
.table_name
.as_ref()
.and_then(|table| find_table(tables, table));
if trigger.table_name.is_some() && only.is_none() {
return;
}
for (index, table) in tables.iter_mut().enumerate() {
if only.is_none_or(|only| only == index) {
table.before_insert_triggers.retain(|other| *other != name);
}
}
}