reifydb_core/interface/
cdc.rs1use reifydb_codec::{key::encoded::EncodedKey, row::bytes::EncodedBytes};
5use reifydb_value::value::datetime::DateTime;
6use serde::{Deserialize, Serialize};
7
8use crate::common::CommitVersion;
9
10#[repr(transparent)]
11#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
12pub struct CdcConsumerId(pub(crate) String);
13
14impl CdcConsumerId {
15 const FLOW: &'static str = "__FLOW_COORDINATOR";
16 const SUBSCRIPTION: &'static str = "__SUBSCRIPTION_CONSUMER";
17
18 pub fn new(id: impl Into<String>) -> Self {
19 let id = id.into();
20 assert_ne!(id, Self::FLOW);
21 assert_ne!(id, Self::SUBSCRIPTION);
22 Self(id)
23 }
24
25 pub fn flow_consumer() -> Self {
26 Self(Self::FLOW.to_string())
27 }
28
29 pub fn subscription_consumer() -> Self {
30 Self(Self::SUBSCRIPTION.to_string())
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum ConsumerClass {
36 Pinning,
37 Ephemeral,
38}
39
40impl ConsumerClass {
41 pub fn encode(self) -> u8 {
42 match self {
43 Self::Pinning => 0,
44 Self::Ephemeral => 1,
45 }
46 }
47
48 pub fn decode(byte: u8) -> Option<Self> {
49 match byte {
50 0 => Some(Self::Pinning),
51 1 => Some(Self::Ephemeral),
52 _ => None,
53 }
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum CheckpointState {
59 Valid,
60 Invalidated,
61}
62
63impl CheckpointState {
64 pub fn encode(self) -> u8 {
65 match self {
66 Self::Valid => 0,
67 Self::Invalidated => 1,
68 }
69 }
70
71 pub fn decode(byte: u8) -> Option<Self> {
72 match byte {
73 0 => Some(Self::Valid),
74 1 => Some(Self::Invalidated),
75 _ => None,
76 }
77 }
78}
79
80impl AsRef<str> for CdcConsumerId {
81 fn as_ref(&self) -> &str {
82 &self.0
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
87pub enum CdcChange {
88 Insert {
89 key: EncodedKey,
90 post: EncodedBytes,
91 },
92 Update {
93 key: EncodedKey,
94 pre: EncodedBytes,
95 post: EncodedBytes,
96 },
97 Delete {
98 key: EncodedKey,
99 pre: Option<EncodedBytes>,
100 visible: bool,
101 },
102}
103
104impl CdcChange {
105 pub fn key(&self) -> &EncodedKey {
106 match self {
107 CdcChange::Insert {
108 key,
109 ..
110 } => key,
111 CdcChange::Update {
112 key,
113 ..
114 } => key,
115 CdcChange::Delete {
116 key,
117 ..
118 } => key,
119 }
120 }
121
122 pub fn value_bytes(&self) -> usize {
123 match self {
124 CdcChange::Insert {
125 post,
126 ..
127 } => post.len(),
128 CdcChange::Update {
129 pre,
130 post,
131 ..
132 } => pre.len() + post.len(),
133 CdcChange::Delete {
134 pre,
135 ..
136 } => pre.as_ref().map(|p| p.len()).unwrap_or(0),
137 }
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct Cdc {
143 pub version: CommitVersion,
144 pub timestamp: DateTime,
145
146 pub changes: Vec<CdcChange>,
147}
148
149impl Cdc {
150 pub fn new(version: CommitVersion, timestamp: DateTime, changes: Vec<CdcChange>) -> Self {
151 Self {
152 version,
153 timestamp,
154 changes,
155 }
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct ConsumerState {
161 pub consumer_id: CdcConsumerId,
162 pub checkpoint: CommitVersion,
163}
164
165#[derive(Debug, Clone)]
166pub struct CdcBatch {
167 pub items: Vec<Cdc>,
168
169 pub has_more: bool,
170}
171
172impl CdcBatch {
173 pub fn empty() -> Self {
174 Self {
175 items: Vec::new(),
176 has_more: false,
177 }
178 }
179
180 pub fn is_empty(&self) -> bool {
181 self.items.is_empty()
182 }
183}