use std::convert;
use std::mem;
use std::sync::Arc;
use super::column_data::BoxColumnData;
use super::column_data::ColumnData;
use super::list::List;
use super::ColumnFrom;
use crate::binary::Encoder;
use crate::binary::ReadEx;
use crate::errors::Result;
use crate::types::column::array::ArrayColumnData;
use crate::types::column::nullable::NullableColumnData;
use crate::types::column::ArcColumnWrapper;
use crate::types::column::ColumnWrapper;
use crate::types::HasSqlType;
use crate::types::Marshal;
use crate::types::SqlType;
use crate::types::StatBuffer;
use crate::types::Unmarshal;
use crate::types::Value;
use crate::types::ValueRef;
pub struct VectorColumnData<T>
where T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Sync
+ HasSqlType
+ 'static
{
pub(crate) data: List<T>
}
impl<T> ColumnFrom for Vec<T>
where T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Send
+ Sync
+ HasSqlType
+ 'static
{
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let mut data = List::with_capacity(source.len());
for s in source {
data.push(s);
}
W::wrap(VectorColumnData { data })
}
}
impl<T> ColumnFrom for Vec<Option<T>>
where
Value: convert::From<T>,
T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Send
+ Sync
+ HasSqlType
+ 'static
{
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let fake: Vec<T> = Vec::with_capacity(source.len());
let inner = Vec::column_from::<ArcColumnWrapper>(fake);
let mut data = NullableColumnData {
inner,
nulls: Vec::with_capacity(source.len())
};
for value in source {
data.push(value.into());
}
W::wrap(data)
}
}
impl<T> ColumnFrom for Vec<Vec<T>>
where
Value: convert::From<T>,
T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Send
+ Sync
+ HasSqlType
+ 'static
{
fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
let fake: Vec<T> = Vec::with_capacity(source.len());
let inner = Vec::column_from::<ArcColumnWrapper>(fake);
let sql_type = inner.sql_type();
let mut data = ArrayColumnData {
inner,
offsets: List::with_capacity(source.len())
};
for array in source {
data.push(to_array(sql_type.clone(), array));
}
W::wrap(data)
}
}
fn to_array<T>(sql_type: SqlType, vs: Vec<T>) -> Value
where
Value: convert::From<T>,
T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Send
+ Sync
+ HasSqlType
+ 'static
{
let mut inner = Vec::with_capacity(vs.len());
for v in vs {
let value: Value = v.into();
inner.push(value)
}
Value::Array(sql_type.into(), Arc::new(inner))
}
impl<T> VectorColumnData<T>
where T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Sync
+ HasSqlType
+ 'static
{
pub(crate) fn with_capacity(capacity: usize) -> VectorColumnData<T> {
VectorColumnData {
data: List::with_capacity(capacity)
}
}
pub(crate) fn load<R: ReadEx>(reader: &mut R, size: usize) -> Result<VectorColumnData<T>> {
let mut data = List::with_capacity(size);
unsafe {
data.set_len(size);
}
reader.read_bytes(data.as_mut())?;
Ok(Self { data })
}
}
impl<T> ColumnData for VectorColumnData<T>
where T: StatBuffer
+ Unmarshal<T>
+ Marshal
+ Copy
+ convert::Into<Value>
+ convert::From<Value>
+ Send
+ Sync
+ HasSqlType
+ 'static
{
fn sql_type(&self) -> SqlType {
T::sql_type()
}
fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
save_data::<T>(self.data.as_ref(), encoder, start, end);
}
fn len(&self) -> usize {
self.data.len()
}
fn push(&mut self, value: Value) {
self.data.push(T::from(value));
}
fn at(&self, index: usize) -> ValueRef {
let v: Value = self.data.at(index).into();
match v {
Value::UInt8(x) => ValueRef::UInt8(x),
Value::UInt16(x) => ValueRef::UInt16(x),
Value::UInt32(x) => ValueRef::UInt32(x),
Value::UInt64(x) => ValueRef::UInt64(x),
Value::Int8(x) => ValueRef::Int8(x),
Value::Int16(x) => ValueRef::Int16(x),
Value::Int32(x) => ValueRef::Int32(x),
Value::Int64(x) => ValueRef::Int64(x),
Value::Float32(x) => ValueRef::Float32(x),
Value::Float64(x) => ValueRef::Float64(x),
_ => panic!("can't convert value to value_ref.")
}
}
fn clone_instance(&self) -> BoxColumnData {
Box::new(Self {
data: self.data.clone()
})
}
unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
assert_eq!(level, 0);
*pointers[0] = self.data.as_ptr() as *const u8;
*(pointers[1] as *mut usize) = self.len();
Ok(())
}
}
pub(crate) fn save_data<T>(data: &[u8], encoder: &mut Encoder, start: usize, end: usize) {
let start_index = start * mem::size_of::<T>();
let end_index = end * mem::size_of::<T>();
encoder.write_bytes(&data[start_index..end_index]);
}