mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-03 02:51:04 +02:00
Merge pull request #4 from ModernRelay/claude/omnigraph-multi-statement-mutations-DxWSA
Support multi-statement mutations (insert + edge in one query)
This commit is contained in:
commit
af9a44e879
9 changed files with 240 additions and 64 deletions
|
|
@ -3335,24 +3335,30 @@ impl Omnigraph {
|
|||
|
||||
let ir = lower_mutation_query(&query_decl)?;
|
||||
|
||||
match &ir.op {
|
||||
MutationOpIR::Insert {
|
||||
type_name,
|
||||
assignments,
|
||||
} => self.execute_insert(type_name, assignments, params).await,
|
||||
MutationOpIR::Update {
|
||||
type_name,
|
||||
assignments,
|
||||
predicate,
|
||||
} => {
|
||||
self.execute_update(type_name, assignments, predicate, params)
|
||||
.await
|
||||
}
|
||||
MutationOpIR::Delete {
|
||||
type_name,
|
||||
predicate,
|
||||
} => self.execute_delete(type_name, predicate, params).await,
|
||||
let mut total = MutationResult::default();
|
||||
for op in &ir.ops {
|
||||
let result = match op {
|
||||
MutationOpIR::Insert {
|
||||
type_name,
|
||||
assignments,
|
||||
} => self.execute_insert(type_name, assignments, params).await?,
|
||||
MutationOpIR::Update {
|
||||
type_name,
|
||||
assignments,
|
||||
predicate,
|
||||
} => {
|
||||
self.execute_update(type_name, assignments, predicate, params)
|
||||
.await?
|
||||
}
|
||||
MutationOpIR::Delete {
|
||||
type_name,
|
||||
predicate,
|
||||
} => self.execute_delete(type_name, predicate, params).await?,
|
||||
};
|
||||
total.affected_nodes += result.affected_nodes;
|
||||
total.affected_edges += result.affected_edges;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
pub async fn branch_merge(&mut self, source: &str, target: &str) -> Result<MergeOutcome> {
|
||||
|
|
|
|||
|
|
@ -644,6 +644,43 @@ async fn mutation_insert_edge() {
|
|||
assert_eq!(names.value(0), "Alice");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn mutation_multi_insert_node_and_edge() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let mut db = init_and_load(&dir).await;
|
||||
|
||||
// In one atomic mutation: insert Eve + edge Eve→Alice
|
||||
let result = mutate_main(
|
||||
&mut db,
|
||||
MUTATION_QUERIES,
|
||||
"insert_person_and_friend",
|
||||
&mixed_params(&[("$name", "Eve"), ("$friend", "Alice")], &[("$age", 22)]),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result.affected_nodes, 1);
|
||||
assert_eq!(result.affected_edges, 1);
|
||||
|
||||
// Verify traversal: Eve → Alice
|
||||
let qr = query_main(
|
||||
&mut db,
|
||||
TEST_QUERIES,
|
||||
"friends_of",
|
||||
¶ms(&[("$name", "Eve")]),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(qr.num_rows(), 1);
|
||||
let batch = qr.concat_batches().unwrap();
|
||||
let names = batch
|
||||
.column(0)
|
||||
.as_any()
|
||||
.downcast_ref::<StringArray>()
|
||||
.unwrap();
|
||||
assert_eq!(names.value(0), "Alice");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn mutation_update_node() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ query remove_person($name: String) {
|
|||
query remove_friendship($from: String) {
|
||||
delete Knows where from = $from
|
||||
}
|
||||
|
||||
query insert_person_and_friend($name: String, $age: I32, $friend: String) {
|
||||
insert Person { name: $name, age: $age }
|
||||
insert Knows { from: $name, to: $friend }
|
||||
}
|
||||
"#;
|
||||
|
||||
/// Init a repo and load the standard test data.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue