opensrv_clickhouse/types/column/
date.rs1use std::convert;
16use std::fmt;
17use std::sync::Arc;
18
19use chrono::prelude::*;
20use chrono::NaiveDate;
21use chrono_tz::Tz;
22use micromarshal::Marshal;
23use micromarshal::Unmarshal;
24
25use crate::binary::Encoder;
26use crate::binary::ReadEx;
27use crate::errors::Result;
28use crate::types::column::array::ArrayColumnData;
29use crate::types::column::column_data::BoxColumnData;
30use crate::types::column::column_data::ColumnData;
31use crate::types::column::list::List;
32use crate::types::column::nullable::NullableColumnData;
33use crate::types::column::numeric::save_data;
34use crate::types::column::ArcColumnWrapper;
35use crate::types::column::ColumnFrom;
36use crate::types::column::ColumnWrapper;
37use crate::types::column::Either;
38use crate::types::DateConverter;
39use crate::types::SqlType;
40use crate::types::StatBuffer;
41use crate::types::Value;
42use crate::types::ValueRef;
43
44pub struct DateColumnData<T>
45where
46 T: StatBuffer
47 + Unmarshal<T>
48 + Marshal
49 + Copy
50 + convert::Into<Value>
51 + convert::From<Value>
52 + fmt::Display
53 + Sync
54 + Default
55 + 'static,
56{
57 data: List<T>,
58 tz: Tz,
59}
60
61impl<T> DateColumnData<T>
62where
63 T: StatBuffer
64 + Unmarshal<T>
65 + Marshal
66 + Copy
67 + convert::Into<Value>
68 + convert::From<Value>
69 + fmt::Display
70 + Sync
71 + Default
72 + 'static,
73{
74 pub(crate) fn with_capacity(capacity: usize, timezone: Tz) -> DateColumnData<T> {
75 DateColumnData {
76 data: List::with_capacity(capacity),
77 tz: timezone,
78 }
79 }
80
81 pub(crate) fn load<R: ReadEx>(
82 reader: &mut R,
83 size: usize,
84 tz: Tz,
85 ) -> Result<DateColumnData<T>> {
86 let mut data = List::with_capacity(size);
87 unsafe {
88 data.set_len(size);
89 }
90 reader.read_bytes(data.as_mut())?;
91 Ok(DateColumnData { data, tz })
92 }
93}
94
95impl ColumnFrom for Vec<NaiveDate> {
96 fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
97 let mut data = List::<u16>::with_capacity(source.len());
98 for s in source {
99 data.push(u16::get_days(s));
100 }
101
102 let column: DateColumnData<u16> = DateColumnData { data, tz: Tz::Zulu };
103 W::wrap(column)
104 }
105}
106
107impl ColumnFrom for Vec<Vec<NaiveDate>> {
108 fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
109 let fake: Vec<NaiveDate> = Vec::with_capacity(source.len());
110 let inner = Vec::column_from::<ArcColumnWrapper>(fake);
111 let sql_type = inner.sql_type();
112
113 let mut data = ArrayColumnData {
114 inner,
115 offsets: List::with_capacity(source.len()),
116 };
117
118 for vs in source {
119 let mut inner = Vec::with_capacity(vs.len());
120 for v in vs {
121 let days = u16::get_days(v);
122 let value: Value = Value::Date(days);
123 inner.push(value);
124 }
125 data.push(Value::Array(sql_type.clone().into(), Arc::new(inner)));
126 }
127
128 W::wrap(data)
129 }
130}
131
132impl ColumnFrom for Vec<Vec<DateTime<Tz>>> {
133 fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
134 let fake: Vec<DateTime<Tz>> = Vec::with_capacity(source.len());
135 let inner = Vec::column_from::<ArcColumnWrapper>(fake);
136 let sql_type = inner.sql_type();
137
138 let mut data = ArrayColumnData {
139 inner,
140 offsets: List::with_capacity(source.len()),
141 };
142
143 for vs in source {
144 let mut inner = Vec::with_capacity(vs.len());
145 for v in vs {
146 let value: Value = Value::DateTime(v.timestamp() as u32, v.timezone());
147 inner.push(value);
148 }
149 data.push(Value::Array(sql_type.clone().into(), Arc::new(inner)));
150 }
151
152 W::wrap(data)
153 }
154}
155
156impl ColumnFrom for Vec<Option<NaiveDate>> {
157 fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
158 let fake: Vec<NaiveDate> = Vec::with_capacity(source.len());
159 let inner = Vec::column_from::<ArcColumnWrapper>(fake);
160
161 let mut data = NullableColumnData {
162 inner,
163 nulls: Vec::with_capacity(source.len()),
164 };
165
166 for value in source {
167 match value {
168 None => data.push(Value::Nullable(Either::Left(SqlType::Date.into()))),
169 Some(d) => {
170 let days = u16::get_days(d);
171 let value = Value::Date(days);
172 data.push(Value::Nullable(Either::Right(Box::new(value))))
173 }
174 }
175 }
176
177 W::wrap(data)
178 }
179}
180
181impl<T> ColumnData for DateColumnData<T>
182where
183 T: StatBuffer
184 + Unmarshal<T>
185 + Marshal
186 + Copy
187 + convert::Into<Value>
188 + convert::From<Value>
189 + fmt::Display
190 + Sync
191 + Send
192 + DateConverter
193 + Default
194 + 'static,
195{
196 fn sql_type(&self) -> SqlType {
197 T::date_type()
198 }
199
200 fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
201 save_data::<T>(self.data.as_ref(), encoder, start, end);
202 }
203
204 fn len(&self) -> usize {
205 self.data.len()
206 }
207
208 fn push(&mut self, value: Value) {
209 self.data.push(T::get_stamp(value));
210 }
211
212 fn at(&self, index: usize) -> ValueRef {
213 self.data.at(index).to_date(self.tz)
214 }
215
216 fn clone_instance(&self) -> BoxColumnData {
217 Box::new(Self {
218 data: self.data.clone(),
219 tz: self.tz,
220 })
221 }
222
223 unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
224 assert_eq!(level, 0);
225 *pointers[0] = self.data.as_ptr() as *const u8;
226 *pointers[1] = &self.tz as *const Tz as *const u8;
227 *(pointers[2] as *mut usize) = self.len();
228 Ok(())
229 }
230}