#[must_use]
pub fn normalize_identifier_to_scope(identifier: String, entity_scope: &[String]) -> String {
let Some((qualifier, leaf)) = split_qualified_identifier(identifier.as_str()) else {
return identifier;
};
if !entity_scope
.iter()
.any(|candidate| identifiers_tail_match(candidate.as_str(), qualifier))
{
return identifier;
}
leaf.to_string()
}
#[must_use]
pub fn split_qualified_identifier(identifier: &str) -> Option<(&str, &str)> {
let (qualifier, leaf) = identifier.rsplit_once('.')?;
if qualifier.is_empty() || leaf.is_empty() {
return None;
}
Some((qualifier, leaf))
}
#[must_use]
pub fn identifier_last_segment(identifier: &str) -> Option<&str> {
identifier.rsplit('.').next()
}
#[must_use]
pub(in crate::db) fn identifiers_tail_match(left: &str, right: &str) -> bool {
if left.eq_ignore_ascii_case(right) {
return true;
}
let left_last = identifier_last_segment(left);
let right_last = identifier_last_segment(right);
match (left_last, right_last) {
(Some(l), Some(r)) => l.eq_ignore_ascii_case(r),
_ => false,
}
}
#[cfg(test)]
mod tests {
use crate::db::sql::identifier::{identifiers_tail_match, normalize_identifier_to_scope};
#[test]
fn identifiers_tail_match_accepts_schema_qualified_forms() {
assert!(identifiers_tail_match("public.FixtureUser", "FixtureUser"));
assert!(identifiers_tail_match("fixtureorder", "FixtureOrder"));
assert!(!identifiers_tail_match("FixtureUser", "FixtureOrder"));
}
#[test]
fn normalize_identifier_to_scope_strips_matching_qualifier() {
let scope = vec!["public.FixtureUser".to_string(), "FixtureUser".to_string()];
assert_eq!(
normalize_identifier_to_scope("FixtureUser.email".to_string(), scope.as_slice()),
"email".to_string()
);
assert_eq!(
normalize_identifier_to_scope("public.FixtureUser.email".to_string(), scope.as_slice()),
"email".to_string()
);
}
#[test]
fn normalize_identifier_to_scope_preserves_non_matching_qualifier() {
let scope = vec!["FixtureUser".to_string()];
assert_eq!(
normalize_identifier_to_scope("FixtureOrder.email".to_string(), scope.as_slice()),
"FixtureOrder.email".to_string()
);
}
}