Module diesel_dynamic_schema::dynamic_value
source · Expand description
This module provides a container that allows to receive a dynamically specified number of fields from the database.
let users = diesel_dynamic_schema::table("users");
let id = users.column::<Untyped, _>("id");
let name = users.column::<Untyped, _>("name");
let mut select = DynamicSelectClause::new();
select.add_field(id);
select.add_field(name);
let actual_data: Vec<DynamicRow<NamedField<MyDynamicValue>>> =
users.select(select).load(conn)?;
assert_eq!(
actual_data[0]["name"],
MyDynamicValue::String("Sean".into())
);
assert_eq!(
actual_data[0][1],
NamedField {
name: "name".into(),
value: MyDynamicValue::String("Sean".into())
}
);
It is required to provide your own inner type to hold the actual database value.
#[derive(PartialEq, Debug)]
enum MyDynamicValue {
String(String),
Integer(i32),
}
impl FromSql<Any, diesel::pg::Pg> for MyDynamicValue {
fn from_sql(value: diesel::pg::PgValue) -> deserialize::Result<Self> {
use diesel::pg::Pg;
use std::num::NonZeroU32;
const VARCHAR_OID: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(1043) };
const TEXT_OID: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(25) };
const INTEGER_OID: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(23) };
match value.get_oid() {
VARCHAR_OID | TEXT_OID => {
<String as FromSql<diesel::sql_types::Text, Pg>>::from_sql(value)
.map(MyDynamicValue::String)
}
INTEGER_OID => <i32 as FromSql<diesel::sql_types::Integer, Pg>>::from_sql(value)
.map(MyDynamicValue::Integer),
e => Err(format!("Unknown type: {}", e).into()),
}
}
}
Structs
- A marker type used to indicate that the provided
FromSql
impl does handle any passed database value, independently from the actual value kind - A dynamically sized container that allows to receive a not at compile time known number of columns from the database
- A helper struct used as field type in
DynamicRow
to also return the name of the field along with the value