tank_postgres/
prepared.rs1use crate::ValueWrap;
2use std::{
3 borrow::Cow,
4 fmt::{self, Debug, Display},
5 mem,
6};
7use tank_core::{AsValue, Error, Prepared, Result, Value};
8use tokio_postgres::Statement;
9
10#[derive(Debug)]
14pub struct PostgresPrepared {
15 pub(crate) statement: Statement,
16 pub(crate) params: Vec<Value>,
17 pub(crate) index: u64,
18}
19
20impl PostgresPrepared {
21 pub(crate) fn new(statement: Statement) -> Self {
22 Self {
23 statement,
24 params: Vec::new(),
25 index: 0,
26 }
27 }
28
29 pub(crate) fn take_params(&mut self) -> Vec<ValueWrap<'static>> {
30 self.index = 0;
31 mem::take(&mut self.params)
32 .into_iter()
33 .map(|v| ValueWrap(Cow::Owned(v)))
34 .collect()
35 }
36}
37
38impl Prepared for PostgresPrepared {
39 fn as_any(self: Box<Self>) -> Box<dyn std::any::Any> {
40 self
41 }
42
43 fn clear_bindings(&mut self) -> Result<&mut Self> {
44 self.params.clear();
45 self.index = 0;
46 Ok(self)
47 }
48
49 fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
50 self.bind_index(value, self.index)
51 }
52
53 fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
54 let len = self.statement.params().len();
55 self.params.resize_with(len, Default::default);
56 let target = self
57 .params
58 .get_mut(index as usize)
59 .ok_or(Error::msg(format!(
60 "Index {index} cannot be bound, the query has only {len} parameters",
61 )))?;
62 *target = value.as_value();
63 self.index = index + 1;
64 Ok(self)
65 }
66}
67
68impl Display for PostgresPrepared {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.write_str("PostgresPrepared: ")?;
71 self.statement.fmt(f)
72 }
73}