mirror of
https://github.com/launchbadge/sqlx.git
synced 2026-03-19 08:39:44 +00:00
chore: remove BoxFuture's (non-breaking) (#3629)
* chore: reduce BoxFuture's when using recursion. * remove BoxFuture's in WithSocket * chore: better document previous changes
This commit is contained in:
@@ -10,7 +10,6 @@ use crate::types::Json;
|
||||
use crate::types::Oid;
|
||||
use crate::HashMap;
|
||||
use crate::{PgColumn, PgConnection, PgTypeInfo};
|
||||
use futures_core::future::BoxFuture;
|
||||
use smallvec::SmallVec;
|
||||
use sqlx_core::query_builder::QueryBuilder;
|
||||
use std::sync::Arc;
|
||||
@@ -169,7 +168,8 @@ impl PgConnection {
|
||||
|
||||
// fallback to asking the database directly for a type name
|
||||
if should_fetch {
|
||||
let info = self.fetch_type_by_oid(oid).await?;
|
||||
// we're boxing this future here so we can use async recursion
|
||||
let info = Box::pin(async { self.fetch_type_by_oid(oid).await }).await?;
|
||||
|
||||
// cache the type name <-> oid relationship in a paired hashmap
|
||||
// so we don't come down this road again
|
||||
@@ -190,19 +190,18 @@ impl PgConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_type_by_oid(&mut self, oid: Oid) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
|
||||
Box::pin(async move {
|
||||
let (name, typ_type, category, relation_id, element, base_type): (
|
||||
String,
|
||||
i8,
|
||||
i8,
|
||||
Oid,
|
||||
Oid,
|
||||
Oid,
|
||||
) = query_as(
|
||||
// Converting the OID to `regtype` and then `text` will give us the name that
|
||||
// the type will need to be found at by search_path.
|
||||
"SELECT oid::regtype::text, \
|
||||
async fn fetch_type_by_oid(&mut self, oid: Oid) -> Result<PgTypeInfo, Error> {
|
||||
let (name, typ_type, category, relation_id, element, base_type): (
|
||||
String,
|
||||
i8,
|
||||
i8,
|
||||
Oid,
|
||||
Oid,
|
||||
Oid,
|
||||
) = query_as(
|
||||
// Converting the OID to `regtype` and then `text` will give us the name that
|
||||
// the type will need to be found at by search_path.
|
||||
"SELECT oid::regtype::text, \
|
||||
typtype, \
|
||||
typcategory, \
|
||||
typrelid, \
|
||||
@@ -210,54 +209,51 @@ impl PgConnection {
|
||||
typbasetype \
|
||||
FROM pg_catalog.pg_type \
|
||||
WHERE oid = $1",
|
||||
)
|
||||
.bind(oid)
|
||||
.fetch_one(&mut *self)
|
||||
.await?;
|
||||
)
|
||||
.bind(oid)
|
||||
.fetch_one(&mut *self)
|
||||
.await?;
|
||||
|
||||
let typ_type = TypType::try_from(typ_type);
|
||||
let category = TypCategory::try_from(category);
|
||||
let typ_type = TypType::try_from(typ_type);
|
||||
let category = TypCategory::try_from(category);
|
||||
|
||||
match (typ_type, category) {
|
||||
(Ok(TypType::Domain), _) => self.fetch_domain_by_oid(oid, base_type, name).await,
|
||||
match (typ_type, category) {
|
||||
(Ok(TypType::Domain), _) => self.fetch_domain_by_oid(oid, base_type, name).await,
|
||||
|
||||
(Ok(TypType::Base), Ok(TypCategory::Array)) => {
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Array(
|
||||
self.maybe_fetch_type_info_by_oid(element, true).await?,
|
||||
),
|
||||
name: name.into(),
|
||||
oid,
|
||||
}))))
|
||||
}
|
||||
|
||||
(Ok(TypType::Pseudo), Ok(TypCategory::Pseudo)) => {
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Pseudo,
|
||||
name: name.into(),
|
||||
oid,
|
||||
}))))
|
||||
}
|
||||
|
||||
(Ok(TypType::Range), Ok(TypCategory::Range)) => {
|
||||
self.fetch_range_by_oid(oid, name).await
|
||||
}
|
||||
|
||||
(Ok(TypType::Enum), Ok(TypCategory::Enum)) => {
|
||||
self.fetch_enum_by_oid(oid, name).await
|
||||
}
|
||||
|
||||
(Ok(TypType::Composite), Ok(TypCategory::Composite)) => {
|
||||
self.fetch_composite_by_oid(oid, relation_id, name).await
|
||||
}
|
||||
|
||||
_ => Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Simple,
|
||||
(Ok(TypType::Base), Ok(TypCategory::Array)) => {
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Array(
|
||||
self.maybe_fetch_type_info_by_oid(element, true).await?,
|
||||
),
|
||||
name: name.into(),
|
||||
oid,
|
||||
})))),
|
||||
}))))
|
||||
}
|
||||
})
|
||||
|
||||
(Ok(TypType::Pseudo), Ok(TypCategory::Pseudo)) => {
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Pseudo,
|
||||
name: name.into(),
|
||||
oid,
|
||||
}))))
|
||||
}
|
||||
|
||||
(Ok(TypType::Range), Ok(TypCategory::Range)) => {
|
||||
self.fetch_range_by_oid(oid, name).await
|
||||
}
|
||||
|
||||
(Ok(TypType::Enum), Ok(TypCategory::Enum)) => self.fetch_enum_by_oid(oid, name).await,
|
||||
|
||||
(Ok(TypType::Composite), Ok(TypCategory::Composite)) => {
|
||||
self.fetch_composite_by_oid(oid, relation_id, name).await
|
||||
}
|
||||
|
||||
_ => Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Simple,
|
||||
name: name.into(),
|
||||
oid,
|
||||
})))),
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch_enum_by_oid(&mut self, oid: Oid, name: String) -> Result<PgTypeInfo, Error> {
|
||||
@@ -280,15 +276,14 @@ ORDER BY enumsortorder
|
||||
}))))
|
||||
}
|
||||
|
||||
fn fetch_composite_by_oid(
|
||||
async fn fetch_composite_by_oid(
|
||||
&mut self,
|
||||
oid: Oid,
|
||||
relation_id: Oid,
|
||||
name: String,
|
||||
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
|
||||
Box::pin(async move {
|
||||
let raw_fields: Vec<(String, Oid)> = query_as(
|
||||
r#"
|
||||
) -> Result<PgTypeInfo, Error> {
|
||||
let raw_fields: Vec<(String, Oid)> = query_as(
|
||||
r#"
|
||||
SELECT attname, atttypid
|
||||
FROM pg_catalog.pg_attribute
|
||||
WHERE attrelid = $1
|
||||
@@ -296,69 +291,60 @@ AND NOT attisdropped
|
||||
AND attnum > 0
|
||||
ORDER BY attnum
|
||||
"#,
|
||||
)
|
||||
.bind(relation_id)
|
||||
.fetch_all(&mut *self)
|
||||
.await?;
|
||||
)
|
||||
.bind(relation_id)
|
||||
.fetch_all(&mut *self)
|
||||
.await?;
|
||||
|
||||
let mut fields = Vec::new();
|
||||
let mut fields = Vec::new();
|
||||
|
||||
for (field_name, field_oid) in raw_fields.into_iter() {
|
||||
let field_type = self.maybe_fetch_type_info_by_oid(field_oid, true).await?;
|
||||
for (field_name, field_oid) in raw_fields.into_iter() {
|
||||
let field_type = self.maybe_fetch_type_info_by_oid(field_oid, true).await?;
|
||||
|
||||
fields.push((field_name, field_type));
|
||||
}
|
||||
fields.push((field_name, field_type));
|
||||
}
|
||||
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
oid,
|
||||
name: name.into(),
|
||||
kind: PgTypeKind::Composite(Arc::from(fields)),
|
||||
}))))
|
||||
})
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
oid,
|
||||
name: name.into(),
|
||||
kind: PgTypeKind::Composite(Arc::from(fields)),
|
||||
}))))
|
||||
}
|
||||
|
||||
fn fetch_domain_by_oid(
|
||||
async fn fetch_domain_by_oid(
|
||||
&mut self,
|
||||
oid: Oid,
|
||||
base_type: Oid,
|
||||
name: String,
|
||||
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
|
||||
Box::pin(async move {
|
||||
let base_type = self.maybe_fetch_type_info_by_oid(base_type, true).await?;
|
||||
) -> Result<PgTypeInfo, Error> {
|
||||
let base_type = self.maybe_fetch_type_info_by_oid(base_type, true).await?;
|
||||
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
oid,
|
||||
name: name.into(),
|
||||
kind: PgTypeKind::Domain(base_type),
|
||||
}))))
|
||||
})
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
oid,
|
||||
name: name.into(),
|
||||
kind: PgTypeKind::Domain(base_type),
|
||||
}))))
|
||||
}
|
||||
|
||||
fn fetch_range_by_oid(
|
||||
&mut self,
|
||||
oid: Oid,
|
||||
name: String,
|
||||
) -> BoxFuture<'_, Result<PgTypeInfo, Error>> {
|
||||
Box::pin(async move {
|
||||
let element_oid: Oid = query_scalar(
|
||||
r#"
|
||||
async fn fetch_range_by_oid(&mut self, oid: Oid, name: String) -> Result<PgTypeInfo, Error> {
|
||||
let element_oid: Oid = query_scalar(
|
||||
r#"
|
||||
SELECT rngsubtype
|
||||
FROM pg_catalog.pg_range
|
||||
WHERE rngtypid = $1
|
||||
"#,
|
||||
)
|
||||
.bind(oid)
|
||||
.fetch_one(&mut *self)
|
||||
.await?;
|
||||
)
|
||||
.bind(oid)
|
||||
.fetch_one(&mut *self)
|
||||
.await?;
|
||||
|
||||
let element = self.maybe_fetch_type_info_by_oid(element_oid, true).await?;
|
||||
let element = self.maybe_fetch_type_info_by_oid(element_oid, true).await?;
|
||||
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Range(element),
|
||||
name: name.into(),
|
||||
oid,
|
||||
}))))
|
||||
})
|
||||
Ok(PgTypeInfo(PgType::Custom(Arc::new(PgCustomType {
|
||||
kind: PgTypeKind::Range(element),
|
||||
name: name.into(),
|
||||
oid,
|
||||
}))))
|
||||
}
|
||||
|
||||
pub(crate) async fn resolve_type_id(&mut self, ty: &PgType) -> Result<Oid, Error> {
|
||||
|
||||
@@ -42,12 +42,12 @@ pub struct PgStream {
|
||||
|
||||
impl PgStream {
|
||||
pub(super) async fn connect(options: &PgConnectOptions) -> Result<Self, Error> {
|
||||
let socket_future = match options.fetch_socket() {
|
||||
let socket_result = match options.fetch_socket() {
|
||||
Some(ref path) => net::connect_uds(path, MaybeUpgradeTls(options)).await?,
|
||||
None => net::connect_tcp(&options.host, options.port, MaybeUpgradeTls(options)).await?,
|
||||
};
|
||||
|
||||
let socket = socket_future.await?;
|
||||
let socket = socket_result?;
|
||||
|
||||
Ok(Self {
|
||||
inner: BufferedSocket::new(socket),
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use futures_core::future::BoxFuture;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::net::tls::{self, TlsConfig};
|
||||
use crate::net::{Socket, SocketIntoBox, WithSocket};
|
||||
@@ -10,10 +8,10 @@ use crate::{PgConnectOptions, PgSslMode};
|
||||
pub struct MaybeUpgradeTls<'a>(pub &'a PgConnectOptions);
|
||||
|
||||
impl<'a> WithSocket for MaybeUpgradeTls<'a> {
|
||||
type Output = BoxFuture<'a, crate::Result<Box<dyn Socket>>>;
|
||||
type Output = crate::Result<Box<dyn Socket>>;
|
||||
|
||||
fn with_socket<S: Socket>(self, socket: S) -> Self::Output {
|
||||
Box::pin(maybe_upgrade(socket, self.0))
|
||||
async fn with_socket<S: Socket>(self, socket: S) -> Self::Output {
|
||||
maybe_upgrade(socket, self.0).await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user