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 shallow copy of `other` unbound relationship. 13 @nogc this(inout ref UnboundRelationship other) { 14 this(other.ptr); 15 } 16 17 /// Create a unbound relationship from a Value. 18 @nogc this(inout ref Value value) { 19 assert(value.type == Type.UnboundRelationship); 20 this(mg_value_unbound_relationship(value.ptr)); 21 } 22 23 /// Return a printable string representation of this unbound 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(type()); 30 str.put("]"); 31 return str.data; 32 } 33 34 /// Compares this unbound relationship with `other`. 35 /// Return: true if same, false otherwise. 36 @nogc auto opEquals(const ref UnboundRelationship other) const { 37 return Detail.areUnboundRelationshipsEqual(ptr, other.ptr); 38 } 39 40 /// Return the hash code for this unbound relationship. 41 size_t toHash() const nothrow @safe { 42 return cast(ulong)ptr_; 43 } 44 45 /// Returns the unbound relationship id. 46 @nogc auto id() const { 47 return mg_unbound_relationship_id(ptr); 48 } 49 50 /// Returns the unbound relationship type. 51 @nogc auto type() const { 52 return Detail.convertString(mg_unbound_relationship_type(ptr)); 53 } 54 55 /// Returns the unbound relationship properties. 56 @nogc auto properties() const { 57 return Map(mg_unbound_relationship_properties(ptr)); 58 } 59 60 package: 61 /// Create a Unbound Relationship using the given `mg_unbound_relationship` pointer. 62 @nogc this(const mg_unbound_relationship *ptr) { 63 assert(ptr != null); 64 ptr_ = ptr; 65 } 66 67 @nogc auto ptr() inout { return ptr_; } 68 69 private: 70 const mg_unbound_relationship *ptr_; 71 } // struct UnboundRelationship 72 73 unittest { 74 import testutils : connectContainer, createTestData, deleteTestData; 75 import memgraph : Client, Type, Value, Node, UnboundRelationship, Path; 76 import std.conv : to; 77 78 auto client = connectContainer(); 79 assert(client); 80 81 deleteTestData(client); 82 83 createTestData(client); 84 85 auto res = client.execute( 86 "MATCH p = ()-[*3]->() " ~ 87 "RETURN p;"); 88 assert(res, client.error); 89 foreach (c; res) { 90 assert(c[0].type == Type.Path); 91 const path = to!Path(c[0]); 92 assert(to!string(path) == to!string(c[0])); 93 94 immutable auto expectedNames = [ "John", "Peter", "Valery", "Oløf" ]; 95 foreach (i; 0..path.length+1) { 96 const n = path.getNodeAt(to!uint(i)); 97 const p = n.properties; 98 assert(to!string(p["name"]) == expectedNames[i], to!string(p["name"])); 99 if (i < path.length) { 100 auto r = path.getRelationshipAt(to!uint(i)); 101 assert(to!string(r) == "[" ~ r.type ~ "]"); 102 } 103 } 104 } 105 assert(to!string(res.columns) == `["p"]`); 106 } 107 108 unittest { 109 auto r = UnboundRelationship(mg_unbound_relationship_make(1, mg_string_make("rel"), mg_map_make_empty(0))); 110 auto v = Value(mg_value_make_unbound_relationship(mg_unbound_relationship_copy(r.ptr))); 111 const r2 = UnboundRelationship(v); 112 assert(r == r2); 113 assert(r == v); 114 115 import std.conv : to; 116 assert(to!string(v) == "[rel]", to!string(v)); 117 118 assert(cast(ulong)r.ptr == r.toHash); 119 }