diff --git a/core/src/doc/event.rs b/core/src/doc/event.rs index f3e63fe4..f76bece8 100644 --- a/core/src/doc/event.rs +++ b/core/src/doc/event.rs @@ -34,18 +34,23 @@ impl<'a> Document<'a> { } else { Value::from("UPDATE") }; + // Depending on type of event, how do we populate the document + let doc = match stm.is_delete() { + true => &self.initial, + false => &self.current, + }; // Configure the context let mut ctx = Context::new(ctx); ctx.add_value("event", met); - ctx.add_value("value", self.current.doc.deref()); + ctx.add_value("value", doc.doc.deref()); ctx.add_value("after", self.current.doc.deref()); ctx.add_value("before", self.initial.doc.deref()); // Process conditional clause - let val = ev.when.compute(&ctx, opt, txn, Some(&self.current)).await?; + let val = ev.when.compute(&ctx, opt, txn, Some(doc)).await?; // Execute event if value is truthy if val.is_truthy() { for v in ev.then.iter() { - v.compute(&ctx, opt, txn, Some(&self.current)).await?; + v.compute(&ctx, opt, txn, Some(doc)).await?; } } } diff --git a/lib/tests/define.rs b/lib/tests/define.rs index 608defb3..0c9ecf59 100644 --- a/lib/tests/define.rs +++ b/lib/tests/define.rs @@ -434,6 +434,64 @@ async fn define_statement_event_when_event() -> Result<(), Error> { Ok(()) } +#[tokio::test] +async fn define_statement_event_check_doc_always_populated() -> Result<(), Error> { + let sql = " + DEFINE EVENT test ON test WHEN true THEN { + LET $doc = $this; + CREATE type::thing('log', $event) SET this = $doc, value = $value, before = $before, after = $after; + }; + CREATE test:1 SET num = 1; + UPDATE test:1 set num = 2; + DELETE test:1; + SELECT * FROM log; + "; + let dbs = new_ds().await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 5); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + r#"[ + { + after: { id: test:1, num: 1 }, + id: log:CREATE, + this: { id: test:1, num: 1 }, + value: { id: test:1, num: 1 } + }, + { + before: { id: test:1, num: 2 }, + id: log:DELETE, + this: { id: test:1, num: 2 }, + value: { id: test:1, num: 2 } + }, + { + after: { id: test:1, num: 2 }, + before: { id: test:1, num: 1 }, + id: log:UPDATE, + this: { id: test:1, num: 2 }, + value: { id: test:1, num: 2 } + } + ]"#, + ); + assert_eq!(tmp, val); + // + Ok(()) +} + #[tokio::test] async fn define_statement_event_when_logic() -> Result<(), Error> { let sql = "