111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
use sqlx::{postgres::types::Oid, query_as, PgExecutor};
|
|
|
|
use crate::pg_acls::PgAclItem;
|
|
|
|
pub struct PgClass {
|
|
/// Row identifier
|
|
pub oid: Oid,
|
|
/// Name of the table, index, view, etc.
|
|
pub relname: String,
|
|
/// The OID of the namespace that contains this relation
|
|
pub relnamespace: Oid,
|
|
/// The OID of the data type that corresponds to this table's row type, if any; zero for indexes, sequences, and toast tables, which have no pg_type entry
|
|
pub reltype: Oid,
|
|
/// For typed tables, the OID of the underlying composite type; zero for all other relations
|
|
pub reloftype: Oid,
|
|
/// Owner of the relation
|
|
pub relowner: Oid,
|
|
/// r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table, I = partitioned index
|
|
pub relkind: i8,
|
|
/// Number of user columns in the relation (system columns not counted). There must be this many corresponding entries in pg_attribute. See also pg_attribute.attnum.
|
|
pub relnatts: i16,
|
|
/// Number of CHECK constraints on the table; see pg_constraint catalog
|
|
pub relchecks: i16,
|
|
/// True if table has (or once had) rules; see pg_rewrite catalog
|
|
pub relhasrules: bool,
|
|
/// True if table has (or once had) triggers; see pg_trigger catalog
|
|
pub relhastriggers: bool,
|
|
/// True if table or index has (or once had) any inheritance children or partitions
|
|
pub relhassubclass: bool,
|
|
/// True if table has row-level security enabled; see pg_policy catalog
|
|
pub relrowsecurity: bool,
|
|
/// True if row-level security (when enabled) will also apply to table owner; see pg_policy catalog
|
|
pub relforcerowsecurity: bool,
|
|
/// True if relation is populated (this is true for all relations other than some materialized views)
|
|
pub relispopulated: bool,
|
|
/// True if table or index is a partition
|
|
pub relispartition: bool,
|
|
pub relacl: Option<Vec<PgAclItem>>,
|
|
}
|
|
|
|
impl PgClass {
|
|
pub async fn fetch_all_by_kind_any<'a, I: IntoIterator<Item = PgRelKind>, E: PgExecutor<'a>>(
|
|
kinds: I,
|
|
client: E,
|
|
) -> Result<Vec<PgClass>, sqlx::Error> {
|
|
let kinds_i8 = kinds
|
|
.into_iter()
|
|
.map(|kind| kind.to_u8() as i8)
|
|
.collect::<Vec<i8>>();
|
|
query_as!(
|
|
PgClass,
|
|
r#"
|
|
select
|
|
oid,
|
|
relname,
|
|
relnamespace,
|
|
reltype,
|
|
reloftype,
|
|
relowner,
|
|
relkind,
|
|
relnatts,
|
|
relchecks,
|
|
relhasrules,
|
|
relhastriggers,
|
|
relhassubclass,
|
|
relrowsecurity,
|
|
relforcerowsecurity,
|
|
relispopulated,
|
|
relispartition,
|
|
relacl::text[] as "relacl: Vec<PgAclItem>"
|
|
from pg_class
|
|
where
|
|
relkind = any($1)
|
|
"#,
|
|
kinds_i8.as_slice(),
|
|
)
|
|
.fetch_all(client)
|
|
.await
|
|
}
|
|
}
|
|
|
|
pub enum PgRelKind {
|
|
OrdinaryTable,
|
|
Index,
|
|
Sequence,
|
|
ToastTable,
|
|
View,
|
|
MaterializedView,
|
|
CompositeType,
|
|
ForeignTable,
|
|
PartitionedTable,
|
|
PartitionedIndex,
|
|
}
|
|
|
|
impl PgRelKind {
|
|
pub fn to_u8(&self) -> u8 {
|
|
let ch = match self {
|
|
Self::OrdinaryTable => 'r',
|
|
Self::Index => 'i',
|
|
Self::Sequence => 'S',
|
|
Self::ToastTable => 't',
|
|
Self::View => 'v',
|
|
Self::MaterializedView => 'm',
|
|
Self::CompositeType => 'c',
|
|
Self::ForeignTable => 'f',
|
|
Self::PartitionedTable => 'p',
|
|
Self::PartitionedIndex => 'I',
|
|
};
|
|
ch as u8
|
|
}
|
|
}
|