1use serde::{Deserialize, Serialize};
10
11use super::{Expr, Statement};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14pub enum TriggerTiming {
15 Before,
16 After,
17 InsteadOf,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21pub enum TriggerEvent {
22 Insert,
23 Update,
24 Delete,
25 Truncate,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29pub struct TriggerTransitionRelation {
30 pub name: String,
31 pub is_new: bool,
32 pub is_table: bool,
33}
34
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
36#[serde(rename_all = "snake_case")]
37pub enum TriggerDeferrability {
38 #[default]
39 NotDeferrable,
40 InitiallyImmediate,
41 InitiallyDeferred,
42}
43
44impl TriggerDeferrability {
45 pub const fn is_deferrable(self) -> bool {
46 !matches!(self, Self::NotDeferrable)
47 }
48
49 pub const fn is_initially_deferred(self) -> bool {
50 matches!(self, Self::InitiallyDeferred)
51 }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct CreateTrigger {
56 pub name: String,
57 pub table: String,
58 pub function: String,
59 pub arguments: Vec<String>,
60 #[serde(default)]
61 pub constraint: bool,
62 #[serde(default)]
63 pub referenced_table: Option<String>,
64 #[serde(default)]
65 pub deferrability: TriggerDeferrability,
66 pub row: bool,
67 pub timing: TriggerTiming,
68 pub events: Vec<TriggerEvent>,
69 pub update_columns: Vec<String>,
70 #[serde(default)]
71 pub transition_relations: Vec<TriggerTransitionRelation>,
72 pub when: Option<Expr>,
73 pub or_replace: bool,
74}
75
76impl CreateTrigger {
77 #[must_use]
78 pub fn old_transition_table(&self) -> Option<&str> {
79 self.transition_relations
80 .iter()
81 .find(|relation| relation.is_table && !relation.is_new)
82 .map(|relation| relation.name.as_str())
83 }
84
85 #[must_use]
86 pub fn new_transition_table(&self) -> Option<&str> {
87 self.transition_relations
88 .iter()
89 .find(|relation| relation.is_table && relation.is_new)
90 .map(|relation| relation.name.as_str())
91 }
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct DropTrigger {
96 pub name: String,
97 pub table: String,
98 pub if_exists: bool,
99 pub cascade: bool,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
103pub enum RuleEvent {
104 Select,
105 Insert,
106 Update,
107 Delete,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct CreateRule {
112 pub name: String,
113 pub table: String,
114 pub event: RuleEvent,
115 pub instead: bool,
116 pub condition: Option<Expr>,
117 pub actions: Vec<Statement>,
118 #[serde(default)]
119 pub action_sql: Vec<String>,
120 pub or_replace: bool,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct DropRule {
125 pub name: String,
126 pub table: String,
127 pub if_exists: bool,
128 pub cascade: bool,
129}
130
131#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
132pub enum EventEnableMode {
133 #[default]
134 Origin,
135 Disabled,
136 Replica,
137 Always,
138}
139
140impl EventEnableMode {
141 #[must_use]
142 pub const fn catalog_code(self) -> &'static str {
143 match self {
144 Self::Origin => "O",
145 Self::Disabled => "D",
146 Self::Replica => "R",
147 Self::Always => "A",
148 }
149 }
150
151 #[must_use]
152 pub const fn fires_in_origin(self) -> bool {
153 matches!(self, Self::Origin | Self::Always)
154 }
155
156 #[must_use]
157 pub const fn fires_in_replica(self) -> bool {
158 matches!(self, Self::Replica | Self::Always)
159 }
160}