1use serde::{Deserialize, Serialize};
4
5use crate::identifier::QualifiedName;
6use crate::ir::column_type::ColumnType;
7use crate::ir::difference::Difference;
8use crate::ir::eq::{Equiv, field_difference};
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct Sequence {
13 pub qname: QualifiedName,
15 pub data_type: ColumnType,
17 pub start: i64,
19 pub increment: i64,
21 pub min_value: Option<i64>,
23 pub max_value: Option<i64>,
25 pub cache: i64,
27 pub cycle: bool,
29 pub owned_by: Option<SequenceOwner>,
31 pub comment: Option<String>,
33 pub owner: Option<crate::identifier::Identifier>,
36 pub grants: Vec<crate::ir::grant::Grant>,
38}
39
40impl Equiv for Sequence {
41 fn differences(&self, other: &Self) -> Vec<Difference> {
42 let Self {
43 qname: _,
44 data_type: _,
45 start: _,
46 increment: _,
47 min_value: _,
48 max_value: _,
49 cache: _,
50 cycle: _,
51 owned_by: _,
52 comment: _,
53 owner: _,
54 grants: _,
55 } = self;
56 let mut out = Vec::new();
57 out.extend(field_difference("qname", &self.qname, &other.qname));
58 out.extend(field_difference(
59 "data_type",
60 &format!("{:?}", self.data_type),
61 &format!("{:?}", other.data_type),
62 ));
63 out.extend(field_difference("start", &self.start, &other.start));
64 out.extend(field_difference(
65 "increment",
66 &self.increment,
67 &other.increment,
68 ));
69 out.extend(field_difference(
70 "min_value",
71 &format!("{:?}", self.min_value),
72 &format!("{:?}", other.min_value),
73 ));
74 out.extend(field_difference(
75 "max_value",
76 &format!("{:?}", self.max_value),
77 &format!("{:?}", other.max_value),
78 ));
79 out.extend(field_difference("cache", &self.cache, &other.cache));
80 out.extend(field_difference("cycle", &self.cycle, &other.cycle));
81 out.extend(field_difference(
82 "owned_by",
83 &format!("{:?}", self.owned_by),
84 &format!("{:?}", other.owned_by),
85 ));
86 out.extend(field_difference(
87 "comment",
88 &format!("{:?}", self.comment),
89 &format!("{:?}", other.comment),
90 ));
91 out.extend(field_difference(
92 "owner",
93 &format!("{:?}", self.owner),
94 &format!("{:?}", other.owner),
95 ));
96 out.extend(field_difference(
97 "grants",
98 &format!("{:?}", self.grants),
99 &format!("{:?}", other.grants),
100 ));
101 out
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
107pub struct SequenceOwner {
108 pub table: QualifiedName,
110 pub column: crate::identifier::Identifier,
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use crate::identifier::{Identifier, QualifiedName};
118 use crate::ir::eq::Equiv;
119
120 fn s(name: &str) -> QualifiedName {
121 QualifiedName::new(
122 Identifier::from_unquoted("app").unwrap(),
123 Identifier::from_unquoted(name).unwrap(),
124 )
125 }
126
127 fn base() -> Sequence {
128 Sequence {
129 qname: s("seq1"),
130 data_type: ColumnType::BigInt,
131 start: 1,
132 increment: 1,
133 min_value: None,
134 max_value: None,
135 cache: 1,
136 cycle: false,
137 owned_by: None,
138 comment: None,
139 owner: None,
140 grants: Vec::new(),
141 }
142 }
143
144 #[test]
145 fn sequences_equal_when_identical() {
146 assert!(base().canonical_eq(&base()));
147 }
148
149 #[test]
150 fn sequence_diff_reports_increment_change() {
151 let mut other = base();
152 other.increment = 2;
153 let d = base().differences(&other);
154 assert!(d.iter().any(|x| x.path == "increment"));
155 }
156
157 #[test]
158 fn sequence_diff_reports_qname_change() {
159 let mut other = base();
160 other.qname = s("seq2");
161 let d = base().differences(&other);
162 assert!(d.iter().any(|x| x.path == "qname"));
163 }
164
165 #[test]
166 fn owner_change_diffs() {
167 let mut b = base();
168 b.owner = Some(Identifier::from_unquoted("new_owner").unwrap());
169 assert!(base().differences(&b).iter().any(|x| x.path == "owner"));
170 }
171
172 #[test]
173 fn grants_change_diffs() {
174 let mut b = base();
175 b.grants.push(crate::ir::grant::Grant {
176 grantee: crate::ir::grant::GrantTarget::Public,
177 privilege: crate::ir::grant::Privilege::Usage,
178 with_grant_option: false,
179 columns: None,
180 });
181 assert!(base().differences(&b).iter().any(|x| x.path == "grants"));
182 }
183}