1use bytes::{Buf, BufMut, BytesMut};
2
3use super::{codec, DecodeContext, Message};
4use crate::error::PgWireResult;
5
6pub const FORMAT_CODE_TEXT: i16 = 0;
7pub const FORMAT_CODE_BINARY: i16 = 1;
8
9#[non_exhaustive]
10#[derive(PartialEq, Eq, Debug, Default, new)]
11pub struct FieldDescription {
12 pub name: String,
14 pub table_id: i32,
16 pub column_id: i16,
18 pub type_id: u32,
20 pub type_size: i16,
22 pub type_modifier: i32,
24 pub format_code: i16,
26}
27
28#[non_exhaustive]
29#[derive(PartialEq, Eq, Debug, Default, new)]
30pub struct RowDescription {
31 pub fields: Vec<FieldDescription>,
32}
33
34pub const MESSAGE_TYPE_BYTE_ROW_DESCRITION: u8 = b'T';
35
36impl Message for RowDescription {
37 #[inline]
38 fn message_type() -> Option<u8> {
39 Some(MESSAGE_TYPE_BYTE_ROW_DESCRITION)
40 }
41
42 #[inline]
43 fn max_message_length() -> usize {
44 super::LONG_BACKEND_PACKET_SIZE_LIMIT
45 }
46
47 fn message_length(&self) -> usize {
48 4 + 2
49 + self
50 .fields
51 .iter()
52 .map(|f| f.name.len() + 1 + 4 + 2 + 4 + 2 + 4 + 2)
53 .sum::<usize>()
54 }
55
56 fn encode_body(&self, buf: &mut BytesMut) -> PgWireResult<()> {
57 buf.put_i16(self.fields.len() as i16);
58
59 for field in &self.fields {
60 codec::put_cstring(buf, &field.name);
61 buf.put_i32(field.table_id);
62 buf.put_i16(field.column_id);
63 buf.put_u32(field.type_id);
64 buf.put_i16(field.type_size);
65 buf.put_i32(field.type_modifier);
66 buf.put_i16(field.format_code);
67 }
68
69 Ok(())
70 }
71
72 fn decode_body(buf: &mut BytesMut, _: usize, _ctx: &DecodeContext) -> PgWireResult<Self> {
73 let fields_len = buf.get_i16();
74 let mut fields = Vec::with_capacity(fields_len as usize);
75
76 for _ in 0..fields_len {
77 let field = FieldDescription {
78 name: codec::get_cstring(buf).unwrap_or_else(|| "".to_owned()),
79 table_id: buf.get_i32(),
80 column_id: buf.get_i16(),
81 type_id: buf.get_u32(),
82 type_size: buf.get_i16(),
83 type_modifier: buf.get_i32(),
84 format_code: buf.get_i16(),
85 };
86
87 fields.push(field);
88 }
89
90 Ok(RowDescription { fields })
91 }
92}
93
94#[non_exhaustive]
96#[derive(PartialEq, Eq, Debug, Default, new, Clone)]
97pub struct ParameterDescription {
98 pub types: Vec<u32>,
100}
101
102pub const MESSAGE_TYPE_BYTE_PARAMETER_DESCRITION: u8 = b't';
103
104impl Message for ParameterDescription {
105 #[inline]
106 fn message_type() -> Option<u8> {
107 Some(MESSAGE_TYPE_BYTE_PARAMETER_DESCRITION)
108 }
109
110 #[inline]
111 fn max_message_length() -> usize {
112 super::SMALL_BACKEND_PACKET_SIZE_LIMIT
113 }
114
115 fn message_length(&self) -> usize {
116 4 + 2 + self.types.len() * 4
117 }
118
119 fn encode_body(&self, buf: &mut BytesMut) -> PgWireResult<()> {
120 buf.put_u16(self.types.len() as u16);
121
122 for t in &self.types {
123 buf.put_i32(*t as i32);
124 }
125
126 Ok(())
127 }
128
129 fn decode_body(buf: &mut BytesMut, _: usize, _ctx: &DecodeContext) -> PgWireResult<Self> {
130 let types_len = buf.get_u16();
131 let mut types = Vec::with_capacity(types_len as usize);
132
133 for _ in 0..types_len {
134 types.push(buf.get_i32() as u32);
135 }
136
137 Ok(ParameterDescription { types })
138 }
139}
140
141#[non_exhaustive]
146#[derive(PartialEq, Eq, Debug, Default, new, Clone)]
147pub struct DataRow {
148 pub data: BytesMut,
149 pub field_count: i16,
150}
151
152impl DataRow {}
153
154pub const MESSAGE_TYPE_BYTE_DATA_ROW: u8 = b'D';
155
156impl Message for DataRow {
157 #[inline]
158 fn message_type() -> Option<u8> {
159 Some(MESSAGE_TYPE_BYTE_DATA_ROW)
160 }
161
162 #[inline]
163 fn max_message_length() -> usize {
164 super::LONG_BACKEND_PACKET_SIZE_LIMIT
165 }
166
167 fn message_length(&self) -> usize {
168 4 + 2 + self.data.len()
169 }
170
171 fn encode_body(&self, buf: &mut BytesMut) -> PgWireResult<()> {
172 buf.put_i16(self.field_count);
173 buf.reserve(self.data.len());
174 buf.put_slice(&self.data);
175
176 Ok(())
177 }
178
179 fn decode_body(buf: &mut BytesMut, msg_len: usize, _ctx: &DecodeContext) -> PgWireResult<Self> {
180 let field_count = buf.get_i16();
181 let data = buf.split_to(msg_len - 4 - 2);
183
184 Ok(DataRow { data, field_count })
185 }
186}
187
188#[non_exhaustive]
191#[derive(PartialEq, Eq, Debug, Default, new)]
192pub struct NoData;
193
194pub const MESSAGE_TYPE_BYTE_NO_DATA: u8 = b'n';
195
196impl Message for NoData {
197 #[inline]
198 fn message_type() -> Option<u8> {
199 Some(MESSAGE_TYPE_BYTE_NO_DATA)
200 }
201
202 #[inline]
203 fn max_message_length() -> usize {
204 super::SMALL_BACKEND_PACKET_SIZE_LIMIT
205 }
206
207 fn message_length(&self) -> usize {
208 4
209 }
210
211 fn encode_body(&self, _buf: &mut BytesMut) -> PgWireResult<()> {
212 Ok(())
213 }
214
215 fn decode_body(_buf: &mut BytesMut, _: usize, _ctx: &DecodeContext) -> PgWireResult<Self> {
216 Ok(NoData::new())
217 }
218}