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