Skip to content

Commit

Permalink
Introduce procedure mode selection for RedisGraph.
Browse files Browse the repository at this point in the history
* Add option to specify procedure mode as specified by `dbms.procedures()`.
* Refactor `GraphCacheList` to use READ mode for `db.labels()`, `db.propertyKeys()`, and `db.relationshipTypes()` in `GraphCache`.
  • Loading branch information
haysch committed Jul 27, 2023
1 parent 78be574 commit 0b8341e
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 56 deletions.
61 changes: 26 additions & 35 deletions src/NRedisStack/Graph/GraphCacheList.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
namespace NRedisStack.Graph
{
internal class GraphCacheList
internal sealed class GraphCacheList
{
protected readonly string GraphName;
protected readonly string Procedure;
private string[] _data;
private readonly string _graphName;
private readonly string _procedure;

protected readonly GraphCommands graph;
protected readonly GraphCommandsAsync asyncGraph;
private bool asyncGraphUsed;
private string[]? _data;

private readonly GraphCommandsAsync _redisGraph;

private readonly object _locker = new object();

internal GraphCacheList(string graphName, string procedure, GraphCommands redisGraph) : this(graphName, procedure)
internal GraphCacheList(string graphName, string procedure, GraphCommands redisGraph)
{
graph = redisGraph;
asyncGraphUsed = false;
}
_graphName = graphName;
_procedure = procedure;

internal GraphCacheList(string graphName, string procedure, GraphCommandsAsync redisGraph) : this(graphName, procedure)
{
asyncGraph = redisGraph;
asyncGraphUsed = true;
_redisGraph = redisGraph;
}

private GraphCacheList(string graphName, string procedure)
internal GraphCacheList(string graphName, string procedure, GraphCommandsAsync redisGraphAsync)
{
GraphName = graphName;
Procedure = procedure;
_graphName = graphName;
_procedure = procedure;

_redisGraph = redisGraphAsync;
}

// TODO: Change this to use Lazy<T>?
Expand All @@ -39,33 +36,27 @@ internal string GetCachedData(int index)
{
if (_data == null || index >= _data.Length)
{
GetProcedureInfo();
_data = GetProcedureInfo();
}
}
}

return _data.ElementAtOrDefault(index);
return _data?.ElementAtOrDefault(index) ?? string.Empty;
}

private void GetProcedureInfo()
private string[] GetProcedureInfo()
{
var resultSet = CallProcedure(asyncGraphUsed);
var newData = new string[resultSet.Count];
var i = 0;

foreach (var record in resultSet)
{
newData[i++] = record.GetString(0);
}

_data = newData;
var resultSet = CallProcedure();
return resultSet
.Select(r => r.GetString(0))
.ToArray();
}

protected virtual ResultSet CallProcedure(bool asyncGraphUsed = false)
private ResultSet CallProcedure()
{
return asyncGraphUsed
? asyncGraph.CallProcedureAsync(GraphName, Procedure).Result
: graph.CallProcedure(GraphName, Procedure);
return _redisGraph is GraphCommands graphSync
? graphSync.CallProcedure(_graphName, _procedure, ProcedureMode.Read)
: _redisGraph.CallProcedureAsync(_graphName, _procedure, ProcedureMode.Read).Result;
}
}
}
16 changes: 9 additions & 7 deletions src/NRedisStack/Graph/GraphCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,20 @@ public ResultSet RO_Query(string graphName, string query, long? timeout = null)
return new ResultSet(_db.Execute(GraphCommandBuilder.RO_Query(graphName, query, timeout)), _graphCaches[graphName]);
}

internal static readonly Dictionary<string, List<string>> EmptyKwargsDictionary =
internal static new readonly Dictionary<string, List<string>> EmptyKwargsDictionary =
new Dictionary<string, List<string>>();

// TODO: Check if this is needed:
/// <inheritdoc/>
public ResultSet CallProcedure(string graphName, string procedure) =>
CallProcedure(graphName, procedure, Enumerable.Empty<string>(), EmptyKwargsDictionary);
public ResultSet CallProcedure(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) =>
CallProcedure(graphName, procedure, Enumerable.Empty<string>(), EmptyKwargsDictionary, procedureMode);

/// <inheritdoc/>
public ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args) =>
CallProcedure(graphName, procedure, args, EmptyKwargsDictionary);
public ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, ProcedureMode procedureMode = ProcedureMode.Write) =>
CallProcedure(graphName, procedure, args, EmptyKwargsDictionary, procedureMode);

/// <inheritdoc/>
public ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs)
public ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs, ProcedureMode procedureMode = ProcedureMode.Write)
{
args = args.Select(a => QuoteString(a));

Expand All @@ -81,7 +81,9 @@ public ResultSet CallProcedure(string graphName, string procedure, IEnumerable<s
queryBody.Append(string.Join(",", kwargsList));
}

return Query(graphName, queryBody.ToString());
return procedureMode is ProcedureMode.Read
? RO_Query(graphName, queryBody.ToString())
: Query(graphName, queryBody.ToString());
}

/// <inheritdoc/>
Expand Down
17 changes: 9 additions & 8 deletions src/NRedisStack/Graph/GraphCommandsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,18 @@ public async Task<ResultSet> RO_QueryAsync(string graphName, string query, long?
internal static readonly Dictionary<string, List<string>> EmptyKwargsDictionary =
new Dictionary<string, List<string>>();

// TODO: Check if this is needed:
/// <inheritdoc/>
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure) =>
await CallProcedureAsync(graphName, procedure, Enumerable.Empty<string>(), EmptyKwargsDictionary);
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) =>
await CallProcedureAsync(graphName, procedure, Enumerable.Empty<string>(), EmptyKwargsDictionary, procedureMode);

/// <inheritdoc/>
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args) =>
await CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary);
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, ProcedureMode procedureMode = ProcedureMode.Write) =>
await CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary, procedureMode);

/// <inheritdoc/>
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs)
public async Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs, ProcedureMode procedureMode = ProcedureMode.Write)
{
args = args.Select(a => QuoteString(a));
args = args.Select(QuoteString);

var queryBody = new StringBuilder();

Expand All @@ -82,7 +81,9 @@ public async Task<ResultSet> CallProcedureAsync(string graphName, string procedu
queryBody.Append(string.Join(",", kwargsList));
}

return await QueryAsync(graphName, queryBody.ToString());
return procedureMode is ProcedureMode.Read
? await RO_QueryAsync(graphName, queryBody.ToString())
: await QueryAsync(graphName, queryBody.ToString());
}


Expand Down
9 changes: 6 additions & 3 deletions src/NRedisStack/Graph/IGraphCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,19 @@ public interface IGraphCommands
/// </summary>
/// <param name="graphName">The graph containing the saved procedure.</param>
/// <param name="procedure">The procedure name.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
ResultSet CallProcedure(string graphName, string procedure);
ResultSet CallProcedure(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Call a saved procedure with parameters.
/// </summary>
/// <param name="graphName">The graph containing the saved procedure.</param>
/// <param name="procedure">The procedure name.</param>
/// <param name="args">A collection of positional arguments.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args);
ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Call a saved procedure with parameters.
Expand All @@ -72,8 +74,9 @@ public interface IGraphCommands
/// <param name="procedure">The procedure name.</param>
/// <param name="args">A collection of positional arguments.</param>
/// <param name="kwargs">A collection of keyword arguments.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs);
ResultSet CallProcedure(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Delete an existing graph.
Expand Down
9 changes: 6 additions & 3 deletions src/NRedisStack/Graph/IGraphCommandsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,19 @@ public interface IGraphCommandsAsync
/// </summary>
/// <param name="graphName">The graph containing the saved procedure.</param>
/// <param name="procedure">The procedure name.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
Task<ResultSet> CallProcedureAsync(string graphName, string procedure);
Task<ResultSet> CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Call a saved procedure with parameters.
/// </summary>
/// <param name="graphName">The graph containing the saved procedure.</param>
/// <param name="procedure">The procedure name.</param>
/// <param name="args">A collection of positional arguments.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args);
Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Call a saved procedure with parameters.
Expand All @@ -72,8 +74,9 @@ public interface IGraphCommandsAsync
/// <param name="procedure">The procedure name.</param>
/// <param name="args">A collection of positional arguments.</param>
/// <param name="kwargs">A collection of keyword arguments.</param>
/// <param name="procedureMode">The mode of the saved procedure. Defaults to <see cref="ProcedureMode.Write"/>.</param>
/// <returns>A result set.</returns>
Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs);
Task<ResultSet> CallProcedureAsync(string graphName, string procedure, IEnumerable<string> args, Dictionary<string, List<string>> kwargs, ProcedureMode procedureMode = ProcedureMode.Write);

/// <summary>
/// Delete an existing graph.
Expand Down
11 changes: 11 additions & 0 deletions src/NRedisStack/Graph/ProcedureMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace NRedisStack.Graph
{
/// <summary>
/// Defines the mode of a saved procedure.
/// </summary>
public enum ProcedureMode
{
Read,
Write
}
}

0 comments on commit 0b8341e

Please sign in to comment.