rbatis html query lang codegen from html logic just like: ```html ``` source code for example: ```rust use rbatis::executor::Executor; use rbatis::rbdc::datetime::DateTime; use rbatis::plugin::page::{Page, PageRequest}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BizActivity { pub id: Option, pub name: Option, pub pc_link: Option, pub h5_link: Option, pub pc_banner_img: Option, pub h5_banner_img: Option, pub sort: Option, pub status: Option, pub remark: Option, pub create_time: Option, pub version: Option, pub delete_flag: Option, } #[html_sql("example/example.html")] async fn select_by_condition(rb: &dyn Executor, page_req: &PageRequest, name: &str, dt: &DateTime) -> Vec { impled!() } ``` ```log 2022-08-17 17:16:23.624803 INFO rbatis::plugin::log - [rbatis] [402390551883812864] query ==> select * from biz_activity where name like ? and create_time < ? and id != '-1' and name != '' [rbatis] Args ==> ["test",DateTime("2022-08-17 17:16:23")] ``` # How it works ### 1. Whenever user define `html_sql` method(Of course, `py_sql` The implementation is also based on the `py_sql` syntax tree escaped to `html_sql`) ```rust #[html_sql(r#" "#)] async fn select_by_condition( rb: &dyn Executor, name: &str, a: bool, ) -> rbatis::Result> { impled!() } ``` ### 2. RBatis expr * RBatis expr is ```#{name}```,```#{age + 1}```,```${age + 1}``` and code test:``` ``` * RBatis expr will be Convert to original rust code,if RBatis expression = ```#{age + 1}```,the code = ``` rb_arg_map["age"].op_add(1) ``` * RBatis expr directly use strings to compare and process date types,just like ``` ```,``` #{dt >= '2009-12-12 00:00:00'}``` ### 3. The function body is generated through the process macro via rbatis-codegen ```rust // pub trait Executor{ //this is rbatis's Executor // fn exec(&mut self, sql: &str, args: Vec) -> BoxFuture<'_, Result>; // fn query(&mut self, sql: &str, args: Vec) -> BoxFuture<'_, Result>; // } pub async fn select_by_condition( rb: &dyn Executor, name: &str, a: bool, ) -> rbatis::Result> { let mut rb_arg_map = rbs::value::map::ValueMap::new(); rb_arg_map.insert( "name".to_string().into(), rbs::to_value(name).unwrap_or_default(), ); rb_arg_map.insert("a".to_string().into(), rbs::to_value(a).unwrap_or_default()); use rbatis::executor::RBatisRef; let driver_type = rb.driver_type()?; use rbatis::rbatis_codegen; pub fn impl_html_sql(arg: &rbs::Value, _tag: char) -> (String, Vec) { use rbatis_codegen::ops::*; let mut sql = String::with_capacity(55usize); let mut args = Vec::with_capacity(20); sql.push_str("select * from biz_activity where "); if { (&arg["name"]).op_ne(&rbs::Value::Null) } .to_owned() .into() { args.push(rbs::to_value({ &arg["name"] }).unwrap_or_default()); sql.push_str(" name like ?"); } return (sql, args); } let (mut sql, rb_args) = impl_html_sql(&rbs::Value::Map(rb_arg_map), '?'); use rbatis::executor::Executor; let r = rb.query(&sql, rb_args).await?; rbatis::decode::decode(r) } ```