hdbconnect_arrow/builders/
boolean.rs1use std::sync::Arc;
4
5use arrow_array::ArrayRef;
6use arrow_array::builder::BooleanBuilder;
7
8use crate::Result;
9use crate::traits::builder::HanaCompatibleBuilder;
10use crate::traits::sealed::private::Sealed;
11
12#[derive(Debug)]
14pub struct BooleanBuilderWrapper {
15 builder: BooleanBuilder,
16 len: usize,
17}
18
19impl BooleanBuilderWrapper {
20 #[must_use]
22 pub fn new(capacity: usize) -> Self {
23 Self {
24 builder: BooleanBuilder::with_capacity(capacity),
25 len: 0,
26 }
27 }
28
29 #[must_use]
31 pub fn default_capacity() -> Self {
32 Self::new(1024)
33 }
34}
35
36impl Sealed for BooleanBuilderWrapper {}
37
38impl HanaCompatibleBuilder for BooleanBuilderWrapper {
39 fn append_hana_value(&mut self, value: &hdbconnect::HdbValue) -> Result<()> {
40 use hdbconnect::HdbValue;
41
42 match value {
43 HdbValue::BOOLEAN(b) => {
44 self.builder.append_value(*b);
45 }
46 other => {
47 return Err(crate::ArrowConversionError::value_conversion(
48 "boolean",
49 format!("expected BOOLEAN, got {other:?}"),
50 ));
51 }
52 }
53 self.len += 1;
54 Ok(())
55 }
56
57 fn append_null(&mut self) {
58 self.builder.append_null();
59 self.len += 1;
60 }
61
62 fn finish(&mut self) -> ArrayRef {
63 self.len = 0;
64 Arc::new(self.builder.finish())
65 }
66
67 fn len(&self) -> usize {
68 self.len
69 }
70
71 fn capacity(&self) -> Option<usize> {
72 Some(self.builder.capacity())
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use arrow_array::{Array, BooleanArray};
79 use hdbconnect::HdbValue;
80
81 use super::*;
82
83 #[test]
84 fn test_boolean_builder() {
85 let mut builder = BooleanBuilderWrapper::new(10);
86
87 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
88 builder.append_null();
89 builder
90 .append_hana_value(&HdbValue::BOOLEAN(false))
91 .unwrap();
92
93 assert_eq!(builder.len(), 3);
94 let array = builder.finish();
95 assert_eq!(array.len(), 3);
96 }
97
98 #[test]
99 fn test_boolean_builder_default_capacity() {
100 let builder = BooleanBuilderWrapper::default_capacity();
101 assert_eq!(builder.len(), 0);
102 assert!(builder.is_empty());
103 assert!(builder.capacity().is_some());
104 }
105
106 #[test]
107 fn test_boolean_builder_new_with_capacity() {
108 let builder = BooleanBuilderWrapper::new(100);
109 assert_eq!(builder.len(), 0);
110 assert!(builder.capacity().is_some());
112 assert!(builder.capacity().unwrap() >= 100);
113 }
114
115 #[test]
116 fn test_boolean_builder_true_values() {
117 let mut builder = BooleanBuilderWrapper::new(5);
118 for _ in 0..5 {
119 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
120 }
121 assert_eq!(builder.len(), 5);
122 let array = builder.finish();
123 let bool_array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
124 for i in 0..5 {
125 assert!(bool_array.value(i));
126 }
127 }
128
129 #[test]
130 fn test_boolean_builder_false_values() {
131 let mut builder = BooleanBuilderWrapper::new(5);
132 for _ in 0..5 {
133 builder
134 .append_hana_value(&HdbValue::BOOLEAN(false))
135 .unwrap();
136 }
137 let array = builder.finish();
138 let bool_array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
139 for i in 0..5 {
140 assert!(!bool_array.value(i));
141 }
142 }
143
144 #[test]
145 fn test_boolean_builder_mixed_values() {
146 let mut builder = BooleanBuilderWrapper::new(4);
147 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
148 builder
149 .append_hana_value(&HdbValue::BOOLEAN(false))
150 .unwrap();
151 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
152 builder
153 .append_hana_value(&HdbValue::BOOLEAN(false))
154 .unwrap();
155
156 let array = builder.finish();
157 let bool_array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
158 assert!(bool_array.value(0));
159 assert!(!bool_array.value(1));
160 assert!(bool_array.value(2));
161 assert!(!bool_array.value(3));
162 }
163
164 #[test]
165 fn test_boolean_builder_null_values() {
166 let mut builder = BooleanBuilderWrapper::new(3);
167 builder.append_null();
168 builder.append_null();
169 builder.append_null();
170
171 let array = builder.finish();
172 let bool_array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
173 assert!(bool_array.is_null(0));
174 assert!(bool_array.is_null(1));
175 assert!(bool_array.is_null(2));
176 }
177
178 #[test]
179 fn test_boolean_builder_mixed_with_nulls() {
180 let mut builder = BooleanBuilderWrapper::new(5);
181 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
182 builder.append_null();
183 builder
184 .append_hana_value(&HdbValue::BOOLEAN(false))
185 .unwrap();
186 builder.append_null();
187 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
188
189 let array = builder.finish();
190 let bool_array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
191 assert!(bool_array.value(0) && !bool_array.is_null(0));
192 assert!(bool_array.is_null(1));
193 assert!(!bool_array.value(2) && !bool_array.is_null(2));
194 assert!(bool_array.is_null(3));
195 assert!(bool_array.value(4) && !bool_array.is_null(4));
196 }
197
198 #[test]
199 fn test_boolean_builder_wrong_type_int() {
200 let mut builder = BooleanBuilderWrapper::new(1);
201 let result = builder.append_hana_value(&HdbValue::INT(42));
202 assert!(result.is_err());
203 let err = result.unwrap_err();
204 assert!(err.is_value_conversion());
205 assert!(err.to_string().contains("BOOLEAN"));
206 }
207
208 #[test]
209 fn test_boolean_builder_wrong_type_string() {
210 let mut builder = BooleanBuilderWrapper::new(1);
211 let result = builder.append_hana_value(&HdbValue::STRING("true".to_string()));
212 assert!(result.is_err());
213 assert!(result.unwrap_err().is_value_conversion());
214 }
215
216 #[test]
217 fn test_boolean_builder_wrong_type_bigint() {
218 let mut builder = BooleanBuilderWrapper::new(1);
219 let result = builder.append_hana_value(&HdbValue::BIGINT(1));
220 assert!(result.is_err());
221 assert!(result.unwrap_err().is_value_conversion());
222 }
223
224 #[test]
225 fn test_boolean_builder_finish_resets_len() {
226 let mut builder = BooleanBuilderWrapper::new(10);
227 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
228 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
229 assert_eq!(builder.len(), 2);
230
231 let _ = builder.finish();
232 assert_eq!(builder.len(), 0);
233 assert!(builder.is_empty());
234 }
235
236 #[test]
237 fn test_boolean_builder_reuse_after_finish() {
238 let mut builder = BooleanBuilderWrapper::new(10);
239 builder.append_hana_value(&HdbValue::BOOLEAN(true)).unwrap();
240 let array1 = builder.finish();
241 assert_eq!(array1.len(), 1);
242
243 builder
244 .append_hana_value(&HdbValue::BOOLEAN(false))
245 .unwrap();
246 builder
247 .append_hana_value(&HdbValue::BOOLEAN(false))
248 .unwrap();
249 let array2 = builder.finish();
250 assert_eq!(array2.len(), 2);
251 }
252
253 #[test]
254 fn test_boolean_builder_debug() {
255 let builder = BooleanBuilderWrapper::new(10);
256 let debug_str = format!("{:?}", builder);
257 assert!(debug_str.contains("BooleanBuilderWrapper"));
258 }
259
260 #[test]
261 fn test_boolean_builder_empty_finish() {
262 let mut builder = BooleanBuilderWrapper::new(10);
263 let array = builder.finish();
264 assert_eq!(array.len(), 0);
265 }
266}