mod common;
mod delete;
mod insert;
mod select;
mod update;
use crate::{DynIden, TableName};
pub trait AuditTrait {
fn audit(&self) -> Result<QueryAccessAudit, Error>;
fn audit_unwrap(&self) -> QueryAccessAudit {
self.audit().unwrap()
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct QueryAccessAudit {
pub requests: Vec<QueryAccessRequest>,
}
#[derive(Debug)]
#[non_exhaustive]
pub struct QueryAccessRequest {
pub access_type: AccessType,
pub schema_table: TableName,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum AccessType {
Select,
Insert,
Update,
Delete,
Schema(SchemaOper),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SchemaOper {
Create,
Alter,
Drop,
Rename,
Truncate,
}
impl AccessType {
pub fn as_str(&self) -> &'static str {
match self {
AccessType::Select => "select",
AccessType::Insert => "insert",
AccessType::Update => "update",
AccessType::Delete => "delete",
AccessType::Schema(SchemaOper::Create) => "schema_create",
AccessType::Schema(SchemaOper::Alter) => "schema_alter",
AccessType::Schema(SchemaOper::Drop) => "schema_drop",
AccessType::Schema(SchemaOper::Rename) => "schema_rename",
AccessType::Schema(SchemaOper::Truncate) => "schema_truncate",
}
}
}
impl QueryAccessAudit {
pub fn selects(&self) -> Vec<TableName> {
self.requests
.iter()
.filter_map(|item| {
if item.access_type == AccessType::Select {
Some(item.schema_table.clone())
} else {
None
}
})
.collect()
}
pub fn selected_tables(&self) -> Vec<DynIden> {
self.filter_table_with_access_type(AccessType::Select)
}
pub fn inserted_tables(&self) -> Vec<DynIden> {
self.filter_table_with_access_type(AccessType::Insert)
}
pub fn updated_tables(&self) -> Vec<DynIden> {
self.filter_table_with_access_type(AccessType::Update)
}
pub fn deleted_tables(&self) -> Vec<DynIden> {
self.filter_table_with_access_type(AccessType::Delete)
}
fn filter_table_with_access_type(&self, access_type: AccessType) -> Vec<DynIden> {
self.requests
.iter()
.filter_map(|item| {
if item.access_type == access_type {
Some(item.schema_table.1.clone())
} else {
None
}
})
.collect()
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum Error {
UnableToParseQuery,
UnsupportedQuery,
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::UnableToParseQuery => f.write_str("Unable to parse query"),
Self::UnsupportedQuery => f.write_str("Unsupported query"),
}
}
}