Rust Compile Time ORM robustness,async, pure Rust Dynamic SQL
APACHE-2.0 License
Bot releases are hidden (Show)
Published by zhuxiujia over 3 years ago
v2.0.4
for now
#[py_sql(RB, "select * from biz_activity where delete_flag = 0
if name != '':
and name=#{name}")]
async fn py_select_page(page_req: &PageRequest, name: &str) -> Page<BizActivity> { todo!() }
befor(Only the 2.0.3 version)
#[py_sql(RB, "select * from biz_activity where delete_flag = 0
if name != '':
and name=#{name}","mysql")]
async fn py_select_page(page_req: &PageRequest, name: &str) -> Page<BizActivity> { todo!() }
Published by zhuxiujia over 3 years ago
v2.0.3
Because of the compile time, the annotations need to declare the database type to be used
#[py_sql(
rb,
"select * from biz_activity where delete_flag = 0
if name != '':
and name=#{name}","mysql")]
async fn py_sql_tx(rb: &Rbatis, tx_id: &String, name: &str) -> Vec<BizActivity> { todo!() }
Because of the compile time, the annotations need to declare the database type to be used
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://github.com/rbatis/rbatis_sql/raw/main/mybatis-3-mapper.dtd">
<mapper>
<select id="select_by_condition">
select * from biz_activity where
<if test="name != ''">
name like #{name}
</if>
</select>
</mapper>
///select page must have '?:&PageRequest' arg and return 'Page<?>'
#[html_sql(rb, "example/example.html","mysql")]
async fn select_by_condition(rb: &mut RbatisExecutor<'_>, page_req: &PageRequest, name: &str) -> Page<BizActivity> { todo!() }
Published by zhuxiujia over 3 years ago
v2.0.2
rb.fetch_by_column::<Option<BizActivity>,_>( "id",&"1").await
rb.fetch_by_column::<Option<BizActivity>,_>( "name",&"joke").await
rb.fetch_by_column::<Option<BizActivity>,_>( "age",1).await
let tx = rb.acquire_begin().await.unwrap();
let v: serde_json::Value = tx
.fetch("select count(1) from biz_activity;",&vec![])
.await
.unwrap();
println!("{}", v.clone());
tx.commit().await.unwrap();
also you can use defer
pub async fn forget_commit(rb: &Rbatis) -> rbatis::core::Result<serde_json::Value> {
// tx will be commit.when func end
let tx = rb.acquire_begin().await?.defer(|tx|{
println!("tx is drop!");
async_std::task::block_on(async{ tx.rollback().await; });
});
let v: serde_json::Value = tx
.fetch( "select count(1) from biz_activity;",&vec![])
.await?;
return Ok(v);
}
#[tokio::test]
pub async fn test_remove_batch_by_id() {
let mut rb = init_rbatis().await;
rb.logic_plugin = Some(Box::new(RbatisLogicDeletePlugin::new("delete_flag")));
rb.link("mysql://root:123456@localhost:3306/test")
.await
.unwrap();
let r = rb
.remove_batch_by_column::<TableNoLogic<BizActivity>,_>( "id",&["1".to_string(), "2".to_string()])
.await;
if r.is_err() {
println!("{}", r.err().unwrap().to_string());
}
}
V2.0 can't be without your support,thanks
Published by zhuxiujia over 3 years ago
v1.8.88
Published by zhuxiujia over 3 years ago
v1.8.87
Published by zhuxiujia over 3 years ago
Published by zhuxiujia over 3 years ago
v1.8.84
Published by zhuxiujia over 3 years ago
v1.8.83
fix #93
Published by zhuxiujia over 3 years ago
v1.8.82
Published by zhuxiujia over 3 years ago
v1.8.81
rbatis = { version = "1.8.81", default-features = false, features = ["mysql","tokio1"] }
Published by zhuxiujia over 3 years ago
v1.8.80
Published by zhuxiujia over 3 years ago
v1.8.79
all-database
,mssql
,mysql
,postgres
, sqlite
Published by zhuxiujia over 3 years ago
v1.8.78
upper_case_sql_keyword
feature enable's bugBlockAttackDeleteInterceptor
and BlockAttackUpdateInterceptor
1, delete,
delete from tablename
2, update,
update tablename set columnname = value
RbatisLogFormatSqlIntercept
for example: /// Formatting precompiled SQL
///
/// [] Exec ==> insert into biz_activity (id,name,pc_link,h5_link,pc_banner_img,h5_banner_img,sort,status,remark,create_time,version,delete_flag)
/// values (?,?,?,?,?,?,?,?,?,?,?,?)
///
/// into
///
/// [rbatis] [] [format_sql]insert into biz_activity (id,name,pc_link,h5_link,pc_banner_img,h5_banner_img,sort,status,remark,create_time,version,delete_flag)
/// values ("12312","12312",null,null,null,null,"1",1,null,"2021-03-10T20:34:47.432751100",1,1)
#[async_std::test]
pub async fn test_show_format_sql() {
fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
let mut rb = Rbatis::new();
rb.add_sql_intercept(RbatisLogFormatSqlIntercept{});
rb.link("mysql://root:123456@localhost:3306/test")
.await
.unwrap();
let activity = BizActivity {
id: Some("12312".to_string()),
name: Some("12312".to_string()),
pc_link: None,
h5_link: None,
pc_banner_img: None,
h5_banner_img: None,
sort: Some("1".to_string()),
status: Some(1),
remark: None,
create_time: Some(NaiveDateTime::now()),
version: Some(1),
delete_flag: Some(1),
};
let r = rb.save("", &activity).await;
}
Published by zhuxiujia over 3 years ago
v1.8.77
save_batch_slice
//One-time insert
rb.save_batch_slice("",&vec![activity],0).await;
// insert 10 vec data every time Until all inserts are done
rb.save_batch_slice("",&vec![activity],10).await;
Published by zhuxiujia over 3 years ago
v1.8.76
make_table
Simplifies table construction by relying on the Default traitmake_table_field_vec
take the target Vec member attribute Vec collectionmake_table_field_map
Gets the HashMap collection of member attributes of the target Vec #[crud_enable]
#[derive(Clone, Debug)]
pub struct BizActivity {
pub id: Option<String>,
pub name: Option<String>,
pub pc_link: Option<String>,
pub h5_link: Option<String>,
pub pc_banner_img: Option<String>,
pub h5_banner_img: Option<String>,
pub sort: Option<String>,
pub status: Option<i32>,
pub remark: Option<String>,
pub create_time: Option<NaiveDateTime>,
pub version: Option<BigDecimal>,
pub delete_flag: Option<i32>,
}
impl Default for BizActivity {
fn default() -> Self {
Self {
id: None,
name: None,
pc_link: None,
h5_link: None,
pc_banner_img: None,
h5_banner_img: None,
sort: None,
status: None,
remark: None,
create_time: None,
version: None,
delete_flag: None,
}
}
}
#[test]
fn test_make_table() {
let table = rbatis::make_table!(BizActivity{
id:"1".to_string(),
});
println!("{:#?}", table);
}
#[test]
fn test_table_field_map() {
let table = rbatis::make_table!(BizActivity{
id:"1".to_string(),
name:"a".to_string()
});
let table_vec = vec![table];
let map = rbatis::make_table_field_map!(&table_vec,name);
println!("{:#?}", map);
assert_eq!(map.len(), table_vec.len());
}
#[test]
fn test_table_field_vec() {
let table = rbatis::make_table!(BizActivity{
id:"1".to_string(),
name:"a".to_string()
});
let table_vec = vec![table];
let names = rbatis::make_table_field_vec!(&table_vec,name);
println!("{:#?}", names);
assert_eq!(names.len(), table_vec.len());
}
#[crud_enable]
#[derive(Clone, Debug)]
pub struct FatherChildVO {
pub id: Option<i32>,
pub father_id: Option<i32>,
pub childs: Vec<FatherChildVO>,
}
impl FatherChildRelationship for FatherChildVO {
fn get_father_id(&self) -> Option<&Self::IdType> {
self.father_id.as_ref()
}
fn set_childs(&mut self, arg: Vec<Self>) {
self.childs = arg;
}
}
#[test]
fn test_to_father_child_relationship() {
let mut father = FatherChildVO {
id: Some(1),
father_id: None,
childs: vec![],
};
let child = FatherChildVO {
id: Some(2),
father_id: Some(1),
childs: vec![],
};
// or childs = rbatis.fetch_list****() get all of childs data.
let childs=vec![child];
let all_record = rbatis::make_table_field_map!(childs,id);
father.recursive_set_childs(&all_record);
println!("{:#?}", father);
}
FatherChildVO {
id: Some(
1,
),
father_id: None,
childs: [
FatherChildVO {
id: Some(
2,
),
father_id: Some(
1,
),
childs: [],
},
],
}
Published by zhuxiujia over 3 years ago
v1.8.75
Lock-Free
impl snowflake Plugin//old impl
// let id = rbatis::plugin::snowflake::async_snowflake_id() .await.to_string();
//new impl
let id = rbatis::plugin::snowflake::new_snowflake_id().to_string();
println!("{}",id);
//205667537625681919
In My computer The new (77ns/op) snowflake is 40% to 50% faster than the old (113ns/op) snowflake algorithm because the runtime context switch is bound to take time, plus the impact time of parking_lot's mutex blocking
bson-rust
) println!("{}",rbatis::plugin::object_id::ObjectId::new().to_string());
//603c86e400299f5900d378b4
Published by zhuxiujia over 3 years ago
v1.8.74
first , define py_sql.sql
select * from biz_activity where delete_flag = 0
if name != '':
and name=#{name}
then,load file
///load from file
fn load_file_str(file_name:&str)->String{
let mut f =File::open(file_name).unwrap();
let mut s=String::new();
f.read_to_string(&mut s);
return s;
}
///load file py_sql(Each read file changes every time)
#[py_sql(rb, load_file_str("py_sql.sql"))]
async fn py_select_file(rb: &Rbatis, page_req: &PageRequest, name: &str) -> Page<BizActivity> {}
lazy_static!(
pub static ref PY_SQL_FILE_STR:String=load_file_str("py_sql.sql");
);
///load file py_sql(only load file once)
#[py_sql(rb, PY_SQL_FILE_STR)]
async fn py_select_file_static(rb: &Rbatis, page_req: &PageRequest, name: &str) -> Page<BizActivity> {}
/// test load py_sql from file
#[async_std::test]
pub async fn test_py_select_file() {
fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
//use static ref
let rb = Rbatis::new();
rb.link("mysql://root:123456@localhost:3306/test")
.await
.unwrap();
let mut result = py_select_file(&rb, &PageRequest::new(1, 10), "test")
.await
.unwrap();
println!("{:?}", result);
result = py_select_file_static(&rb, &PageRequest::new(1, 10), "test")
.await
.unwrap();
println!("{:?}", result);
}
Published by zhuxiujia over 3 years ago
v1.8.72
is_debug_mode()
method,Used to check if DEBUG is enabledfetch_count_by_wrapper(context_id: &str, w: &Wrapper)
method#[cfg(test)]
mod test {
use rbatis::rbatis::Rbatis;
use rbatis::plugin::logic_delete::RbatisLogicDeletePlugin;
use crate::BizActivity;
use rbatis::crud::CRUD;
use chrono::NaiveDateTime;
use rbatis::core::value::DateTimeNow;
#[async_std::test]
async fn plugin_exclude(){
fast_log::init_log("requests.log", 1000, log::Level::Info, None, true);
let mut rb = Rbatis::new();
let mut plugin=RbatisLogicDeletePlugin::new("delete_flag");
plugin.excludes.push("disable_del:".to_string());
plugin.excludes.push("tx:disable_del:".to_string());
rb.set_logic_plugin(Some(plugin));
rb.link("mysql://root:123456@localhost:3306/test")
.await
.unwrap();
let id="12312".to_string();
//logic delete sql: "UPDATE biz_activity SET delete_flag = 1 WHERE id = ?"
rb.remove_by_id::<BizActivity>("", &id).await;
//delete sql "DELETE FROM biz_activity WHERE id = ?"
rb.remove_by_id::<BizActivity>("disable_del:", &id).await;
}
Published by zhuxiujia over 3 years ago
v1.8.72
Published by zhuxiujia over 3 years ago
v1.8.71
page
to page_no
, size
to page_size
,current
to page_no
use async_std::*
fetch_prepare_wrapper
and exec_prepare_wrapper
method