tank_postgres/
prepared.rs

1use crate::ValueWrap;
2use std::{
3    fmt::{self, Debug, Display},
4    mem,
5};
6use tank_core::{AsValue, Error, Prepared, Result};
7use tokio_postgres::Statement;
8
9pub struct PostgresPrepared {
10    pub(crate) statement: Statement,
11    pub(crate) index: u64,
12    pub(crate) params: Vec<ValueWrap>,
13}
14
15impl PostgresPrepared {
16    pub(crate) fn new(statement: Statement) -> Self {
17        Self {
18            statement,
19            index: 0,
20            params: Vec::new(),
21        }
22    }
23    pub(crate) fn take_params(&mut self) -> Vec<ValueWrap> {
24        mem::take(&mut self.params)
25    }
26}
27
28impl Prepared for PostgresPrepared {
29    fn clear_bindings(&mut self) -> Result<&mut Self> {
30        self.params.clear();
31        self.index = 0;
32        Ok(self)
33    }
34    fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
35        self.bind_index(value, self.index)?;
36        Ok(self)
37    }
38    fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
39        let len = self.statement.params().len();
40        self.params.resize_with(len, Default::default);
41        let target = self
42            .params
43            .get_mut(index as usize)
44            .ok_or(Error::msg(format!(
45                "Index {index} cannot be bound, the query has only {} parameters",
46                len
47            )))?;
48        *target = value.as_value().into();
49        self.index += 1;
50        Ok(self)
51    }
52}
53
54impl Display for PostgresPrepared {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        self.statement.fmt(f)
57    }
58}
59
60impl Debug for PostgresPrepared {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.debug_struct("PostgresPrepared")
63            .field("statement", &self.statement)
64            .field("index", &self.index)
65            .finish()
66    }
67}