1use serde::Serialize;
2use serde_json::Error as SerdeError;
3use sqlx_core::{arguments::Arguments, encode::Encode, error::BoxDynError, types::Type};
4
5use crate::{database::Exasol, error::ExaProtocolError, type_info::ExaTypeInfo};
6
7#[derive(Debug, Default)]
9pub struct ExaArguments {
10 pub buf: ExaBuffer,
11 pub types: Vec<ExaTypeInfo>,
12}
13
14impl<'q> Arguments<'q> for ExaArguments {
15 type Database = Exasol;
16
17 fn reserve(&mut self, additional: usize, size: usize) {
18 self.types.reserve(additional);
19 self.buf.buffer.reserve(size);
20 }
21
22 fn add<T>(&mut self, value: T) -> Result<(), BoxDynError>
23 where
24 T: 'q + Encode<'q, Self::Database> + Type<Self::Database>,
25 {
26 let ty = value.produces().unwrap_or_else(T::type_info);
27
28 self.buf.start_seq();
29 let _ = value.encode(&mut self.buf)?;
30 self.buf.end_seq();
31 self.buf.add_separator();
32
33 self.buf.check_param_count()?;
34
35 self.types.push(ty);
36
37 Ok(())
38 }
39
40 fn len(&self) -> usize {
41 self.types.len()
42 }
43}
44
45#[derive(Debug)]
47pub struct ExaBuffer {
48 pub(crate) buffer: String,
53 pub(crate) col_params_counter: usize,
59 pub(crate) first_col_params_num: Option<usize>,
63}
64
65impl ExaBuffer {
66 pub fn append<T>(&mut self, value: T) -> Result<(), SerdeError>
68 where
69 T: Serialize,
70 {
71 self.col_params_counter += 1;
72 serde_json::to_writer(unsafe { self.buffer.as_mut_vec() }, &value)
74 }
75
76 pub fn append_iter<'q, I, T>(&mut self, iter: I) -> Result<(), BoxDynError>
78 where
79 I: IntoIterator<Item = T>,
80 T: 'q + Encode<'q, Exasol> + Type<Exasol>,
81 {
82 let mut iter = iter.into_iter();
83
84 if let Some(value) = iter.next() {
85 let _ = value.encode(self)?;
86 }
87
88 for value in iter {
89 self.add_separator();
90 let _ = value.encode(self)?;
91 }
92
93 Ok(())
94 }
95
96 pub(crate) fn num_param_sets(&self) -> usize {
98 self.first_col_params_num.unwrap_or_default()
99 }
100
101 pub(crate) fn finish(mut self) -> String {
103 self.buffer.pop();
105 self.end_seq();
106 self.buffer
107 }
108
109 fn start_seq(&mut self) {
111 self.buffer.push('[');
112 }
113
114 fn end_seq(&mut self) {
116 self.buffer.push(']');
117 }
118
119 fn add_separator(&mut self) {
121 self.buffer.push(',');
122 }
123
124 fn check_param_count(&mut self) -> Result<(), ExaProtocolError> {
131 let count = self.col_params_counter;
132
133 self.col_params_counter = 0;
135
136 match self.first_col_params_num {
137 Some(n) if n == count => (),
138 Some(n) => Err(ExaProtocolError::ParameterLengthMismatch(count, n))?,
139 None => self.first_col_params_num = Some(count),
140 };
141
142 Ok(())
143 }
144}
145
146impl Default for ExaBuffer {
147 fn default() -> Self {
148 let mut buffer = Self {
149 buffer: String::with_capacity(1),
150 col_params_counter: 0,
151 first_col_params_num: None,
152 };
153
154 buffer.start_seq();
155 buffer
156 }
157}