diff --git a/tokio-postgres/src/row.rs b/tokio-postgres/src/row.rs index 842216ad..e3ed696c 100644 --- a/tokio-postgres/src/row.rs +++ b/tokio-postgres/src/row.rs @@ -1,6 +1,7 @@ //! Rows. use crate::row::sealed::{AsName, Sealed}; +use crate::simple_query::SimpleColumn; use crate::statement::Column; use crate::types::{FromSql, Type, WrongType}; use crate::{Error, Statement}; @@ -188,16 +189,25 @@ impl Row { } } +impl AsName for SimpleColumn { + fn as_name(&self) -> &str { + self.name() + } +} + /// A row of data returned from the database by a simple query. pub struct SimpleQueryRow { - columns: Arc<[String]>, + columns: Arc<[SimpleColumn]>, body: DataRowBody, ranges: Vec>>, } impl SimpleQueryRow { #[allow(clippy::new_ret_no_self)] - pub(crate) fn new(columns: Arc<[String]>, body: DataRowBody) -> Result { + pub(crate) fn new( + columns: Arc<[SimpleColumn]>, + body: DataRowBody, + ) -> Result { let ranges = body.ranges().collect().map_err(Error::parse)?; Ok(SimpleQueryRow { columns, @@ -206,6 +216,11 @@ impl SimpleQueryRow { }) } + /// Returns information about the columns of data in the row. + pub fn columns(&self) -> &[SimpleColumn] { + &self.columns + } + /// Determines if the row contains no values. pub fn is_empty(&self) -> bool { self.len() == 0 diff --git a/tokio-postgres/src/simple_query.rs b/tokio-postgres/src/simple_query.rs index 82ac3566..ade2e1d6 100644 --- a/tokio-postgres/src/simple_query.rs +++ b/tokio-postgres/src/simple_query.rs @@ -14,6 +14,22 @@ use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; +/// Information about a column of a single query row. +pub struct SimpleColumn { + name: String, +} + +impl SimpleColumn { + pub(crate) fn new(name: String) -> SimpleColumn { + SimpleColumn { name } + } + + /// Returns the name of the column. + pub fn name(&self) -> &str { + &self.name + } +} + pub async fn simple_query(client: &InnerClient, query: &str) -> Result { debug!("executing simple query: {}", query); @@ -56,7 +72,7 @@ pin_project! { /// A stream of simple query results. pub struct SimpleQueryStream { responses: Responses, - columns: Option>, + columns: Option>, #[pin] _p: PhantomPinned, } @@ -86,10 +102,11 @@ impl Stream for SimpleQueryStream { Message::RowDescription(body) => { let columns = body .fields() - .map(|f| Ok(f.name().to_string())) + .map(|f| Ok(SimpleColumn::new(f.name().to_string()))) .collect::>() .map_err(Error::parse)? .into(); + *this.columns = Some(columns); } Message::DataRow(body) => { diff --git a/tokio-postgres/tests/test/main.rs b/tokio-postgres/tests/test/main.rs index c367dbea..c0b4bf20 100644 --- a/tokio-postgres/tests/test/main.rs +++ b/tokio-postgres/tests/test/main.rs @@ -282,6 +282,8 @@ async fn simple_query() { } match &messages[2] { SimpleQueryMessage::Row(row) => { + assert_eq!(row.columns().get(0).map(|c| c.name()), Some("id")); + assert_eq!(row.columns().get(1).map(|c| c.name()), Some("name")); assert_eq!(row.get(0), Some("1")); assert_eq!(row.get(1), Some("steven")); } @@ -289,6 +291,8 @@ async fn simple_query() { } match &messages[3] { SimpleQueryMessage::Row(row) => { + assert_eq!(row.columns().get(0).map(|c| c.name()), Some("id")); + assert_eq!(row.columns().get(1).map(|c| c.name()), Some("name")); assert_eq!(row.get(0), Some("2")); assert_eq!(row.get(1), Some("joe")); }