rbatis

Rust Compile Time ORM robustness,async, pure Rust Dynamic SQL

APACHE-2.0 License

Downloads
1.1M
Stars
2.3K
Committers
25

Bot releases are visible (Hide)

rbatis - v1.8.45

Published by zhuxiujia almost 4 years ago

v1.8.45

  • fix mssql database Precompile parameter bug
  • fix mssql page plugin bug
  • async_std up to version = "1.8"
  • expr engine reduce loop method fill token. Improve lexer performance
  • #[crud_enable] macro auto impl #[derive(CRUDEnable, Serialize)], so you can Reduce code volume for example:
#[crud_enable]
#[derive(Clone, Debug)]
pub struct BizActivity {
    pub id: Option<String>,
    pub name: Option<String>,
}
rbatis - v1.8.44

Published by zhuxiujia almost 4 years ago

v1.8.44

  • json interpreter lexer add fill_lost_token() method, fix py_sql Resolve a bug where the minus sign is incorrect
rbatis - v1.8.43

Published by zhuxiujia almost 4 years ago

v1.8.43

  • fix support choose features,now ,async-io,tokio03,tokio02,actix feature are stable
rbatis - v1.8.42

Published by zhuxiujia almost 4 years ago

v1.8.42

  • Replace some unwrap to '?' or safer operations
  • fix PySql StringNode(use ${} express) can run on interpreter for example: ${arg+1}
  • decode.rs add 'std::collections:#️⃣:set' support
rbatis - v1.8.41

Published by zhuxiujia almost 4 years ago

v1.8.41

  • rbatis::core db_adapter package move to db package.
  • add DBConnectOption support custom connect option. for example(Used to resolve complex password resolution failures)
    for example:
 pub async fn init_rbatis() -> Rbatis {
        fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
        let rb = Rbatis::new();

        // custom connection option
        let db_cfg=DBConnectOption::from("mysql://root:123456@localhost:3306/test")?;
       //let db_cfg=DBConnectOption::from_mysql(MySqlConnectOptions::default())?; 
       //let db_cfg=DBConnectOption::from_pg(PgConnectOptions::default())?; 
       /// ......and more
        rb.link_cfg(&db_cfg,PoolOptions::new());
}
rbatis - v1.8.40

Published by zhuxiujia almost 4 years ago

v1.8.40

  • tx_id rename to context_id, use tx_id,ctx_id,context_id Will be recognized by the Rbatis.
  • Rbatis add begin_tx_defer()method and begin_tx()method. begin_tx_defer Used to automatically Drop or Commit transactions after Drop,
    for example:
#[async_std::test]
    pub async fn test_tx_commit_defer() {
        fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
        let rb: Rbatis = Rbatis::new();
        rb.link(MYSQL_URL).await.unwrap();
        let guard = rb.begin_tx_defer(true).await.unwrap();
        let v: serde_json::Value = rb.fetch(&guard.tx_id, "SELECT count(1) FROM biz_activity;").await.unwrap();
        // tx will be commit
        drop(guard);
        println!("{}", v.clone());
        sleep(Duration::from_secs(1));
    }

2020-12-03 14:53:24.908263 +08:00    INFO rbatis::plugin::log - [rbatis] [tx:4b190951-7a94-429a-b253-3ec3df487b57] Begin
2020-12-03 14:53:24.909074 +08:00    INFO rbatis::plugin::log - [rbatis] [tx:4b190951-7a94-429a-b253-3ec3df487b57] Query ==> SELECT count(1) FROM biz_activity;
2020-12-03 14:53:24.912973 +08:00    INFO rbatis::plugin::log - [rbatis] [tx:4b190951-7a94-429a-b253-3ec3df487b57] ReturnRows <== 1
2020-12-03 14:53:24.914487 +08:00    INFO rbatis::plugin::log - [rbatis] [tx:4b190951-7a94-429a-b253-3ec3df487b57] Commit

begin_tx() method Automatically generate transactions that use UUIDs

    pub async fn test_tx_commit() {
        fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
        let rb: Rbatis = Rbatis::new();
        rb.link(MYSQL_URL).await.unwrap();
        let tx_id = rb.begin_tx().await.unwrap();
        let v: serde_json::Value = rb.fetch(&tx_id, "SELECT count(1) FROM biz_activity;").await.unwrap();
        println!("{}", v.clone());
        rb.commit(&tx_id).await.unwrap();
    }
rbatis - v1.8.39

Published by zhuxiujia almost 4 years ago

v1.8.39

  • start a new transaction ,tx_id must be start with 'tx' for example :
        let tx_id = "tx:1";
        rb.begin(tx_id).await.unwrap();
        let v: serde_json::Value = rb.fetch(tx_id, "SELECT count(1) FROM biz_activity;").await.unwrap();

so, if you send an tx_id ="123456"; So SQL is executed in a normal session,and You can track records based on this ID

  • AST string node use Vec<(String,String)> save data.
  • decode type add vec_deque
rbatis - v1.8.38

Published by zhuxiujia almost 4 years ago

v1.8.38

  • fix Parameter sequencing problem,use BtreeMap<i32,(String,String)> replace BtreeMap<String,String>
rbatis - v1.8.37

Published by zhuxiujia almost 4 years ago

v1.8.37

  • use macro #[crud_enable] No import is required ‘use rbatis::crud::CRUDEnable;‘
  • fix express interpreter decode brackets deep more than 3 bug
rbatis - v1.8.36

Published by zhuxiujia almost 4 years ago

v1.8.36

  • SQL parameter replaces partial IndexMap with BtreeMap
  • fix some express bug for fill null value. for now express engine is correct and stable
        let arg = json!({
        "a":1,
        "b":2,
        "c":"c",
        "d":null,
        "e":[1],
        "f":[{"field":1}]
         });
        let exec_expr = |arg: &serde_json::Value, expr: &str| -> serde_json::Value{
            println!("{}", expr.clone());
            let box_node = parser::parse(expr, &OptMap::new()).unwrap();
            let v = box_node.eval(arg).unwrap();
            println!("'{}' -> {}", expr.clone(), &v);
            v
        };
        assert_eq!(exec_expr(&arg, "d.a == null"), json!(true));
        assert_eq!(exec_expr(&arg, "1 == 1.0"), json!(true));
        assert_eq!(exec_expr(&arg, "'2019-02-26' == '2019-02-26'"), json!(true));
        assert_eq!(exec_expr(&arg, "`f`+`s`"), json!("fs"));
        assert_eq!(exec_expr(&arg, "a +1 > b * 8"), json!(false));
        assert_eq!(exec_expr(&arg, "a >= 0"), json!(true));
        assert_eq!(exec_expr(&arg, "'a'+c"), json!("ac"));
        assert_eq!(exec_expr(&arg, "b"), json!(2));
        assert_eq!(exec_expr(&arg, "a < 1"), json!(false));
        assert_eq!(exec_expr(&arg, "a +1 > b*8"), json!(false));
        assert_eq!(exec_expr(&arg, "a * b == 2"), json!(true));
        assert_eq!(exec_expr(&arg, "a - b == 0"), json!(false));
        assert_eq!(exec_expr(&arg, "a >= 0 && a != 0"), json!(true));
        assert_eq!(exec_expr(&arg, "a == 1 && a != 0"), json!(true));
        assert_eq!(exec_expr(&arg, "1 > 3 "), json!(false));
        assert_eq!(exec_expr(&arg, "1 + 2 != null"), json!(true));
        assert_eq!(exec_expr(&arg, "1 != null"), json!(true));
        assert_eq!(exec_expr(&arg, "1 + 2 != null && 1 > 0 "), json!(true));
        assert_eq!(exec_expr(&arg, "1 + 2 != null && 2 < b*8 "), json!(true));
        assert_eq!(exec_expr(&arg, "-1 != null"), json!(true));
        assert_eq!(exec_expr(&arg, "-1 != -2 && -1 == 2-3 "), json!(true));
        assert_eq!(exec_expr(&arg, "-3 == b*-1-1 "), json!(true));
        assert_eq!(exec_expr(&arg, "0-1 + a*0-1 "), json!(-2));
        assert_eq!(exec_expr(&arg, "2 ** 3"), json!(8.0));
        assert_eq!(exec_expr(&arg, "0-1 + -1*0-1 "), json!(-2));
        assert_eq!(exec_expr(&arg, "1-"), json!(1));
        assert_eq!(exec_expr(&arg, "-1"), json!(-1));
        assert_eq!(exec_expr(&arg, "1- -1"), json!(1--1));
        assert_eq!(exec_expr(&arg, "1-2 -1+"), json!(1-2-1));
        assert_eq!(exec_expr(&arg, "e[1]"), json!(null));
        assert_eq!(exec_expr(&arg, "e[0]"), json!(1));
        assert_eq!(exec_expr(&arg, "f[0].field"), json!(1));
        assert_eq!(exec_expr(&arg, "f.0.field"), json!(1));
        assert_eq!(exec_expr(&arg, "0.1"), json!(0.1));
        assert_eq!(exec_expr(&arg, "1"), json!(1));
        assert_eq!(exec_expr(&arg, "(1+1)"), json!(2));
        assert_eq!(exec_expr(&arg, "(1+5)>5"), json!((1+5)>5));
        assert_eq!(exec_expr(&arg, "(18*19)<19*19"), json!((18*19)<19*19));
        assert_eq!(exec_expr(&arg, "2*(1+1)"), json!(2*(1+1)));
        assert_eq!(exec_expr(&arg, "2*(1+(1+1)+1)"), json!(2*(1+(1+1)+1)));
        assert_eq!(exec_expr(&arg, "(1+2)+(8*(2+1)*9)"), json!((1+2)+(8*(2+1)*9)));
rbatis - v1.8.35

Published by zhuxiujia almost 4 years ago

v1.8.35

  • express engine support deep opt of example:
        assert_eq!(exec_expr(&arg, "(1+1)"), json!(2));
        assert_eq!(exec_expr(&arg, "(1+5)>5"), json!(true));
        assert_eq!(exec_expr(&arg, "(18*19)<19*19"), json!(true));
        assert_eq!(exec_expr(&arg, "2*(1+1)"), json!(4));
        assert_eq!(exec_expr(&arg, "2*(1+(1+1)+1)"), json!(8));
        assert_eq!(exec_expr(&arg, "(1+2)+(8*(2+1)*9)"), json!(3+8*3*9));
rbatis - v1.8.34

Published by zhuxiujia almost 4 years ago

v1.8.34

  • express engine support '(' ')'
    for example:
        assert_eq!(exec_expr(&arg, "(1+1)"), json!(2));
        assert_eq!(exec_expr(&arg, "(1+5)>5"), json!(true));
        assert_eq!(exec_expr(&arg, "(18*19)<19*19"), json!(true));
  • default close ssl-mode, if you not config in driver url string.
rbatis - v1.8.33

Published by zhuxiujia almost 4 years ago

v1.8.33

  • fix DBPool macro Conditional compilation
rbatis - v1.8.32

Published by zhuxiujia almost 4 years ago

v1.8.32

  • Use an ordered Map to solve sequential bugs
  • default close ssl
rbatis - v1.8.31

Published by zhuxiujia almost 4 years ago

v1.8.31

  • auto call sqlx pool.close() when Rbatis Drop !
rbatis - v1.8.30

Published by zhuxiujia almost 4 years ago

v1.8.30

  • fix only cfg compile, support only compile one database
#rbatis dep(this code only use mysql driver)
rbatis = { version = "1.8", default-features = false, features = ["async-io-mysql","snowflake"] }
rbatis-macro-driver = { version = "1.8", features = ["no_print"] }
  • log plugin use ARC Keep the only instance(Share with the transaction manager and Rbatis)
  • add RbatisOption for easy to build Rbatis instance(you can use Rbatis::new_with_opt(option) build this)
  • RbatisAST trait add name() method,The custom ‘py’ syntax requires a name
rbatis - v1.8.26

Published by zhuxiujia almost 4 years ago

v1.8.26

  • support Compile only the target database for #53
rbatis - v1.8.25

Published by zhuxiujia almost 4 years ago

v1.8.25

  • add transaction manager, The timeout transaction is rolled back。(default run more than 60s,you can change this)
rbatis - v1.8.24

Published by zhuxiujia almost 4 years ago

v1.8.24

  • CRUDEnable macro Generate cleaner table columns,for example: "id,name,age".to_string()
  • support custom py lang,for example:
    #[derive(Debug)]
    pub struct MyNode {}

    impl RbatisAST for MyNode {
        fn eval(&self, convert: &DriverType, env: &mut Value, engine: &RbatisEngine, arg_result: &mut Vec<Value>) -> Result<String, Error> {
            Ok(" AND id = 1 ".to_string())
        }
    }

    pub struct MyGen {}

    impl CustomNodeGenerate for MyGen {
        fn generate(&self, express: &str, child_nodes: Vec<NodeType>) -> Result<Option<CustomNode>, Error> {
            if express.starts_with("custom") {
                return Ok(Option::from(CustomNode::from(MyNode {}, child_nodes)));
            }
            //skip
            return Ok(None);
        }
    }

    //示例-Rbatis扩展py风格的语法
    #[async_std::test]
    pub async fn test_py_sql_custom() {
        fast_log::init_log("requests.log",
                           1000,
                           log::Level::Info,
                           None,
                           true);
        let mut rb = Rbatis::new();
        rb.link(MYSQL_URL).await.unwrap();
        rb.py.add_gen(MyGen {});
        let py = "
    SELECT * FROM biz_activity
    WHERE delete_flag = 0
    custom :
    ";
        let data: Page<BizActivity> = rb.py_fetch_page("", py, &json!({}), &PageRequest::new(1, 20)).await.unwrap();
        println!("{}", serde_json::to_string(&data).unwrap());
    }
//[rbatis] [] Query ==> SELECT count(1) FROM biz_activity WHERE delete_flag = 0 AND id = 1
rbatis - v1.8.21

Published by zhuxiujia almost 4 years ago

v1.8.21

  • disable sqlx log level. Because this would cause a Chinese format exception