coven_database/
declaration.rs1#[derive(Clone, Debug, Eq, PartialEq)]
5pub enum RowIdentity {
6 IndependentUuid,
8 SharedKey,
10}
11
12#[derive(Clone, Debug, Eq, PartialEq)]
13pub(crate) enum AudienceSource {
14 Store,
15 Column(String),
16 ForeignKey(String),
17 Both { column: String, foreign_key: String },
18}
19
20#[derive(Clone, Debug, Eq, PartialEq)]
23pub struct SyncedTable {
24 pub(crate) name: String,
25 pub(crate) identity: RowIdentity,
26 pub(crate) key: Vec<String>,
27 pub(crate) audience: AudienceSource,
28 pub(crate) files: Vec<FileColumn>,
29 pub(crate) shared_triggers: Vec<String>,
30 pub(crate) owner_only: bool,
31}
32
33impl SyncedTable {
34 pub fn name(&self) -> &str {
36 &self.name
37 }
38
39 pub fn identity(&self) -> &RowIdentity {
41 &self.identity
42 }
43
44 pub fn get_key_columns(&self) -> &[String] {
46 &self.key
47 }
48
49 pub fn is_owner_only(&self) -> bool {
51 self.owner_only
52 }
53
54 pub fn get_audience_column(&self) -> Option<&str> {
57 match &self.audience {
58 AudienceSource::Column(column) | AudienceSource::Both { column, .. } => Some(column),
59 AudienceSource::Store | AudienceSource::ForeignKey(_) => None,
60 }
61 }
62
63 pub fn get_audience_from(&self) -> Option<&str> {
66 match &self.audience {
67 AudienceSource::ForeignKey(foreign_key) | AudienceSource::Both { foreign_key, .. } => {
68 Some(foreign_key)
69 }
70 AudienceSource::Store | AudienceSource::Column(_) => None,
71 }
72 }
73
74 pub fn file_columns(&self) -> &[FileColumn] {
76 &self.files
77 }
78
79 pub fn shared_triggers(&self) -> &[String] {
81 &self.shared_triggers
82 }
83
84 pub fn new(name: impl Into<String>, identity: RowIdentity) -> Self {
86 Self {
87 name: name.into(),
88 identity,
89 key: vec!["id".into()],
90 audience: AudienceSource::Store,
91 files: Vec::new(),
92 shared_triggers: Vec::new(),
93 owner_only: false,
94 }
95 }
96
97 pub fn owner_only(mut self) -> Self {
103 self.owner_only = true;
104 self
105 }
106
107 pub fn key_columns<I, S>(mut self, columns: I) -> Self
109 where
110 I: IntoIterator<Item = S>,
111 S: Into<String>,
112 {
113 self.key = columns.into_iter().map(Into::into).collect();
114 self
115 }
116
117 pub fn audience_column(mut self, column: impl Into<String>) -> Self {
119 let column = column.into();
120 self.audience = match self.audience {
121 AudienceSource::ForeignKey(foreign_key) | AudienceSource::Both { foreign_key, .. } => {
122 AudienceSource::Both { column, foreign_key }
123 }
124 AudienceSource::Store | AudienceSource::Column(_) => AudienceSource::Column(column),
125 };
126 self
127 }
128
129 pub fn audience_from(mut self, foreign_key: impl Into<String>) -> Self {
131 let foreign_key = foreign_key.into();
132 self.audience = match self.audience {
133 AudienceSource::Column(column) | AudienceSource::Both { column, .. } => {
134 AudienceSource::Both { column, foreign_key }
135 }
136 AudienceSource::Store | AudienceSource::ForeignKey(_) => {
137 AudienceSource::ForeignKey(foreign_key)
138 }
139 };
140 self
141 }
142
143 pub fn file_column(mut self, column: FileColumn) -> Self {
146 self.files.push(column);
147 self
148 }
149
150 pub fn shared_trigger(mut self, name: impl Into<String>) -> Self {
152 self.shared_triggers.push(name.into());
153 self
154 }
155}
156
157#[derive(Clone, Debug, Eq, PartialEq)]
159pub enum Provenance {
160 UserProvided,
162 AppProvided,
164}
165
166#[derive(Clone, Debug, Eq, PartialEq)]
168pub enum Binding {
169 Bound {
173 limit: u64,
175 },
176 Trailing,
178}
179
180pub const BOUND_FILE_LIMIT: u64 = 3 << 19;
182
183#[derive(Clone, Debug, Eq, PartialEq)]
186pub struct FileColumn {
187 pub(crate) column: String,
188 pub(crate) write_once: bool,
189 pub(crate) binding: Binding,
190}
191
192impl FileColumn {
193 pub fn new(column: impl Into<String>) -> Self {
195 Self { column: column.into(), write_once: false, binding: Binding::Trailing }
196 }
197
198 pub fn bound(self) -> Self {
200 self.bound_with_limit(BOUND_FILE_LIMIT)
201 }
202
203 pub fn bound_with_limit(mut self, limit: u64) -> Self {
205 self.binding = Binding::Bound { limit };
206 self
207 }
208
209 pub fn write_once(mut self) -> Self {
211 self.write_once = true;
212 self
213 }
214
215 pub fn column(&self) -> &str {
217 &self.column
218 }
219
220 pub fn binding(&self) -> &Binding {
222 &self.binding
223 }
224
225 pub fn is_write_once(&self) -> bool {
227 self.write_once
228 }
229}
230
231#[derive(Clone, Debug, Eq, PartialEq)]
234pub struct Namespace {
235 pub(crate) name: String,
236 pub(crate) kind: Provenance,
237 pub(crate) cache_budget: u64,
238}
239
240impl Namespace {
241 pub fn new(name: impl Into<String>, kind: Provenance, cache_budget: u64) -> Self {
244 Self { name: name.into(), kind, cache_budget }
245 }
246
247 pub fn name(&self) -> &str {
249 &self.name
250 }
251
252 pub fn kind(&self) -> &Provenance {
254 &self.kind
255 }
256
257 pub fn cache_budget(&self) -> u64 {
260 self.cache_budget
261 }
262}
263
264#[cfg(test)]
265#[path = "declaration_tests.rs"]
266mod tests;