From c37d93bcb9786c8fa7377980ea2afb9e1b51fb1b Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Tue, 17 Jan 2023 10:41:34 +0000 Subject: [PATCH] Ensure edge records are output as `RELATE` statements in SQL export Closes #1496 --- lib/src/doc/edges.rs | 3 +++ lib/src/doc/purge.rs | 5 +++-- lib/src/kvs/tx.rs | 24 +++++++++++++++++++++--- lib/src/sql/paths.rs | 2 ++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/src/doc/edges.rs b/lib/src/doc/edges.rs index f07dfe5d..4e5d21c8 100644 --- a/lib/src/doc/edges.rs +++ b/lib/src/doc/edges.rs @@ -5,8 +5,10 @@ use crate::dbs::Transaction; use crate::dbs::Workable; use crate::doc::Document; use crate::err::Error; +use crate::sql::paths::EDGE; use crate::sql::paths::IN; use crate::sql::paths::OUT; +use crate::sql::value::Value; use crate::sql::Dir; impl<'a> Document<'a> { @@ -44,6 +46,7 @@ impl<'a> Document<'a> { let key = crate::key::graph::new(opt.ns(), opt.db(), &r.tb, &r.id, i, rid); run.set(key, vec![]).await?; // Store the edges on the record + self.current.to_mut().set(ctx, opt, txn, &*EDGE, Value::True).await?; self.current.to_mut().set(ctx, opt, txn, &*IN, l.clone().into()).await?; self.current.to_mut().set(ctx, opt, txn, &*OUT, r.clone().into()).await?; } diff --git a/lib/src/doc/purge.rs b/lib/src/doc/purge.rs index 6a6dab0c..574a73fd 100644 --- a/lib/src/doc/purge.rs +++ b/lib/src/doc/purge.rs @@ -6,6 +6,7 @@ use crate::doc::Document; use crate::err::Error; use crate::sql::dir::Dir; use crate::sql::edges::Edges; +use crate::sql::paths::EDGE; use crate::sql::paths::IN; use crate::sql::paths::OUT; use crate::sql::statements::DeleteStatement; @@ -38,8 +39,8 @@ impl<'a> Document<'a> { let key = crate::key::thing::new(opt.ns(), opt.db(), &rid.tb, &rid.id); run.del(key).await?; // Purge the record edges - match (self.initial.pick(&*IN), self.initial.pick(&*OUT)) { - (Value::Thing(ref l), Value::Thing(ref r)) => { + match (self.initial.pick(&*EDGE), self.initial.pick(&*IN), self.initial.pick(&*OUT)) { + (Value::True, Value::Thing(ref l), Value::Thing(ref r)) => { // Get temporary edge references let (ref o, ref i) = (Dir::Out, Dir::In); // Purge the left pointer edge diff --git a/lib/src/kvs/tx.rs b/lib/src/kvs/tx.rs index 6841fc4e..4b62f385 100644 --- a/lib/src/kvs/tx.rs +++ b/lib/src/kvs/tx.rs @@ -7,7 +7,11 @@ use crate::key::thing; use crate::kvs::cache::Cache; use crate::kvs::cache::Entry; use crate::sql; +use crate::sql::paths::EDGE; +use crate::sql::paths::IN; +use crate::sql::paths::OUT; use crate::sql::thing::Thing; +use crate::sql::Value; use channel::Sender; use sql::permission::Permissions; use sql::statements::DefineDatabaseStatement; @@ -1461,12 +1465,26 @@ impl Transaction { if n == i + 1 { nxt = Some(k.clone()); } - // Parse the key-value + // Parse the key and the value let k: crate::key::thing::Thing = (&k).into(); let v: crate::sql::value::Value = (&v).into(); let t = Thing::from((k.tb, k.id)); - // Write record - chn.send(bytes!(format!("UPDATE {} CONTENT {};", t, v))).await?; + // Check if this is a graph edge + match (v.pick(&*EDGE), v.pick(&*IN), v.pick(&*OUT)) { + // This is a graph edge record + (Value::True, Value::Thing(l), Value::Thing(r)) => { + let sql = format!( + "RELATE {} -> {} -> {} CONTENT {};", + l, t, r, v + ); + chn.send(bytes!(sql)).await?; + } + // This is a normal record + _ => { + let sql = format!("UPDATE {} CONTENT {};", t, v); + chn.send(bytes!(sql)).await?; + } + } } continue; } diff --git a/lib/src/sql/paths.rs b/lib/src/sql/paths.rs index 6c44b75e..eabbf656 100644 --- a/lib/src/sql/paths.rs +++ b/lib/src/sql/paths.rs @@ -22,3 +22,5 @@ pub static IN: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("in")]); pub static OUT: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("out")]); pub static META: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("__")]); + +pub static EDGE: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("__")]);