opensrv_clickhouse/types/column/
date.rs

1// Copyright 2021 Datafuse Labs.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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}