Derive Macro edgedb_query_derive::InsertQuery

source ·
#[derive(InsertQuery)]
{
    // Attributes available to this derive:
    #[meta]
    #[result]
    #[conflict_on]
    #[conflict_else]
    #[scalar]
    #[nested_query]
    #[unless_conflict]
}
Expand description

InsertQuery creates implementations of following traits for the annotated struct :

  • edgedb_query::ToEdgeValue
  • edgedb_query::ToEdgeQl
  • edgedb_query::ToEdgeScalar
  • edgedb_query::models::edge_query::ToEdgeQuery
  • ToString

Usage

 use edgedb_protocol::value::Value;
 use edgedb_protocol::codec::EnumValue;
 use edgedb_query::{*, ToEdgeShape, models::{ edge_query::*, query_result::BasicResult}};

 #[derive(Default, EdgedbResult)]
 pub struct UserResult {
     pub id: String,
     pub name: NameResult,
 }

 #[derive(EdgedbEnum)]
 pub enum Sex {
     #[value("male")]
     Male,
     #[value("female")]
     Female,
 }

 #[derive(InsertQuery)]
 pub struct InsertUser {
     #[meta(module = "users", table = "User")]
     #[result(type = "UserResult")]
     __meta__: (),

     pub name: String,
     pub surname: Option<String>,
     pub age: i32,
     pub major: bool,
     pub vs: Vec<String>,
     #[scalar(type = "enum", module = "users", name = "Gender")]
     pub gender: Sex,
     #[nested_query]
     pub wallet: Wallet,
 }
 #[derive(InsertQuery)]
 pub struct Wallet {
     #[meta(module = "users", table = "Wallet")]
     __meta__: (),
     pub money: i16,
 }

 fn main() {
    let insert_user = InsertUser {
            __meta__: (),
            name: "Joe".to_string(),
            surname: Some("sj".to_string()),
            age: 35,
            major: true,
            vs: vec!["vs1".to_string()],
            gender: Sex::Male,
            wallet: Wallet {
                __meta__: (),
                money: 0 }
        };

        let query: EdgeQuery = insert_user.to_edge_query();

        println!("{:#?}", query.query);

        let expected = r#"
           select (
              insert users::User {
                name := (select <str>$name),
                surname := (select <str>$surname),
                age := (select <int32>$age),
                major := (select <bool>$major),
                vs := (select <array<str>>$vs),
                gender := (select <users::Gender>$gender),
                wallet := (
                    insert users::Wallet{
                        money := (select <int16>$money),
                    }),
                })
                {
                    id,
                    name : { name }
                }
        "#.to_owned().replace("\n", "");

        assert_eq!(query.query.replace(" ", ""), expected.replace(" ", ""));

        if let Some(Value::Object { shape, mut fields}) = query.args {

            crate::test_utils::check_shape(&shape, vec!["name", "surname", "age", "major", "vs", "gender", "wallet"]);

            let wallet_field = fields.pop();

            let vs_val = &insert_user.vs[0];

            assert_eq!(fields, vec![
                Some(Value::Str(insert_user.name)),
                Some(Value::Str(insert_user.surname.unwrap())),
                Some(Value::Int32(insert_user.age as i32)),
                Some(Value::Bool(insert_user.major)),
                Some(Value::Array(vec![Value::Str(vs_val.clone())])),
                Some(Value::Enum(EnumValue::from("male")))
            ]);

            if let Some(Some(Value::Object { shape, fields})) = wallet_field {
                let w_elmts = &shape.elements;
                assert_eq!(w_elmts.len(), 1);
                assert_eq!(fields, vec![Some(Value::Int16(insert_user.wallet.money as i16))])
            }
        } else {
            assert!(false)
        }
 }