Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Releases: rbatis/rbatis

v4.7.2

11 Feb 06:29

Choose a tag to compare

what changes?

  • remove #[html_sql] for mod
  • add Page support for #[html_sql] for struct
    for example:
#[rbatis::html_sql("example/example.html")]
impl Activity {
    /// Paginated query - automatically detected by return type Page<Activity>
    /// Maps to <select id="select_by_page"> in HTML
    /// The macro automatically generates pagination logic using PageIntercept
    pub async fn select_by_page(
        rb: &dyn Executor,
        page_req: &dyn PageRequest,
        name: &str,
        dt: Option<DateTime>,
    ) -> rbatis::Result<rbatis::Page<Activity>> {
        impled!()
    }
}
<!-- Paginated query - automatically detected by return type Page<Activity> -->
    <select id="select_by_page">
        `select * from activity`
        <where>
            <if test="name != ''">
                ` and name like #{name}`
            </if>
            <if test="dt != null">
                ` and create_time < #{dt}`
            </if>
        </where>
        <!-- PageIntercept will add limit/offset automatically -->
    </select>

v4.7.1

06 Feb 07:24

Choose a tag to compare

what changes?

  • merge #609 for struct/mod html_sql mapping
    for example:
use rbatis::dark_std::defer;
use rbatis::executor::Executor;
use rbatis::rbdc::datetime::DateTime;
use rbatis::RBatis;

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Activity {
    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<DateTime>,
    pub version: Option<i64>,
    pub delete_flag: Option<i32>,
}

/// All methods read SQL from example/example.html
#[rbatis::html_sql("example/example.html")]
impl Activity {
    /// Maps to <select id="select_by_condition"> in HTML
    pub async fn select_by_condition(
        rb: &dyn Executor,
        name: &str,
        dt: &DateTime,
    ) -> rbatis::Result<Vec<Activity>> {
        impled!()
    }

    /// Maps to <select id="select_page_data"> in HTML
    pub async fn select_page_data(
        rb: &dyn Executor,
        name: &str,
        dt: &DateTime,
    ) -> rbatis::Result<Vec<Activity>> {
        impled!()
    }

    /// Maps to <update id="update_by_id"> in HTML
    pub async fn update_by_id(
        rb: &dyn Executor,
        arg: &Activity,
    ) -> rbatis::Result<rbatis::rbdc::db::ExecResult> {
        impled!()
    }
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "https://raw.githubusercontent.com/rbatis/rbatis/master/rbatis-codegen/mybatis-3-mapper.dtd">
<mapper>
    <select id="select_by_condition">
        `select * from activity`
        <where>
            <if test="name != ''">
                ` and name like #{name}`
            </if>
            <if test="dt >= '2009-12-12 00:00:00'">
                ` and create_time < #{dt}`
            </if>
            <choose>
                <when test="true">
                    ` and id != '-1'`
                </when>
                <otherwise>and id != -2</otherwise>
            </choose>
            ` and `
            <trim prefixOverrides=" and">
                ` and name != '' `
            </trim>
        </where>
    </select>

    <select id="select_page_data">
        `select * from activity `
        <where>
            <if test="name != ''">
                ` and name like #{name}`
            </if>
            <if test="dt >= '2009-12-12 00:00:00'">
                ` and create_time < #{dt}`
            </if>
            <choose>
                <when test="true">
                    ` and id != '-1'`
                </when>
                <otherwise>and id != -2</otherwise>
            </choose>
            ` and `
            <trim prefixOverrides=" and">
                ` and name != '' `
            </trim>
        </where>
    </select>
    <update id="update_by_id">
        ` update activity `
        <set collection="arg"></set>
        ` where id = #{id} `
    </update>
</mapper>

v4.7.0

20 Jan 16:27

Choose a tag to compare

what changes?

  • RBatis Engine All use dyn Trait for example:
pub struct RBatis {
    // the connection pool
    pub pool: Arc<OnceLock<Box<dyn Pool>>>,
    // intercept vec(default the intercepts[0] is a log interceptor)
    pub intercepts: Arc<SyncVec<Arc<dyn Intercept>>>,
    //rb task id gen
    pub task_id_generator: Arc<dyn IdGenerator>,
}
  • performance
| Optimization Item               | Save Time |
|---------------------------------|-----------|
| Avoid `vec![]` allocation       | ~50 ns    |
| Avoid creating RBAtisKonExecutor| ~100 ns   |
| Avoid `task_id` generation      | ~11 ns    |
| Avoid `Arc` cloning             | ~20 ns    |
| Reduce function call hierarchy  | ~50 ns    |
| Empty string fast path          | ~30 ns    |
| **Total**                       | **~260 ns** |
  • intercept add Action
use rbatis::Error;
use rbatis::executor::Executor;
use rbatis::intercept::{Intercept, ResultType};
use rbdc::db::ExecResult;
use rbs::Value;
use rbatis::Action;

 #[derive(Debug)]
pub struct ReturningIdPlugin{}

#[rbatis::async_trait]
impl Intercept for ReturningIdPlugin {
    async fn before(
        &self,
       _task_id: i64,
       rb: &dyn Executor,
        sql: &mut String,
       args: &mut Vec<Value>,
        result: ResultType<&mut Result<ExecResult, Error>, &mut Result<Value, Error>>,
   ) -> Result<Action, Error> {
        Ok(Action::Next)
    }
}

v4.6.15

04 Jan 17:51

Choose a tag to compare

  • up rbdc version

v4.6.14

27 Dec 11:37

Choose a tag to compare

  • Simplify implementation for intercept

v4.6.13

03 Dec 03:31

Choose a tag to compare

what changes?

  • Support for temporarily replacing the interceptor list
    for example:
/// Mock intercept that just prints SQL
#[derive(Debug)]
pub struct MockIntercept;

#[async_trait]
impl Intercept for MockIntercept {
    async fn before(
        &self,
        task_id: i64,
        _rb: &dyn Executor,
        sql: &mut String,
        _args: &mut Vec<Value>,
        _result: ResultType<&mut Result<ExecResult, rbatis::Error>, &mut Result<Vec<Value>, rbatis::Error>>,
    ) -> Result<Option<bool>, rbatis::Error> {
        *sql = sql.replace("<my_table_name>", &format!("activity_{}",task_id % 2));
        println!("MockIntercept: SQL = {}", sql);
        Ok(Some(true))
    }
}

#[tokio::main]
pub async fn main() -> Result<(), rbatis::Error> {
    _ = fast_log::init(fast_log::Config::new().console());
    let rb = RBatis::new();
    rb.init(rbdc_sqlite::driver::SqliteDriver {}, "sqlite://target/sqlite.db")?;
    // create table
    _=rb.exec("CREATE TABLE activity_0 ( id INTEGER PRIMARY KEY);", vec![]).await;
    _=rb.exec("CREATE TABLE activity_1 ( id INTEGER PRIMARY KEY);", vec![]).await;
    
    let len = rb.intercepts.len();
    println!("len={}", len);
    
    // Create new intercept list and add our mock intercept
    let new_intercept = Arc::new(SyncVec::new());
    let intercept: Arc<dyn Intercept> = Arc::new(MockIntercept {});
    new_intercept.push(intercept);
    
    // Create connection and replace its intercepts
    let mut conn = rb.acquire().await?;
    conn.intercepts = new_intercept;
    println!("conn.intercepts.len={}", conn.intercepts.len());
    
    // Execute query to see the mock intercept in action
    let _ = conn.query("SELECT <my_table_name>", vec![]).await;
    let data = Activity::select_all(&conn).await?;
    println!("data={:?}", json!(data));
    Ok(())
}

/// table
#[derive(serde::Serialize, serde::Deserialize, Clone)]
pub struct Activity {
    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<DateTime>,
    pub version: Option<i64>,
    pub delete_flag: Option<i32>,
}

//crud!(Activity {},"activity");
crud!(Activity {},"<my_table_name>");

v4.6.12

12 Oct 14:22

Choose a tag to compare

what changes?

 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
struct MockTable {
        pub id: Option<String>,
        pub name: Option<String>,
        pub status: Option<i32>
}
crud!(MockTable{});
let r = MockTable::update_by_map(rb, &table, value!{"id":"1", "column": ["name", "status"]}).await;
  • impl crud! for select target columns
 #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
struct MockTable {
        pub id: Option<String>,
        pub name: Option<String>,
        pub status: Option<i32>
}
crud!(MockTable{});
let tables = MockTable::select_by_map(rb,value!{"id":"1", "column": ["id", "name"]}).await?; 

v4.6.9

11 Oct 17:47

Choose a tag to compare

  • this is an doc fix version
  • merge #586

v4.6.8

02 Jul 10:43

Choose a tag to compare

add page method:

/// create Vec<PageRequest> from (total: u64, page_size: u64)
    pub fn make_page_requests(total: u64, page_size: u64) -> Vec<PageRequest> {
        let mut result = vec![];
        let pages = PageRequest::new(1, page_size).set_total(total).pages();
        for idx in 0..pages {
            let current_page = PageRequest::new(idx + 1, page_size).set_total(total);
            result.push(current_page);
        }
        result
    }

v4.6.7

01 Jun 15:12

Choose a tag to compare

  • fix PageIntercept remove order by sql when run count sql