1use bigdecimal::BigDecimal;
2use std::fmt;
3use uuid::Uuid;
4
5use crate::protocol::binary::value::BinaryObject;
6
7pub mod type_code {
10 #![allow(dead_code)]
11 pub const BYTE: u8 = 1;
12 pub const SHORT: u8 = 2;
13 pub const INT: u8 = 3;
14 pub const LONG: u8 = 4;
15 pub const FLOAT: u8 = 5;
16 pub const DOUBLE: u8 = 6;
17 pub const CHAR: u8 = 7;
18 pub const BOOL: u8 = 8;
19 pub const STRING: u8 = 9;
20 pub const UUID: u8 = 10;
21 pub const DATE: u8 = 11;
22 pub const BYTE_ARRAY: u8 = 12;
23 pub const SHORT_ARRAY: u8 = 13;
24 pub const INT_ARRAY: u8 = 14;
25 pub const LONG_ARRAY: u8 = 15;
26 pub const FLOAT_ARRAY: u8 = 16;
27 pub const DOUBLE_ARRAY: u8 = 17;
28 pub const CHAR_ARRAY: u8 = 18;
29 pub const BOOL_ARRAY: u8 = 19;
30 pub const STRING_ARRAY: u8 = 20;
31 pub const UUID_ARRAY: u8 = 21;
32 pub const DATE_ARRAY: u8 = 22;
33 pub const DECIMAL: u8 = 30;
34 pub const DECIMAL_ARRAY: u8 = 31;
35 pub const TIMESTAMP: u8 = 33;
36 pub const TIMESTAMP_ARRAY: u8 = 34;
37 pub const TIME: u8 = 36;
38 pub const TIME_ARRAY: u8 = 37;
39 pub const ENUM: u8 = 28;
40 pub const ENUM_ARRAY: u8 = 29;
41 pub const BINARY_OBJECT: u8 = 27;
42 pub const COMPLEX_OBJECT: u8 = 103;
43 pub const NULL: u8 = 101;
44 pub const HANDLE: u8 = 104;
45 pub const OBJECT_ARRAY: u8 = 23;
46 pub const COLLECTION: u8 = 24;
47 pub const PROTO_VER: u8 = 1;
48 pub const MAP: u8 = 25;
49 pub const OPTM_MARSH: u8 = 0xFE;
54}
55
56pub mod op_code {
59 #![allow(dead_code)]
60 pub const RESOURCE_CLOSE: i16 = 0;
61 pub const CACHE_GET: i16 = 1000;
62 pub const CACHE_PUT: i16 = 1001;
63 pub const CACHE_PUT_IF_ABSENT: i16 = 1002;
64 pub const CACHE_GET_ALL: i16 = 1003;
65 pub const CACHE_PUT_ALL: i16 = 1004;
66 pub const CACHE_GET_AND_PUT: i16 = 1005;
67 pub const CACHE_GET_AND_REMOVE: i16 = 1007;
68 pub const CACHE_GET_AND_REPLACE: i16 = 1006;
69 pub const CACHE_REPLACE: i16 = 1009;
70 pub const CACHE_CONTAINS_KEY: i16 = 1011;
71 pub const CACHE_REMOVE_KEY: i16 = 1019;
72 pub const CACHE_REMOVE_KEYS: i16 = 1021;
73 pub const CACHE_REMOVE_ALL: i16 = 1022;
74 pub const CACHE_GET_NAMES: i16 = 1050;
75 pub const CACHE_GET_OR_CREATE_WITH_NAME: i16 = 1052;
76 pub const CACHE_CREATE_WITH_CONFIGURATION: i16 = 1051;
77 pub const CACHE_GET_OR_CREATE_WITH_CONFIGURATION: i16 = 1053;
78 pub const CACHE_DESTROY: i16 = 1056;
79 pub const CACHE_GET_SIZE: i16 = 1020;
80 pub const CACHE_PARTITIONS: i16 = 1101;
81 pub const CLUSTER_GROUP_GET_NODE_ENDPOINTS: i16 = 5102;
82 pub const QUERY_SQL: i16 = 2002; pub const QUERY_SQL_FIELDS: i16 = 2004;
84 pub const QUERY_SQL_FIELDS_CURSOR_GET_PAGE: i16 = 2005;
85 pub const TX_START: i16 = 4000;
86 pub const TX_END: i16 = 4001;
87 pub const BINARY_TYPE_GET: i16 = 3002;
88 pub const BINARY_TYPE_PUT: i16 = 3003;
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum ExpiryDuration {
102 Unchanged,
104 Eternal,
106 Immediate,
108 Millis(u64),
110}
111
112impl ExpiryDuration {
113 pub fn from_duration(d: std::time::Duration) -> Self {
116 let ms = d.as_millis();
117 if ms == 0 {
118 ExpiryDuration::Immediate
119 } else {
120 ExpiryDuration::Millis(ms.min(i64::MAX as u128) as u64)
121 }
122 }
123
124 pub(crate) fn to_wire(self) -> i64 {
126 match self {
127 ExpiryDuration::Unchanged => -2,
128 ExpiryDuration::Eternal => -1,
129 ExpiryDuration::Immediate => 0,
130 ExpiryDuration::Millis(n) => n.min(i64::MAX as u64) as i64,
131 }
132 }
133}
134
135#[derive(Debug, Clone, Copy, PartialEq, Eq)]
139pub struct ExpiryPolicy {
140 pub create: ExpiryDuration,
142 pub update: ExpiryDuration,
144 pub access: ExpiryDuration,
146}
147
148impl ExpiryPolicy {
149 pub fn new(create: ExpiryDuration, update: ExpiryDuration, access: ExpiryDuration) -> Self {
151 Self {
152 create,
153 update,
154 access,
155 }
156 }
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq)]
162#[repr(i32)]
163pub enum TxConcurrency {
164 Optimistic = 0,
165 Pessimistic = 1,
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq)]
169#[repr(i32)]
170pub enum TxIsolation {
171 ReadCommitted = 0,
172 RepeatableRead = 1,
173 Serializable = 2,
174}
175
176#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179#[repr(i8)]
180pub enum StatementType {
181 Any = 0,
182 Select = 1,
183 Update = 2,
184}
185
186#[derive(Debug, Clone, PartialEq)]
190#[non_exhaustive]
191pub enum IgniteValue {
192 Null,
194 Bool(bool),
196 Byte(i8),
198 Short(i16),
200 Int(i32),
202 Long(i64),
204 Float(f32),
206 Double(f64),
208 Char(u16),
210 String(String),
212 Uuid(Uuid),
214 Date(i64),
216 Timestamp(i64, i32),
218 Time(i64),
220 Decimal(BigDecimal),
222 ByteArray(Vec<u8>),
224 RawObject(Vec<u8>),
230 Object(BinaryObject),
238 IntArray(Vec<i32>),
240 StringArray(Vec<Option<String>>),
243 Collection(u8, Vec<IgniteValue>),
247 Map(u8, Vec<(IgniteValue, IgniteValue)>),
250 Enum { type_id: i32, ordinal: i32 },
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq)]
262#[non_exhaustive]
263pub enum ColumnType {
264 Boolean,
265 Byte,
266 Short,
267 Int,
268 Long,
269 Float,
270 Double,
271 Char,
272 String,
273 Uuid,
274 Date,
275 Timestamp,
276 Time,
277 Decimal,
278 Binary,
279 Unknown,
281}
282
283impl ColumnType {
284 pub fn as_str(&self) -> &'static str {
286 match self {
287 ColumnType::Boolean => "BOOLEAN",
288 ColumnType::Byte => "TINYINT",
289 ColumnType::Short => "SMALLINT",
290 ColumnType::Int => "INT",
291 ColumnType::Long => "BIGINT",
292 ColumnType::Float => "FLOAT",
293 ColumnType::Double => "DOUBLE",
294 ColumnType::Char => "CHAR",
295 ColumnType::String => "VARCHAR",
296 ColumnType::Uuid => "UUID",
297 ColumnType::Date => "DATE",
298 ColumnType::Timestamp => "TIMESTAMP",
299 ColumnType::Time => "TIME",
300 ColumnType::Decimal => "DECIMAL",
301 ColumnType::Binary => "BINARY",
302 ColumnType::Unknown => "UNKNOWN",
303 }
304 }
305}
306
307impl fmt::Display for ColumnType {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 f.write_str(self.as_str())
310 }
311}
312
313impl From<&IgniteValue> for ColumnType {
314 fn from(v: &IgniteValue) -> Self {
315 match v {
316 IgniteValue::Null => ColumnType::Unknown,
317 IgniteValue::Bool(_) => ColumnType::Boolean,
318 IgniteValue::Byte(_) => ColumnType::Byte,
319 IgniteValue::Short(_) => ColumnType::Short,
320 IgniteValue::Int(_) => ColumnType::Int,
321 IgniteValue::Long(_) => ColumnType::Long,
322 IgniteValue::Float(_) => ColumnType::Float,
323 IgniteValue::Double(_) => ColumnType::Double,
324 IgniteValue::Char(_) => ColumnType::Char,
325 IgniteValue::String(_) => ColumnType::String,
326 IgniteValue::Uuid(_) => ColumnType::Uuid,
327 IgniteValue::Date(_) => ColumnType::Date,
328 IgniteValue::Timestamp(_, _) => ColumnType::Timestamp,
329 IgniteValue::Time(_) => ColumnType::Time,
330 IgniteValue::Decimal(_) => ColumnType::Decimal,
331 IgniteValue::ByteArray(_) | IgniteValue::RawObject(_) => ColumnType::Binary,
332 IgniteValue::Object(_)
333 | IgniteValue::IntArray(_)
334 | IgniteValue::StringArray(_)
335 | IgniteValue::Collection(_, _)
336 | IgniteValue::Map(_, _)
337 | IgniteValue::Enum { .. } => ColumnType::Binary,
338 }
339 }
340}
341
342impl IgniteValue {
343 pub fn column_type(&self) -> ColumnType {
352 ColumnType::from(self)
353 }
354}
355
356pub fn java_hash(s: &str) -> i32 {
367 s.chars()
368 .fold(0i32, |h, c| h.wrapping_mul(31).wrapping_add(c as i32))
369}
370
371pub fn cache_id(name: &str) -> i32 {
381 java_hash(name)
382}
383
384#[cfg(test)]
385mod tests {
386 use super::*;
387
388 #[test]
389 fn java_hash_empty() {
390 assert_eq!(java_hash(""), 0);
391 }
392
393 #[test]
394 fn java_hash_known() {
395 assert_eq!(java_hash("abc"), 96354);
397 assert_eq!(java_hash("Hello"), 69609650);
398 assert_eq!(java_hash("PUBLIC"), -1924094359_i32);
400 }
401
402 #[test]
403 fn cache_id_is_case_sensitive() {
404 assert_ne!(cache_id("myCache"), cache_id("MYCACHE"));
409 assert_eq!(cache_id("MYCACHE"), java_hash("MYCACHE"));
410 }
411
412 #[test]
413 fn cache_partitions_opcode_matches_java() {
414 assert_eq!(op_code::CACHE_PARTITIONS, 1101);
417 }
418
419 #[test]
420 fn node_endpoints_opcode_matches_java() {
421 assert_eq!(op_code::CLUSTER_GROUP_GET_NODE_ENDPOINTS, 5102);
423 }
424
425 #[test]
426 fn binary_type_opcodes_match_java() {
427 assert_eq!(op_code::BINARY_TYPE_GET, 3002);
429 assert_eq!(op_code::BINARY_TYPE_PUT, 3003);
430 }
431
432 #[test]
433 fn expiry_duration_to_wire_sentinels() {
434 assert_eq!(ExpiryDuration::Unchanged.to_wire(), -2);
436 assert_eq!(ExpiryDuration::Eternal.to_wire(), -1);
437 assert_eq!(ExpiryDuration::Immediate.to_wire(), 0);
438 assert_eq!(ExpiryDuration::Millis(60_000).to_wire(), 60_000);
439 }
440
441 #[test]
442 fn expiry_duration_from_std_duration() {
443 use std::time::Duration;
444 assert_eq!(
445 ExpiryDuration::from_duration(Duration::from_secs(1)),
446 ExpiryDuration::Millis(1000)
447 );
448 assert_eq!(
449 ExpiryDuration::from_duration(Duration::ZERO),
450 ExpiryDuration::Immediate
451 );
452 }
453}