1use std::collections::HashMap;
2use std::io::Read;
3
4use bigdecimal::BigDecimal;
5use bigdecimal::num_bigint::BigInt;
6use bytebuffer::ByteBuffer;
7use chrono::{DateTime, TimeZone, Utc};
8
9use crate::encode::*;
10use crate::response::ResponseStatus::Success;
11use crate::response::VoltResponseInfo;
12
13const MIN_INT8: i8 = -1 << 7;
14
15#[derive(Debug, Clone, PartialEq)]
16pub struct Column {
17 pub header_name: String,
18 pub header_type: i8,
19}
20
21#[derive(Debug)]
22#[allow(dead_code)]
23pub struct VoltTable {
24 info: VoltResponseInfo,
25 column_count: i16,
26 info_bytes: ByteBuffer,
27 column_info_bytes: ByteBuffer,
28 columns: Vec<Column>,
29 num_rows: i32,
30 rows: Vec<ByteBuffer>,
31 row_index: i32,
32 cn_to_ci: HashMap<String, i16>,
33 column_offsets: Vec<i32>,
34 header_size: i32,
35 total_size: i32,
36}
37
38impl Value for VoltTable {
39 fn get_write_length(&self) -> i32 {
40 self.total_size + 5
41 }
42
43 fn marshal(&self, bytebuffer: &mut ByteBuffer) {
44 bytebuffer.write_i8(TABLE);
45 bytebuffer.write_u32(self.total_size as u32);
46 bytebuffer.write_u32(self.header_size as u32);
47 bytebuffer.write_u8(128);
48 bytebuffer.write_bytes(self.column_info_bytes.as_bytes());
49 bytebuffer.write_u32(self.num_rows as u32);
50 self.rows.iter().for_each(|f| {
51 bytebuffer.write_u32(f.len() as u32);
52 bytebuffer.write_bytes(f.as_bytes());
53 });
54 println!("{}", bytebuffer.len())
55 }
56
57 fn marshal_in_table(&self, _bytebuffer: &mut ByteBuffer, _column_type: i8) {
58 }
60
61 fn to_value_string(&self) -> String {
62 "table".to_owned()
63 }
64
65 fn from_bytes(_bs: Vec<u8>, _column: &Column) -> Result<Self, VoltError>
66 where
67 Self: Sized,
68 {
69 todo!()
70 }
71}
72
73impl VoltTable {
74 pub fn new_table(types: Vec<i8>, header: Vec<String>) -> Self {
84 let mut columns = Vec::with_capacity(types.len());
85 for (i, tp) in types.iter().enumerate() {
86 columns.push(Column {
87 header_name: header.get(i).unwrap().clone(),
88 header_type: *tp,
89 })
90 }
91 VoltTable::new_voltdb_table(columns)
92 }
93
94 pub fn new_voltdb_table(columns: Vec<Column>) -> Self {
95 let mut column_info_bytes = ByteBuffer::new();
96
97 let column_count = columns.len() as i16;
98 column_info_bytes.write_i16(column_count);
99 columns
100 .iter()
101 .for_each(|f| column_info_bytes.write_i8(f.header_type));
102 columns
103 .iter()
104 .for_each(|f| column_info_bytes.write_string(f.header_name.as_str()));
105 let header_size = (1 + column_info_bytes.len()) as i32;
106 let total_size = header_size + 8;
107 VoltTable {
109 info: Default::default(),
110 column_count,
111 info_bytes: Default::default(),
112 column_info_bytes,
113 columns,
114 num_rows: 0,
115 rows: vec![],
116 row_index: 0,
117 cn_to_ci: Default::default(),
118 column_offsets: vec![],
119 header_size,
120 total_size,
121 }
122 }
123
124 pub fn add_row(&mut self, row: Vec<&dyn Value>) -> Result<i16, VoltError> {
125 let mut bf: ByteBuffer = ByteBuffer::new();
126 self.columns.iter().enumerate().for_each(|(f, v)| {
127 let da = *row.get(f).unwrap();
128 da.marshal_in_table(&mut bf, v.header_type);
129 });
130 let len = bf.len();
131 self.rows.push(bf);
132 self.num_rows += 1;
133 self.total_size += (len + 4) as i32;
134 Ok(1)
135 }
136
137 pub fn get_column_index(&mut self, column: &str) -> Result<i16, VoltError> {
138 let idx = self
139 .cn_to_ci
140 .get(column.to_uppercase().as_str())
141 .ok_or(VoltError::NoValue(column.to_owned()))?;
142 Ok(*idx)
143 }
144
145 pub fn map_row<'a, T: From<&'a mut VoltTable>>(&'a mut self) -> T {
146 T::from(self)
147 }
148 pub fn take<T: Value>(&mut self, column: i16) -> Result<T, VoltError> {
149 let bs = self.get_bytes_by_idx(column)?;
150 let column = self.get_column_by_index(column)?;
151 T::from_bytes(bs, column)
152 }
153
154 pub fn fetch<T: Value>(&mut self, column: &str) -> Result<T, VoltError> {
155 let idx = self.get_column_index(column)?;
156 let bs = self.get_bytes_by_idx(idx)?;
157 let column = self.get_column_by_index(idx)?;
158 T::from_bytes(bs, column)
159 }
160
161 pub fn debug_row(&mut self) -> String {
162 let x: Vec<String> = self
163 .columns()
164 .into_iter()
165 .enumerate()
166 .map(|(idx, column)| {
167 format!(
168 "{} {:?}",
169 column.header_name,
170 self.get_value_by_idx_type(idx as i16, column.header_type)
171 )
172 })
173 .collect();
174 x.join(" ")
175 }
176
177 pub fn has_error(&mut self) -> Option<VoltError> {
178 if self.info.get_status() == Success {
179 return Option::None;
180 }
181 Option::Some(VoltError::ExecuteFail(self.info.clone()))
182 }
183
184 pub fn advance_row(&mut self) -> bool {
185 self.advance_to_row(self.row_index + 1)
186 }
187
188 pub fn columns(&self) -> Vec<Column> {
189 self.columns.clone()
190 }
191
192 pub fn col_length(r: &mut ByteBuffer, offset: i32, col_type: i8) -> Result<i32, VoltError> {
193 match col_type {
194 crate::encode::ARRAY_COLUMN => Err(VoltError::InvalidColumnType(col_type)),
195 crate::encode::NULL_COLUMN => Ok(0),
196 crate::encode::TINYINT_COLUMN => Ok(1),
197 crate::encode::SHORT_COLUMN => Ok(2),
199
200 crate::encode::INT_COLUMN => Ok(4),
201 crate::encode::LONG_COLUMN => Ok(8),
202 crate::encode::FLOAT_COLUMN => Ok(8),
203 crate::encode::STRING_COLUMN => {
204 r.set_rpos(offset as usize);
205 let str_len = r.read_i32()?;
206 if str_len == -1 {
207 return Ok(4);
209 }
210 Ok(4 + str_len)
211 }
212 crate::encode::TIMESTAMP_COLUMN => Ok(8),
213 crate::encode::DECIMAL_COLUMN => Ok(16),
214 crate::encode::VAR_BIN_COLUMN => {
215 r.set_rpos(offset as usize);
216 let str_len = r.read_i32()?;
217 if str_len == -1 {
218 return Ok(4);
220 }
221 Ok(4 + str_len) }
223 _ => Err(VoltError::InvalidColumnType(col_type)),
224 }
225 }
226
227 fn calc_offsets(&mut self) -> Result<(), VoltError> {
228 let mut offsets = Vec::with_capacity((self.column_count + 1) as usize);
229 let reader = self
230 .rows
231 .get_mut(self.row_index as usize)
232 .ok_or(VoltError::NoValue(self.row_index.to_string()))?;
233 offsets.push(0);
234 let mut offset = 0;
235 for i in 0..self.column_count {
236 let column = self
237 .columns
238 .get(i as usize)
239 .ok_or(VoltError::NoValue(i.to_string()))?;
240 let length = crate::table::VoltTable::col_length(reader, offset, column.header_type)?;
241 offset += length;
242 offsets.push(offset);
243 }
244 reader.set_rpos(0);
245 self.column_offsets = offsets;
246 Ok(())
247 }
248
249 pub fn get_value_by_column(
250 &mut self,
251 column: &str,
252 ) -> Result<Option<Box<dyn Value>>, VoltError> {
253 let idx = self.get_column_index(column)?;
254 self.get_value_by_idx(idx)
255 }
256
257 pub(crate) fn get_value_by_idx_column(
258 column: &Column,
259 bs: Vec<u8>,
260 ) -> Result<Option<Box<dyn Value>>, VoltError> {
261 match column.header_type {
262 crate::encode::TINYINT_COLUMN => {
263 let res = i8::from_bytes(bs, column)?;
264 match res {
265 i8::MIN => Ok(None),
266 _ => Ok(Some(Box::new(res))),
267 }
268 }
269 crate::encode::SHORT_COLUMN => {
270 let res = i16::from_bytes(bs, column)?;
271 match res {
272 i16::MIN => Ok(None),
273 _ => Ok(Some(Box::new(res))),
274 }
275 }
276 crate::encode::INT_COLUMN => {
277 let res = i32::from_bytes(bs, column)?;
278 match res {
279 i32::MIN => Ok(None),
280 _ => Ok(Some(Box::new(res))),
281 }
282 }
283
284 crate::encode::LONG_COLUMN => {
285 let res = i64::from_bytes(bs, column)?;
286 match res {
287 i64::MIN => Ok(None),
288 _ => Ok(Some(Box::new(res))),
289 }
290 }
291
292 crate::encode::FLOAT_COLUMN => {
293 if bs == NULL_FLOAT_VALUE {
294 return Ok(None);
295 }
296 let res = f64::from_bytes(bs, column)?;
297 Ok(Some(Box::new(res)))
298 }
299
300 crate::encode::STRING_COLUMN => {
301 if bs.len() == 4 {
302 return Ok(None);
303 }
304 let res = String::from_bytes(bs, column)?;
305 Ok(Some(Box::new(res)))
306 }
307
308 crate::encode::TIMESTAMP_COLUMN => {
309 if bs == NULL_TIMESTAMP {
310 return Ok(None);
311 }
312 let res = DateTime::from_bytes(bs, column)?;
313 Ok(Some(Box::new(res)))
314 }
315 crate::encode::DECIMAL_COLUMN => {
316 if bs == NULL_DECIMAL {
317 return Ok(None);
318 }
319 let res = DateTime::from_bytes(bs, column)?;
320 Ok(Some(Box::new(res)))
321 }
322 crate::encode::VAR_BIN_COLUMN => {
323 if bs.len() == 4 {
324 return Ok(None);
325 }
326 let res = Vec::from_bytes(bs, column)?;
327 Ok(Some(Box::new(res)))
328 }
329 _ => {
330 let res = i16::from_bytes(bs, column)?;
331 Ok(Some(Box::new(res)))
334 }
337 }
338 }
339
340 pub(crate) fn get_value_by_idx_type(
341 &mut self,
342 column: i16,
343 _tp: i8,
344 ) -> Result<Option<Box<dyn Value>>, VoltError> {
345 let bs = self.get_bytes_by_idx(column)?;
346 let column = self.get_column_by_index(column)?;
347 crate::table::VoltTable::get_value_by_idx_column(column, bs)
348 }
349
350 pub fn get_value_by_idx(&mut self, column: i16) -> Result<Option<Box<dyn Value>>, VoltError> {
351 let tp = self.get_column_type_by_idx(column)?;
352 self.get_value_by_idx_type(column, tp)
353 }
354
355 pub fn get_bool_by_column(&mut self, column: &str) -> Result<Option<bool>, VoltError> {
356 let idx = self.get_column_index(column)?;
357 self.get_bool_by_idx(idx)
358 }
359
360 pub fn get_bool_by_idx(&mut self, column: i16) -> Result<Option<bool>, VoltError> {
361 let bs = self.get_bytes_by_idx(column)?;
362 if bs == NULL_BIT_VALUE {
363 return Ok(Option::None);
364 }
365 if bs[0] == 0 {
366 return Ok(Some(false));
367 }
368 Ok(Some(true))
369 }
370
371 pub fn get_bytes_op_by_column(&mut self, column: &str) -> Result<Option<Vec<u8>>, VoltError> {
372 let idx = self.get_column_index(column)?;
373 self.get_bytes_op_by_idx(idx)
374 }
375
376 pub fn get_bytes_op_by_idx(&mut self, column: i16) -> Result<Option<Vec<u8>>, VoltError> {
377 let mut bs = self.get_bytes_by_idx(column)?;
378 if bs == NULL_VARCHAR {
379 return Ok(Option::None);
380 }
381 bs.drain(0..4);
382 Ok(Option::Some(bs))
383 }
384
385 pub fn get_bytes_by_column(&mut self, column: &str) -> Result<Vec<u8>, VoltError> {
386 let idx = self.get_column_index(column)?;
387 self.get_bytes_by_idx(idx)
388 }
389
390 pub fn get_decimal_by_column(&mut self, column: &str) -> Result<Option<BigDecimal>, VoltError> {
391 let idx = self.get_column_index(column)?;
392 self.get_decimal_by_idx(idx)
393 }
394
395 pub fn get_decimal_by_idx(&mut self, column: i16) -> Result<Option<BigDecimal>, VoltError> {
396 let bs = self.get_bytes_by_idx(column)?;
397 if bs == NULL_DECIMAL {
398 return Ok(Option::None);
399 }
400 let int = BigInt::from_signed_bytes_be(&bs);
401 let decimal = BigDecimal::new(int, 12);
402 Ok(Some(decimal))
403 }
404
405 pub fn get_string_by_column(&mut self, column: &str) -> Result<Option<String>, VoltError> {
406 let idx = self.get_column_index(column)?;
407 self.get_string_by_idx(idx)
408 }
409
410 pub fn get_column_by_index(&self, column: i16) -> Result<&Column, VoltError> {
411 let res = self.columns.get(column as usize);
412 match res {
413 None => Err(VoltError::NoValue(self.row_index.to_string())),
414 Some(e) => Ok(e),
415 }
416 }
417
418 pub fn get_string_by_idx(&mut self, column: i16) -> Result<Option<String>, VoltError> {
419 let table_column = self.get_column_by_index(column)?; match table_column.header_type {
421 STRING_COLUMN => {
422 let bs = self.get_bytes_by_idx(column)?;
423 if bs == NULL_VARCHAR {
424 return Ok(Option::None);
425 }
426 let mut buffer = ByteBuffer::from_bytes(&bs);
427 Ok(Option::Some(buffer.read_string()?))
428 }
429 _ => {
430 let res = self.get_value_by_idx_type(column, table_column.header_type)?;
431 match res {
432 Some(v) => Ok(Option::Some(v.to_value_string())),
433 None => Ok(Option::None),
434 }
435 }
436 }
437 }
438
439 pub fn get_time_by_column(&mut self, column: &str) -> Result<Option<DateTime<Utc>>, VoltError> {
440 let idx = self.get_column_index(column)?;
441 self.get_time_by_idx(idx)
442 }
443
444 pub fn get_time_by_idx(&mut self, column: i16) -> Result<Option<DateTime<Utc>>, VoltError> {
445 let bs = self.get_bytes_by_idx(column)?;
446 if bs == NULL_TIMESTAMP {
447 return Ok(Option::None);
448 }
449 let mut buffer = ByteBuffer::from_bytes(&bs);
450 let time = buffer.read_i64()?;
451 Ok(Option::Some(Utc.timestamp_millis_opt(time / 1000).unwrap()))
452 }
453
454 pub fn get_bytes_by_idx(&mut self, column_index: i16) -> Result<Vec<u8>, VoltError> {
455 if self.column_offsets.is_empty() {
456 self.calc_offsets()?;
457 }
458 let buffer = self
459 .rows
460 .get_mut(self.row_index as usize)
461 .ok_or(VoltError::NoValue(self.row_index.to_string()))?;
462 let start = self
463 .column_offsets
464 .get(column_index as usize)
465 .ok_or(VoltError::NoValue(column_index.to_string()))?;
466 let end = self
467 .column_offsets
468 .get(column_index as usize + 1)
469 .ok_or(VoltError::NoValue(column_index.to_string()))?;
470 buffer.set_rpos(*start as usize);
471 let rsize = (*end - *start) as usize;
472 Ok(buffer.read_bytes(rsize)?)
473 }
474
475 pub fn advance_to_row(&mut self, row_index: i32) -> bool {
476 if row_index >= self.num_rows {
477 return false;
478 }
479 self.column_offsets = vec![];
480 self.row_index = row_index;
481 true
482 }
483
484 fn get_column_type_by_idx(&self, column_idx: i16) -> Result<i8, VoltError> {
485 if let Some(v) = self.columns.get(column_idx as usize) {
486 return Ok(v.header_type);
487 }
488 Err(VoltError::NoValue(column_idx.to_string()))
489 }
490}
491
492pub fn new_volt_table(
493 bytebuffer: &mut ByteBuffer,
494 info: VoltResponseInfo,
495) -> Result<VoltTable, VoltError> {
496 if info.get_status() != Success {
497 return Ok(VoltTable {
498 info,
499 column_count: -1,
500 info_bytes: Default::default(),
501 column_info_bytes: Default::default(),
502 columns: vec![],
503 num_rows: -1,
504 rows: vec![],
505 row_index: -1,
506 cn_to_ci: Default::default(),
507 column_offsets: vec![],
508 header_size: 0,
509 total_size: 0,
510 });
511 }
512
513 let column_counts = decode_table_common(bytebuffer)?;
514 let mut column_types: Vec<i8> = Vec::with_capacity(column_counts as usize);
515 let mut column_info_bytes = ByteBuffer::new();
516 for _ in 0..column_counts {
517 let tp = bytebuffer.read_i8()?;
518 column_types.push(tp);
519 column_info_bytes.write_i8(tp);
520 }
521 let mut columns: Vec<Column> = Vec::with_capacity(column_counts as usize);
522 let mut cn_to_ci = HashMap::with_capacity(column_counts as usize);
523 for i in 0..column_counts {
524 let name = bytebuffer.read_string()?;
525 columns.push(Column {
526 header_name: name.clone(),
527 header_type: *(column_types.get(i as usize).unwrap()),
528 });
529 column_info_bytes.write_string(name.as_str());
530 cn_to_ci.insert(name, i);
531 }
532 let row_count = bytebuffer.read_i32()?;
533 let mut rows: Vec<ByteBuffer> = Vec::with_capacity(column_counts as usize);
534 for _ in 0..row_count {
535 let row_len = bytebuffer.read_i32()?;
536 let mut build = vec![0; row_len as usize];
537 bytebuffer.read_exact(&mut build)?;
538 let row = ByteBuffer::from_bytes(&build);
539 rows.push(row);
540 }
541 Ok(VoltTable {
542 info,
543 column_count: column_counts,
544 info_bytes: Default::default(),
545 column_info_bytes,
546 columns,
547 num_rows: row_count,
548 rows,
549 row_index: -1,
550 cn_to_ci,
551 column_offsets: vec![],
552 header_size: 0,
553 total_size: 0,
554 })
555}
556
557fn decode_table_common(bytebuffer: &mut ByteBuffer) -> Result<i16, VoltError> {
558 let _ttl_length = bytebuffer.read_i32();
559 let _meta_length = bytebuffer.read_i32();
560 let status_code = bytebuffer.read_i8()?;
561 if status_code != 0 && status_code != MIN_INT8 {
562 return Err(VoltError::BadReturnStatusOnTable(status_code));
564 }
565 Ok(bytebuffer.read_i16()?)
566}
567
568#[cfg(test)]
569mod tests {
570 use crate::encode::{
571 DECIMAL_COLUMN, FLOAT_COLUMN, INT_COLUMN, LONG_COLUMN, SHORT_COLUMN, STRING_COLUMN,
572 TIMESTAMP_COLUMN, TINYINT_COLUMN, VAR_BIN_COLUMN,
573 };
574 use crate::volt_param;
575
576 use super::*;
577
578 fn template(tps: Vec<&str>, none: &str) {
579 for tp in tps {
580 let shader = r#"
581 pub fn get_${type}_by_column (&mut self, column: &str) -> Result<Option<${type}>, VoltError> {
582 let idx = self.get_column_index(column)?;
583 return Ok(self.get_${type}_by_idx>](idx)?);
584 }
585
586 pub fn get_${type}_by_idx (&mut self, column: i16) -> Result<Option<${type}>, VoltError> {
587 let bs = self.get_bytes_by_idx(column)?;
588 if bs == ${none} {
589 return Ok(Option::None);
590 }
591 let mut buffer = ByteBuffer::from_bytes(&bs);
592 let value = buffer.read_${type}()?;
593 return Ok(Some(value));
594 }
595"#;
596 println!("{}", shader.replace("${type}", tp).replace("${none}", none));
597 }
598 }
599
600 #[test]
601 fn test_encode_table() -> Result<(), VoltError> {
602 let bs = vec![
603 21, 0, 0, 0, 86, 0, 0, 0, 49, 128, 0, 4, 6, 6, 3, 6, 0, 0, 0, 2, 73, 68, 0, 0, 0, 7,
604 86, 69, 82, 83, 73, 79, 78, 0, 0, 0, 7, 68, 69, 76, 69, 84, 69, 68, 0, 0, 0, 10, 67,
605 82, 69, 65, 84, 69, 68, 95, 66, 89, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 1, 0,
606 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
607 ];
608 let header = vec!["ID", "VERSION", "DELETED", "CREATED_BY"];
609 let tp = vec![LONG_COLUMN, LONG_COLUMN, TINYINT_COLUMN, LONG_COLUMN];
610 let header: Vec<String> = header
611 .iter()
612 .map(|f| f.to_string())
613 .collect::<Vec<String>>();
614 let mut x = VoltTable::new_table(tp, header);
615 let data = volt_param! {1 as i64, 1 as i64, false, 1 as i64 };
616 x.add_row(data)?;
617 let mut bf = ByteBuffer::new();
618 x.marshal(&mut bf);
619 assert_eq!(bs, bf.into_vec());
620 Ok({})
621 }
622
623 #[test]
624 fn test_table() {
625 let bs = vec![
626 0 as u8, 1, 128, 0, 0, 0, 3, 0, 1, 0, 0, 0, 133, 0, 0, 0, 66, 128, 0, 9, 3, 4, 5, 6, 8,
627 22, 9, 25, 11, 0, 0, 0, 2, 84, 49, 0, 0, 0, 2, 84, 50, 0, 0, 0, 2, 84, 51, 0, 0, 0, 2,
628 84, 52, 0, 0, 0, 2, 84, 53, 0, 0, 0, 2, 84, 54, 0, 0, 0, 2, 84, 55, 0, 0, 0, 2, 84, 56,
629 0, 0, 0, 2, 84, 57, 0, 0, 0, 1, 0, 0, 0, 55, 128, 128, 0, 128, 0, 0, 0, 128, 0, 0, 0,
630 0, 0, 0, 0, 255, 239, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
631 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0,
632 ];
633 let mut b = ByteBuffer::from_bytes(&bs);
634 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
635 let mut table = new_volt_table(&mut b, info).unwrap();
636 table.advance_row();
637
638 let header = table.columns();
639 assert_eq!(header.len(), 9);
640 assert_eq!(
641 *header.get(0).unwrap(),
642 Column {
643 header_name: "T1".to_owned(),
644 header_type: TINYINT_COLUMN,
645 }
646 );
647 assert_eq!(
648 *header.get(1).unwrap(),
649 Column {
650 header_name: "T2".to_owned(),
651 header_type: SHORT_COLUMN,
652 }
653 );
654 assert_eq!(
655 *header.get(2).unwrap(),
656 Column {
657 header_name: "T3".to_owned(),
658 header_type: INT_COLUMN,
659 }
660 );
661 assert_eq!(
662 *header.get(3).unwrap(),
663 Column {
664 header_name: "T4".to_owned(),
665 header_type: LONG_COLUMN,
666 }
667 );
668 assert_eq!(
669 *header.get(4).unwrap(),
670 Column {
671 header_name: "T5".to_owned(),
672 header_type: FLOAT_COLUMN,
673 }
674 );
675 assert_eq!(
676 *header.get(5).unwrap(),
677 Column {
678 header_name: "T6".to_owned(),
679 header_type: DECIMAL_COLUMN,
680 }
681 );
682 assert_eq!(
683 *header.get(6).unwrap(),
684 Column {
685 header_name: "T7".to_owned(),
686 header_type: STRING_COLUMN,
687 }
688 );
689 assert_eq!(
690 *header.get(7).unwrap(),
691 Column {
692 header_name: "T8".to_owned(),
693 header_type: VAR_BIN_COLUMN,
694 }
695 );
696 assert_eq!(
697 *header.get(8).unwrap(),
698 Column {
699 header_name: "T9".to_owned(),
700 header_type: TIMESTAMP_COLUMN,
701 }
702 );
703
704 let i1 = table.get_bool_by_idx(0).unwrap();
705 let i2 = table.get_i16_by_idx(1).unwrap();
706 let i3 = table.get_i32_by_idx(2).unwrap();
707 let i4 = table.get_i64_by_idx(3).unwrap();
708 let i5 = table.get_f64_by_idx(4).unwrap();
709 let i6 = table.get_decimal_by_idx(5).unwrap();
710 let i7 = table.get_string_by_idx(6).unwrap();
711 let i8 = table.get_bytes_op_by_idx(7).unwrap();
712 let i9 = table.get_time_by_idx(8).unwrap();
713
714 assert_eq!(i1, None);
715 assert_eq!(i2, None);
716 assert_eq!(i3, None);
717 assert_eq!(i4, None);
718 assert_eq!(i5, None);
719 assert_eq!(i6, None);
720 assert_eq!(i7, None);
721 assert_eq!(i8, None);
722 assert_eq!(i9, None);
723 let offsets = vec![0, 1, 3, 7, 15, 23, 39, 43, 47, 55];
724 assert_eq!(offsets, table.column_offsets);
725 }
726
727 #[test]
728 fn test_big_decimal() {
729 template(vec!["i8", "u8"], "NULL_BYTE_VALUE");
730 template(vec!["i16", "u16"], "NULL_SHORT_VALUE");
731 template(vec!["i32", "u32"], "NULL_INT_VALUE");
732 template(vec!["i64", "u64"], "NULL_LONG_VALUE");
733 template(vec!["f32", "f64"], "NULL_FLOAT_VALUE");
734 }
735
736 fn get_value_test_bytes() -> Vec<u8> {
738 vec![
740 0, 1, 128, 0, 0, 0, 3, 0, 1, 0, 0, 0, 133, 0, 0, 0, 66, 128, 0, 9, 3, 4, 5, 6, 8, 22,
741 9, 25, 11, 0, 0, 0, 2, 84, 49, 0, 0, 0, 2, 84, 50, 0, 0, 0, 2, 84, 51, 0, 0, 0, 2, 84, 52, 0, 0, 0, 2, 84, 53, 0, 0, 0, 2, 84, 54, 0, 0, 0, 2, 84, 55, 0, 0, 0, 2, 84, 56, 0, 0, 0, 2, 84, 57, 0, 0, 0, 1, 0, 0, 0, 63, 1, 0, 100, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 42, 64, 9, 33, 251, 84, 68, 45, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 212, 165, 16, 0, 0, 0, 0, 5, 104, 101, 108, 108, 111, 0, 0, 0, 3, 1, 2, 3, 0, 0, 0, 0, 0, 15, 66, 64, ]
762 }
763
764 #[test]
765 fn test_get_bool_by_column() {
766 let bs = get_value_test_bytes();
767 let mut b = ByteBuffer::from_bytes(&bs);
768 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
769 let mut table = new_volt_table(&mut b, info).unwrap();
770 table.advance_row();
771
772 let result = table.get_bool_by_column("T1").unwrap();
773 assert_eq!(result, Some(true));
774 }
775
776 #[test]
777 fn test_get_string_by_column() {
778 let bs = get_value_test_bytes();
779 let mut b = ByteBuffer::from_bytes(&bs);
780 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
781 let mut table = new_volt_table(&mut b, info).unwrap();
782 table.advance_row();
783
784 let result = table.get_string_by_column("T7").unwrap();
785 assert_eq!(result, Some("hello".to_string()));
786 }
787
788 #[test]
789 fn test_get_string_by_idx_from_int() {
790 let bs = get_value_test_bytes();
791 let mut b = ByteBuffer::from_bytes(&bs);
792 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
793 let mut table = new_volt_table(&mut b, info).unwrap();
794 table.advance_row();
795
796 let result = table.get_string_by_idx(2).unwrap();
798 assert_eq!(result, Some("256".to_string()));
799 }
800
801 #[test]
802 fn test_get_bytes_op_by_column() {
803 let bs = get_value_test_bytes();
804 let mut b = ByteBuffer::from_bytes(&bs);
805 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
806 let mut table = new_volt_table(&mut b, info).unwrap();
807 table.advance_row();
808
809 let result = table.get_bytes_op_by_column("T8").unwrap();
810 assert_eq!(result, Some(vec![1, 2, 3]));
811 }
812
813 #[test]
814 fn test_get_decimal_by_column() {
815 let bs = get_value_test_bytes();
816 let mut b = ByteBuffer::from_bytes(&bs);
817 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
818 let mut table = new_volt_table(&mut b, info).unwrap();
819 table.advance_row();
820
821 let result = table.get_decimal_by_column("T6").unwrap();
822 assert!(result.is_some());
823 }
824
825 #[test]
826 fn test_get_time_by_column() {
827 let bs = get_value_test_bytes();
828 let mut b = ByteBuffer::from_bytes(&bs);
829 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
830 let mut table = new_volt_table(&mut b, info).unwrap();
831 table.advance_row();
832
833 let result = table.get_time_by_column("T9").unwrap();
834 assert!(result.is_some());
835 }
836
837 #[test]
838 fn test_get_bytes_by_column() {
839 let bs = get_value_test_bytes();
840 let mut b = ByteBuffer::from_bytes(&bs);
841 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
842 let mut table = new_volt_table(&mut b, info).unwrap();
843 table.advance_row();
844
845 let result = table.get_bytes_by_column("T1").unwrap();
846 assert_eq!(result, vec![1]); }
848
849 #[test]
850 fn test_get_value_by_idx_tinyint() {
851 let bs = get_value_test_bytes();
852 let mut b = ByteBuffer::from_bytes(&bs);
853 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
854 let mut table = new_volt_table(&mut b, info).unwrap();
855 table.advance_row();
856
857 let result = table.get_value_by_idx(0).unwrap();
858 assert!(result.is_some());
859 }
860
861 #[test]
862 fn test_get_value_by_idx_short() {
863 let bs = get_value_test_bytes();
864 let mut b = ByteBuffer::from_bytes(&bs);
865 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
866 let mut table = new_volt_table(&mut b, info).unwrap();
867 table.advance_row();
868
869 let result = table.get_value_by_idx(1).unwrap();
870 assert!(result.is_some());
871 }
872
873 #[test]
874 fn test_get_value_by_idx_int() {
875 let bs = get_value_test_bytes();
876 let mut b = ByteBuffer::from_bytes(&bs);
877 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
878 let mut table = new_volt_table(&mut b, info).unwrap();
879 table.advance_row();
880
881 let result = table.get_value_by_idx(2).unwrap();
882 assert!(result.is_some());
883 }
884
885 #[test]
886 fn test_get_value_by_idx_long() {
887 let bs = get_value_test_bytes();
888 let mut b = ByteBuffer::from_bytes(&bs);
889 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
890 let mut table = new_volt_table(&mut b, info).unwrap();
891 table.advance_row();
892
893 let result = table.get_value_by_idx(3).unwrap();
894 assert!(result.is_some());
895 }
896
897 #[test]
898 fn test_get_value_by_idx_float() {
899 let bs = get_value_test_bytes();
900 let mut b = ByteBuffer::from_bytes(&bs);
901 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
902 let mut table = new_volt_table(&mut b, info).unwrap();
903 table.advance_row();
904
905 let result = table.get_value_by_idx(4).unwrap();
906 assert!(result.is_some());
907 }
908
909 #[test]
910 fn test_get_value_by_idx_string() {
911 let bs = get_value_test_bytes();
912 let mut b = ByteBuffer::from_bytes(&bs);
913 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
914 let mut table = new_volt_table(&mut b, info).unwrap();
915 table.advance_row();
916
917 let result = table.get_value_by_idx(6).unwrap();
918 assert!(result.is_some());
919 }
920
921 #[test]
922 fn test_get_value_by_idx_timestamp() {
923 let bs = get_value_test_bytes();
924 let mut b = ByteBuffer::from_bytes(&bs);
925 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
926 let mut table = new_volt_table(&mut b, info).unwrap();
927 table.advance_row();
928
929 let result = table.get_value_by_idx(8).unwrap();
930 assert!(result.is_some());
931 }
932
933 #[test]
934 fn test_advance_to_row() {
935 let bs = get_value_test_bytes();
936 let mut b = ByteBuffer::from_bytes(&bs);
937 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
938 let mut table = new_volt_table(&mut b, info).unwrap();
939
940 assert!(table.advance_row()); assert!(!table.advance_row()); assert!(table.advance_to_row(0));
946 assert!(!table.advance_to_row(1)); }
948
949 #[test]
950 fn test_fetch() {
951 let bs = get_value_test_bytes();
952 let mut b = ByteBuffer::from_bytes(&bs);
953 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
954 let mut table = new_volt_table(&mut b, info).unwrap();
955 table.advance_row();
956
957 let result: i32 = table.fetch("T3").unwrap();
958 assert_eq!(result, 256);
959 }
960
961 #[test]
962 fn test_take() {
963 let bs = get_value_test_bytes();
964 let mut b = ByteBuffer::from_bytes(&bs);
965 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
966 let mut table = new_volt_table(&mut b, info).unwrap();
967 table.advance_row();
968
969 let result: i32 = table.take(2).unwrap();
970 assert_eq!(result, 256);
971 }
972
973 #[test]
974 fn test_columns() {
975 let bs = get_value_test_bytes();
976 let mut b = ByteBuffer::from_bytes(&bs);
977 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
978 let table = new_volt_table(&mut b, info).unwrap();
979
980 let columns = table.columns();
981 assert_eq!(columns.len(), 9);
982 assert_eq!(columns[0].header_name, "T1");
983 assert_eq!(columns[0].header_type, TINYINT_COLUMN);
984 }
985
986 #[test]
987 fn test_columns_count() {
988 let bs = get_value_test_bytes();
989 let mut b = ByteBuffer::from_bytes(&bs);
990 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
991 let table = new_volt_table(&mut b, info).unwrap();
992
993 assert_eq!(table.columns().len(), 9);
995 }
996
997 #[test]
998 fn test_get_column_by_index() {
999 let bs = get_value_test_bytes();
1000 let mut b = ByteBuffer::from_bytes(&bs);
1001 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
1002 let table = new_volt_table(&mut b, info).unwrap();
1003
1004 let col = table.get_column_by_index(0).unwrap();
1005 assert_eq!(col.header_name, "T1");
1006 assert_eq!(col.header_type, TINYINT_COLUMN);
1007
1008 let err = table.get_column_by_index(100);
1010 assert!(err.is_err());
1011 }
1012
1013 #[test]
1014 fn test_get_column_index_not_found() {
1015 let bs = get_value_test_bytes();
1016 let mut b = ByteBuffer::from_bytes(&bs);
1017 let info = VoltResponseInfo::new(&mut b, 1).unwrap();
1018 let mut table = new_volt_table(&mut b, info).unwrap();
1019 table.advance_row();
1020
1021 let result = table.get_column_index("NONEXISTENT");
1022 assert!(result.is_err());
1023 }
1024
1025 #[test]
1026 fn test_volt_table_to_value_string() {
1027 let header = vec!["ID".to_string()];
1028 let tp = vec![LONG_COLUMN];
1029 let table = VoltTable::new_table(tp, header);
1030
1031 assert_eq!(table.to_value_string(), "table");
1032 }
1033
1034 #[test]
1035 fn test_volt_table_get_write_length() {
1036 let header = vec!["ID".to_string()];
1037 let tp = vec![LONG_COLUMN];
1038 let table = VoltTable::new_table(tp, header);
1039
1040 assert!(table.get_write_length() > 0);
1045 }
1046
1047 #[test]
1048 fn test_new_voltdb_table() {
1049 let columns = vec![
1050 Column {
1051 header_name: "COL1".to_string(),
1052 header_type: INT_COLUMN,
1053 },
1054 Column {
1055 header_name: "COL2".to_string(),
1056 header_type: STRING_COLUMN,
1057 },
1058 ];
1059 let table = VoltTable::new_voltdb_table(columns);
1060
1061 assert_eq!(table.columns().len(), 2);
1062 }
1063}