use crate::catalog::id::DbObjectId;
pub use crate::catalog::raw::exclusion::is_system_schema;
pub fn resolve_type_dependency(
type_schema: Option<&str>,
type_name: Option<&str>,
typtype: Option<&str>,
relkind: Option<&str>,
is_extension: bool,
extension_name: Option<&str>,
) -> Option<DbObjectId> {
if is_extension {
return extension_name.map(|n| DbObjectId::Extension {
name: n.to_string(),
});
}
let (schema, name) = match (type_schema, type_name) {
(Some(s), Some(n)) if !is_system_schema(s) => (s.to_string(), n.to_string()),
_ => return None,
};
Some(match typtype {
Some("d") => DbObjectId::Domain { schema, name },
Some("c") => {
match relkind {
Some("r") | Some("p") => DbObjectId::Table { schema, name },
Some("v") | Some("m") => DbObjectId::View { schema, name },
_ => DbObjectId::Type { schema, name },
}
}
_ => DbObjectId::Type { schema, name },
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_resolve_type_dependency_extension() {
let result = resolve_type_dependency(
Some("public"),
Some("citext"),
Some("d"), None,
true,
Some("citext"),
);
assert_eq!(
result,
Some(DbObjectId::Extension {
name: "citext".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_domain() {
let result = resolve_type_dependency(
Some("app"),
Some("positive_int"),
Some("d"),
None,
false,
None,
);
assert_eq!(
result,
Some(DbObjectId::Domain {
schema: "app".to_string(),
name: "positive_int".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_table_composite() {
let result = resolve_type_dependency(
Some("app"),
Some("orders"),
Some("c"),
Some("r"), false,
None,
);
assert_eq!(
result,
Some(DbObjectId::Table {
schema: "app".to_string(),
name: "orders".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_partitioned_table_composite() {
let result = resolve_type_dependency(
Some("app"),
Some("events"),
Some("c"),
Some("p"), false,
None,
);
assert_eq!(
result,
Some(DbObjectId::Table {
schema: "app".to_string(),
name: "events".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_view_composite() {
let result = resolve_type_dependency(
Some("app"),
Some("order_summary"),
Some("c"),
Some("v"), false,
None,
);
assert_eq!(
result,
Some(DbObjectId::View {
schema: "app".to_string(),
name: "order_summary".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_materialized_view_composite() {
let result = resolve_type_dependency(
Some("app"),
Some("cached_stats"),
Some("c"),
Some("m"), false,
None,
);
assert_eq!(
result,
Some(DbObjectId::View {
schema: "app".to_string(),
name: "cached_stats".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_explicit_composite() {
let result = resolve_type_dependency(
Some("app"),
Some("address"),
Some("c"),
None, false,
None,
);
assert_eq!(
result,
Some(DbObjectId::Type {
schema: "app".to_string(),
name: "address".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_enum() {
let result =
resolve_type_dependency(Some("app"), Some("status"), Some("e"), None, false, None);
assert_eq!(
result,
Some(DbObjectId::Type {
schema: "app".to_string(),
name: "status".to_string()
})
);
}
#[test]
fn test_resolve_type_dependency_system_schema() {
let result = resolve_type_dependency(
Some("pg_catalog"),
Some("int4"),
Some("b"),
None,
false,
None,
);
assert_eq!(result, None);
}
#[test]
fn test_resolve_type_dependency_missing_info() {
assert_eq!(
resolve_type_dependency(None, Some("mytype"), Some("e"), None, false, None),
None
);
assert_eq!(
resolve_type_dependency(Some("app"), None, Some("e"), None, false, None),
None
);
}
}