odbc_api/buffers/
column_with_indicator.rs1use crate::{
2 fixed_sized::{Bit, Pod},
3 handles::{CData, CDataMut},
4};
5use odbc_sys::{Date, NULL_DATA, Time, Timestamp};
6use std::{
7 ffi::c_void,
8 mem::size_of,
9 ptr::{null, null_mut},
10};
11
12pub type OptF64Column = ColumnWithIndicator<f64>;
13pub type OptF32Column = ColumnWithIndicator<f32>;
14pub type OptDateColumn = ColumnWithIndicator<Date>;
15pub type OptTimestampColumn = ColumnWithIndicator<Timestamp>;
16pub type OptTimeColumn = ColumnWithIndicator<Time>;
17pub type OptI8Column = ColumnWithIndicator<i8>;
18pub type OptI16Column = ColumnWithIndicator<i16>;
19pub type OptI32Column = ColumnWithIndicator<i32>;
20pub type OptI64Column = ColumnWithIndicator<i64>;
21pub type OptU8Column = ColumnWithIndicator<u8>;
22pub type OptBitColumn = ColumnWithIndicator<Bit>;
23
24#[derive(Debug)]
26pub struct ColumnWithIndicator<T> {
27 values: Vec<T>,
28 indicators: Vec<isize>,
29}
30
31impl<T> ColumnWithIndicator<T>
32where
33 T: Default + Clone,
34{
35 pub fn new(batch_size: usize) -> Self {
36 Self {
37 values: vec![T::default(); batch_size],
38 indicators: vec![NULL_DATA; batch_size],
39 }
40 }
41
42 pub fn iter(&self, num_rows: usize) -> NullableSlice<'_, T> {
49 NullableSlice {
50 indicators: &self.indicators[0..num_rows],
51 values: &self.values[0..num_rows],
52 }
53 }
54
55 pub fn fill_null(&mut self, from: usize, to: usize) {
57 for index in from..to {
58 self.indicators[index] = NULL_DATA;
59 }
60 }
61
62 pub fn writer_n(&mut self, n: usize) -> NullableSliceMut<'_, T> {
64 NullableSliceMut {
65 indicators: &mut self.indicators[0..n],
66 values: &mut self.values[0..n],
67 }
68 }
69
70 pub fn capacity(&self) -> usize {
72 self.indicators.len()
73 }
74}
75
76#[derive(Debug, Clone, Copy)]
79pub struct NullableSlice<'a, T> {
80 indicators: &'a [isize],
81 values: &'a [T],
82}
83
84impl<'a, T> NullableSlice<'a, T> {
85 pub fn is_empty(&self) -> bool {
87 self.values.is_empty()
88 }
89
90 pub fn len(&self) -> usize {
92 self.values.len()
93 }
94
95 pub fn raw_values(&self) -> (&'a [T], &'a [isize]) {
123 (self.values, self.indicators)
124 }
125
126 pub fn get(&self, index: usize) -> Option<&'a T> {
128 if self.indicators[index] == NULL_DATA {
129 None
130 } else {
131 Some(&self.values[index])
132 }
133 }
134}
135
136impl<'a, T> Iterator for NullableSlice<'a, T> {
137 type Item = Option<&'a T>;
138
139 fn next(&mut self) -> Option<Self::Item> {
140 if let Some(&ind) = self.indicators.first() {
141 let item = if ind == NULL_DATA {
142 None
143 } else {
144 Some(&self.values[0])
145 };
146 self.indicators = &self.indicators[1..];
147 self.values = &self.values[1..];
148 Some(item)
149 } else {
150 None
151 }
152 }
153}
154
155unsafe impl<T> CData for ColumnWithIndicator<T>
156where
157 T: Pod,
158{
159 fn cdata_type(&self) -> odbc_sys::CDataType {
160 T::C_DATA_TYPE
161 }
162
163 fn indicator_ptr(&self) -> *const isize {
164 self.indicators.as_ptr()
165 }
166
167 fn value_ptr(&self) -> *const c_void {
168 self.values.as_ptr() as *const c_void
169 }
170
171 fn buffer_length(&self) -> isize {
172 size_of::<T>().try_into().unwrap()
173 }
174}
175
176unsafe impl<T> CDataMut for ColumnWithIndicator<T>
177where
178 T: Pod,
179{
180 fn mut_indicator_ptr(&mut self) -> *mut isize {
181 self.indicators.as_mut_ptr()
182 }
183
184 fn mut_value_ptr(&mut self) -> *mut c_void {
185 self.values.as_mut_ptr() as *mut c_void
186 }
187}
188
189unsafe impl<T> CData for Vec<T>
190where
191 T: Pod,
192{
193 fn cdata_type(&self) -> odbc_sys::CDataType {
194 T::C_DATA_TYPE
195 }
196
197 fn indicator_ptr(&self) -> *const isize {
198 null()
199 }
200
201 fn value_ptr(&self) -> *const c_void {
202 self.as_ptr() as *const c_void
203 }
204
205 fn buffer_length(&self) -> isize {
206 size_of::<T>().try_into().unwrap()
207 }
208}
209
210unsafe impl<T> CDataMut for Vec<T>
211where
212 T: Pod,
213{
214 fn mut_indicator_ptr(&mut self) -> *mut isize {
215 null_mut()
216 }
217
218 fn mut_value_ptr(&mut self) -> *mut c_void {
219 self.as_mut_ptr() as *mut c_void
220 }
221}
222
223#[derive(Debug)]
226pub struct NullableSliceMut<'a, T> {
227 indicators: &'a mut [isize],
228 values: &'a mut [T],
229}
230
231impl<T> NullableSliceMut<'_, T> {
232 pub fn is_empty(&self) -> bool {
234 self.values.is_empty()
235 }
236
237 pub fn len(&self) -> usize {
239 self.values.len()
240 }
241
242 pub fn set_cell(&mut self, index: usize, cell: Option<T>) {
244 if let Some(value) = cell {
245 self.indicators[index] = 0;
246 self.values[index] = value;
247 } else {
248 self.indicators[index] = NULL_DATA;
249 }
250 }
251
252 pub fn raw_values(&mut self) -> (&mut [T], &mut [isize]) {
284 (self.values, self.indicators)
285 }
286}
287
288impl<T> NullableSliceMut<'_, T> {
289 pub fn write(&mut self, it: impl Iterator<Item = Option<T>>) {
292 for (index, item) in it.enumerate().take(self.values.len()) {
293 self.set_cell(index, item)
294 }
295 }
296}