域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。
  • 方案1️⃣AXUM.RS 域名 = 3000
  • 方案2️⃣方案1️⃣ + 本站所有专题原始 Markdown 文档 = 5000
  • 方案3️⃣方案2️⃣ + 本站原始数据库 = 5500
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名(方案1️⃣),或者该域名到期,本站将启用新的免费域名继续提供服务。
  2. 如果有人购买了 AXUM.RS 域名,且同时购买了内容和/或数据库(方案2️⃣/方案3️⃣),本站将关闭。届时我们或许会以另一种方式与你再相遇。

内容介绍

本专题将通过实现一个自动生成数据库 CRUD 的 Derive宏 来对过程宏 proc-macro 进行一步步的探讨。我们希望通过本专题的学习,能让你掌握 rust 过程宏的知识要点,并将其应用到实际开发中。

目标

#[derive(Db)]
#[db(table = "users", pk = "id")]
pub struct User {
    #[db(find)]
    pub id: String,
    
    #[db(find)]
    #[db(list_opt)]
    #[db(opt_like)]
    pub email: String,
    
    pub password: String,
    
    #[db(list_opt)]
    #[db(opt_like)]
    pub nickname: String,
    
    #[db(skip_update)]
    pub dateline: chrono::DateTime<chrono::Local>,
}

#[derive(Db)]
#[db(table = "messages", pk = "id")]
pub struct Message {
    #[db(find)]
    #[db(skip_insert)]
    pub id: i32,
    
    #[db(list_opt)]
    #[db(skip_update)]
    pub user_id: String,
    
    #[db(list_opt)]
    #[db(opt_like)]
    pub content: String,
    
    #[db(skip_update)]
    pub dateline: chrono::DateTime<chrono::Local>,
    
}

#[derive(Db)]
#[db(table = "v_user_messages", pk = "user_id, message_id", is_view)]
pub struct UserMessage {
    #[db(list_opt)]
    #[db(opt_like)]
    pub email: String,
    
    #[db(list_opt)]
    #[db(opt_like)]
    pub nickname: String,
    
    #[db(find_opt)]
    #[db(list_opt)]
    pub message_id: i32,
    
    #[db(find_opt)]
    #[db(list_opt)]
    pub user_id: String,
    
    #[db(list_opt)]
    #[db(opt_like)]
    pub content: String,
    
    pub dateline: chrono::DateTime<chrono::Local>,
}

User 为例,将自动为其生成以下方法:

/// 插入
User::insert<'a>(&self, e: impl sqlx::PgExecutor<'a>) -> sqlx::Result<String>;

/// 更新
User::update<'a>(&self, e: impl sqlx::PgExecutor<'a>) -> sqlx::Result<u64>;

/// 查找单条
User::find<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserFindFilter) -> sqlx::Result<Option<Self>>;

/// 列表
User::list_data<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserListFilter) -> sqlx::Result<Vec<Self>>;

/// 统计
User::list_count<'a>(e: impl sqlx::PgExecutor<'a>, f:&UserListFilter) -> sqlx::Result<i64>;

/// 分页
User::list(p: &sqlx::PgPool, f:&UserListFilter) -> sqlx::Result<UserPaginate<Self>>;

/// 删除
User::list_count<'a>(e: impl sqlx::PgExecutor<'a>, id:&String) -> sqlx::Result<u64>;
pub enum UserFindBy {
    Id(String),
    Email(String),
}

pub struct UserFindFilter {
    pub by: UserFindBy,
}

pub struct UserListFilter {
    pub page: u32,
    pub page_size: u32,
    pub email: Option<String>,
    pub nickname: Option<String>,
}

pub struct UserPaginate {
    pub page: u32,
    pub page_size: u32,
    pub total: u32,
    pub total_page: u32,
    pub data: Vec<User>,
}
要查看完整内容,请先登录