opensrv_clickhouse/types/column/
ip.rs1use std::marker::PhantomData;
16use std::net::Ipv4Addr;
17use std::net::Ipv6Addr;
18use std::sync::Arc;
19
20use super::column_data::ColumnData;
21use super::ColumnFrom;
22use crate::binary::Encoder;
23use crate::binary::ReadEx;
24use crate::errors::Result;
25use crate::types::column::column_data::BoxColumnData;
26use crate::types::column::nullable::NullableColumnData;
27use crate::types::column::ColumnWrapper;
28use crate::types::SqlType;
29use crate::types::Value;
30use crate::types::ValueRef;
31
32pub(crate) trait IpVersion: Copy + Sync + Send + 'static {
33 fn sql_type() -> SqlType;
34 fn size() -> usize;
35 fn push(inner: &mut Vec<u8>, value: Value);
36 fn get(inner: &[u8], index: usize) -> ValueRef;
37}
38
39#[derive(Copy, Clone)]
40pub(crate) struct Ipv4;
41
42#[derive(Copy, Clone)]
43pub(crate) struct Ipv6;
44
45#[derive(Copy, Clone)]
46pub(crate) struct Uuid;
47
48impl IpVersion for Ipv4 {
49 #[inline(always)]
50 fn sql_type() -> SqlType {
51 SqlType::Ipv4
52 }
53
54 #[inline(always)]
55 fn size() -> usize {
56 4
57 }
58
59 #[inline(always)]
60 fn push(inner: &mut Vec<u8>, value: Value) {
61 if let Value::Ipv4(v) = value {
62 inner.extend(v);
63 } else {
64 panic!();
65 }
66 }
67
68 #[inline(always)]
69 fn get(inner: &[u8], index: usize) -> ValueRef {
70 let mut v: [u8; 4] = Default::default();
71 v.copy_from_slice(&inner[index * 4..(index + 1) * 4]);
72 ValueRef::Ipv4(v)
73 }
74}
75
76impl IpVersion for Ipv6 {
77 #[inline(always)]
78 fn sql_type() -> SqlType {
79 SqlType::Ipv6
80 }
81
82 #[inline(always)]
83 fn size() -> usize {
84 16
85 }
86
87 #[inline(always)]
88 fn push(inner: &mut Vec<u8>, value: Value) {
89 if let Value::Ipv6(v) = value {
90 inner.extend(v);
91 } else {
92 panic!();
93 }
94 }
95
96 #[inline(always)]
97 fn get(inner: &[u8], index: usize) -> ValueRef {
98 let mut v: [u8; 16] = Default::default();
99 v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
100 ValueRef::Ipv6(v)
101 }
102}
103
104impl IpVersion for Uuid {
105 #[inline(always)]
106 fn sql_type() -> SqlType {
107 SqlType::Uuid
108 }
109
110 #[inline(always)]
111 fn size() -> usize {
112 16
113 }
114
115 #[inline(always)]
116 fn push(inner: &mut Vec<u8>, value: Value) {
117 if let Value::Uuid(v) = value {
118 inner.extend(v);
119 } else {
120 panic!();
121 }
122 }
123
124 #[inline(always)]
125 fn get(inner: &[u8], index: usize) -> ValueRef {
126 let mut v: [u8; 16] = Default::default();
127 v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
128 ValueRef::Uuid(v)
129 }
130}
131
132impl ColumnFrom for Vec<Ipv4Addr> {
133 fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
134 let mut inner = Vec::with_capacity(data.len());
135 for ip in data {
136 let mut buffer = ip.octets();
137 buffer.reverse();
138 inner.extend(buffer);
139 }
140
141 W::wrap(IpColumnData::<Ipv4> {
142 inner,
143 phantom: PhantomData,
144 })
145 }
146}
147
148impl ColumnFrom for Vec<Ipv6Addr> {
149 fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
150 let mut inner = Vec::with_capacity(data.len());
151 for ip in data {
152 inner.extend(ip.octets());
153 }
154
155 W::wrap(IpColumnData::<Ipv6> {
156 inner,
157 phantom: PhantomData,
158 })
159 }
160}
161
162impl ColumnFrom for Vec<uuid::Uuid> {
163 fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
164 let mut inner = Vec::with_capacity(data.len());
165 for uuid in data {
166 let mut buffer = *uuid.as_bytes();
167 buffer[..8].reverse();
168 buffer[8..].reverse();
169 inner.extend(buffer);
170 }
171
172 W::wrap(IpColumnData::<Uuid> {
173 inner,
174 phantom: PhantomData,
175 })
176 }
177}
178
179impl ColumnFrom for Vec<Option<Ipv4Addr>> {
180 fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
181 let n = source.len();
182 let mut inner: Vec<u8> = Vec::with_capacity(n * 4);
183 let mut nulls: Vec<u8> = Vec::with_capacity(n);
184
185 for ip in source {
186 match ip {
187 None => {
188 inner.extend([0; 4]);
189 nulls.push(1);
190 }
191 Some(ip) => {
192 let mut buffer = ip.octets();
193 buffer.reverse();
194 inner.extend(buffer);
195 nulls.push(0);
196 }
197 }
198 }
199
200 let inner = Arc::new(IpColumnData::<Ipv4> {
201 inner,
202 phantom: PhantomData,
203 });
204
205 let data = NullableColumnData { inner, nulls };
206
207 W::wrap(data)
208 }
209}
210
211impl ColumnFrom for Vec<Option<Ipv6Addr>> {
212 fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
213 let n = source.len();
214 let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
215 let mut nulls: Vec<u8> = Vec::with_capacity(n);
216
217 for ip in source {
218 match ip {
219 None => {
220 inner.extend([0; 16]);
221 nulls.push(1);
222 }
223 Some(ip) => {
224 inner.extend(ip.octets());
225 nulls.push(0);
226 }
227 }
228 }
229
230 let inner = Arc::new(IpColumnData::<Ipv6> {
231 inner,
232 phantom: PhantomData,
233 });
234
235 let data = NullableColumnData { inner, nulls };
236
237 W::wrap(data)
238 }
239}
240
241impl ColumnFrom for Vec<Option<uuid::Uuid>> {
242 fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
243 let n = source.len();
244 let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
245 let mut nulls: Vec<u8> = Vec::with_capacity(n);
246
247 for uuid in source {
248 match uuid {
249 None => {
250 inner.extend([0; 16]);
251 nulls.push(1);
252 }
253 Some(uuid) => {
254 let mut buffer = *uuid.as_bytes();
255 buffer[..8].reverse();
256 buffer[8..].reverse();
257 inner.extend(buffer);
258 nulls.push(0);
259 }
260 }
261 }
262
263 let inner = Arc::new(IpColumnData::<Uuid> {
264 inner,
265 phantom: PhantomData,
266 });
267
268 let data = NullableColumnData { inner, nulls };
269
270 W::wrap(data)
271 }
272}
273
274pub(crate) struct IpColumnData<V: IpVersion> {
275 pub(crate) inner: Vec<u8>,
276 pub(crate) phantom: PhantomData<V>,
277}
278
279impl<V: IpVersion> IpColumnData<V> {
280 pub fn with_capacity(capacity: usize) -> Self {
281 Self {
282 inner: vec![0; capacity * V::size()],
283 phantom: PhantomData,
284 }
285 }
286
287 pub(crate) fn load<R: ReadEx>(reader: &mut R, size: usize) -> Result<Self> {
288 let mut inner = vec![0; size * V::size()];
289 reader.read_bytes(inner.as_mut())?;
290
291 Ok(Self {
292 inner,
293 phantom: PhantomData,
294 })
295 }
296}
297
298impl<V: IpVersion> ColumnData for IpColumnData<V> {
299 fn sql_type(&self) -> SqlType {
300 V::sql_type()
301 }
302
303 fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
304 let start_index = start * V::size();
305 let end_index = end * V::size();
306
307 let slice: &[u8] = self.inner.as_ref();
308 encoder.write_bytes(&slice[start_index..end_index]);
309 }
310
311 fn len(&self) -> usize {
312 self.inner.len() / V::size()
313 }
314
315 fn push(&mut self, value: Value) {
316 V::push(&mut self.inner, value)
317 }
318
319 fn at(&self, index: usize) -> ValueRef {
320 V::get(&self.inner, index)
321 }
322
323 fn clone_instance(&self) -> BoxColumnData {
324 Box::new(Self {
325 inner: self.inner.clone(),
326 phantom: PhantomData,
327 })
328 }
329
330 unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
331 assert_eq!(level, 0);
332 *pointers[0] = &self.inner as *const Vec<u8> as *const u8;
333 Ok(())
334 }
335}