mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-30 05:11:13 +00:00
feat(core): refine runtime abstraction
- traits from sqlx::blocking::_ have sqlx::_ traits as dependents - methods in sqlx::_ traits are cfg-d on "async" with an additional Rt: Async bound
This commit is contained in:
parent
fb4f2ca602
commit
7a323f3471
@ -1,11 +1,18 @@
|
||||
//! Types and traits used to implement a database driver with **blocking** I/O.
|
||||
//!
|
||||
|
||||
pub(crate) mod runtime;
|
||||
|
||||
mod connection;
|
||||
mod options;
|
||||
mod runtime;
|
||||
|
||||
pub use connection::Connection;
|
||||
pub use options::ConnectOptions;
|
||||
pub use runtime::Runtime;
|
||||
pub use runtime::{Blocking, Runtime};
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::Database as _;
|
||||
|
||||
pub use super::ConnectOptions as _;
|
||||
pub use super::Connection as _;
|
||||
pub use super::Runtime as _;
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use super::{ConnectOptions, Runtime};
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`Connection`][crate::Connection].
|
||||
///
|
||||
pub trait Connection<Rt>: 'static + Send
|
||||
pub trait Connection<Rt>: crate::Connection<Rt>
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
@ -20,7 +20,7 @@ where
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
url.parse::<Self::Options>()?.connect()
|
||||
url.parse::<<Self as Connection<Rt>>::Options>()?.connect()
|
||||
}
|
||||
|
||||
/// Explicitly close this database connection.
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{Connection, Runtime};
|
||||
use super::Runtime;
|
||||
|
||||
/// Options which can be used to configure how a SQL connection is opened.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`ConnectOptions`][crate::ConnectOptions].
|
||||
///
|
||||
pub trait ConnectOptions<Rt>:
|
||||
'static + Send + Sync + Default + Debug + Clone + FromStr<Err = crate::Error>
|
||||
pub trait ConnectOptions<Rt>: crate::ConnectOptions<Rt>
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Connection: Connection<Rt> + ?Sized;
|
||||
|
||||
/// Establish a connection to the database.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
|
||||
@ -2,23 +2,25 @@ use std::io;
|
||||
use std::net::TcpStream;
|
||||
|
||||
/// Describes a set of types and functions used to open and manage
|
||||
/// resources within SQLx using blocking I/O.
|
||||
/// resources within SQLx.
|
||||
///
|
||||
pub trait Runtime {
|
||||
type TcpStream;
|
||||
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`Runtime`][crate::Runtime].
|
||||
///
|
||||
pub trait Runtime: crate::Runtime {
|
||||
/// Opens a TCP connection to a remote host at the specified port.
|
||||
fn connect_tcp(host: &str, port: u16) -> io::Result<Self::TcpStream>;
|
||||
}
|
||||
|
||||
/// Uses the `std::net` primitives to implement a blocking runtime for SQLx.
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "blocking")))]
|
||||
#[derive(Debug)]
|
||||
pub struct Blocking;
|
||||
|
||||
impl Runtime for Blocking {
|
||||
impl crate::Runtime for Blocking {
|
||||
type TcpStream = TcpStream;
|
||||
}
|
||||
|
||||
impl Runtime for Blocking {
|
||||
fn connect_tcp(host: &str, port: u16) -> io::Result<Self::TcpStream> {
|
||||
TcpStream::connect((host, port))
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use futures_util::future::BoxFuture;
|
||||
use crate::{ConnectOptions, Database, Runtime};
|
||||
|
||||
use crate::{ConnectOptions, Runtime};
|
||||
#[cfg(feature = "async")]
|
||||
use futures_util::future::BoxFuture;
|
||||
|
||||
/// A unique connection (session) with a specific database.
|
||||
///
|
||||
@ -14,6 +15,8 @@ pub trait Connection<Rt>: 'static + Send
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Database: Database<Rt, Connection = Self>;
|
||||
|
||||
type Options: ConnectOptions<Rt, Connection = Self>;
|
||||
|
||||
/// Establish a new database connection.
|
||||
@ -43,9 +46,11 @@ where
|
||||
/// .connect().await?;
|
||||
/// ```
|
||||
///
|
||||
#[cfg(feature = "async")]
|
||||
fn connect(url: &str) -> BoxFuture<'_, crate::Result<Self>>
|
||||
where
|
||||
Self: Sized,
|
||||
Rt: crate::Async,
|
||||
{
|
||||
let options = url.parse::<Self::Options>();
|
||||
Box::pin(async move { options?.connect().await })
|
||||
@ -57,7 +62,10 @@ where
|
||||
/// recommended to call it instead of letting a connection `drop` as the database backend
|
||||
/// will be faster at cleaning up resources.
|
||||
///
|
||||
fn close(self) -> BoxFuture<'static, crate::Result<()>>;
|
||||
#[cfg(feature = "async")]
|
||||
fn close(self) -> BoxFuture<'static, crate::Result<()>>
|
||||
where
|
||||
Rt: crate::Async;
|
||||
|
||||
/// Checks if a connection to the database is still valid.
|
||||
///
|
||||
@ -66,5 +74,8 @@ where
|
||||
/// PostgreSQL, `ping` will issue a query consisting of a comment `/* SQLx ping */` which,
|
||||
/// in effect, does nothing apart from getting a response from the server.
|
||||
///
|
||||
fn ping(&mut self) -> BoxFuture<'_, crate::Result<()>>;
|
||||
#[cfg(feature = "async")]
|
||||
fn ping(&mut self) -> BoxFuture<'_, crate::Result<()>>
|
||||
where
|
||||
Rt: crate::Async;
|
||||
}
|
||||
|
||||
25
sqlx-core/src/database.rs
Normal file
25
sqlx-core/src/database.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::{Connection, Runtime};
|
||||
|
||||
/// A database driver.
|
||||
///
|
||||
/// This trait encapsulates a complete set of traits that implement a driver for a
|
||||
/// specific database (e.g., MySQL, PostgreSQL).
|
||||
///
|
||||
// 'x: execution
|
||||
pub trait Database<Rt>: 'static + Sized + Debug + for<'x> HasOutput<'x>
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
/// The concrete [`Connection`] implementation for this database.
|
||||
type Connection: Connection<Rt, Database = Self> + ?Sized;
|
||||
}
|
||||
|
||||
/// Associates [`Database`] with a `Output` of a generic lifetime.
|
||||
/// 'x: single execution
|
||||
pub trait HasOutput<'x> {
|
||||
/// The concrete type to hold the output for `Encode` for this database. This may be
|
||||
/// a simple alias to `&'x mut Vec<u8>`.
|
||||
type Output;
|
||||
}
|
||||
@ -27,34 +27,51 @@ extern crate _async_std as async_std;
|
||||
#[cfg(feature = "tokio")]
|
||||
extern crate _tokio as tokio;
|
||||
|
||||
mod connection;
|
||||
mod database;
|
||||
mod error;
|
||||
|
||||
pub use error::{Error, Result};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
mod options;
|
||||
mod runtime;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
mod connection;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
mod options;
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "blocking")))]
|
||||
pub mod blocking;
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub use blocking::runtime::Blocking;
|
||||
pub use connection::Connection;
|
||||
pub use database::Database;
|
||||
pub use error::{Error, Result};
|
||||
pub use options::ConnectOptions;
|
||||
pub use runtime::Runtime;
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
pub use runtime::AsyncStd;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub use runtime::Tokio;
|
||||
|
||||
#[cfg(feature = "actix")]
|
||||
pub use runtime::Actix;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub use {connection::Connection, options::ConnectOptions, runtime::Runtime};
|
||||
pub(crate) use runtime::Async;
|
||||
|
||||
#[cfg(all(feature = "async", feature = "async-std"))]
|
||||
pub use runtime::async_std::AsyncStd;
|
||||
#[cfg(feature = "async-std")]
|
||||
pub type DefaultRuntime = AsyncStd;
|
||||
|
||||
#[cfg(all(feature = "async", feature = "tokio"))]
|
||||
pub use runtime::tokio::Tokio;
|
||||
#[cfg(all(not(feature = "async-std"), feature = "tokio"))]
|
||||
pub type DefaultRuntime = Tokio;
|
||||
|
||||
#[cfg(all(feature = "async", feature = "actix"))]
|
||||
pub use runtime::actix::Actix;
|
||||
#[cfg(all(not(all(feature = "async-std", feature = "tokio")), feature = "actix"))]
|
||||
pub type DefaultRuntime = Actix;
|
||||
|
||||
#[cfg(not(feature = "async"))]
|
||||
pub type DefaultRuntime = blocking::Blocking;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::ConnectOptions as _;
|
||||
pub use super::Connection as _;
|
||||
pub use super::Database as _;
|
||||
pub use super::Runtime as _;
|
||||
|
||||
#[cfg(all(not(feature = "async"), feature = "blocking"))]
|
||||
pub use super::blocking::prelude::*;
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
use futures_util::future::BoxFuture;
|
||||
|
||||
use crate::{Connection, Runtime};
|
||||
|
||||
/// Options which can be used to configure how a SQL connection is opened.
|
||||
@ -14,7 +12,9 @@ where
|
||||
type Connection: Connection<Rt> + ?Sized;
|
||||
|
||||
/// Establish a connection to the database.
|
||||
fn connect(&self) -> BoxFuture<'_, crate::Result<Self::Connection>>
|
||||
#[cfg(feature = "async")]
|
||||
fn connect(&self) -> futures_util::future::BoxFuture<'_, crate::Result<Self::Connection>>
|
||||
where
|
||||
Self::Connection: Sized;
|
||||
Self::Connection: Sized,
|
||||
Rt: crate::Async;
|
||||
}
|
||||
|
||||
@ -1,25 +1,40 @@
|
||||
use std::io;
|
||||
|
||||
use futures_util::future::BoxFuture;
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
pub(crate) mod async_std;
|
||||
mod async_std;
|
||||
|
||||
#[cfg(feature = "actix")]
|
||||
pub(crate) mod actix;
|
||||
mod actix;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub(crate) mod tokio;
|
||||
mod tokio;
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
pub use self::async_std::AsyncStd;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub use self::tokio::Tokio;
|
||||
|
||||
#[cfg(feature = "actix")]
|
||||
pub use self::actix::Actix;
|
||||
|
||||
/// Describes a set of types and functions used to open and manage
|
||||
/// resources within SQLx using asynchronous I/O.
|
||||
#[cfg_attr(
|
||||
doc_cfg,
|
||||
doc(cfg(any(feature = "async-std", feature = "tokio", feature = "actix")))
|
||||
)]
|
||||
/// resources within SQLx.
|
||||
pub trait Runtime {
|
||||
type TcpStream;
|
||||
|
||||
/// Opens a TCP connection to a remote host at the specified port.
|
||||
fn connect_tcp(host: &str, port: u16) -> BoxFuture<'_, io::Result<Self::TcpStream>>;
|
||||
#[cfg(feature = "async")]
|
||||
#[allow(unused_variables)]
|
||||
fn connect_tcp(
|
||||
host: &str,
|
||||
port: u16,
|
||||
) -> futures_util::future::BoxFuture<'_, std::io::Result<Self::TcpStream>>
|
||||
where
|
||||
Self: Async,
|
||||
{
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Marker trait that identifies a `Runtime` as supporting asynchronous I/O.
|
||||
#[cfg(feature = "async")]
|
||||
pub trait Async: Runtime {}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::io;
|
||||
use actix_rt::net::TcpStream;
|
||||
use futures_util::{future::BoxFuture, FutureExt};
|
||||
|
||||
use crate::runtime::Runtime;
|
||||
use crate::{Async, Runtime};
|
||||
|
||||
/// Actix SQLx runtime. Uses [`actix-rt`][actix_rt] to provide [`Runtime`].
|
||||
///
|
||||
@ -15,6 +15,8 @@ use crate::runtime::Runtime;
|
||||
#[derive(Debug)]
|
||||
pub struct Actix;
|
||||
|
||||
impl Async for Actix {}
|
||||
|
||||
impl Runtime for Actix {
|
||||
type TcpStream = TcpStream;
|
||||
|
||||
|
||||
@ -3,13 +3,15 @@ use std::io;
|
||||
use async_std::{net::TcpStream, task::block_on};
|
||||
use futures_util::{future::BoxFuture, FutureExt};
|
||||
|
||||
use crate::runtime::Runtime;
|
||||
use crate::{Async, Runtime};
|
||||
|
||||
/// [`async-std`](async_std) implementation of [`Runtime`].
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "async-std")))]
|
||||
#[derive(Debug)]
|
||||
pub struct AsyncStd;
|
||||
|
||||
impl Async for AsyncStd {}
|
||||
|
||||
impl Runtime for AsyncStd {
|
||||
type TcpStream = TcpStream;
|
||||
|
||||
@ -20,8 +22,6 @@ impl Runtime for AsyncStd {
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
impl crate::blocking::Runtime for AsyncStd {
|
||||
type TcpStream = TcpStream;
|
||||
|
||||
fn connect_tcp(host: &str, port: u16) -> io::Result<Self::TcpStream> {
|
||||
block_on(<AsyncStd as Runtime>::connect_tcp(host, port))
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use std::io;
|
||||
use futures_util::{future::BoxFuture, FutureExt};
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
use crate::runtime::Runtime;
|
||||
use crate::{Async, Runtime};
|
||||
|
||||
/// Tokio SQLx runtime. Uses [`tokio`] to provide [`Runtime`].
|
||||
///
|
||||
@ -13,6 +13,8 @@ use crate::runtime::Runtime;
|
||||
#[derive(Debug)]
|
||||
pub struct Tokio;
|
||||
|
||||
impl Async for Tokio {}
|
||||
|
||||
impl Runtime for Tokio {
|
||||
type TcpStream = TcpStream;
|
||||
|
||||
|
||||
@ -16,11 +16,12 @@
|
||||
#![warn(clippy::useless_let_if_seq)]
|
||||
#![allow(clippy::doc_markdown)]
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub use sqlx_core::{blocking, Blocking};
|
||||
pub use sqlx_core::{
|
||||
prelude, ConnectOptions, Connection, Database, DefaultRuntime, Error, Result, Runtime,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "async-std", feature = "tokio", feature = "actix"))]
|
||||
pub use sqlx_core::Runtime;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub use sqlx_core::blocking;
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
pub use sqlx_core::AsyncStd;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user