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