1 /// Provides a wrapper around a `Relationship`. 2 module memgraph.relationship; 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 /// Consists of a unique identifier (within the scope of its origin graph), 9 /// identifiers for the start and end nodes of that relationship, a type and a 10 /// map of properties. A relationship owns its type string and property map. 11 struct Relationship { 12 /// Create a copy of `other` relationship. 13 this(inout ref Relationship other) { 14 this(mg_relationship_copy(other.ptr)); 15 } 16 17 /// Create a relationship from a Value. 18 this(inout ref Value value) { 19 assert(value.type == Type.Relationship); 20 this(mg_relationship_copy(mg_value_relationship(value.ptr))); 21 } 22 23 /// Return a printable string representation of this relationship. 24 const (string) toString() const { 25 return type(); 26 } 27 28 /// Compares this relationship with `other`. 29 /// Return: true if same, false otherwise. 30 bool opEquals(const ref Relationship other) const { 31 return Detail.areRelationshipsEqual(ptr_, other.ptr_); 32 } 33 34 /// Returns the relationship id. 35 const (long) id() const { 36 return mg_relationship_id(ptr_); 37 } 38 39 /// Returns the relationship start id. 40 const (long) startId() const { 41 return mg_relationship_start_id(ptr_); 42 } 43 44 /// Returns the relationship end id. 45 const (long) endId() const { 46 return mg_relationship_end_id(ptr_); 47 } 48 49 /// Returns the relationship type. 50 const (string) type() const { 51 return Detail.convertString(mg_relationship_type(ptr_)); 52 } 53 54 /// Returns the relationship properties. 55 const (Map) properties() const { 56 return Map(mg_relationship_properties(ptr_)); 57 } 58 59 this(this) { 60 if (ptr_) 61 ptr_ = mg_relationship_copy(ptr_); 62 } 63 64 ~this() { 65 if (ptr_) 66 mg_relationship_destroy(ptr_); 67 } 68 69 package: 70 /// Create a Relationship using the given `mg_relationship`. 71 this(mg_relationship *ptr) { 72 assert(ptr != null); 73 ptr_ = ptr; 74 } 75 76 /// Create a Relationship from a copy of the given `mg_relationship`. 77 this(const mg_relationship *const_ptr) { 78 assert(const_ptr != null); 79 this(mg_relationship_copy(const_ptr)); 80 } 81 82 const (mg_relationship *) ptr() const { return ptr_; } 83 84 private: 85 mg_relationship *ptr_; 86 } 87 88 unittest { 89 import testutils : connectContainer, createTestData, deleteTestData; 90 import memgraph : Client, Type, Value, Node, Relationship; 91 import std.conv : to; 92 93 auto client = connectContainer(); 94 assert(client); 95 96 deleteTestData(client); 97 98 createTestData(client); 99 100 auto res = client.execute( 101 "MATCH (a:Person)-[r:IS_MANAGER]->(b:Person) " ~ 102 "RETURN a, r, b;"); 103 assert(res, client.error); 104 foreach (c; res) { 105 assert(c[0].type == Type.Node); 106 assert(c[1].type == Type.Relationship); 107 assert(c[2].type == Type.Node); 108 auto a = to!Node(c[0]); 109 auto r = to!Relationship(c[1]); 110 auto b = to!Node(c[2]); 111 assert(to!string(a) == to!string(c[0])); 112 assert(to!string(r) == to!string(c[1])); 113 assert(to!string(b) == to!string(c[2])); 114 115 const r2 = r; 116 assert(r2 == r); 117 118 const r3 = Relationship(r); 119 assert(r3 == r); 120 121 const r4 = Relationship(r.ptr); 122 assert(r4 == r); 123 124 assert(r.id == r2.id); 125 assert(r.startId == r2.startId); 126 assert(r.endId == r2.endId); 127 assert(r.properties == r2.properties); 128 129 const v = Value(r); 130 assert(v == r); 131 assert(r == v); 132 assert(v == c[1]); 133 134 const r5 = Relationship(r3); 135 assert(r5 == r3); 136 } 137 assert(to!string(res.columns) == `["a", "r", "b"]`); 138 }