Skip to content

Commit

Permalink
Merge pull request #3908 from colem213/multiconnection-documentation
Browse files Browse the repository at this point in the history
Include more detail for implementing custom types for diesel::MultiCo…
  • Loading branch information
weiznich authored Jan 26, 2024
2 parents 166b97c + 4c7b6ea commit ec455eb
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 6 deletions.
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

0 comments on commit ec455eb

Please sign in to comment.