Skip to content

Commit

Permalink
Merge pull request #4132 from fiadliel/same_rust_type_multiple_db_types
Browse files Browse the repository at this point in the history
Specify type of diesel::row::NamedRow::get in QueryableByName macro.
  • Loading branch information
weiznich committed Aug 2, 2024
2 parents 4763e7c + 302fcd2 commit e21dfb9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,6 @@ error: All fields of tuple structs must be annotated with `#[diesel(column_name)
|
= note: this error originates in the derive macro `QueryableByName` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: cannot deserialize a value of the database type `_` as `i32`
--> tests/fail/derive/queryable_by_name_requires_table_name_or_sql_type_annotation.rs:4:10
|
4 | #[derive(QueryableByName)]
| ^^^^^^^^^^^^^^^ the trait `FromSql<_, __DB>` is not implemented for `i32`
|
= note: double check your type mappings via the documentation of `_`
= help: the following other types implement trait `FromSql<A, DB>`:
<i32 as FromSql<diesel::sql_types::Integer, Mysql>>
<i32 as FromSql<diesel::sql_types::Integer, Pg>>
<i32 as FromSql<diesel::sql_types::Integer, Sqlite>>
note: required by a bound in `diesel::row::NamedRow::get`
--> $DIESEL/src/row.rs
|
| fn get<ST, T>(&self, column_name: &str) -> deserialize::Result<T>
| --- required by a bound in this associated function
| where
| T: FromSql<ST, DB>;
| ^^^^^^^^^^^^^^^ required by this bound in `NamedRow::get`
= note: this error originates in the derive macro `QueryableByName` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: cannot deserialize a value of the database type `_` as `*const str`
--> tests/fail/derive/queryable_by_name_requires_table_name_or_sql_type_annotation.rs:4:10
|
4 | #[derive(QueryableByName)]
| ^^^^^^^^^^^^^^^ the trait `FromSql<_, __DB>` is not implemented for `*const str`, which is required by `std::string::String: FromSql<_, __DB>`
|
= note: double check your type mappings via the documentation of `_`
= help: the following other types implement trait `FromSql<A, DB>`:
<*const str as FromSql<diesel::sql_types::Text, Mysql>>
<*const str as FromSql<diesel::sql_types::Text, Pg>>
<*const str as FromSql<diesel::sql_types::Text, Sqlite>>
= note: required for `std::string::String` to implement `FromSql<_, __DB>`
note: required by a bound in `diesel::row::NamedRow::get`
--> $DIESEL/src/row.rs
|
| fn get<ST, T>(&self, column_name: &str) -> deserialize::Result<T>
| --- required by a bound in this associated function
| where
| T: FromSql<ST, DB>;
| ^^^^^^^^^^^^^^^ required by this bound in `NamedRow::get`
= note: this error originates in the derive macro `QueryableByName` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0433]: failed to resolve: use of undeclared crate or module `foos`
--> tests/fail/derive/queryable_by_name_requires_table_name_or_sql_type_annotation.rs:5:8
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,3 @@ error[E0412]: cannot find type `foo` in this scope
|
27 | #[sql_type = "foo"]
| ^^^^^ not found in this scope

error[E0277]: cannot deserialize a value of the database type `_` as `i32`
--> tests/fail/derive_deprecated/deprecated_sql_type.rs:25:10
|
25 | #[derive(QueryableByName)]
| ^^^^^^^^^^^^^^^ the trait `FromSql<_, __DB>` is not implemented for `i32`
|
= note: double check your type mappings via the documentation of `_`
= help: the following other types implement trait `FromSql<A, DB>`:
<i32 as FromSql<diesel::sql_types::Integer, Mysql>>
<i32 as FromSql<diesel::sql_types::Integer, Pg>>
<i32 as FromSql<diesel::sql_types::Integer, Sqlite>>
note: required by a bound in `diesel::row::NamedRow::get`
--> $DIESEL/src/row.rs
|
| fn get<ST, T>(&self, column_name: &str) -> deserialize::Result<T>
| --- required by a bound in this associated function
| where
| T: FromSql<ST, DB>;
| ^^^^^^^^^^^^^^^ required by this bound in `NamedRow::get`
= note: this error originates in the derive macro `QueryableByName` (in Nightly builds, run with -Z macro-backtrace for more info)
3 changes: 2 additions & 1 deletion diesel_derives/src/queryable_by_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ pub fn derive(item: DeriveInput) -> Result<TokenStream> {
if f.embed() {
Ok(quote!(<#field_ty as QueryableByName<__DB>>::build(row)?))
} else {
let st = sql_type(f, &model)?;
let deserialize_ty = f.ty_for_deserialize();
let name = f.column_name()?;
let name = LitStr::new(&name.to_string(), name.span());
Ok(quote!(
{
let field = diesel::row::NamedRow::get(row, #name)?;
let field = diesel::row::NamedRow::get::<#st, #deserialize_ty>(row, #name)?;
<#deserialize_ty as Into<#field_ty>>::into(field)
}
))
Expand Down
53 changes: 52 additions & 1 deletion diesel_derives/tests/queryable_by_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ table! {
}
}

#[cfg(feature = "sqlite")]
table! {
multiple_sql_types_for_text {
id -> Integer,
string -> Text,
time -> Timestamp,
}
}

#[test]
fn named_struct_definition() {
#[derive(Debug, Clone, Copy, PartialEq, Eq, QueryableByName)]
Expand Down Expand Up @@ -86,8 +95,50 @@ fn struct_with_path_in_name() {
);
}

// FIXME: Test usage with renamed columns
#[cfg(feature = "sqlite")]
#[test]
fn struct_with_multiple_sql_types_for_text() {
#[derive(Debug, PartialEq, QueryableByName)]
struct MultipleSqlTypesForText {
#[diesel(sql_type = diesel::sql_types::Text)]
string: String,
#[diesel(sql_type = diesel::sql_types::Timestamp)]
time: String,
}

let conn = &mut connection();
let data = sql_query("SELECT 'name' AS string, '2024-07-31T21:09:00' AS time").get_result(conn);
assert_eq!(
Ok(MultipleSqlTypesForText {
string: "name".into(),
time: "2024-07-31T21:09:00".into()
}),
data
);
}

#[cfg(feature = "sqlite")]
#[test]
fn struct_with_multiple_sql_types_for_text_from_table() {
#[derive(Debug, PartialEq, QueryableByName)]
#[diesel(table_name = multiple_sql_types_for_text)]
struct MultipleSqlTypesForText {
string: String,
time: String,
}

let conn = &mut connection();
let data = sql_query("SELECT 'name' AS string, '2024-07-31T21:09:00' AS time").get_result(conn);
assert_eq!(
Ok(MultipleSqlTypesForText {
string: "name".into(),
time: "2024-07-31T21:09:00".into()
}),
data
);
}

// FIXME: Test usage with renamed columns
#[test]
fn struct_with_no_table() {
#[derive(Debug, Clone, Copy, PartialEq, Eq, QueryableByName)]
Expand Down

0 comments on commit e21dfb9

Please sign in to comment.