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

Include more detail for implementing custom types for diesel::MultiCo… #3908

Merged
merged 5 commits into from
Jan 26, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions diesel/src/pg/types/date_and_time/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ mod tests {
let query = select(sql::<Date>("'J0'::date").eq(julian_epoch));
assert!(query.get_result::<bool>(connection).unwrap());

let max_date = NaiveDate::MAX;
let query = select(sql::<Date>("'262143-12-31'::date").eq(max_date));
let max_date = NaiveDate::from_ymd_opt(262142, 12, 31).unwrap();
let query = select(sql::<Date>("'262142-12-31'::date").eq(max_date));
assert!(query.get_result::<bool>(connection).unwrap());

let january_first_2018 = NaiveDate::from_ymd_opt(2018, 1, 1).unwrap();
Expand Down Expand Up @@ -311,8 +311,8 @@ mod tests {
let query = select(sql::<Date>("'J0'::date"));
assert_eq!(Ok(julian_epoch), query.get_result::<NaiveDate>(connection));

let max_date = NaiveDate::MAX;
let query = select(sql::<Date>("'262143-12-31'::date"));
let max_date = NaiveDate::from_ymd_opt(262142, 12, 31).unwrap();
let query = select(sql::<Date>("'262142-12-31'::date"));
assert_eq!(Ok(max_date), query.get_result::<NaiveDate>(connection));

let january_first_2018 = NaiveDate::from_ymd_opt(2018, 1, 1).unwrap();
Expand Down
95 changes: 93 additions & 2 deletions diesel_derives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,8 +1630,99 @@ pub fn table_proc(input: TokenStream) -> TokenStream {
/// * `diesel::sql_types::Timestamp`
///
/// Support for additional types can be added by providing manual implementations of
/// `HasSqlType`, `FromSql` and `ToSql` for the corresponding type + the generated
/// database backend.
/// `HasSqlType`, `FromSql` and `ToSql` for the corresponding type, all databases included
/// in your enum, and the backend generated by this derive called `MultiBackend`.
/// For example to support a custom enum `MyEnum` with the custom SQL type `MyInteger`:
/// ```
/// extern crate diesel;
/// use diesel::backend::Backend;
/// use diesel::deserialize::{self, FromSql, FromSqlRow};
/// use diesel::serialize::{self, IsNull, ToSql};
/// use diesel::AsExpression;
/// use diesel::sql_types::{HasSqlType, SqlType};
/// use diesel::prelude::*;
///
/// #[derive(diesel::MultiConnection)]
/// pub enum AnyConnection {
/// # #[cfg(feature = "postgres")]
/// Postgresql(diesel::PgConnection),
/// # #[cfg(feature = "mysql")]
/// Mysql(diesel::MysqlConnection),
/// # #[cfg(feature = "sqlite")]
/// Sqlite(diesel::SqliteConnection),
/// }
///
/// // defining an custom SQL type is optional
/// // you can also use types from `diesel::sql_types`
/// #[derive(Copy, Clone, Debug, SqlType)]
/// #[diesel(postgres_type(name = "Int4"))]
/// #[diesel(mysql_type(name = "Long"))]
/// #[diesel(sqlite_type(name = "Integer"))]
/// struct MyInteger;
///
///
/// // our custom enum
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy, AsExpression, FromSqlRow)]
/// #[diesel(sql_type = MyInteger)]
/// pub enum MyEnum {
/// A = 1,
/// B = 2,
/// }
///
/// // The `MultiBackend` type is generated by `#[derive(diesel::MultiConnection)]`
/// // This part is only required if you define a custom sql type
/// impl HasSqlType<MyInteger> for MultiBackend {
/// fn metadata(lookup: &mut Self::MetadataLookup) -> Self::TypeMetadata {
/// // The `lookup_sql_type` function is exposed by the `MultiBackend` type
/// MultiBackend::lookup_sql_type::<MyInteger>(lookup)
/// }
/// }
///
/// impl FromSql<MyInteger, MultiBackend> for MyEnum {
/// fn from_sql(bytes: <MultiBackend as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
/// // The `from_sql` function is exposed by the `RawValue` type of the
/// // `MultiBackend` type
/// // This requires a `FromSql` impl for each backend
/// bytes.from_sql::<MyEnum, MyInteger>()
/// }
/// }
///
/// impl ToSql<MyInteger, MultiBackend> for MyEnum {
/// fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, MultiBackend>) -> serialize::Result {
/// /// `set_value` expects a tuple consisting of the target SQL type
/// /// and self for `MultiBackend`
/// /// This requires a `ToSql` impl for each backend
/// out.set_value((MyInteger, self));
/// Ok(IsNull::No)
/// }
/// }
/// # #[cfg(feature = "postgres")]
/// # impl ToSql<MyInteger, diesel::pg::Pg> for MyEnum {
/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result { todo!() }
/// # }
/// # #[cfg(feature = "mysql")]
/// # impl ToSql<MyInteger, diesel::mysql::Mysql> for MyEnum {
/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::mysql::Mysql>) -> serialize::Result { todo!() }
/// # }
/// # #[cfg(feature = "sqlite")]
/// # impl ToSql<MyInteger, diesel::sqlite::Sqlite> for MyEnum {
/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::sqlite::Sqlite>) -> serialize::Result { todo!() }
/// # }
/// # #[cfg(feature = "postgres")]
/// # impl FromSql<MyInteger, diesel::pg::Pg> for MyEnum {
/// # fn from_sql(bytes: <diesel::pg::Pg as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
/// # }
/// # #[cfg(feature = "mysql")]
/// # impl FromSql<MyInteger, diesel::mysql::Mysql> for MyEnum {
/// # fn from_sql(bytes: <diesel::mysql::Mysql as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
/// # }
/// # #[cfg(feature = "sqlite")]
/// # impl FromSql<MyInteger, diesel::sqlite::Sqlite> for MyEnum {
/// # fn from_sql(bytes: <diesel::sqlite::Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
/// # }
/// # fn main() {}
/// ```
#[proc_macro_derive(MultiConnection)]
pub fn derive_multiconnection(input: TokenStream) -> TokenStream {
multiconnection::derive(syn::parse_macro_input!(input)).into()
Expand Down
Loading