Skip to main content

surreal_sync_core/
relation_change.rs

1//! Relation change type for incremental sync of graph edges.
2//!
3//! Provides [`RelationChange`] which represents a create, update, or
4//! delete operation on a SurrealDB relation (graph edge).
5
6use crate::values::{ChangeOp, Relation};
7use serde::{Deserialize, Serialize};
8
9/// A change event for a graph relation (edge).
10///
11/// Used when a PostgreSQL join/relation table row is inserted, updated, or
12/// deleted and needs to be synced as a SurrealDB `RELATE` or `DELETE` operation.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct RelationChange {
15    /// The operation type (Create/Update/Delete)
16    pub operation: ChangeOp,
17    /// The relation data (contains relation_type, id, input, output, data)
18    pub relation: Relation,
19}
20
21impl RelationChange {
22    /// Create a new relation change.
23    pub fn new(operation: ChangeOp, relation: Relation) -> Self {
24        Self {
25            operation,
26            relation,
27        }
28    }
29
30    /// Create a CREATE relation change.
31    pub fn create(relation: Relation) -> Self {
32        Self::new(ChangeOp::Create, relation)
33    }
34
35    /// Create an UPDATE relation change.
36    pub fn update(relation: Relation) -> Self {
37        Self::new(ChangeOp::Update, relation)
38    }
39
40    /// Create a DELETE relation change.
41    pub fn delete(relation: Relation) -> Self {
42        Self::new(ChangeOp::Delete, relation)
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49    use crate::values::{ThingRef, Value};
50    use std::collections::HashMap;
51
52    #[test]
53    fn test_create_relation_change() {
54        let rel = Relation::new(
55            "book_tags",
56            Value::Int64(1),
57            ThingRef::new("books", Value::Int64(10)),
58            ThingRef::new("tags", Value::Int64(20)),
59            HashMap::new(),
60        );
61        let change = RelationChange::create(rel);
62        assert_eq!(change.operation, ChangeOp::Create);
63        assert_eq!(change.relation.relation_type, "book_tags");
64    }
65
66    #[test]
67    fn test_delete_relation_change() {
68        let rel = Relation::new(
69            "book_tags",
70            Value::Int64(1),
71            ThingRef::new("books", Value::Int64(10)),
72            ThingRef::new("tags", Value::Int64(20)),
73            HashMap::new(),
74        );
75        let change = RelationChange::delete(rel);
76        assert_eq!(change.operation, ChangeOp::Delete);
77    }
78}