tokio_postgres/
statement.rs

1use crate::client::InnerClient;
2use crate::codec::FrontendMessage;
3use crate::connection::RequestMessages;
4use crate::types::Type;
5use postgres_protocol::message::frontend;
6use std::sync::{Arc, Weak};
7
8struct StatementInner {
9    client: Weak<InnerClient>,
10    name: String,
11    params: Vec<Type>,
12    columns: Vec<Column>,
13}
14
15impl Drop for StatementInner {
16    fn drop(&mut self) {
17        if self.name.is_empty() {
18            // Unnamed statements don't need to be closed
19            return;
20        }
21        if let Some(client) = self.client.upgrade() {
22            let buf = client.with_buf(|buf| {
23                frontend::close(b'S', &self.name, buf).unwrap();
24                frontend::sync(buf);
25                buf.split().freeze()
26            });
27            let _ = client.send(RequestMessages::Single(FrontendMessage::Raw(buf)));
28        }
29    }
30}
31
32/// A prepared statement.
33///
34/// Prepared statements can only be used with the connection that created them.
35#[derive(Clone)]
36pub struct Statement(Arc<StatementInner>);
37
38impl Statement {
39    pub(crate) fn new(
40        inner: &Arc<InnerClient>,
41        name: String,
42        params: Vec<Type>,
43        columns: Vec<Column>,
44    ) -> Statement {
45        Statement(Arc::new(StatementInner {
46            client: Arc::downgrade(inner),
47            name,
48            params,
49            columns,
50        }))
51    }
52
53    pub(crate) fn unnamed(params: Vec<Type>, columns: Vec<Column>) -> Statement {
54        Statement(Arc::new(StatementInner {
55            client: Weak::new(),
56            name: String::new(),
57            params,
58            columns,
59        }))
60    }
61
62    pub(crate) fn name(&self) -> &str {
63        &self.0.name
64    }
65
66    /// Returns the expected types of the statement's parameters.
67    pub fn params(&self) -> &[Type] {
68        &self.0.params
69    }
70
71    /// Returns information about the columns returned when the statement is queried.
72    pub fn columns(&self) -> &[Column] {
73        &self.0.columns
74    }
75}
76
77impl std::fmt::Debug for Statement {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
79        f.debug_struct("Statement")
80            .field("name", &self.0.name)
81            .field("params", &self.0.params)
82            .field("columns", &self.0.columns)
83            .finish_non_exhaustive()
84    }
85}
86
87/// Information about a column of a query.
88#[derive(Debug)]
89pub struct Column {
90    pub(crate) name: String,
91    pub(crate) table_oid: Option<u32>,
92    pub(crate) column_id: Option<i16>,
93    pub(crate) r#type: Type,
94}
95
96impl Column {
97    /// Returns the name of the column.
98    pub fn name(&self) -> &str {
99        &self.name
100    }
101
102    /// Returns the OID of the underlying database table.
103    pub fn table_oid(&self) -> Option<u32> {
104        self.table_oid
105    }
106
107    /// Return the column ID within the underlying database table.
108    pub fn column_id(&self) -> Option<i16> {
109        self.column_id
110    }
111
112    /// Returns the type of the column.
113    pub fn type_(&self) -> &Type {
114        &self.r#type
115    }
116}