1 /// Provides a wrapper around a `UnboundRelationship`. 2 module memgraph.unboundrelationship; 3 4 import memgraph.mgclient, memgraph.detail, memgraph.map, memgraph.value, memgraph.enums; 5 6 /// Represents a relationship from a labeled property graph. 7 /// 8 /// Like `mg_relationship`, but without identifiers for start and end nodes. 9 /// Mainly used as a supporting type for `mg_path`. An unbound relationship 10 /// owns its type string and property map. 11 struct UnboundRelationship { 12 /// Create a copy of `other` unbound relationship. 13 this(inout ref UnboundRelationship other) { 14 this(mg_unbound_relationship_copy(other.ptr)); 15 } 16 17 /// Create a unbound relationship from a Value. 18 this(inout ref Value value) { 19 assert(value.type == Type.UnboundRelationship); 20 this(mg_unbound_relationship_copy(mg_value_unbound_relationship(value.ptr))); 21 } 22 23 /// Return a printable string representation of this unbound relationship. 24 const (string) toString() const { 25 return type; 26 } 27 28 /// Compares this unbound relationship with `other`. 29 /// Return: true if same, false otherwise. 30 bool opEquals(const ref UnboundRelationship other) const { 31 return Detail.areUnboundRelationshipsEqual(ptr, other.ptr); 32 } 33 34 /// Returns the unbound relationship id. 35 const (long) id() const { 36 assert(ptr != null); 37 return mg_unbound_relationship_id(ptr); 38 } 39 40 /// Returns the unbound relationship type. 41 const (string) type() const { 42 assert(ptr != null); 43 return Detail.convertString(mg_unbound_relationship_type(ptr)); 44 } 45 46 /// Returns the unbound relationship properties. 47 const (Map) properties() const { 48 assert(ptr != null); 49 return Map(mg_unbound_relationship_properties(ptr)); 50 } 51 52 this(this) { 53 if (ptr_) 54 ptr_ = mg_unbound_relationship_copy(ptr_); 55 } 56 57 ~this() { 58 if (ptr_) 59 mg_unbound_relationship_destroy(ptr_); 60 } 61 62 package: 63 /// Create a Unbound Relationship using the given `mg_unbound_relationship`. 64 this(mg_unbound_relationship *ptr) { 65 assert(ptr != null); 66 ptr_ = ptr; 67 } 68 69 /// Create a Unbound Relationship from a copy of the given `mg_unbound_relationship`. 70 this(const mg_unbound_relationship *ptr) { 71 assert(ptr != null); 72 this(mg_unbound_relationship_copy(ptr)); 73 } 74 75 const (mg_unbound_relationship *) ptr() const { return ptr_; } 76 77 private: 78 mg_unbound_relationship *ptr_; 79 } 80 81 unittest { 82 import testutils : connectContainer, createTestData, deleteTestData; 83 import memgraph : Client, Type, Value, Node, Relationship; 84 import std.conv : to; 85 86 auto client = connectContainer(); 87 assert(client); 88 89 deleteTestData(client); 90 91 createTestData(client); 92 93 // TODO: fix unit test, ie. use unbound relationship, e.g. via Path 94 auto res = client.execute( 95 "MATCH (a:Person)-[r:IS_MANAGER]-(b:Person) " ~ 96 "RETURN a, r, b;"); 97 assert(res, client.error); 98 foreach (c; res) { 99 assert(c[0].type == Type.Node); 100 assert(c[1].type == Type.Relationship); 101 assert(c[2].type == Type.Node); 102 auto a = to!Node(c[0]); 103 auto r = to!Relationship(c[1]); 104 auto b = to!Node(c[2]); 105 assert(to!string(a) == to!string(c[0])); 106 assert(to!string(r) == to!string(c[1])); 107 assert(to!string(b) == to!string(c[2])); 108 109 const r2 = r; 110 assert(r2 == r); 111 112 const r3 = Relationship(r); 113 assert(r3 == r); 114 115 const r4 = Relationship(r.ptr); 116 assert(r4 == r); 117 118 assert(r.id == r2.id); 119 assert(r.startId == r2.startId); 120 assert(r.endId == r2.endId); 121 assert(r.properties == r2.properties); 122 123 auto v = Value(r); 124 assert(v == r); 125 assert(r == v); 126 assert(to!string(v) == to!string(r)); 127 } 128 assert(to!string(res.columns) == `["a", "r", "b"]`); 129 }