Oyelowo / surreal-orm

Powerful & expressive ORM/query-builder/static checker for raw queries/Fully Automated migration tooling , designed to offer an intuitive API, strict type-checking, novel features, & full specification support. It provides a fresh perspective in data management. Currently supports SurrealDB engine. RDMSs(PG, MYSQL etc) and others coming soon
93 stars 3 forks source link

25 implement for loop statement #26

Closed Oyelowo closed 1 year ago

Oyelowo commented 1 year ago

Implement for loop statement function and macro

Example:

    use super::*;
    use crate::{statements::{if_, select::{select, select_value}}, *};

    #[test]
    fn test_for_macro() {
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = for_!((name in vec!["Oyelowo", "Oyedayo"]) {
            select(All).from(person_table).where_(user_name.eq(name));
        });

        assert_eq!(
            for_loop.fine_tune_params(),
            "FOR $name IN $_param_00000001 {\nSELECT * FROM person WHERE user_name = $name;\n};"
        );
        assert_eq!(
            for_loop.to_raw().build(),
            "FOR $name IN ['Oyelowo', 'Oyedayo'] {\nSELECT * FROM person WHERE user_name = $name;\n};"
        );
    }

    #[test]
    fn test_for_macro_nested() {
        let ref __name = Param::new("name");
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = for_!((__name in vec!["Oyelowo", "Oyedayo"]) {
            select(All).from(person_table).where_(user_name.eq(__name));
            for_!((__name in vec!["Oyelowo", "Oyedayo"]) {
                select(All).from(person_table).where_(user_name.eq(__name));
            });
        });

        insta::assert_snapshot!(for_loop.fine_tune_params());
        insta::assert_snapshot!(for_loop.to_raw().build());
    }

    #[test]
    fn test_for_macro_and_block_macro() {
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = block! {
            FOR (__name IN vec!["Oyelowo", "Oyedayo"]) {
                select(All).from(person_table).where_(user_name.eq(__name));
                select(All).from(person_table).where_(user_name.eq(__name));

                for_!((__moniker IN select_value(user_name).from(person_table)) {  
                    select(All).from(person_table).where_(user_name.eq(__moniker));
                    select(All).from(person_table).where_(user_name.eq(__name));
                });

                for_(__name).in_(vec!["Oyelowo", "Oyedayo"])
                    .block(block! {
                        select(All).from(person_table).where_(user_name.eq(__name));
                });

            };

            FOR (__name IN vec!["Oyelowo", "Oyedayo"]) {
                select(All).from(person_table).where_(user_name.eq(__name));
                select(All).from(person_table).where_(user_name.eq(__name));
            };

            FOR (__name IN vec!["Oyelowo", "Oyedayo"]) {
                select(All).from(person_table).where_(user_name.eq(__name));
                select(All).from(person_table).where_(user_name.eq(__name));
            };

            if_(__name.eq("Oyelowo")).then(6).end();

        };
            for_!((__name in vec!["Oyelowo"]) { 
                select(All).from(person_table).where_(user_name.eq(__name));
                select(All).from(person_table).where_(user_name.eq(__name));

                for_!((__name in vec!["Oyelowo"]) { 
                    select(All).from(person_table).where_(user_name.eq(__name));
                    select(All).from(person_table).where_(user_name.eq(__name));

                    for_!((__name in vec!["Oyelowo"]) { 
                        select(All).from(person_table).where_(user_name.eq(__name));
                        select(All).from(person_table).where_(user_name.eq(__name));
                    });

                    for_!((__name in vec!["Oyelowo"]) { 
                        select(All).from(person_table).where_(user_name.eq(__name));
                        select(All).from(person_table).where_(user_name.eq(__name));
                    });

                });
            });

        insta::assert_snapshot!(for_loop.fine_tune_params());
        insta::assert_snapshot!(for_loop.to_raw().build());
    }

    #[test]
    fn test_for_in_block() {
        let ref __name = Param::new("name");
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = for_(__name).in_(vec!["Oyelowo", "Oyedayo"]).block(block! {
            select(All).from(person_table).where_(user_name.eq(__name));
        });

        assert_eq!(
            for_loop.fine_tune_params(),
            "FOR $name IN $_param_00000001 {\nSELECT * FROM person WHERE user_name = $name;\n};"
        );
        assert_eq!(
            for_loop.to_raw().build(),
            "FOR $name IN ['Oyelowo', 'Oyedayo'] {\nSELECT * FROM person WHERE user_name = $name;\n};"
        );
    }

    #[test]
    fn test_for_in_with_block_macro() {
        let ref __name = Param::new("name");
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = for_(__name).in_(vec!["Oyelowo", "Oyedayo"]).block(block! {
            LET nick_name = select(user_name).from_only(person_table).where_(user_name.eq(__name));

            select(All).from(person_table).where_(user_name.eq(nick_name));
        });

        assert_eq!(
            for_loop.fine_tune_params(),
            "FOR $name IN $_param_00000001 {\nLET $nick_name = $_param_00000002;\n\nSELECT * FROM person WHERE user_name = $nick_name;\n};"
        );

        assert_eq!(
            for_loop.to_raw().build(),
            "FOR $name IN ['Oyelowo', 'Oyedayo'] {\nLET $nick_name = (SELECT user_name FROM ONLY person WHERE user_name = $name);\n\nSELECT * FROM person WHERE user_name = $nick_name;\n};"
        );
    }

    #[test]
    fn test_for_in_block_with_subquery_iterable() {
        let ref __name = Param::new("name");
        let ref person_table = Table::from("person");
        let ref user_name = Field::from("user_name");

        let for_loop = for_(__name)
            .in_(
                select_value(user_name)
                    .from(person_table)
                    .where_(user_name.eq(__name)),
            )
            .block(block! {
                LET __nick_name = select(user_name).from_only(person_table).where_(user_name.eq(__name));

                select(All).from(person_table).where_(user_name.eq(__nick_name));
            });

        assert_eq!(
            for_loop.fine_tune_params(),
            "FOR $name IN $_param_00000001 {\nLET $__nick_name = $_param_00000002;\n\nSELECT * FROM person WHERE user_name = $__nick_name;\n};"
        );

        assert_eq!(
            for_loop.to_raw().build(),
            "FOR $name IN (SELECT VALUE user_name FROM person WHERE user_name = $name) {\nLET $__nick_name = (SELECT user_name FROM ONLY person WHERE user_name = $name);\n\nSELECT * FROM person WHERE user_name = $__nick_name;\n};"
        );
    }