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