mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-30 05:11:13 +00:00
feat(core): add minimal Connection and ConnectOptions traits
This commit is contained in:
parent
f613b3c7b5
commit
fb4f2ca602
79
Cargo.lock
generated
79
Cargo.lock
generated
@ -261,6 +261,16 @@ dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
@ -372,6 +382,17 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
@ -448,6 +469,12 @@ dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
@ -596,6 +623,12 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.2"
|
||||
@ -737,6 +770,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"tokio 0.2.24",
|
||||
"tokio 1.0.1",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -759,6 +793,21 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.2.24"
|
||||
@ -790,12 +839,42 @@ dependencies = [
|
||||
"pin-project-lite 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec-arena"
|
||||
version = "1.0.0"
|
||||
|
||||
@ -39,3 +39,4 @@ _async-std = { version = "1.8.0", optional = true, package = "async-std" }
|
||||
futures-util = { version = "0.3.8", optional = true }
|
||||
_tokio = { version = "1.0.1", optional = true, package = "tokio", features = ["net"] }
|
||||
tokio_02 = { version = "0.2.24", optional = true, package = "tokio", features = ["net"] }
|
||||
url = "2.2.0"
|
||||
|
||||
@ -3,4 +3,9 @@
|
||||
|
||||
pub(crate) mod runtime;
|
||||
|
||||
mod connection;
|
||||
mod options;
|
||||
|
||||
pub use connection::Connection;
|
||||
pub use options::ConnectOptions;
|
||||
pub use runtime::Runtime;
|
||||
|
||||
39
sqlx-core/src/blocking/connection.rs
Normal file
39
sqlx-core/src/blocking/connection.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use super::{ConnectOptions, Runtime};
|
||||
|
||||
/// A unique connection (session) with a specific database.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`Connection`][crate::Connection].
|
||||
///
|
||||
pub trait Connection<Rt>: 'static + Send
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Options: ConnectOptions<Rt, Connection = Self>;
|
||||
|
||||
/// Establish a new database connection.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`connect()`][crate::Connection::connect].
|
||||
///
|
||||
fn connect(url: &str) -> crate::Result<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
url.parse::<Self::Options>()?.connect()
|
||||
}
|
||||
|
||||
/// Explicitly close this database connection.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`close()`][crate::Connection::close].
|
||||
///
|
||||
fn close(self) -> crate::Result<()>;
|
||||
|
||||
/// Checks if a connection to the database is still valid.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`ping()`][crate::Connection::ping].
|
||||
///
|
||||
fn ping(&mut self) -> crate::Result<()>;
|
||||
}
|
||||
26
sqlx-core/src/blocking/options.rs
Normal file
26
sqlx-core/src/blocking/options.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{Connection, 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>
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Connection: Connection<Rt> + ?Sized;
|
||||
|
||||
/// Establish a connection to the database.
|
||||
///
|
||||
/// For detailed information, refer to the asynchronous version of
|
||||
/// this: [`connect()`][crate::ConnectOptions::connect].
|
||||
///
|
||||
fn connect(&self) -> crate::Result<Self::Connection>
|
||||
where
|
||||
Self::Connection: Sized;
|
||||
}
|
||||
70
sqlx-core/src/connection.rs
Normal file
70
sqlx-core/src/connection.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use futures_util::future::BoxFuture;
|
||||
|
||||
use crate::{ConnectOptions, Runtime};
|
||||
|
||||
/// A unique connection (session) with a specific database.
|
||||
///
|
||||
/// With a client/server model, this is equivalent to a network connection
|
||||
/// to the server.
|
||||
///
|
||||
/// SQL statements will be executed and results returned within the context
|
||||
/// of this single SQL connection.
|
||||
///
|
||||
pub trait Connection<Rt>: 'static + Send
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Options: ConnectOptions<Rt, Connection = Self>;
|
||||
|
||||
/// Establish a new database connection.
|
||||
///
|
||||
/// A value of [`Options`](#associatedtype.Options) is parsed from the provided connection string. This parsing
|
||||
/// is database-specific.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use sqlx::postgres::PgConnection;
|
||||
/// use sqlx::ConnectOptions;
|
||||
///
|
||||
/// let mut conn = PgConnection::connect(
|
||||
/// "postgres://postgres:password@localhost/database",
|
||||
/// ).await?;
|
||||
/// ```
|
||||
///
|
||||
/// You may alternatively build the connection options imperatively.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use sqlx::mysql::{MySqlConnection, MySqlConnectOptions};
|
||||
/// use sqlx::ConnectOptions;
|
||||
///
|
||||
/// let mut conn: MySqlConnection = MySqlConnectOptions::builder()
|
||||
/// .host("localhost")
|
||||
/// .username("root")
|
||||
/// .password("password")
|
||||
/// .connect().await?;
|
||||
/// ```
|
||||
///
|
||||
fn connect(url: &str) -> BoxFuture<'_, crate::Result<Self>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let options = url.parse::<Self::Options>();
|
||||
Box::pin(async move { options?.connect().await })
|
||||
}
|
||||
|
||||
/// Explicitly close this database connection.
|
||||
///
|
||||
/// This method is **not required** for safe and consistent operation. However, it is
|
||||
/// 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<()>>;
|
||||
|
||||
/// Checks if a connection to the database is still valid.
|
||||
///
|
||||
/// The method of operation greatly depends on the database driver. In MySQL, there is an
|
||||
/// explicit [`COM_PING`](https://dev.mysql.com/doc/internals/en/com-ping.html) command. In
|
||||
/// 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<()>>;
|
||||
}
|
||||
26
sqlx-core/src/error.rs
Normal file
26
sqlx-core/src/error.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
InvalidConnectionUrl(url::ParseError),
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::InvalidConnectionUrl(source) => write!(f, "invalid connection url: {}", source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
match self {
|
||||
Self::InvalidConnectionUrl(source) => Some(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,9 +27,19 @@ extern crate _async_std as async_std;
|
||||
#[cfg(feature = "tokio")]
|
||||
extern crate _tokio as tokio;
|
||||
|
||||
mod error;
|
||||
|
||||
pub use error::{Error, Result};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
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;
|
||||
@ -38,7 +48,7 @@ pub mod blocking;
|
||||
pub use blocking::runtime::Blocking;
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub use runtime::Runtime;
|
||||
pub use {connection::Connection, options::ConnectOptions, runtime::Runtime};
|
||||
|
||||
#[cfg(all(feature = "async", feature = "async-std"))]
|
||||
pub use runtime::async_std::AsyncStd;
|
||||
|
||||
20
sqlx-core/src/options.rs
Normal file
20
sqlx-core/src/options.rs
Normal file
@ -0,0 +1,20 @@
|
||||
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.
|
||||
pub trait ConnectOptions<Rt>:
|
||||
'static + Send + Sync + Default + Debug + Clone + FromStr<Err = crate::Error>
|
||||
where
|
||||
Rt: Runtime,
|
||||
{
|
||||
type Connection: Connection<Rt> + ?Sized;
|
||||
|
||||
/// Establish a connection to the database.
|
||||
fn connect(&self) -> BoxFuture<'_, crate::Result<Self::Connection>>
|
||||
where
|
||||
Self::Connection: Sized;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user