diesel-oci 0.2.0

A oci database adapter for diesel
Documentation
extern crate diesel_dynamic_schema;
use self::diesel_dynamic_schema::dynamic_value::*;
use self::diesel_dynamic_schema::DynamicSelectClause;
use crate::oracle::{OciDataType, Oracle, OracleValue};
use diesel::deserialize::*;
use diesel::prelude::*;
use diesel::sql_query;
use diesel::sql_types::*;

#[derive(PartialEq, Debug)]
enum MyDynamicValue {
    String(String),
    Integer(i32),
    Null,
}

impl FromSql<Any, Oracle> for MyDynamicValue {
    fn from_sql(value: OracleValue) -> Result<Self> {
        match value.value_type() {
            OciDataType::Integer => {
                <i32 as FromSql<Integer, Oracle>>::from_sql(value).map(MyDynamicValue::Integer)
            }
            OciDataType::Text => {
                <String as FromSql<Text, Oracle>>::from_sql(value).map(MyDynamicValue::String)
            }
            e => Err(format!("Unknown data type: {:?}", e).into()),
        }
    }

    fn from_nullable_sql(value: Option<OracleValue>) -> Result<Self> {
        if let Some(value) = value {
            Self::from_sql(value)
        } else {
            Ok(MyDynamicValue::Null)
        }
    }
}

#[test]
fn dynamic_query() {
    let mut connection = super::init_testing();
    let _ = sql_query("DROP TABLE my_users").execute(&mut connection);
    sql_query("CREATE TABLE my_users (id NUMBER(10) NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL, hair_color VARCHAR(50))")
        .execute(&mut connection)
        .unwrap();
    sql_query(
        "INSERT ALL
    INTO my_users (id, name) VALUES (3, 'Sean')
    INTO my_users (id, name) VALUES (2, 'Tess')
SELECT * FROM DUAL",
    )
    .execute(&mut connection)
    .unwrap();

    let users = diesel_dynamic_schema::table("my_users");
    let id = users.column::<Integer, _>("id");
    let name = users.column::<Text, _>("name");
    let hair_color = users.column::<Nullable<Text>, _>("hair_color");

    let mut select = DynamicSelectClause::new();

    select.add_field(id);
    select.add_field(name);
    select.add_field(hair_color);

    let actual_data: Vec<DynamicRow<NamedField<MyDynamicValue>>> =
        users.select(select).load(&mut connection).unwrap();

    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())
        }
    );
    assert_eq!(
        actual_data[1]["NAME"],
        MyDynamicValue::String("Tess".into())
    );
    assert_eq!(
        actual_data[1][1],
        NamedField {
            name: "NAME".into(),
            value: MyDynamicValue::String("Tess".into())
        }
    );
    assert_eq!(actual_data[0]["HAIR_COLOR"], MyDynamicValue::Null);
    assert_eq!(
        actual_data[0][2],
        NamedField {
            name: "HAIR_COLOR".into(),
            value: MyDynamicValue::Null
        }
    );
    assert_eq!(actual_data[1]["HAIR_COLOR"], MyDynamicValue::Null);
    assert_eq!(
        actual_data[1][2],
        NamedField {
            name: "HAIR_COLOR".into(),
            value: MyDynamicValue::Null
        }
    );

    let mut select = DynamicSelectClause::new();

    select.add_field(id);
    select.add_field(name);
    select.add_field(hair_color);

    let actual_data: Vec<DynamicRow<MyDynamicValue>> =
        users.select(select).load(&mut connection).unwrap();

    assert_eq!(actual_data[0][1], MyDynamicValue::String("Sean".into()));
    assert_eq!(actual_data[1][1], MyDynamicValue::String("Tess".into()));
    assert_eq!(actual_data[0][2], MyDynamicValue::Null);
    assert_eq!(actual_data[1][2], MyDynamicValue::Null);
}

#[test]
fn mixed_value_query() {
    use diesel::dsl::sql;
    let mut connection = super::init_testing();
    let _ = sql_query("DROP TABLE my_users").execute(&mut connection);
    sql_query("CREATE TABLE my_users (id NUMBER(10) NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL, hair_color VARCHAR(50))")
        .execute(&mut connection)
        .unwrap();

    sql_query(
        "INSERT ALL
    INTO my_users (id, name, hair_color) VALUES (42, 'Sean', 'black')
    INTO my_users (id, name, hair_color) VALUES (43, 'Tess', 'black')
SELECT * FROM DUAL",
    )
    .execute(&mut connection)
    .unwrap();

    let users = diesel_dynamic_schema::table("my_users");
    let id = users.column::<Integer, _>("id");

    let (id, row) = users
        .select((id, sql::<Untyped>("name, hair_color")))
        .first::<(i32, DynamicRow<NamedField<MyDynamicValue>>)>(&mut connection)
        .unwrap();

    assert_eq!(id, 42);
    assert_eq!(row["NAME"], MyDynamicValue::String("Sean".into()));
    assert_eq!(row["HAIR_COLOR"], MyDynamicValue::String("black".into()));
}