Derive Macro diesel_derives::QueryableByName
source · #[derive(QueryableByName)]
{
// Attributes available to this derive:
#[diesel]
#[table_name]
#[column_name]
#[sql_type]
}
Expand description
Implements QueryableByName
for untyped sql queries, such as that one generated
by sql_query
To derive this trait, Diesel needs to know the SQL type of each field. You
can do this by either annotating your struct with #[diesel(table_name = some_table)]
(in which case the SQL type will be
diesel::dsl::SqlTypeOf<table_name::column_name>
), or by annotating each
field with #[diesel(sql_type = SomeType)]
.
If the name of a field on your struct is different than the column in your
table!
declaration, or if you are deriving this trait on a tuple struct,
you can annotate the field with #[diesel(column_name = some_column)]
. For tuple
structs, all fields must have this annotation.
If a field is another struct which implements QueryableByName
,
instead of a column, you can annotate that struct with #[diesel(embed)]
.
Then all fields contained by that inner struct are loaded into
the embedded struct.
To provide custom deserialization behavior for a field, you can use
#[diesel(deserialize_as = SomeType)]
. If this attribute is present, Diesel
will deserialize the corresponding field into SomeType
, rather than the
actual field type on your struct and then call .into
to convert it to the
actual field type. This can be used to add custom behavior for a
single field, or use types that are otherwise unsupported by Diesel.
§Attributes
§Optional container attributes
#[diesel(table_name = path::to::table)]
, to specify that this type contains columns for the specified table. The path is relative to the current module. If no field attributes are specified the derive will use the sql type of the corresponding column.
§Optional field attributes
#[diesel(column_name = some_column)]
, overrides the column name for a given field. If not set, the name of the field is used as column name. This attribute is required on tuple structs, if#[diesel(table_name = some_table)]
is used, otherwise it’s optional.#[diesel(sql_type = SomeType)]
, assumesSomeType
as sql type of the corresponding field. This attributes has precedence over all other variants to specify the sql type.#[diesel(deserialize_as = Type)]
, instead of deserializing directly into the field type, the implementation will deserialize intoType
. ThenType
is converted via.into()
into the field type. By default this derive will deserialize directly into the field type#[diesel(embed)]
, specifies that the current field maps not only single database column, but is a type that implementsQueryableByName
on it’s own
§Examples
If we just want to map a query to our struct, we can use derive
.
#[derive(QueryableByName, PartialEq, Debug)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
}
let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
.get_result(connection)?;
let expected = User { id: 1, name: "Sean".into() };
assert_eq!(expected, first_user);
If we want to do additional work during deserialization, we can use
deserialize_as
to use a different implementation.
struct LowercaseString(String);
impl Into<String> for LowercaseString {
fn into(self) -> String {
self.0
}
}
impl<DB, ST> FromSql<ST, DB> for LowercaseString
where
DB: Backend,
String: FromSql<ST, DB>,
{
fn from_sql(bytes: backend::RawValue<DB>) -> deserialize::Result<Self> {
String::from_sql(bytes)
.map(|s| LowercaseString(s.to_lowercase()))
}
}
#[derive(QueryableByName, PartialEq, Debug)]
#[diesel(table_name = users)]
struct User {
id: i32,
#[diesel(deserialize_as = LowercaseString)]
name: String,
}
let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
.get_result(connection)?;
let expected = User { id: 1, name: "sean".into() };
assert_eq!(expected, first_user);
The custom derive generates impls similar to the follownig one
#[derive(PartialEq, Debug)]
struct User {
id: i32,
name: String,
}
impl<DB> QueryableByName<DB> for User
where
DB: Backend,
i32: FromSql<diesel::dsl::SqlTypeOf<users::id>, DB>,
String: FromSql<diesel::dsl::SqlTypeOf<users::name>, DB>,
{
fn build<'a>(row: &impl NamedRow<'a, DB>) -> deserialize::Result<Self> {
let id = NamedRow::get::<diesel::dsl::SqlTypeOf<users::id>, _>(row, "id")?;
let name = NamedRow::get::<diesel::dsl::SqlTypeOf<users::name>, _>(row, "name")?;
Ok(Self { id, name })
}
}
let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
.get_result(connection)?;
let expected = User { id: 1, name: "Sean".into() };
assert_eq!(expected, first_user);