From 0b8341e514068797e499025e8cc4ec225767823e Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:42:20 +0200 Subject: [PATCH] Introduce procedure mode selection for RedisGraph. * 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`. --- src/NRedisStack/Graph/GraphCacheList.cs | 61 +++++++++----------- src/NRedisStack/Graph/GraphCommands.cs | 16 ++--- src/NRedisStack/Graph/GraphCommandsAsync.cs | 17 +++--- src/NRedisStack/Graph/IGraphCommands.cs | 9 ++- src/NRedisStack/Graph/IGraphCommandsAsync.cs | 9 ++- src/NRedisStack/Graph/ProcedureMode.cs | 11 ++++ 6 files changed, 67 insertions(+), 56 deletions(-) create mode 100644 src/NRedisStack/Graph/ProcedureMode.cs diff --git a/src/NRedisStack/Graph/GraphCacheList.cs b/src/NRedisStack/Graph/GraphCacheList.cs index b490a7fb..1591f06a 100644 --- a/src/NRedisStack/Graph/GraphCacheList.cs +++ b/src/NRedisStack/Graph/GraphCacheList.cs @@ -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? @@ -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; } } } \ No newline at end of file diff --git a/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs index 59fc4f56..3f74ac1a 100644 --- a/src/NRedisStack/Graph/GraphCommands.cs +++ b/src/NRedisStack/Graph/GraphCommands.cs @@ -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> EmptyKwargsDictionary = + internal static new readonly Dictionary> EmptyKwargsDictionary = new Dictionary>(); // TODO: Check if this is needed: /// - public ResultSet CallProcedure(string graphName, string procedure) => - CallProcedure(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); + public ResultSet CallProcedure(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) => + CallProcedure(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); /// - public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args) => - CallProcedure(graphName, procedure, args, EmptyKwargsDictionary); + public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write) => + CallProcedure(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); /// - public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, Dictionary> kwargs) + public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write) { args = args.Select(a => QuoteString(a)); @@ -81,7 +81,9 @@ public ResultSet CallProcedure(string graphName, string procedure, IEnumerable diff --git a/src/NRedisStack/Graph/GraphCommandsAsync.cs b/src/NRedisStack/Graph/GraphCommandsAsync.cs index cdbb7517..ab2b8c5f 100644 --- a/src/NRedisStack/Graph/GraphCommandsAsync.cs +++ b/src/NRedisStack/Graph/GraphCommandsAsync.cs @@ -59,19 +59,18 @@ public async Task RO_QueryAsync(string graphName, string query, long? internal static readonly Dictionary> EmptyKwargsDictionary = new Dictionary>(); - // TODO: Check if this is needed: /// - public async Task CallProcedureAsync(string graphName, string procedure) => - await CallProcedureAsync(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary); + public async Task CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) => + await CallProcedureAsync(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); /// - public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args) => - await CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary); + public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write) => + await CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); /// - public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, Dictionary> kwargs) + public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write) { - args = args.Select(a => QuoteString(a)); + args = args.Select(QuoteString); var queryBody = new StringBuilder(); @@ -82,7 +81,9 @@ public async Task 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()); } diff --git a/src/NRedisStack/Graph/IGraphCommands.cs b/src/NRedisStack/Graph/IGraphCommands.cs index 3be792c4..8995d072 100644 --- a/src/NRedisStack/Graph/IGraphCommands.cs +++ b/src/NRedisStack/Graph/IGraphCommands.cs @@ -53,8 +53,9 @@ public interface IGraphCommands /// /// The graph containing the saved procedure. /// The procedure name. + /// The mode of the saved procedure. Defaults to . /// A result set. - ResultSet CallProcedure(string graphName, string procedure); + ResultSet CallProcedure(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Call a saved procedure with parameters. @@ -62,8 +63,9 @@ public interface IGraphCommands /// The graph containing the saved procedure. /// The procedure name. /// A collection of positional arguments. + /// The mode of the saved procedure. Defaults to . /// A result set. - ResultSet CallProcedure(string graphName, string procedure, IEnumerable args); + ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Call a saved procedure with parameters. @@ -72,8 +74,9 @@ public interface IGraphCommands /// The procedure name. /// A collection of positional arguments. /// A collection of keyword arguments. + /// The mode of the saved procedure. Defaults to . /// A result set. - ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, Dictionary> kwargs); + ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Delete an existing graph. diff --git a/src/NRedisStack/Graph/IGraphCommandsAsync.cs b/src/NRedisStack/Graph/IGraphCommandsAsync.cs index 62ea118f..7ea98ec8 100644 --- a/src/NRedisStack/Graph/IGraphCommandsAsync.cs +++ b/src/NRedisStack/Graph/IGraphCommandsAsync.cs @@ -53,8 +53,9 @@ public interface IGraphCommandsAsync /// /// The graph containing the saved procedure. /// The procedure name. + /// The mode of the saved procedure. Defaults to . /// A result set. - Task CallProcedureAsync(string graphName, string procedure); + Task CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Call a saved procedure with parameters. @@ -62,8 +63,9 @@ public interface IGraphCommandsAsync /// The graph containing the saved procedure. /// The procedure name. /// A collection of positional arguments. + /// The mode of the saved procedure. Defaults to . /// A result set. - Task CallProcedureAsync(string graphName, string procedure, IEnumerable args); + Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Call a saved procedure with parameters. @@ -72,8 +74,9 @@ public interface IGraphCommandsAsync /// The procedure name. /// A collection of positional arguments. /// A collection of keyword arguments. + /// The mode of the saved procedure. Defaults to . /// A result set. - Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, Dictionary> kwargs); + Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write); /// /// Delete an existing graph. diff --git a/src/NRedisStack/Graph/ProcedureMode.cs b/src/NRedisStack/Graph/ProcedureMode.cs new file mode 100644 index 00000000..092b4d56 --- /dev/null +++ b/src/NRedisStack/Graph/ProcedureMode.cs @@ -0,0 +1,11 @@ +namespace NRedisStack.Graph +{ + /// + /// Defines the mode of a saved procedure. + /// + public enum ProcedureMode + { + Read, + Write + } +} \ No newline at end of file