Skip to content

Add Redis Graph Commands #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c775e51
Start Working Graph Module
shacharPash Oct 18, 2022
a01a444
Adding tests
shacharPash Oct 18, 2022
e1d8490
Add Tests
shacharPash Oct 20, 2022
c323587
Fix Some Tests
shacharPash Oct 20, 2022
bd4c592
Add Commands
shacharPash Oct 24, 2022
e0c8643
Fix Tests
shacharPash Oct 25, 2022
4d6d0e7
Add Tests
shacharPash Oct 26, 2022
67cbd4b
Add Async Commands & Tests
shacharPash Oct 26, 2022
09d232e
Fixing some TODOs
shacharPash Oct 26, 2022
94cfc27
Fix Test
shacharPash Oct 26, 2022
c7b47f2
Start Working on Transaction Tests
shacharPash Oct 27, 2022
9514b61
Fix Tests
shacharPash Nov 2, 2022
2565990
Fix Tests
shacharPash Nov 2, 2022
51b28af
Add TestParseInfinity
shacharPash Nov 2, 2022
79bbf54
Add TestMultiExec
shacharPash Nov 2, 2022
8f3223b
Fixing TODOs
shacharPash Nov 3, 2022
5a1d400
Fixing things
shacharPash Nov 6, 2022
544702b
Delete Unnecessary Label Class
shacharPash Nov 8, 2022
d936e9d
Delete Unnecessary Comments
shacharPash Nov 8, 2022
9688d0c
Delete Property Class & Fix Tests
shacharPash Nov 8, 2022
79dbd11
Efficiency of Lists and Naming
shacharPash Nov 8, 2022
fdf260d
Naming & Cleanup
shacharPash Nov 9, 2022
e5975ac
Nullable checks & Change Node Labels to public & PropertyToString
shacharPash Nov 13, 2022
16d4e07
Mark as Comment the Transaction class
shacharPash Nov 13, 2022
3f45ea0
Add GetHashCode Method to class Header
shacharPash Nov 13, 2022
f611435
Delete RedisGraphTransaction and fix GetIntValue warning
shacharPash Nov 22, 2022
af06fb4
Merge branch 'master' into AddGraphCommands
shacharPash Nov 22, 2022
760b814
Delete comments
shacharPash Nov 22, 2022
f0446d8
Add IGraphCommands
shacharPash Nov 22, 2022
db314fc
Fix Build Failure
shacharPash Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/NRedisStack/Graph/DataTypes/Edge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System.Text;

namespace NRedisStack.Graph.DataTypes
{
/// <summary>
/// A class reprenting an edge (graph entity). In addition to the base class properties, an edge shows its source,
/// destination, and relationship type.
/// </summary>
public class Edge : GraphEntity
{
/// <summary>
/// The relationship type.
/// </summary>
/// <value></value>
public string RelationshipType { get; set; }

/// <summary>
/// The ID of the source node.
/// </summary>
/// <value></value>
public long Source { get; set; }

/// <summary>
/// The ID of the desination node.
/// </summary>
/// <value></value>
public long Destination { get; set; }

/// <summary>
/// Overriden from the base `Equals` implementation. In addition to the expected behavior of checking
/// reference equality, we'll also fall back and check to see if the: Source, Destination, and RelationshipType
/// are equal.
/// </summary>
/// <param name="obj">Another `Edge` object to compare to.</param>
/// <returns>True if the two instances are equal, false if not.</returns>
public override bool Equals(object? obj)
{
if (obj == null) return this == null;

if (this == obj)
{
return true;
}

if (!(obj is Edge that))
{
return false;
}

if (!base.Equals(obj))
{
return false;
}

return Source == that.Source && Destination == that.Destination && RelationshipType == that.RelationshipType;
}

/// <summary>
/// Overriden from base to compute a deterministic hashcode based on RelationshipType, Source, and Destination.
/// </summary>
/// <returns>An integer representing the hash code for this instance.</returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;

hash = hash * 31 + base.GetHashCode();
hash = hash * 31 + RelationshipType.GetHashCode();
hash = hash * 31 + Source.GetHashCode();
hash = hash * 31 + Destination.GetHashCode();

return hash;
}
}

/// <summary>
/// Override from base to emit a string that contains: RelationshipType, Source, Destination, Id, and PropertyMap.
/// </summary>
/// <returns>A string containing a description of the Edge containing a RelationshipType, Source, Destination, Id, and PropertyMap.</returns>
public override string ToString()
{
var sb = new StringBuilder();

sb.Append("Edge{");
sb.Append($"relationshipType='{RelationshipType}'");
sb.Append($", source={Source}");
sb.Append($", destination={Destination}");
sb.Append($", id={Id}");
sb.Append($", {PropertyMapToString()}");
sb.Append("}");

return sb.ToString();
}
}
}
89 changes: 89 additions & 0 deletions src/NRedisStack/Graph/DataTypes/GraphEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Text;

namespace NRedisStack.Graph.DataTypes
{
/// <summary>
/// An abstract representation of a graph entity.
/// A graph entity has an ID and a set of properties. The properties are mapped and accessed by their names.
/// </summary>
public abstract class GraphEntity
{
public long Id { get; set; }

public IDictionary<string, object> PropertyMap = new Dictionary<string, object>();

/// <summary>
/// Overriden Equals that considers the equality of the entity ID as well as the equality of the
/// properties that each entity has.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object? obj)
{
if (obj == null) return this == null;

if (this == obj)
{
return true;
}

if (!(obj is GraphEntity that))
{
return false;
}

return Id == that.Id && (PropertyMap.SequenceEqual(that.PropertyMap));
}

/// <summary>
/// Overriden GetHashCode that computes a deterministic hash code based on the value of the ID
/// and the name/value of each of the associated properties.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;

hash = hash * 31 + Id.GetHashCode();

foreach(var prop in PropertyMap)
{
hash = hash * 31 + prop.Key.GetHashCode();
hash = hash * 31 + prop.Value.GetHashCode();
}

return hash;
}
}

/// <summary>
/// Overriden ToString that emits a string containing the ID and property map of the entity.
/// </summary>
/// <returns></returns>
public override string ToString()
{
var sb = new StringBuilder();

sb.Append("GraphEntity{id=");
sb.Append(Id);
sb.Append(", propertyMap=");
sb.Append(PropertyMap);
sb.Append('}');

return sb.ToString();
}

public string PropertyMapToString()
{
var sb = new StringBuilder();

sb.Append("propertyMap={");
sb.Append(string.Join(", ", PropertyMap.Select(pm => $"{pm.Key}={pm.Value}")));
sb.Append("}");

return sb.ToString();
}
}
}
86 changes: 86 additions & 0 deletions src/NRedisStack/Graph/DataTypes/Node.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NRedisStack.Graph.DataTypes
{
/// <summary>
/// A class representing a node (graph entity). In addition to the base class ID and properties, a node has labels.
/// </summary>
public sealed class Node : GraphEntity
{
public List<string> Labels { get; }

public Node()
{
Labels = new List<string>();
}

/// <summary>
/// Overriden member that checks to see if the names of the labels of a node are equal
/// (in addition to base `Equals` functionality).
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object? obj)
{
if (obj == null) return this == null;

if (this == obj)
{
return true;
}

if (!(obj is Node that))
{
return false;
}

if (!base.Equals(obj))
{
return false;
}

return Enumerable.SequenceEqual(Labels, that.Labels);
}

/// <summary>
/// Overridden member that computes a hash code based on the base `GetHashCode` implementation
/// as well as the hash codes of all labels.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;

foreach(var label in Labels)
{
hash = hash * 31 + label.GetHashCode();
}

hash = hash * 31 + base.GetHashCode();

return hash;
}
}

/// <summary>
/// Overridden member that emits a string containing the labels, ID, and property map of a node.
/// </summary>
/// <returns></returns>
public override string ToString()
{
var sb = new StringBuilder();

sb.Append("Node{labels=");
sb.Append($"[{string.Join(", ", Labels)}]");
sb.Append($", id={Id}");
sb.Append($", {PropertyMapToString()}");
sb.Append("}");

return sb.ToString();
}
}
}
93 changes: 93 additions & 0 deletions src/NRedisStack/Graph/DataTypes/Path.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Text;

[assembly: InternalsVisibleTo("NRedisStack.Tests.Graph")]

namespace NRedisStack.Graph.DataTypes
{
/// <summary>
/// This class represents a path in the graph.
/// </summary>
public class Path
{
public ReadOnlyCollection<Node> Nodes { get;}
public ReadOnlyCollection<Edge> Edges { get;}

public Path(IList<Node> nodes, IList<Edge> edges)
{
Nodes = new ReadOnlyCollection<Node>(nodes);
Edges = new ReadOnlyCollection<Edge>(edges);
}


/// <summary>
/// How many edges exist on this path.
/// </summary>
public int Length => Edges.Count;

/// <summary>
/// Overriden `Equals` method that will consider the equality of the Nodes and Edges between two paths.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(object? obj)
{
if (obj == null) return this == null;

if (this == obj)
{
return true;
}

if (!(obj is Path path))
{
return false;
}

return Enumerable.SequenceEqual(Nodes, path.Nodes) && Enumerable.SequenceEqual(Edges, path.Edges);
}

/// <summary>
/// Overridden `GetHashCode` method that will compute a hash code using the hash code of each node and edge on
/// the path.
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
unchecked
{
int hash = 17;

foreach (var node in Nodes)
{
hash = hash * 31 + node.GetHashCode();
}

foreach (var edge in Edges)
{
hash = hash * 31 + edge.GetHashCode();
}

return hash;
}
}

/// <summary>
/// Overridden `ToString` method that will emit a string based on the string values of the nodes and edges
/// on the path.
/// </summary>
/// <returns></returns>
public override string ToString()
{
var sb = new StringBuilder();

sb.Append("Path{");
sb.Append($"nodes={Nodes}");
sb.Append($", edges={Edges}");
sb.Append("}");

return sb.ToString();
}
}
}
23 changes: 23 additions & 0 deletions src/NRedisStack/Graph/GraphCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace NRedisStack.Graph
{
internal sealed class GraphCache
{
public GraphCacheList Labels { get; set; }
public GraphCacheList PropertyNames { get; set; }
public GraphCacheList RelationshipTypes { get; set; }

public GraphCache(string graphName, GraphCommands redisGraph)
{
Labels = new GraphCacheList(graphName, "db.labels", redisGraph);
PropertyNames = new GraphCacheList(graphName, "db.propertyKeys", redisGraph);
RelationshipTypes = new GraphCacheList(graphName, "db.relationshipTypes", redisGraph);
}

public string GetLabel(int index) => Labels.GetCachedData(index);

public string GetRelationshipType(int index) => RelationshipTypes.GetCachedData(index);

public string GetPropertyName(int index) => PropertyNames.GetCachedData(index);

}
}
Loading