1use crate::errors::OxiaError;
4use crate::key;
5use crate::proto;
6use bytes::Bytes;
7use std::cmp::Ordering;
8use std::fmt;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12#[non_exhaustive]
13pub struct Version {
14 pub version_id: i64,
19 pub modifications_count: i64,
21 pub created_timestamp: u64,
23 pub modified_timestamp: u64,
25 pub session_id: Option<i64>,
27 pub client_identity: Option<String>,
29}
30
31impl Version {
32 pub fn is_ephemeral(&self) -> bool {
34 self.session_id.is_some()
35 }
36}
37
38impl From<proto::Version> for Version {
39 fn from(v: proto::Version) -> Self {
40 Version {
41 version_id: v.version_id,
42 modifications_count: v.modifications_count,
43 created_timestamp: v.created_timestamp,
44 modified_timestamp: v.modified_timestamp,
45 session_id: v.session_id,
46 client_identity: v.client_identity,
47 }
48 }
49}
50
51#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
53#[non_exhaustive]
54pub enum ComparisonType {
55 #[default]
57 Equal,
58 Floor,
60 Ceiling,
62 Lower,
64 Higher,
66}
67
68impl ComparisonType {
69 pub(crate) fn to_proto(self) -> proto::KeyComparisonType {
70 match self {
71 ComparisonType::Equal => proto::KeyComparisonType::Equal,
72 ComparisonType::Floor => proto::KeyComparisonType::Floor,
73 ComparisonType::Ceiling => proto::KeyComparisonType::Ceiling,
74 ComparisonType::Lower => proto::KeyComparisonType::Lower,
75 ComparisonType::Higher => proto::KeyComparisonType::Higher,
76 }
77 }
78}
79
80#[derive(Clone, Debug, PartialEq, Eq)]
82#[non_exhaustive]
83pub struct PutResult {
84 pub key: String,
87 pub version: Version,
89}
90
91#[derive(Clone, Debug, PartialEq, Eq)]
94#[non_exhaustive]
95pub struct GetResult {
96 pub key: String,
99 pub value: Option<Bytes>,
102 pub version: Version,
104 pub secondary_index_key: Option<String>,
107}
108
109impl GetResult {
110 pub(crate) fn from_proto(
114 response: proto::GetResponse,
115 fallback_key: Option<String>,
116 ) -> Result<Self, OxiaError> {
117 let version = response
118 .version
119 .ok_or_else(|| OxiaError::Decode("missing version in get response".to_string()))?;
120 let key = response
121 .key
122 .or(fallback_key)
123 .ok_or_else(|| OxiaError::Decode("missing key in record".to_string()))?;
124 Ok(GetResult {
125 key,
126 value: response.value,
127 version: version.into(),
128 secondary_index_key: response.secondary_index_key,
129 })
130 }
131
132 pub(crate) fn compare_keys(&self, other: &Self) -> Ordering {
133 key::compare(&self.key, &other.key)
134 }
135}
136
137#[derive(Clone, Debug, PartialEq, Eq)]
140#[non_exhaustive]
141pub enum Notification {
142 KeyCreated {
144 key: String,
146 version_id: Option<i64>,
148 },
149 KeyModified {
151 key: String,
153 version_id: Option<i64>,
155 },
156 KeyDeleted {
158 key: String,
160 },
161 KeyRangeDeleted {
163 key: String,
165 key_range_last: Option<String>,
167 },
168}
169
170impl Notification {
171 pub(crate) fn from_proto(entry: proto::NotificationEntry) -> Option<Self> {
174 let key = entry.key.unwrap_or_default();
175 let notification = entry.value?;
176 match proto::NotificationType::try_from(notification.r#type).ok()? {
177 proto::NotificationType::KeyCreated => Some(Notification::KeyCreated {
178 key,
179 version_id: notification.version_id,
180 }),
181 proto::NotificationType::KeyModified => Some(Notification::KeyModified {
182 key,
183 version_id: notification.version_id,
184 }),
185 proto::NotificationType::KeyDeleted => Some(Notification::KeyDeleted { key }),
186 proto::NotificationType::KeyRangeDeleted => Some(Notification::KeyRangeDeleted {
187 key,
188 key_range_last: notification.key_range_last,
189 }),
190 }
191 }
192
193 pub fn key(&self) -> &str {
196 match self {
197 Notification::KeyCreated { key, .. }
198 | Notification::KeyModified { key, .. }
199 | Notification::KeyDeleted { key }
200 | Notification::KeyRangeDeleted { key, .. } => key,
201 }
202 }
203}
204
205impl fmt::Display for Notification {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 match self {
208 Notification::KeyCreated { key, version_id } => {
209 write!(f, "KeyCreated(key={key}, version_id={version_id:?})")
210 }
211 Notification::KeyModified { key, version_id } => {
212 write!(f, "KeyModified(key={key}, version_id={version_id:?})")
213 }
214 Notification::KeyDeleted { key } => write!(f, "KeyDeleted(key={key})"),
215 Notification::KeyRangeDeleted {
216 key,
217 key_range_last,
218 } => {
219 write!(f, "KeyRangeDeleted(key={key}, last={key_range_last:?})")
220 }
221 }
222 }
223}
224
225pub(crate) const VERSION_ID_NOT_EXISTS: i64 = -1;