tank_postgres/
prepared.rs

1use 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/// Prepared statement wrapper for Postgres.
11///
12/// Holds the `tokio_postgres::Statement` and collected parameter `Value`s for binding/execution through the `Executor` APIs.
13#[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    pub(crate) fn take_params(&mut self) -> Vec<ValueWrap<'static>> {
29        self.index = 0;
30        mem::take(&mut self.params)
31            .into_iter()
32            .map(|v| ValueWrap(Cow::Owned(v)))
33            .collect()
34    }
35}
36
37impl Prepared for PostgresPrepared {
38    fn clear_bindings(&mut self) -> Result<&mut Self> {
39        self.params.clear();
40        self.index = 0;
41        Ok(self)
42    }
43    fn bind(&mut self, value: impl AsValue) -> Result<&mut Self> {
44        self.bind_index(value, self.index)
45    }
46    fn bind_index(&mut self, value: impl AsValue, index: u64) -> Result<&mut Self> {
47        let len = self.statement.params().len();
48        self.params.resize_with(len, Default::default);
49        let target = self
50            .params
51            .get_mut(index as usize)
52            .ok_or(Error::msg(format!(
53                "Index {index} cannot be bound, the query has only {len} parameters",
54            )))?;
55        *target = value.as_value();
56        self.index = index + 1;
57        Ok(self)
58    }
59}
60
61impl Display for PostgresPrepared {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        f.write_str("PostgresPrepared: ")?;
64        self.statement.fmt(f)
65    }
66}