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 #[serde(default, skip_serializing_if = "Option::is_none")]
118 pub condition_sql: Option<String>,
119 pub actions: Vec<Statement>,
120 #[serde(default)]
121 pub action_sql: Vec<String>,
122 pub or_replace: bool,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct DropRule {
127 pub name: String,
128 pub table: String,
129 pub if_exists: bool,
130 pub cascade: bool,
131}
132
133#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
134pub enum EventEnableMode {
135 #[default]
136 Origin,
137 Disabled,
138 Replica,
139 Always,
140}
141
142impl EventEnableMode {
143 #[must_use]
144 pub const fn catalog_code(self) -> &'static str {
145 match self {
146 Self::Origin => "O",
147 Self::Disabled => "D",
148 Self::Replica => "R",
149 Self::Always => "A",
150 }
151 }
152
153 #[must_use]
154 pub const fn fires_in_origin(self) -> bool {
155 matches!(self, Self::Origin | Self::Always)
156 }
157
158 #[must_use]
159 pub const fn fires_in_replica(self) -> bool {
160 matches!(self, Self::Replica | Self::Always)
161 }
162}