1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::{
fixed_sized::{Bit, FixedSizedCType},
handles::{CData, CDataMut},
};
use odbc_sys::{Date, Numeric, Time, Timestamp, NULL_DATA};
use std::{
convert::TryInto,
ffi::c_void,
mem::size_of,
ptr::{null, null_mut},
};
pub type OptF64Column = OptFixedSizedColumn<f64>;
pub type OptF32Column = OptFixedSizedColumn<f32>;
pub type OptDateColumn = OptFixedSizedColumn<Date>;
pub type OptTimestampColumn = OptFixedSizedColumn<Timestamp>;
pub type OptTimeColumn = OptFixedSizedColumn<Time>;
pub type OptI32Column = OptFixedSizedColumn<i32>;
pub type OptI64Column = OptFixedSizedColumn<i64>;
pub type OptNumericColumn = OptFixedSizedColumn<Numeric>;
pub type OptU8Column = OptFixedSizedColumn<u8>;
pub type OptI8Column = OptFixedSizedColumn<i8>;
pub type OptBitColumn = OptFixedSizedColumn<Bit>;
pub struct OptFixedSizedColumn<T> {
values: Vec<T>,
indicators: Vec<isize>,
}
impl<T> OptFixedSizedColumn<T>
where
T: Default + Clone,
{
pub fn new(batch_size: usize) -> Self {
Self {
values: vec![T::default(); batch_size],
indicators: vec![NULL_DATA; batch_size],
}
}
pub unsafe fn value_at(&self, row_index: usize) -> Option<&T> {
if self.indicators[row_index] == NULL_DATA {
None
} else {
Some(&self.values[row_index])
}
}
pub fn values(&self) -> &[T] {
&self.values
}
pub fn indicators(&self) -> &[isize] {
&self.indicators
}
}
unsafe impl<T> CData for OptFixedSizedColumn<T>
where
T: FixedSizedCType,
{
fn cdata_type(&self) -> odbc_sys::CDataType {
T::C_DATA_TYPE
}
fn indicator_ptr(&self) -> *const isize {
self.indicators.as_ptr() as *const isize
}
fn value_ptr(&self) -> *const c_void {
self.values.as_ptr() as *const c_void
}
fn buffer_length(&self) -> isize {
size_of::<T>().try_into().unwrap()
}
}
unsafe impl<T> CDataMut for OptFixedSizedColumn<T>
where
T: FixedSizedCType,
{
fn mut_indicator_ptr(&mut self) -> *mut isize {
self.indicators.as_mut_ptr() as *mut isize
}
fn mut_value_ptr(&mut self) -> *mut c_void {
self.values.as_mut_ptr() as *mut c_void
}
}
unsafe impl<T> CData for Vec<T>
where
T: FixedSizedCType,
{
fn cdata_type(&self) -> odbc_sys::CDataType {
T::C_DATA_TYPE
}
fn indicator_ptr(&self) -> *const isize {
null()
}
fn value_ptr(&self) -> *const c_void {
self.as_ptr() as *const c_void
}
fn buffer_length(&self) -> isize {
size_of::<T>().try_into().unwrap()
}
}
unsafe impl<T> CDataMut for Vec<T>
where
T: FixedSizedCType,
{
fn mut_indicator_ptr(&mut self) -> *mut isize {
null_mut()
}
fn mut_value_ptr(&mut self) -> *mut c_void {
self.as_mut_ptr() as *mut c_void
}
}