Feat: Include record ID in live queries notifications. (#2950)
Co-authored-by: Tobie Morgan Hitchcock <tobie@surrealdb.com>
This commit is contained in:
parent
218fa83c10
commit
be24734048
5 changed files with 21 additions and 10 deletions
|
@ -33,6 +33,8 @@ pub struct Notification {
|
|||
pub id: Uuid,
|
||||
/// The CREATE / UPDATE / DELETE action which caused this notification
|
||||
pub action: Action,
|
||||
/// The id of the document to which this notification has been made
|
||||
pub record: Value,
|
||||
/// The resulting notification content, usually the altered record content
|
||||
pub result: Value,
|
||||
}
|
||||
|
@ -42,6 +44,7 @@ impl Display for Notification {
|
|||
let obj: Object = map! {
|
||||
"id".to_string() => self.id.to_string().into(),
|
||||
"action".to_string() => self.action.to_string().into(),
|
||||
"record".to_string() => self.record.clone(),
|
||||
"result".to_string() => self.result.clone(),
|
||||
}
|
||||
.into();
|
||||
|
@ -51,10 +54,11 @@ impl Display for Notification {
|
|||
|
||||
impl Notification {
|
||||
/// Construct a new notification
|
||||
pub const fn new(id: Uuid, action: Action, result: Value) -> Self {
|
||||
pub const fn new(id: Uuid, action: Action, record: Value, result: Value) -> Self {
|
||||
Self {
|
||||
id,
|
||||
action,
|
||||
record,
|
||||
result,
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +67,6 @@ impl Notification {
|
|||
#[cfg(test)]
|
||||
impl FuzzyEq for Notification {
|
||||
fn fuzzy_eq(&self, other: &Self) -> bool {
|
||||
self.action == other.action && self.result == other.result
|
||||
self.action == other.action && self.record == other.record && self.result == other.result
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ impl Document {
|
|||
} else {
|
||||
Value::from("UPDATE")
|
||||
};
|
||||
// Get the record if of this docunent
|
||||
let rid = self.id.as_ref().unwrap();
|
||||
// Get the current and initial docs
|
||||
let current = self.current.doc.as_arc();
|
||||
let initial = self.initial.doc.as_arc();
|
||||
// Check if this is a delete statement
|
||||
|
@ -119,6 +122,7 @@ impl Document {
|
|||
chn.send(Notification {
|
||||
id: lv.id,
|
||||
action: Action::Delete,
|
||||
record: Value::Thing(rid.as_ref().clone()),
|
||||
result: {
|
||||
// Ensure futures are run
|
||||
let lqopt: &Options = &lqopt.new_with_futures(true);
|
||||
|
@ -141,6 +145,7 @@ impl Document {
|
|||
chn.send(Notification {
|
||||
id: lv.id,
|
||||
action: Action::Create,
|
||||
record: Value::Thing(rid.as_ref().clone()),
|
||||
result: self.pluck(stk, &lqctx, &lqopt, &lq).await?,
|
||||
})
|
||||
.await?;
|
||||
|
@ -153,6 +158,7 @@ impl Document {
|
|||
chn.send(Notification {
|
||||
id: lv.id,
|
||||
action: Action::Update,
|
||||
record: Value::Thing(rid.as_ref().clone()),
|
||||
result: self.pluck(stk, &lqctx, &lqopt, &lq).await?,
|
||||
})
|
||||
.await?;
|
||||
|
|
|
@ -162,6 +162,7 @@ mod tests {
|
|||
use crate::kvs::Datastore;
|
||||
use crate::kvs::LockType::Optimistic;
|
||||
use crate::kvs::TransactionType::Write;
|
||||
use crate::sql::Thing;
|
||||
use crate::sql::Value;
|
||||
use crate::syn::Parse;
|
||||
|
||||
|
@ -202,15 +203,14 @@ mod tests {
|
|||
tx.cancel().await.unwrap();
|
||||
|
||||
// Initiate a Create record
|
||||
let create_statement = format!("CREATE {}:test_true SET condition = true", tb);
|
||||
let create_statement = format!("CREATE {tb}:test_true SET condition = true");
|
||||
let create_response = &mut dbs.execute(&create_statement, &ses, None).await.unwrap();
|
||||
assert_eq!(create_response.len(), 1);
|
||||
let expected_record = Value::parse(&format!(
|
||||
"[{{
|
||||
id: {}:test_true,
|
||||
id: {tb}:test_true,
|
||||
condition: true,
|
||||
}}]",
|
||||
tb
|
||||
}}]"
|
||||
));
|
||||
|
||||
let tmp = create_response.remove(0).result.unwrap();
|
||||
|
@ -231,12 +231,12 @@ mod tests {
|
|||
Notification::new(
|
||||
live_id,
|
||||
Action::Create,
|
||||
Value::Thing(Thing::from((tb, "test_true"))),
|
||||
Value::parse(&format!(
|
||||
"{{
|
||||
id: {}:test_true,
|
||||
id: {tb}:test_true,
|
||||
condition: true,
|
||||
}}",
|
||||
tb
|
||||
}}"
|
||||
),),
|
||||
)
|
||||
);
|
||||
|
|
|
@ -416,6 +416,7 @@ async fn delete_filtered_live_notification() -> Result<(), Error> {
|
|||
Notification::new(
|
||||
live_id,
|
||||
Action::Delete,
|
||||
Value::Thing(Thing::from(("person", "test_true"))),
|
||||
Value::parse(
|
||||
"{
|
||||
id: person:test_true,
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn is_notification(msg: &serde_json::Value) -> bool {
|
|||
.as_object()
|
||||
.unwrap()
|
||||
.keys()
|
||||
.all(|k| ["id", "action", "result"].contains(&k.as_str()))
|
||||
.all(|k| ["id", "action", "record", "result"].contains(&k.as_str()))
|
||||
}
|
||||
|
||||
/// Check if the given message is a notification from LQ and comes from the given LQ ID.
|
||||
|
|
Loading…
Reference in a new issue