use super::super::naming::snake;
use crate::database::introspection::Table;
use std::collections::BTreeSet;
pub(super) fn keys(table: &Table) -> Vec<Vec<String>> {
if table.view {
return Vec::new();
}
let mut seen = BTreeSet::new();
let mut targets = Vec::new();
for key in table
.uniques
.iter()
.map(|key| &key.columns)
.chain(
table
.indexes
.iter()
.filter(|index| index.unique)
.map(|index| &index.columns),
)
.filter(|key| !key.is_empty() && key.iter().all(|name| table.column(name).is_some()))
{
let mut ordered = Vec::new();
for name in key {
if !ordered.contains(name) {
ordered.push(name.clone());
}
}
let mut identity = ordered.clone();
identity.sort();
if seen.insert(identity) {
targets.push(ordered);
}
}
targets.sort_by(|left, right| {
let mut left_sorted = left.clone();
let mut right_sorted = right.clone();
left_sorted.sort();
right_sorted.sort();
left_sorted.cmp(&right_sorted)
});
targets
}
pub(super) fn suffix(key: &[String]) -> String {
key.iter()
.map(|name| snake(name))
.collect::<Vec<_>>()
.join("_and_")
}