1mod common;
2mod delete;
3mod insert;
4mod select;
5mod update;
6
7use crate::{DynIden, TableName};
8
9pub trait AuditTrait {
10 fn audit(&self) -> Result<QueryAccessAudit, Error>;
11
12 fn audit_unwrap(&self) -> QueryAccessAudit {
14 self.audit().unwrap()
15 }
16}
17
18#[derive(Debug)]
19#[non_exhaustive]
20pub struct QueryAccessAudit {
21 pub requests: Vec<QueryAccessRequest>,
22}
23
24#[derive(Debug)]
25#[non_exhaustive]
26pub struct QueryAccessRequest {
27 pub access_type: AccessType,
28 pub schema_table: TableName,
30}
31
32#[derive(Debug, Copy, Clone, PartialEq, Eq)]
33pub enum AccessType {
34 Select,
35 Insert,
36 Update,
37 Delete,
38 Schema(SchemaOper),
39}
40
41#[derive(Debug, Copy, Clone, PartialEq, Eq)]
43pub enum SchemaOper {
44 Create,
45 Alter,
46 Drop,
47 Rename,
48 Truncate,
49}
50
51impl AccessType {
52 pub fn as_str(&self) -> &'static str {
53 match self {
54 AccessType::Select => "select",
55 AccessType::Insert => "insert",
56 AccessType::Update => "update",
57 AccessType::Delete => "delete",
58 AccessType::Schema(SchemaOper::Create) => "schema_create",
59 AccessType::Schema(SchemaOper::Alter) => "schema_alter",
60 AccessType::Schema(SchemaOper::Drop) => "schema_drop",
61 AccessType::Schema(SchemaOper::Rename) => "schema_rename",
62 AccessType::Schema(SchemaOper::Truncate) => "schema_truncate",
63 }
64 }
65}
66
67impl QueryAccessAudit {
68 pub fn selects(&self) -> Vec<TableName> {
70 self.requests
71 .iter()
72 .filter_map(|item| {
73 if item.access_type == AccessType::Select {
74 Some(item.schema_table.clone())
75 } else {
76 None
77 }
78 })
79 .collect()
80 }
81
82 pub fn selected_tables(&self) -> Vec<DynIden> {
85 self.filter_table_with_access_type(AccessType::Select)
86 }
87
88 pub fn inserted_tables(&self) -> Vec<DynIden> {
91 self.filter_table_with_access_type(AccessType::Insert)
92 }
93
94 pub fn updated_tables(&self) -> Vec<DynIden> {
97 self.filter_table_with_access_type(AccessType::Update)
98 }
99
100 pub fn deleted_tables(&self) -> Vec<DynIden> {
103 self.filter_table_with_access_type(AccessType::Delete)
104 }
105
106 fn filter_table_with_access_type(&self, access_type: AccessType) -> Vec<DynIden> {
107 self.requests
108 .iter()
109 .filter_map(|item| {
110 if item.access_type == access_type {
111 Some(item.schema_table.1.clone())
112 } else {
113 None
114 }
115 })
116 .collect()
117 }
118}
119
120#[derive(Debug, PartialEq, Eq)]
121pub enum Error {
122 UnableToParseQuery,
124 UnsupportedQuery,
126}
127
128impl std::error::Error for Error {}
129
130impl std::fmt::Display for Error {
131 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
132 match self {
133 Self::UnableToParseQuery => f.write_str("Unable to parse query"),
134 Self::UnsupportedQuery => f.write_str("Unsupported query"),
135 }
136 }
137}