use ormer::{AfterInsert, AfterUpdate, BeforeInsert, BeforeUpdate, Model};
#[cfg(feature = "sqlite")]
use ormer::{Database, DbType};
#[cfg(feature = "sqlite")]
use std::sync::atomic::{AtomicUsize, Ordering};
#[cfg(feature = "sqlite")]
static INSERT_COUNT: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "sqlite")]
static UPDATE_COUNT: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "sqlite")]
#[derive(Debug, Model)]
#[table = "hook_demo_users"]
struct HookDemoUser {
#[primary(auto)]
id: i32,
name: String,
email: String,
}
#[cfg(feature = "sqlite")]
#[async_trait::async_trait]
impl BeforeInsert for HookDemoUser {
async fn before_insert(&mut self) {
INSERT_COUNT.fetch_add(1, Ordering::SeqCst);
println!("BeforeInsert: 准备插入用户 {}", self.name);
}
}
#[cfg(feature = "sqlite")]
#[async_trait::async_trait]
impl AfterInsert for HookDemoUser {
async fn after_insert(&self) {
println!(
"AfterInsert: 用户 {} 已成功插入 (ID: {})",
self.name, self.id
);
}
}
#[cfg(feature = "sqlite")]
#[async_trait::async_trait]
impl BeforeUpdate for HookDemoUser {
async fn before_update(&mut self) {
UPDATE_COUNT.fetch_add(1, Ordering::SeqCst);
println!("BeforeUpdate: 准备更新用户 {}", self.name);
}
}
#[cfg(feature = "sqlite")]
#[async_trait::async_trait]
impl AfterUpdate for HookDemoUser {
async fn after_update(&self) {
println!("AfterUpdate: 用户 {} 已成功更新", self.name);
}
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_hooks_demo() {
#[cfg(feature = "sqlite")]
{
let db = Database::connect(DbType::Sqlite, ":memory:").await.unwrap();
db.create_table::<HookDemoUser>().execute().await.unwrap();
let user = HookDemoUser {
id: 0,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
};
let mut user = user;
user.before_insert().await;
let _ = db.insert(&user).execute().await.unwrap();
user.after_insert().await;
assert_eq!(INSERT_COUNT.load(Ordering::SeqCst), 1);
user.name = "Alice Updated".to_string();
user.before_update().await;
user.after_update().await;
assert_eq!(UPDATE_COUNT.load(Ordering::SeqCst), 1);
}
}