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