From 4ba916c9790ef8a7fcc5d4dd3ca73ced969919a0 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Fri, 26 Jul 2019 09:11:11 -0700 Subject: [PATCH] Simplify describe message --- src/postgres/protocol/describe.rs | 78 ++++++++++++++----------------- src/postgres/protocol/mod.rs | 14 ++++-- 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/src/postgres/protocol/describe.rs b/src/postgres/protocol/describe.rs index 3ee80bb0..9d8509d6 100644 --- a/src/postgres/protocol/describe.rs +++ b/src/postgres/protocol/describe.rs @@ -1,63 +1,55 @@ -use super::Encode; -use std::io; -#[derive(Debug)] -pub enum DescribeKind { - Portal, - PreparedStatement, +/// The Describe message (portal variant) specifies the name of an existing portal +/// (or an empty string for the unnamed portal). The response is a RowDescription message +/// describing the rows that will be returned by executing the portal; or a NoData message +/// if the portal does not contain a query that will return rows; or ErrorResponse if there is no such portal. +pub fn portal(buf: &mut Vec, name: &str) { + buf.push(b'D'); + + let len = 4 + name.len() + 1 + 4; + buf.extend_from_slice(&(len as i32).to_be_bytes()); + + buf.push(b'P'); + + buf.extend_from_slice(name.as_bytes()); + buf.push(b'\0'); } -#[derive(Debug)] -pub struct Describe<'a> { - kind: DescribeKind, - name: &'a str, -} +/// The Describe message (statement variant) specifies the name of an existing prepared statement +/// (or an empty string for the unnamed prepared statement). The response is a ParameterDescription +/// message describing the parameters needed by the statement, followed by a RowDescription message +/// describing the rows that will be returned when the statement is eventually executed +/// (or a NoData message if the statement will not return rows). ErrorResponse is issued if +/// there is no such prepared statement. Note that since Bind has not yet been issued, +/// the formats to be used for returned columns are not yet known to the backend; the +/// format code fields in the RowDescription message will be zeroes in this case. +pub fn statement(buf: &mut Vec, name: &str) { + buf.push(b'D'); -impl<'a> Describe<'a> { - pub fn new(kind: DescribeKind, name: &'a str) -> Self { - Self { kind, name } - } -} + let len = 4 + name.len() + 1 + 4; + buf.extend_from_slice(&(len as i32).to_be_bytes()); -impl<'a> Encode for Describe<'a> { - fn encode(&self, buf: &mut Vec) -> io::Result<()> { - buf.push(b'D'); + buf.push(b'S'); - let len = 4 + self.name.len() + 1 + 4; - buf.extend_from_slice(&(len as i32).to_be_bytes()); - - match &self.kind { - DescribeKind::Portal => buf.push(b'P'), - DescribeKind::PreparedStatement => buf.push(b'S'), - }; - - buf.extend_from_slice(self.name.as_bytes()); - buf.push(b'\0'); - - Ok(()) - } + buf.extend_from_slice(name.as_bytes()); + buf.push(b'\0'); } #[cfg(test)] mod test { - use super::{Describe, DescribeKind, Encode}; - use std::io; - #[test] - fn it_encodes_describe_portal() -> io::Result<()> { + fn it_encodes_describe_portal() { let mut buf = vec![]; - Describe::new(DescribeKind::Portal, "ABC123").encode(&mut buf)?; - assert_eq!(&buf, b"D\x00\x00\x00\x0fPABC123\x00"); + super::portal(&mut buf, "ABC123"); - Ok(()) + assert_eq!(&buf, b"D\x00\x00\x00\x0fPABC123\x00"); } #[test] - fn it_encodes_describe_statement() -> io::Result<()> { + fn it_encodes_describe_statement() { let mut buf = vec![]; - Describe::new(DescribeKind::PreparedStatement, "95 apples").encode(&mut buf)?; - assert_eq!(&buf, b"D\x00\x00\x00\x12S95 apples\x00"); + super::statement(&mut buf, "95 apples"); - Ok(()) + assert_eq!(&buf, b"D\x00\x00\x00\x12S95 apples\x00"); } } diff --git a/src/postgres/protocol/mod.rs b/src/postgres/protocol/mod.rs index 1de8ee7f..dd6d5b34 100644 --- a/src/postgres/protocol/mod.rs +++ b/src/postgres/protocol/mod.rs @@ -1,11 +1,9 @@ -pub mod bind; +// Unsorted -mod authentication; mod backend_key_data; mod command_complete; mod data_row; mod decode; -mod describe; mod encode; mod execute; mod message; @@ -22,13 +20,21 @@ mod startup_message; mod sync; mod terminate; +// Front-end + +pub mod bind; +pub mod describe; + +// Back-end + +mod authentication; + pub use self::{ authentication::Authentication, backend_key_data::BackendKeyData, command_complete::CommandComplete, data_row::DataRow, decode::Decode, - describe::{Describe, DescribeKind}, encode::Encode, execute::Execute, message::Message,