Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
zzhengzhuo committed Mar 4, 2021
2 parents 61293ba + edcc91c commit 99fdc3a
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ sqlx = { version = "0.5", features = [ "runtime-async-std-native-tls" ] }

- `chrono`: Add support for date and time types from `chrono`.

- `time`: Add support for date and time types from `time` crate (alternative to `chrono`, prefered by `query!` macro, if both enabled)
- `time`: Add support for date and time types from `time` crate (alternative to `chrono`, which is preferred by `query!` macro, if both enabled)

- `bstr`: Add support for `bstr::BString`.

Expand Down
80 changes: 80 additions & 0 deletions sqlx-core/src/any/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,83 @@ impl_any_decode!(f64);

impl_any_decode!(&'r str);
impl_any_decode!(String);

// Conversions for Time SQL types
// Type
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_type!(chrono::NaiveDate);
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_type!(chrono::NaiveTime);

#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_type!(chrono::DateTime<chrono::offset::Utc>);
#[cfg(all(
feature = "chrono",
any(feature = "sqlite", feature = "postgres"),
not(any(feature = "mysql", feature = "mssql"))
))]
impl_any_type!(chrono::DateTime<chrono::offset::Local>);

// Encode
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_encode!(chrono::NaiveDate);
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_encode!(chrono::NaiveTime);
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_encode!(chrono::DateTime<chrono::offset::Utc>);
#[cfg(all(
feature = "chrono",
any(feature = "sqlite", feature = "postgres"),
not(any(feature = "mysql", feature = "mssql"))
))]
impl_any_encode!(chrono::DateTime<chrono::offset::Local>);

// Decode
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_decode!(chrono::NaiveDate);
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_decode!(chrono::NaiveTime);
#[cfg(all(
feature = "chrono",
any(feature = "mysql", feature = "sqlite", feature = "postgres"),
not(feature = "mssql")
))]
impl_any_decode!(chrono::DateTime<chrono::offset::Utc>);
#[cfg(all(
feature = "chrono",
any(feature = "sqlite", feature = "postgres"),
not(any(feature = "mysql", feature = "mssql"))
))]
impl_any_decode!(chrono::DateTime<chrono::offset::Local>);
1 change: 1 addition & 0 deletions sqlx-core/src/migrate/migrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl Migrator {
/// # })
/// # }
/// ```
/// See [MigrationSource] for details on structure of the `./migrations` directory.
pub async fn new<'s, S>(source: S) -> Result<Self, MigrateError>
where
S: MigrationSource<'s>,
Expand Down
6 changes: 6 additions & 0 deletions sqlx-core/src/migrate/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ pub trait MigrationSource<'s>: Debug {
fn resolve(self) -> BoxFuture<'s, Result<Vec<Migration>, BoxDynError>>;
}

/// Implementation of the `MigrationSource` for [std::path::Path].
///
/// The path has to point to a directory, which contains the migration SQL scripts. All these
/// scripts must be stored in files with names using the format `<VERSION>_<DESCRIPTION>.sql`,
/// where `<VERSION>` is a string that can be parsed into `i64` and its value is greater than zero,
/// and `<DESCRIPTION>` is a string.
impl<'s> MigrationSource<'s> for &'s Path {
fn resolve(self) -> BoxFuture<'s, Result<Vec<Migration>, BoxDynError>> {
Box::pin(async move {
Expand Down
43 changes: 23 additions & 20 deletions sqlx-core/src/pool/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,29 @@ impl<DB: Database> Drop for PoolConnection<DB> {
fn drop(&mut self) {
if let Some(mut live) = self.live.take() {
let pool = self.pool.clone();

if live.raw.should_flush() {
spawn(async move {
// flush the connection (will immediately return if not needed) before
// we fully release to the pool
if let Err(e) = live.raw.flush().await {
log::error!("error occurred while flushing the connection: {}", e);

// we now consider the connection to be broken
// close the connection and drop from the pool
let _ = live.float(&pool).into_idle().close().await;
} else {
// after we have flushed successfully, release to the pool
pool.release(live.float(&pool));
}
});
} else {
// nothing to flush, release immediately outside of a spawn
pool.release(live.float(&pool));
}
spawn(async move {
let mut floating = live.float(&pool);

// test the connection on-release to ensure it is still viable
// if an Executor future/stream is dropped during an `.await` call, the connection
// is likely to be left in an inconsistent state, in which case it should not be
// returned to the pool; also of course, if it was dropped due to an error
// this is simply a band-aid as SQLx-next (0.6) connections should be able
// to recover from cancellations
if let Err(e) = floating.raw.ping().await {
log::warn!(
"error occurred while testing the connection on-release: {}",
e
);

// we now consider the connection to be broken; just drop it to close
// trying to close gracefully might cause something weird to happen
drop(floating);
} else {
// if the connection is still viable, release it to th epool
pool.release(floating);
}
});
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions sqlx-core/src/pool/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ impl<DB: Database> SharedPool<DB> {
let mut size = self.size();

while size < self.options.max_connections {
let new_size = self.size.compare_and_swap(size, size + 1, Ordering::AcqRel);

if new_size == size {
return Some(DecrementSizeGuard::new(self));
match self
.size
.compare_exchange(size, size + 1, Ordering::AcqRel, Ordering::Acquire)
{
Ok(_) => return Some(DecrementSizeGuard::new(self)),
Err(new_size) => size = new_size,
}

size = new_size;
}

None
Expand Down
1 change: 1 addition & 0 deletions sqlx-core/src/types/bstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;

#[doc(no_inline)]
pub use bstr::{BStr, BString, ByteSlice};

impl<DB> Type<DB> for BString
Expand Down
1 change: 1 addition & 0 deletions sqlx-core/src/types/git2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;

#[doc(no_inline)]
pub use git2::Oid;

impl<DB> Type<DB> for Oid
Expand Down
7 changes: 7 additions & 0 deletions sqlx-core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,44 @@ mod json;

#[cfg(feature = "uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid")))]
#[doc(no_inline)]
pub use uuid::{self, Uuid};

#[cfg(feature = "chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
pub mod chrono {
#[doc(no_inline)]
pub use chrono::{
DateTime, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc,
};
}

#[cfg(feature = "bit-vec")]
#[cfg_attr(docsrs, doc(cfg(feature = "bit-vec")))]
#[doc(no_inline)]
pub use bit_vec::BitVec;

#[cfg(feature = "time")]
#[cfg_attr(docsrs, doc(cfg(feature = "time")))]
pub mod time {
#[doc(no_inline)]
pub use time::{Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
}

#[cfg(feature = "bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "bigdecimal")))]
#[doc(no_inline)]
pub use bigdecimal::BigDecimal;

#[cfg(feature = "decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "decimal")))]
#[doc(no_inline)]
pub use rust_decimal::Decimal;

#[cfg(feature = "ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "ipnetwork")))]
pub mod ipnetwork {
#[doc(no_inline)]
pub use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
}

Expand Down
6 changes: 6 additions & 0 deletions sqlx-macros/src/derives/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fn expand_derive_decode_transparent(
let (impl_generics, _, where_clause) = generics.split_for_impl();

let tts = quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::decode::Decode<'r, DB> for #ident #ty_generics #where_clause {
fn decode(
value: <DB as ::sqlx::database::HasValueRef<'r>>::ValueRef,
Expand Down Expand Up @@ -111,6 +112,7 @@ fn expand_derive_decode_weak_enum(
.collect::<Vec<Arm>>();

Ok(quote!(
#[automatically_derived]
impl<'r, DB: ::sqlx::Database> ::sqlx::decode::Decode<'r, DB> for #ident
where
#repr: ::sqlx::decode::Decode<'r, DB>,
Expand Down Expand Up @@ -173,6 +175,7 @@ fn expand_derive_decode_strong_enum(

if cfg!(feature = "mysql") {
tts.extend(quote!(
#[automatically_derived]
impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::mysql::MySql> for #ident {
fn decode(
value: ::sqlx::mysql::MySqlValueRef<'r>,
Expand All @@ -198,6 +201,7 @@ fn expand_derive_decode_strong_enum(

if cfg!(feature = "postgres") {
tts.extend(quote!(
#[automatically_derived]
impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::postgres::Postgres> for #ident {
fn decode(
value: ::sqlx::postgres::PgValueRef<'r>,
Expand All @@ -223,6 +227,7 @@ fn expand_derive_decode_strong_enum(

if cfg!(feature = "sqlite") {
tts.extend(quote!(
#[automatically_derived]
impl<'r> ::sqlx::decode::Decode<'r, ::sqlx::sqlite::Sqlite> for #ident {
fn decode(
value: ::sqlx::sqlite::SqliteValueRef<'r>,
Expand Down Expand Up @@ -291,6 +296,7 @@ fn expand_derive_decode_struct(
let names = fields.iter().map(|field| &field.ident);

tts.extend(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::decode::Decode<'r, ::sqlx::Postgres> for #ident #ty_generics
#where_clause
{
Expand Down
4 changes: 4 additions & 0 deletions sqlx-macros/src/derives/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ fn expand_derive_encode_transparent(
let (impl_generics, _, where_clause) = generics.split_for_impl();

Ok(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::encode::Encode<#lifetime, DB> for #ident #ty_generics
#where_clause
{
Expand Down Expand Up @@ -115,6 +116,7 @@ fn expand_derive_encode_weak_enum(
}

Ok(quote!(
#[automatically_derived]
impl<'q, DB: ::sqlx::Database> ::sqlx::encode::Encode<'q, DB> for #ident
where
#repr: ::sqlx::encode::Encode<'q, DB>,
Expand Down Expand Up @@ -164,6 +166,7 @@ fn expand_derive_encode_strong_enum(
}

Ok(quote!(
#[automatically_derived]
impl<'q, DB: ::sqlx::Database> ::sqlx::encode::Encode<'q, DB> for #ident
where
&'q ::std::primitive::str: ::sqlx::encode::Encode<'q, DB>,
Expand Down Expand Up @@ -239,6 +242,7 @@ fn expand_derive_encode_struct(
});

tts.extend(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::encode::Encode<'_, ::sqlx::Postgres> for #ident #ty_generics
#where_clause
{
Expand Down
2 changes: 2 additions & 0 deletions sqlx-macros/src/derives/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ fn expand_derive_from_row_struct(

let mut extend_block = |exprpath: ExprPath| {
block.extend(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::FromRow<#lifetime, R> for #ident #ty_generics #where_clause,R: ::sqlx::Row<Database = #exprpath>, {
fn from_row(row: &#lifetime R) -> ::sqlx::Result<Self> {
#(#reads)*
Expand Down Expand Up @@ -222,6 +223,7 @@ fn expand_derive_from_row_struct_unnamed(
.map(|(idx, _)| quote!(row.try_get(#idx)?));

Ok(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::FromRow<#lifetime, R> for #ident #ty_generics #where_clause {
fn from_row(row: &#lifetime R) -> ::sqlx::Result<Self> {
::std::result::Result::Ok(#ident (
Expand Down
7 changes: 7 additions & 0 deletions sqlx-macros/src/derives/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ fn expand_derive_has_sql_type_transparent(
let (impl_generics, _, where_clause) = generics.split_for_impl();

return Ok(quote!(
#[automatically_derived]
impl #impl_generics ::sqlx::Type< DB > for #ident #ty_generics #where_clause {
fn type_info() -> DB::TypeInfo {
<#ty as ::sqlx::Type<DB>>::type_info()
Expand All @@ -89,6 +90,7 @@ fn expand_derive_has_sql_type_transparent(
let ty_name = type_name(ident, attr.type_name.as_ref());

tts.extend(quote!(
#[automatically_derived]
impl ::sqlx::Type<::sqlx::postgres::Postgres> for #ident #ty_generics {
fn type_info() -> ::sqlx::postgres::PgTypeInfo {
::sqlx::postgres::PgTypeInfo::with_name(#ty_name)
Expand All @@ -108,6 +110,7 @@ fn expand_derive_has_sql_type_weak_enum(
let repr = attr.repr.unwrap();
let ident = &input.ident;
let ts = quote!(
#[automatically_derived]
impl<DB: ::sqlx::Database> ::sqlx::Type<DB> for #ident
where
#repr: ::sqlx::Type<DB>,
Expand All @@ -132,6 +135,7 @@ fn expand_derive_has_sql_type_strong_enum(

if cfg!(feature = "mysql") {
tts.extend(quote!(
#[automatically_derived]
impl ::sqlx::Type<::sqlx::MySql> for #ident {
fn type_info() -> ::sqlx::mysql::MySqlTypeInfo {
::sqlx::mysql::MySqlTypeInfo::__enum()
Expand All @@ -148,6 +152,7 @@ fn expand_derive_has_sql_type_strong_enum(
let ty_name = type_name(ident, attributes.type_name.as_ref());

tts.extend(quote!(
#[automatically_derived]
impl ::sqlx::Type<::sqlx::Postgres> for #ident {
fn type_info() -> ::sqlx::postgres::PgTypeInfo {
::sqlx::postgres::PgTypeInfo::with_name(#ty_name)
Expand All @@ -158,6 +163,7 @@ fn expand_derive_has_sql_type_strong_enum(

if cfg!(feature = "sqlite") {
tts.extend(quote!(
#[automatically_derived]
impl sqlx::Type<::sqlx::Sqlite> for #ident {
fn type_info() -> ::sqlx::sqlite::SqliteTypeInfo {
<::std::primitive::str as ::sqlx::Type<sqlx::Sqlite>>::type_info()
Expand Down Expand Up @@ -186,6 +192,7 @@ fn expand_derive_has_sql_type_struct(
let ty_name = type_name(ident, attributes.type_name.as_ref());

tts.extend(quote!(
#[automatically_derived]
impl ::sqlx::Type<::sqlx::Postgres> for #ident {
fn type_info() -> ::sqlx::postgres::PgTypeInfo {
::sqlx::postgres::PgTypeInfo::with_name(#ty_name)
Expand Down
Loading

0 comments on commit 99fdc3a

Please sign in to comment.