mongreldb_kit/
arrow_util.rs1use arrow::array::{
8 Array, BooleanArray, Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array,
9 NullArray, StringArray, UInt16Array, UInt32Array, UInt64Array, UInt8Array,
10};
11use arrow::ipc::reader::FileReader;
12use arrow::ipc::writer::FileWriter;
13use arrow::record_batch::RecordBatch;
14use serde_json::{json, Map, Value};
15
16use crate::error::{KitError, Result};
17
18pub fn read_arrow_ipc(bytes: &[u8]) -> Result<Vec<RecordBatch>> {
21 if bytes.is_empty() {
22 return Ok(Vec::new());
23 }
24 let cursor = std::io::Cursor::new(bytes);
25 let reader = FileReader::try_new(cursor, None)
26 .map_err(|e| KitError::Storage(format!("arrow ipc decode: {e}")))?;
27 reader
28 .into_iter()
29 .collect::<std::result::Result<Vec<_>, _>>()
30 .map_err(|e| KitError::Storage(format!("arrow ipc decode: {e}")))
31}
32
33pub fn batches_to_ipc(batches: &[RecordBatch]) -> Result<Vec<u8>> {
37 let schema = batches
38 .first()
39 .map(|b| b.schema())
40 .unwrap_or_else(|| std::sync::Arc::new(arrow::datatypes::Schema::empty()));
41 let mut out = Vec::new();
42 let mut writer =
43 FileWriter::try_new(&mut out, &schema).map_err(|e| KitError::Storage(e.to_string()))?;
44 for batch in batches {
45 writer
46 .write(batch)
47 .map_err(|e| KitError::Storage(format!("arrow ipc encode: {e}")))?;
48 }
49 writer
50 .finish()
51 .map_err(|e| KitError::Storage(format!("arrow ipc encode: {e}")))?;
52 Ok(out)
53}
54
55pub fn batch_to_rows(b: &RecordBatch) -> Result<Vec<Map<String, Value>>> {
57 let schema = b.schema();
58 let mut rows = Vec::with_capacity(b.num_rows());
59 for r in 0..b.num_rows() {
60 let mut row = Map::new();
61 for (c, field) in schema.fields().iter().enumerate() {
62 let name = field.name();
63 let arr = b.column(c);
64 row.insert(name.clone(), cell_value(arr.as_ref(), r));
65 }
66 rows.push(row);
67 }
68 Ok(rows)
69}
70
71pub fn batches_to_rows(batches: &[RecordBatch]) -> Result<Vec<Map<String, Value>>> {
73 let mut rows = Vec::new();
74 for batch in batches {
75 rows.extend(batch_to_rows(batch)?);
76 }
77 Ok(rows)
78}
79
80fn cell_value(arr: &dyn Array, r: usize) -> Value {
81 if arr.is_null(r) {
82 return Value::Null;
83 }
84 if let Some(a) = arr.as_any().downcast_ref::<Int64Array>() {
86 return json!(a.value(r));
87 }
88 if let Some(a) = arr.as_any().downcast_ref::<Int32Array>() {
89 return json!(a.value(r));
90 }
91 if let Some(a) = arr.as_any().downcast_ref::<Int16Array>() {
92 return json!(a.value(r));
93 }
94 if let Some(a) = arr.as_any().downcast_ref::<Int8Array>() {
95 return json!(a.value(r));
96 }
97 if let Some(a) = arr.as_any().downcast_ref::<UInt64Array>() {
99 return json!(a.value(r) as i64);
100 }
101 if let Some(a) = arr.as_any().downcast_ref::<UInt32Array>() {
102 return json!(a.value(r) as i64);
103 }
104 if let Some(a) = arr.as_any().downcast_ref::<UInt16Array>() {
105 return json!(a.value(r) as i64);
106 }
107 if let Some(a) = arr.as_any().downcast_ref::<UInt8Array>() {
108 return json!(a.value(r) as i64);
109 }
110 if let Some(a) = arr.as_any().downcast_ref::<Float64Array>() {
112 return serde_json::Number::from_f64(a.value(r))
113 .map(Value::Number)
114 .unwrap_or(Value::Null);
115 }
116 if let Some(a) = arr.as_any().downcast_ref::<Float32Array>() {
117 return serde_json::Number::from_f64(a.value(r) as f64)
118 .map(Value::Number)
119 .unwrap_or(Value::Null);
120 }
121 if let Some(a) = arr.as_any().downcast_ref::<BooleanArray>() {
123 return Value::Bool(a.value(r));
124 }
125 if let Some(a) = arr.as_any().downcast_ref::<StringArray>() {
127 return Value::String(a.value(r).to_string());
128 }
129 if arr.as_any().downcast_ref::<NullArray>().is_some() {
130 return Value::Null;
131 }
132 Value::String(format!("{arr:?}"))
134}