Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop GAT workarounds #3395

Merged
merged 23 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 9 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,12 @@ jobs:
- name: Install sqlite (MacOS)
if: runner.os == 'macOS' && matrix.backend == 'sqlite'
run: |
brew update
brew install sqlite
echo "SQLITE_DATABASE_URL=/tmp/test.db" >> $GITHUB_ENV

- name: Install mysql (MacOS)
if: runner.os == 'macOS' && matrix.backend == 'mysql'
run: |
brew update
brew install mariadb@10.5
/usr/local/opt/mariadb@10.5/bin/mysql_install_db
/usr/local/opt/mariadb@10.5/bin/mysql.server start
Expand Down Expand Up @@ -295,7 +293,7 @@ jobs:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2022-08-12
toolchain: nightly-2023-01-10
- name: Cache cargo registry
uses: actions/cache@v3
with:
Expand All @@ -311,7 +309,7 @@ jobs:

- name: Run compile tests
shell: bash
run: cargo +nightly-2022-08-12 test --manifest-path diesel_compile_tests/Cargo.toml
run: cargo +nightly-2023-01-10 test --manifest-path diesel_compile_tests/Cargo.toml

rustfmt_and_clippy:
name: Check rustfmt style && run clippy
Expand Down Expand Up @@ -423,11 +421,11 @@ jobs:
run: cargo +nightly -Z build-std test --manifest-path diesel/Cargo.toml --no-default-features --features "sqlite extras libsqlite3-sys libsqlite3-sys/bundled libsqlite3-sys/with-asan" --target x86_64-unknown-linux-gnu

minimal_rust_version:
name: Check Minimal supported rust version (1.60.0)
name: Check Minimal supported rust version (1.65.0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires an change log entry.

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@1.60.0
- uses: dtolnay/rust-toolchain@1.65.0
- uses: dtolnay/rust-toolchain@nightly
- uses: taiki-e/install-action@cargo-hack
- uses: taiki-e/install-action@cargo-minimal-versions
Expand All @@ -443,12 +441,12 @@ jobs:
sudo apt-get update
sudo apt-get -y install libsqlite3-dev libpq-dev libmysqlclient-dev
- name: Check diesel_derives
run: cargo +1.60.0 minimal-versions check -p diesel_derives --all-features
run: cargo +1.65.0 minimal-versions check -p diesel_derives --all-features
- name: Check diesel
run: cargo +1.60.0 minimal-versions check -p diesel --features "postgres mysql sqlite extras"
run: cargo +1.65.0 minimal-versions check -p diesel --features "postgres mysql sqlite extras"
- name: Check diesel_dynamic_schema
run: cargo +1.60.0 minimal-versions check -p diesel-dynamic-schema --all-features
run: cargo +1.65.0 minimal-versions check -p diesel-dynamic-schema --all-features
- name: Check diesel_migrations
run: cargo +1.60.0 minimal-versions check -p diesel_migrations --all-features
run: cargo +1.65.0 minimal-versions check -p diesel_migrations --all-features
- name: Check diesel_cli
run: cargo +1.60.0 minimal-versions check -p diesel_cli --all-features
run: cargo +1.65.0 minimal-versions check -p diesel_cli --all-features
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Increasing the minimal supported Rust version will always be coupled at least wi

### Changed

* The minimal officially supported rustc version is now 1.60.0
* The minimal officially supported rustc version is now 1.65.0

### Added

Expand Down
2 changes: 1 addition & 1 deletion diesel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository = "https://github.com/diesel-rs/diesel"
keywords = ["orm", "database", "sql"]
categories = ["database"]
edition = "2018"
rust-version = "1.60.0"
rust-version = "1.65.0"

[dependencies]
byteorder = { version = "1.0", optional = true }
Expand Down
98 changes: 26 additions & 72 deletions diesel/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ use crate::sql_types::{self, HasSqlType, TypeMetadata};
#[diesel_derives::__diesel_public_if(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::private::{
DieselReserveSpecialization, HasBindCollector, HasRawValue, TrustedBackend,
};
pub(crate) use self::private::{DieselReserveSpecialization, TrustedBackend};

/// A database backend
///
Expand Down Expand Up @@ -52,25 +50,9 @@ pub(crate) use self::private::{
/// * Specify how a query should be build from string parts by providing a [`QueryBuilder`]
/// matching your backend
/// * Specify the bind value format used by your database connection library by providing
/// a [`BindCollector`] matching your backend via
#[cfg_attr(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
doc = "[`HasBindCollector`]"
)]
#[cfg_attr(
not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
doc = "`HasBindCollector`"
)]
/// a [`BindCollector`](crate::query_builder::bind_collector::BindCollector) matching your backend
/// * Specify how values are receive from the database by providing a corresponding raw value
/// definition via
#[cfg_attr(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes",
doc = "[`HasRawValue`]"
)]
#[cfg_attr(
not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"),
doc = "`HasRawValue`"
)]
/// definition
/// * Control sql dialect specific parts of diesels query dsl implementation by providing a
/// matching [`SqlDialect`] implementation
/// * Implement [`TypeMetadata`] to specify how your backend identifies types
Expand Down Expand Up @@ -100,7 +82,7 @@ pub(crate) use self::private::{
/// [`QueryFragment`]: crate::query_builder::QueryFragment
pub trait Backend
where
Self: Sized + SqlDialect,
Self: Sized + SqlDialect + TypeMetadata,
Self: HasSqlType<sql_types::SmallInt>,
Self: HasSqlType<sql_types::Integer>,
Self: HasSqlType<sql_types::BigInt>,
Expand All @@ -111,22 +93,34 @@ where
Self: HasSqlType<sql_types::Date>,
Self: HasSqlType<sql_types::Time>,
Self: HasSqlType<sql_types::Timestamp>,
Self: for<'a> HasRawValue<'a>,
Self: for<'a> HasBindCollector<'a>,
{
/// The concrete [`QueryBuilder`] implementation for this backend.
type QueryBuilder: QueryBuilder<Self>;

/// The actual type given to [`FromSql`], with lifetimes applied. This type
/// should not be used directly.
///
/// [`FromSql`]: crate::deserialize::FromSql
type RawValue<'a>;

/// The concrete [`BindCollector`](crate::query_builder::bind_collector::BindCollector)
/// implementation for this backend.
///
/// Most backends should use [`RawBytesBindCollector`].
///
/// [`RawBytesBindCollector`]: crate::query_builder::bind_collector::RawBytesBindCollector
type BindCollector<'a>: crate::query_builder::bind_collector::BindCollector<'a, Self> + 'a;
}

/// A helper type to get the raw representation of a database type given to
/// [`FromSql`]. Equivalent to `<DB as Backend>::RawValue<'a>`.
///
/// [`FromSql`]: crate::deserialize::FromSql
pub type RawValue<'a, DB> = <DB as HasRawValue<'a>>::RawValue;
#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[deprecated(note = "Use `Backend::RawValue` directly")]
pub type RawValue<'a, DB> = <DB as Backend>::RawValue<'a>;

/// A helper type to get the bind collector for a database backend.
/// Equivalent to `<DB as HasBindCollector<'a>>::BindCollector<'a>`j
pub type BindCollector<'a, DB> = <DB as HasBindCollector<'a>>::BindCollector;
#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[deprecated(note = "Use `Backend::BindCollector` directly")]
pub type BindCollector<'a, DB> = <DB as Backend>::BindCollector<'a>;

/// This trait provides various options to configure the
/// generated SQL for a specific backend.
Expand Down Expand Up @@ -521,25 +515,6 @@ pub(crate) mod sql_dialect {
// because we want to replace them by with an associated type
// in the child trait later if GAT's are finally stable
mod private {
use super::TypeMetadata;

/// The raw representation of a database value given to `FromSql`.
///
/// This trait is separate from [`Backend`](super::Backend) to imitate `type RawValue<'a>`. It
/// should only be referenced directly by implementors. Users of this type
/// should instead use the [`RawValue`](super::RawValue) helper type instead.
#[cfg_attr(
doc_cfg,
doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
)]
pub trait HasRawValue<'a> {
/// The actual type given to [`FromSql`], with lifetimes applied. This type
/// should not be used directly. Use the [`RawValue`](super::RawValue)
/// helper type instead.
///
/// [`FromSql`]: crate::deserialize::FromSql
type RawValue;
}

/// This is a marker trait which indicates that
/// diesel may specialize a certain [`QueryFragment`]
Expand All @@ -562,27 +537,6 @@ mod private {
)]
pub trait DieselReserveSpecialization {}

/// The bind collector type used to collect query binds for this backend
///
/// This trait is separate from [`Backend`](super::Backend) to imitate `type BindCollector<'a>`. It
/// should only be referenced directly by implementors. Users of this type
/// should instead use the [`BindCollector`] helper type instead.
///
/// [`BindCollector`]: super::BindCollector
#[cfg_attr(
doc_cfg,
doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
)]
pub trait HasBindCollector<'a>: TypeMetadata + Sized {
/// The concrete [`BindCollector`](crate::query_builder::bind_collector::BindCollector)
/// implementation for this backend.
///
/// Most backends should use [`RawBytesBindCollector`].
///
/// [`RawBytesBindCollector`]: crate::query_builder::bind_collector::RawBytesBindCollector
type BindCollector: crate::query_builder::bind_collector::BindCollector<'a, Self> + 'a;
}

/// This trait just indicates that noone implements
/// [`SqlDialect`](super::SqlDialect) without enabling the
/// `i-implement-a-third-party-backend-and-opt-into-breaking-changes`
Expand Down
85 changes: 49 additions & 36 deletions diesel/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use self::transaction_manager::{
#[diesel_derives::__diesel_public_if(
feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"
)]
pub(crate) use self::private::ConnectionGatWorkaround;
pub(crate) use self::private::ConnectionSealed;

#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
pub use self::private::MultiConnectionHelper;
Expand All @@ -45,11 +45,11 @@ pub trait SimpleConnection {
fn batch_execute(&mut self, query: &str) -> QueryResult<()>;
}

/// Return type of [`LoadConnection::load`].
///
/// Users should threat this type as `impl Iterator<Item = QueryResult<impl Row<DB>>>`
#[doc(hidden)]
weiznich marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
#[deprecated(note = "Directly use `LoadConnection::Cursor` instead")]
pub type LoadRowIter<'conn, 'query, C, DB, B = DefaultLoadingMode> =
<C as ConnectionGatWorkaround<'conn, 'query, DB, B>>::Cursor;
<C as self::private::ConnectionHelperType<DB, B>>::Cursor<'conn, 'query>;

/// A connection to a database
///
Expand Down Expand Up @@ -203,8 +203,7 @@ where
// This trait bound is there so that implementing a new connection is
// gated behind the `i-implement-a-third-party-backend-and-opt-into-breaking-changes`
// feature flag
for<'conn, 'query> Self:
ConnectionGatWorkaround<'conn, 'query, Self::Backend, DefaultLoadingMode>,
Self: ConnectionSealed,
{
/// The backend this type connects to
type Backend: Backend;
Expand Down Expand Up @@ -388,10 +387,22 @@ where
///
/// This is a separate trait to allow connection implementations to specify
/// different loading modes via the generic paramater.
pub trait LoadConnection<B = DefaultLoadingMode>: Connection
where
for<'conn, 'query> Self: ConnectionGatWorkaround<'conn, 'query, Self::Backend, B>,
{
pub trait LoadConnection<B = DefaultLoadingMode>: Connection {
/// The cursor type returned by [`LoadConnection::load`]
///
/// Users should handle this as opaque type that implements [`Iterator`]
type Cursor<'conn, 'query>: Iterator<
Item = QueryResult<<Self as LoadConnection<B>>::Row<'conn, 'query>>,
>
where
Self: 'conn;

/// The row type used as [`Iterator::Item`] for the iterator implementation
/// of [`LoadConnection::Cursor`]
type Row<'conn, 'query>: crate::row::Row<'conn, Self::Backend>
where
Self: 'conn;

/// Executes a given query and returns any requested values
///
/// This function executes a given query and returns the
Expand All @@ -409,7 +420,7 @@ where
fn load<'conn, 'query, T>(
&'conn mut self,
source: T,
) -> QueryResult<LoadRowIter<'conn, 'query, Self, Self::Backend, B>>
) -> QueryResult<Self::Cursor<'conn, 'query>>
where
T: Query + QueryFragment<Self::Backend> + QueryId + 'query,
Self::Backend: QueryMetadata<T::SqlType>;
Expand Down Expand Up @@ -495,40 +506,26 @@ impl<DB: Backend + 'static> dyn BoxableConnection<DB> {
}
}

// `ConnectionGatWorkaround` is not part of the public API
// because we want to replace them by with an associated type
// in the child trait later if GAT's are finally stable
// These traits are considered private for different reasons:
//
// `ConnectionSealed` to control who can implement `Connection`,
// so that we can later change the `Connection` trait
//
// `MultiConnectionHelper` is a workaround needed for the
// `MultiConnection` derive. We might stabilize this trait with
// the corresponding derive
//
// `ConnectionHelperType` as a workaround for the `LoadRowIter`
// type def. That trait should not be used by any user outside of diesel,
// it purely exists for backward compatibility reasons.
pub(crate) mod private {
use crate::backend::Backend;
use crate::QueryResult;

use super::DefaultLoadingMode;

/// This trait describes which cursor type is used by a given connection
/// implementation. This trait is only useful in combination with [`Connection`].
///
/// Implementation wise this is a workaround for GAT's
///
/// [`Connection`]: super::Connection
/// This trait restricts who can implement `Connection`
#[cfg_attr(
doc_cfg,
doc(cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))
)]
pub trait ConnectionGatWorkaround<'conn, 'query, DB: Backend, B = DefaultLoadingMode> {
/// The cursor type returned by [`LoadConnection::load`]
///
/// Users should handle this as opaque type that implements [`Iterator`]
///
/// [`LoadConnection::load`]: super::LoadConnection::load
type Cursor: Iterator<Item = QueryResult<Self::Row>>;
/// The row type used as [`Iterator::Item`] for the iterator implementation
/// of [`ConnectionGatWorkaround::Cursor`]
type Row: crate::row::Row<'conn, DB>;
}
pub trait ConnectionSealed {}

/// This trait provides helper methods to convert a database lookup type
/// to/from an `std::any::Any` reference. This is used internally by the `#[derive(MultiConnection)]`
Expand All @@ -548,4 +545,20 @@ pub(crate) mod private {
lookup: &mut dyn std::any::Any,
) -> Option<&mut <Self::Backend as crate::sql_types::TypeMetadata>::MetadataLookup>;
}

// These impls are only there for backward compatibility reasons
// Remove them on the next breaking release
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
pub trait ConnectionHelperType<DB, B>: super::LoadConnection<B, Backend = DB> {
type Cursor<'conn, 'query>
where
Self: 'conn;
}
#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
impl<T, B> ConnectionHelperType<T::Backend, B> for T
where
T: super::LoadConnection<B>,
{
type Cursor<'conn, 'query> = <T as super::LoadConnection<B>>::Cursor<'conn, 'query> where T: 'conn;
}
}