#[cfg(feature = "geo-types")]
mod geo_types;
#[cfg(feature = "json")]
mod json;
use serde::Serialize;
use serde_json::Error as SerdeError;
use sqlx_core::{arguments::Arguments, encode::Encode, error::BoxDynError, types::Type};
use crate::{database::Exasol, error::ExaProtocolError, type_info::ExaTypeInfo};
#[derive(Debug, Default)]
pub struct ExaArguments {
pub buf: ExaBuffer,
pub types: Vec<ExaTypeInfo>,
}
impl Arguments for ExaArguments {
type Database = Exasol;
fn reserve(&mut self, additional: usize, size: usize) {
self.types.reserve(additional);
self.buf.buffer.reserve(size);
}
fn add<'t, T>(&mut self, value: T) -> Result<(), BoxDynError>
where
T: Encode<'t, Self::Database> + Type<Self::Database>,
{
let ty = value.produces().unwrap_or_else(T::type_info);
self.buf.start_seq();
let _ = value.encode(&mut self.buf)?;
self.buf.end_seq();
self.buf.add_separator();
self.buf.check_param_count()?;
self.types.push(ty);
Ok(())
}
fn len(&self) -> usize {
self.types.len()
}
}
#[derive(Debug)]
pub struct ExaBuffer {
pub(crate) buffer: String,
pub(crate) col_params_counter: usize,
pub(crate) first_col_params_num: Option<usize>,
}
impl ExaBuffer {
pub fn append<T>(&mut self, value: T) -> Result<(), SerdeError>
where
T: Serialize,
{
self.col_params_counter += 1;
serde_json::to_writer(unsafe { self.buffer.as_mut_vec() }, &value)
}
pub fn append_iter<'q, I, T>(&mut self, iter: I) -> Result<(), BoxDynError>
where
I: IntoIterator<Item = T>,
T: 'q + Encode<'q, Exasol>,
{
let mut iter = iter.into_iter();
if let Some(value) = iter.next() {
let _ = value.encode(self)?;
}
for value in iter {
self.add_separator();
let _ = value.encode(self)?;
}
Ok(())
}
pub(crate) fn num_param_sets(&self) -> usize {
self.first_col_params_num.unwrap_or_default()
}
pub(crate) fn finish(mut self) -> String {
self.buffer.pop();
self.end_seq();
self.buffer
}
fn start_seq(&mut self) {
self.buffer.push('[');
}
fn end_seq(&mut self) {
self.buffer.push(']');
}
fn add_separator(&mut self) {
self.buffer.push(',');
}
fn check_param_count(&mut self) -> Result<(), ExaProtocolError> {
let count = self.col_params_counter;
self.col_params_counter = 0;
match self.first_col_params_num {
Some(n) if n == count => (),
Some(n) => Err(ExaProtocolError::ParameterLengthMismatch(count, n))?,
None => self.first_col_params_num = Some(count),
}
Ok(())
}
}
impl Default for ExaBuffer {
fn default() -> Self {
let mut buffer = Self {
buffer: String::with_capacity(1),
col_params_counter: 0,
first_col_params_num: None,
};
buffer.start_seq();
buffer
}
}