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    }
37    fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
38        let len = self.statement.params().len();
39        self.params.resize_with(len, Default::default);
40        let target = self
41            .params
42            .get_mut(index as usize)
43            .ok_or(Error::msg(format!(
44                "Index {index} cannot be bound, the query has only {} parameters",
45                len
46            )))?;
47        *target = value.as_value().into();
48        self.index = index + 1;
49        Ok(self)
50    }
51}
52
53impl Display for PostgresPrepared {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        self.statement.fmt(f)
56    }
57}
58
59impl Debug for PostgresPrepared {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        f.debug_struct("PostgresPrepared")
62            .field("statement", &self.statement)
63            .field("index", &self.index)
64            .finish()
65    }
66}