Line data Source code
1 : use crate::client::InnerClient;
2 : use crate::codec::FrontendMessage;
3 : use crate::connection::RequestMessages;
4 : use crate::types::Type;
5 : use postgres_protocol2::{
6 : message::{backend::Field, frontend},
7 : Oid,
8 : };
9 : use std::{
10 : fmt,
11 : sync::{Arc, Weak},
12 : };
13 :
14 : struct StatementInner {
15 : client: Weak<InnerClient>,
16 : name: &'static str,
17 : params: Vec<Type>,
18 : columns: Vec<Column>,
19 : }
20 :
21 : impl Drop for StatementInner {
22 0 : fn drop(&mut self) {
23 0 : if let Some(client) = self.client.upgrade() {
24 0 : let buf = client.with_buf(|buf| {
25 0 : frontend::close(b'S', self.name, buf).unwrap();
26 0 : frontend::sync(buf);
27 0 : buf.split().freeze()
28 0 : });
29 0 : let _ = client.send(RequestMessages::Single(FrontendMessage::Raw(buf)));
30 0 : }
31 0 : }
32 : }
33 :
34 : /// A prepared statement.
35 : ///
36 : /// Prepared statements can only be used with the connection that created them.
37 : #[derive(Clone)]
38 : pub struct Statement(Arc<StatementInner>);
39 :
40 : impl Statement {
41 0 : pub(crate) fn new(
42 0 : inner: &Arc<InnerClient>,
43 0 : name: &'static str,
44 0 : params: Vec<Type>,
45 0 : columns: Vec<Column>,
46 0 : ) -> Statement {
47 0 : Statement(Arc::new(StatementInner {
48 0 : client: Arc::downgrade(inner),
49 0 : name,
50 0 : params,
51 0 : columns,
52 0 : }))
53 0 : }
54 :
55 0 : pub(crate) fn new_anonymous(params: Vec<Type>, columns: Vec<Column>) -> Statement {
56 0 : Statement(Arc::new(StatementInner {
57 0 : client: Weak::new(),
58 0 : name: "<anonymous>",
59 0 : params,
60 0 : columns,
61 0 : }))
62 0 : }
63 :
64 0 : pub(crate) fn name(&self) -> &str {
65 0 : self.0.name
66 0 : }
67 :
68 : /// Returns the expected types of the statement's parameters.
69 0 : pub fn params(&self) -> &[Type] {
70 0 : &self.0.params
71 0 : }
72 :
73 : /// Returns information about the columns returned when the statement is queried.
74 0 : pub fn columns(&self) -> &[Column] {
75 0 : &self.0.columns
76 0 : }
77 : }
78 :
79 : /// Information about a column of a query.
80 : pub struct Column {
81 : name: String,
82 : type_: Type,
83 :
84 : // raw fields from RowDescription
85 : table_oid: Oid,
86 : column_id: i16,
87 : format: i16,
88 :
89 : // that better be stored in self.type_, but that is more radical refactoring
90 : type_oid: Oid,
91 : type_size: i16,
92 : type_modifier: i32,
93 : }
94 :
95 : impl Column {
96 0 : pub(crate) fn new(name: String, type_: Type, raw_field: Field<'_>) -> Column {
97 0 : Column {
98 0 : name,
99 0 : type_,
100 0 : table_oid: raw_field.table_oid(),
101 0 : column_id: raw_field.column_id(),
102 0 : format: raw_field.format(),
103 0 : type_oid: raw_field.type_oid(),
104 0 : type_size: raw_field.type_size(),
105 0 : type_modifier: raw_field.type_modifier(),
106 0 : }
107 0 : }
108 :
109 : /// Returns the name of the column.
110 0 : pub fn name(&self) -> &str {
111 0 : &self.name
112 0 : }
113 :
114 : /// Returns the type of the column.
115 0 : pub fn type_(&self) -> &Type {
116 0 : &self.type_
117 0 : }
118 :
119 : /// Returns the table OID of the column.
120 0 : pub fn table_oid(&self) -> Oid {
121 0 : self.table_oid
122 0 : }
123 :
124 : /// Returns the column ID of the column.
125 0 : pub fn column_id(&self) -> i16 {
126 0 : self.column_id
127 0 : }
128 :
129 : /// Returns the format of the column.
130 0 : pub fn format(&self) -> i16 {
131 0 : self.format
132 0 : }
133 :
134 : /// Returns the type OID of the column.
135 0 : pub fn type_oid(&self) -> Oid {
136 0 : self.type_oid
137 0 : }
138 :
139 : /// Returns the type size of the column.
140 0 : pub fn type_size(&self) -> i16 {
141 0 : self.type_size
142 0 : }
143 :
144 : /// Returns the type modifier of the column.
145 0 : pub fn type_modifier(&self) -> i32 {
146 0 : self.type_modifier
147 0 : }
148 : }
149 :
150 : impl fmt::Debug for Column {
151 0 : fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
152 0 : fmt.debug_struct("Column")
153 0 : .field("name", &self.name)
154 0 : .field("type", &self.type_)
155 0 : .finish()
156 0 : }
157 : }
|