Simplify describe message

This commit is contained in:
Ryan Leckey 2019-07-26 09:11:11 -07:00
parent 3d01db84a0
commit 4ba916c979
2 changed files with 45 additions and 47 deletions

View File

@ -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<u8>, 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<u8>, 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<u8>) -> 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");
}
}

View File

@ -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,