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 shallow copy of `other` relationship. 13 @nogc this(inout ref Relationship other) { 14 this(other.ptr); 15 } 16 17 /// Create a relationship from a Value. 18 @nogc this(inout ref Value value) { 19 assert(value.type == Type.Relationship); 20 this(mg_value_relationship(value.ptr)); 21 } 22 23 /// Return a printable string representation of this relationship. 24 string toString() const { 25 import std.array : appender; 26 import std.conv : to; 27 auto str = appender!string; 28 str.put("("); 29 str.put(to!string(startId)); 30 str.put(")-["); 31 str.put(type()); 32 str.put("]-("); 33 str.put(to!string(endId)); 34 str.put(")"); 35 return str.data; 36 } 37 38 /// Compares this relationship with `other`. 39 /// Return: true if same, false otherwise. 40 @nogc auto opEquals(const ref Relationship other) const { 41 return Detail.areRelationshipsEqual(ptr_, other.ptr_); 42 } 43 44 /// Return the hash code for this relationship. 45 size_t toHash() const nothrow @safe { 46 return cast(ulong)ptr_; 47 } 48 49 /// Returns the relationship id. 50 @nogc auto id() const { 51 return mg_relationship_id(ptr_); 52 } 53 54 /// Returns the relationship start id. 55 @nogc auto startId() const { 56 return mg_relationship_start_id(ptr_); 57 } 58 59 /// Returns the relationship end id. 60 @nogc auto endId() const { 61 return mg_relationship_end_id(ptr_); 62 } 63 64 /// Returns the relationship type. 65 @nogc auto type() const { 66 return Detail.convertString(mg_relationship_type(ptr_)); 67 } 68 69 /// Returns the relationship properties. 70 @nogc auto properties() const { 71 return Map(mg_relationship_properties(ptr_)); 72 } 73 74 package: 75 /// Create a Relationship using the given `mg_relationship` pointer. 76 @nogc this(const mg_relationship *ptr) { 77 assert(ptr != null); 78 ptr_ = ptr; 79 } 80 81 /// Return pointer to internal mg_relationship. 82 @nogc auto ptr() inout { return ptr_; } 83 84 private: 85 const 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 r5 = Relationship(r3); 130 assert(r5 == r3); 131 132 assert(cast(ulong)r.ptr == r.toHash); 133 } 134 assert(to!string(res.columns) == `["a", "r", "b"]`); 135 }