用法
// 建立 DB
let db = Surreal::new::<Mem>(()).await?;
db.use_ns("test").use_db("test").await?;
let repo = SurrealEventRepository { db: db.clone() };
// 建立 reader cqrs,這次注入昨天寫好的Query
let reader_query = ReaderQuery { db: db.clone() };
let reader_service = ReaderService {};
let reader_store: PersistedEventStore<SurrealEventRepository, Reader>
= PersistedEventStore::new_event_store(repo.clone());
let reader_cqrs = CqrsFramework::new(
reader_store,
vec![Box::new(reader_query)],
reader_service);
執行以下建立讀者指令
let _ = reader_cqrs.execute("test-reader-1", ReaderCommand::CreateReader {
name: "John Smith".to_string(),
}).await;
let _ = reader_cqrs.execute("test-reader-2", ReaderCommand::CreateReader {
name: "Mary Ann".to_string(),
}).await;
查閱我們 CQRS 中 Query專用的資料表
let reader_dtos: Vec<ReaderDto> = repo.db
.query("SELECT * FROM readers ORDER BY id")
.await?
.take(0)?;
println!("======== Readers ========\n{:#?}", reader_dtos);
======== Readers ========
[
ReaderDto {
reader_id: "test-reader-1",
name: "John Smith",
books_borrowed: 0,
books_borrows: [],
next_due_date: None,
},
ReaderDto {
reader_id: "test-reader-2",
name: "Mary Ann",
books_borrowed: 0,
books_borrows: [],
next_due_date: None,
},
]
借閱指令
let _ = reader_cqrs.execute("test-reader-1", ReaderCommand::BorrowBook {
book_id: "test-book-1".to_string(),
borrowed_date: Utc::now(),
due_date: Utc::now().add(chrono::Duration::days(7)),
}).await;
Query資料表
======== Readers ========
[
ReaderDto {
reader_id: "test-reader-1",
name: "John Smith",
books_borrowed: 1,
books_borrows: [
ReaderBorrows {
book_id: "test-book-1",
book_name: "Rust 語言開發實戰",
borrowed_date: 2023-10-05T04:50:06.196949500Z,
due_date: 2023-10-12T04:50:06.196981600Z,
},
],
next_due_date: Some(
2023-10-12T04:50:06.196981600Z,
),
},
ReaderDto {
reader_id: "test-reader-2",
name: "Mary Ann",
books_borrowed: 0,
books_borrows: [],
next_due_date: None,
},
]
對比前一次使用InMemory Store是用HashMap,reader無法參照book的aggregate,這回使用surrealDB我們在Query的dispatch裡呼叫讀取book的 title,就可以帶出書名。在此查詢就不需要去JOIN 書籍的資料表。
歸還書籍的操作
let _ = reader_cqrs.execute("test-reader-1", ReaderCommand::ReturnBook {
book_id: "test-book-1".to_string(),
return_date: Utc::now().add(chrono::Duration::days(2)),
}).await;
結果
======== Readers ========
[
ReaderDto {
reader_id: "test-reader-1",
name: "John Smith",
books_borrowed: 0,
books_borrows: [],
next_due_date: None,
},
ReaderDto {
reader_id: "test-reader-2",
name: "Mary Ann",
books_borrowed: 0,
books_borrows: [],
next_due_date: None,
},
]
正確顯示當下狀態