feat: expose Connection::describe

This commit is contained in:
Ryan Leckey 2021-02-28 12:18:42 -08:00
parent 22e11e59a0
commit 4204f1dc16
No known key found for this signature in database
GPG Key ID: F8AA68C235AB08C9
10 changed files with 113 additions and 10 deletions

View File

@ -1,3 +1,5 @@
use crate::Describe;
use super::{Close, Connect, ConnectOptions, Runtime};
/// A unique connection (session) with a specific database.
@ -16,4 +18,12 @@ where
/// this: [`ping()`][crate::Connection::ping].
///
fn ping(&mut self) -> crate::Result<()>;
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str
) -> crate::Result<Describe<Self::Database>>
where
'e: 'x,
'q: 'x;
}

View File

@ -1,7 +1,7 @@
#[cfg(feature = "async")]
use futures_util::future::BoxFuture;
use crate::{Close, Connect, Database, Runtime};
use crate::{Close, Connect, Database, Describe, Runtime};
/// A single connection (also known as a session) with a specific database.
///
@ -29,4 +29,14 @@ where
fn ping(&mut self) -> BoxFuture<'_, crate::Result<()>>
where
Rt: crate::Async;
#[cfg(feature = "async")]
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str
) -> BoxFuture<'x, crate::Result<Describe<Self::Database>>>
where
Rt: crate::Async,
'e: 'x,
'q: 'x;
}

17
sqlx-core/src/describe.rs Normal file
View File

@ -0,0 +1,17 @@
use crate::Database;
#[derive(Debug)]
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "offline",
serde(bound(
serialize = "DB::TypeInfo: serde::Serialize, DB::Column: serde::Serialize",
deserialize = "DB::TypeInfo: serde::de::DeserializeOwned, DB::Column: serde::de::DeserializeOwned",
))
)]
#[doc(hidden)]
pub struct Describe<Db: Database> {
pub columns: Vec<Db::Column>,
pub parameters: Vec<Db::TypeInfo>,
pub nullable: Vec<Option<bool>>,
}

View File

@ -22,6 +22,7 @@
mod acquire;
pub mod arguments;
mod close;
mod describe;
mod column;
mod connect;
mod connection;
@ -85,3 +86,4 @@ pub use runtime::Runtime;
#[cfg(feature = "tokio")]
pub use runtime::Tokio;
pub use type_info::TypeInfo;
pub use describe::Describe;

View File

@ -1,7 +1,7 @@
use std::fmt::{self, Debug, Formatter};
#[cfg(feature = "async")]
use futures_util::future::{BoxFuture, FutureExt};
use futures_util::future::{BoxFuture, FutureExt, TryFutureExt};
use sqlx_core::net::Stream as NetStream;
use sqlx_core::{Close, Connect, Connection, Runtime};
@ -13,9 +13,11 @@ use crate::{MySql, MySqlConnectOptions};
#[macro_use]
mod flush;
#[macro_use]
mod executor;
mod command;
mod connect;
mod executor;
mod ping;
/// A single connection (also known as a session) to a MySQL database server.
@ -88,6 +90,19 @@ where
{
Box::pin(self.ping_async())
}
#[cfg(feature = "async")]
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str,
) -> BoxFuture<'x, sqlx_core::Result<sqlx_core::Describe<MySql>>>
where
Rt: sqlx_core::Async,
'e: 'x,
'q: 'x,
{
self.raw_prepare_async(query).map_ok(Into::into).boxed()
}
}
impl<Rt: Runtime> Connect<Rt> for MySqlConnection<Rt> {
@ -121,13 +136,24 @@ impl<Rt: Runtime> Close<Rt> for MySqlConnection<Rt> {
mod blocking {
use sqlx_core::blocking::{Close, Connect, Connection, Runtime};
use super::{MySqlConnectOptions, MySqlConnection};
use super::{MySqlConnectOptions, MySqlConnection, MySql};
impl<Rt: Runtime> Connection<Rt> for MySqlConnection<Rt> {
#[inline]
fn ping(&mut self) -> sqlx_core::Result<()> {
self.ping_blocking()
}
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str,
) -> sqlx_core::Result<sqlx_core::Describe<MySql>>
where
'e: 'x,
'q: 'x,
{
self.raw_prepare_blocking(query).map(Into::into)
}
}
impl<Rt: Runtime> Connect<Rt> for MySqlConnection<Rt> {

View File

@ -56,7 +56,7 @@ macro_rules! impl_raw_prepare {
impl<Rt: Runtime> super::MySqlConnection<Rt> {
#[cfg(feature = "async")]
pub(super) async fn raw_prepare_async(&mut self, sql: &str) -> Result<RawStatement>
pub(crate) async fn raw_prepare_async(&mut self, sql: &str) -> Result<RawStatement>
where
Rt: sqlx_core::Async,
{
@ -65,7 +65,7 @@ impl<Rt: Runtime> super::MySqlConnection<Rt> {
}
#[cfg(feature = "blocking")]
pub(super) fn raw_prepare_blocking(&mut self, sql: &str) -> Result<RawStatement>
pub(crate) fn raw_prepare_blocking(&mut self, sql: &str) -> Result<RawStatement>
where
Rt: sqlx_core::blocking::Runtime,
{

View File

@ -1,5 +1,7 @@
use sqlx_core::Describe;
use crate::protocol::PrepareOk;
use crate::{MySqlColumn, MySqlTypeInfo};
use crate::{MySql, MySqlColumn, MySqlTypeInfo};
#[derive(Debug, Clone)]
pub(crate) struct RawStatement {
@ -37,3 +39,13 @@ impl RawStatement {
&mut self.parameters
}
}
impl From<RawStatement> for Describe<MySql> {
fn from(stmt: RawStatement) -> Self {
Self {
nullable: stmt.columns.iter().map(|col| Some(col.is_nullable())).collect(),
columns: stmt.columns,
parameters: stmt.parameters,
}
}
}

View File

@ -71,5 +71,5 @@ pub use sqlx_core::AsyncStd;
pub use sqlx_core::Tokio;
pub use sqlx_core::{
Acquire, Arguments, Close, Connect, ConnectOptions, Connection, Database, Decode, Encode,
Error, Execute, Executor, FromRow, Result, Row, Runtime, Type,
Error, Execute, Executor, FromRow, Result, Row, Runtime, Type, Describe,
};

View File

@ -1,7 +1,7 @@
use crate::blocking::{Close, Connect, Connection, Executor, Runtime};
use crate::mysql::connection::MySqlConnection;
use crate::mysql::{MySql, MySqlConnectOptions, MySqlQueryResult, MySqlRow};
use crate::{Blocking, Execute, Result};
use crate::{Blocking, Execute, Result, Describe};
impl MySqlConnection<Blocking> {
/// Open a new database connection.
@ -68,6 +68,18 @@ impl<Rt: Runtime> Connection<Rt> for MySqlConnection<Rt> {
fn ping(&mut self) -> Result<()> {
self.0.ping()
}
#[inline]
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str,
) -> Result<Describe<MySql>>
where
'e: 'x,
'q: 'x,
{
self.0.describe(query)
}
}
impl<Rt: Runtime> Executor<Rt> for MySqlConnection<Rt> {

View File

@ -8,7 +8,7 @@ use sqlx_core::{Execute, Executor};
use super::{MySql, MySqlConnectOptions, MySqlQueryResult, MySqlRow};
#[cfg(feature = "blocking")]
use crate::blocking;
use crate::{Arguments, Close, Connect, Connection, DefaultRuntime, Runtime};
use crate::{Arguments, Describe, Close, Connect, Connection, DefaultRuntime, Runtime};
#[cfg(feature = "async")]
use crate::{Async, Result};
@ -131,6 +131,20 @@ impl<Rt: Runtime> Connection<Rt> for MySqlConnection<Rt> {
{
self.0.ping()
}
#[cfg(feature = "async")]
#[inline]
fn describe<'x, 'e, 'q>(
&'e mut self,
query: &'q str,
) -> BoxFuture<'x, Result<Describe<MySql>>>
where
Rt: Async,
'e: 'x,
'q: 'x,
{
self.0.describe(query)
}
}
impl<Rt: Runtime> Executor<Rt> for MySqlConnection<Rt> {