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 1/6] 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 From 926f57860a5208ac33dffdc598e9c93b4fbd3bee Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:39:44 +0200 Subject: [PATCH 2/6] Document constructor and initialize data array to avoid nulls. --- src/NRedisStack/Graph/GraphCacheList.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/NRedisStack/Graph/GraphCacheList.cs b/src/NRedisStack/Graph/GraphCacheList.cs index 1591f06a..551e8476 100644 --- a/src/NRedisStack/Graph/GraphCacheList.cs +++ b/src/NRedisStack/Graph/GraphCacheList.cs @@ -5,12 +5,18 @@ internal sealed class GraphCacheList private readonly string _graphName; private readonly string _procedure; - private string[]? _data; + private string[] _data = Array.Empty(); private readonly GraphCommandsAsync _redisGraph; private readonly object _locker = new object(); + /// + /// Constructs a for providing cached information about the graph. + /// + /// The name of the graph to cache information for. + /// The saved procedure to call to populate cache. Must be a `read` procedure. + /// The graph used for the calling the . internal GraphCacheList(string graphName, string procedure, GraphCommands redisGraph) { _graphName = graphName; @@ -19,6 +25,12 @@ internal GraphCacheList(string graphName, string procedure, GraphCommands redisG _redisGraph = redisGraph; } + /// + /// Constructs a for providing cached information about the graph. + /// + /// The name of the graph to cache information for. + /// The saved procedure to call to populate cache. Must be a `read` procedure. + /// The graph used for the calling the . internal GraphCacheList(string graphName, string procedure, GraphCommandsAsync redisGraphAsync) { _graphName = graphName; @@ -30,18 +42,18 @@ internal GraphCacheList(string graphName, string procedure, GraphCommandsAsync r // TODO: Change this to use Lazy? internal string GetCachedData(int index) { - if (_data == null || index >= _data.Length) + if (index >= _data.Length) { lock (_locker) { - if (_data == null || index >= _data.Length) + if (index >= _data.Length) { _data = GetProcedureInfo(); } } } - return _data?.ElementAtOrDefault(index) ?? string.Empty; + return _data.ElementAtOrDefault(index); } private string[] GetProcedureInfo() From f9b8acbbb908a14c2f13e7a07c5eb41c41a3f9d7 Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:40:16 +0200 Subject: [PATCH 3/6] Minor formatting changes. --- src/NRedisStack/Graph/GraphCommands.cs | 9 ++++----- src/NRedisStack/Graph/GraphCommandsAsync.cs | 12 ++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs index 3f74ac1a..9bfd4db8 100644 --- a/src/NRedisStack/Graph/GraphCommands.cs +++ b/src/NRedisStack/Graph/GraphCommands.cs @@ -8,7 +8,7 @@ namespace NRedisStack { public class GraphCommands : GraphCommandsAsync, IGraphCommands { - IDatabase _db; + readonly IDatabase _db; public GraphCommands(IDatabase db) : base(db) { @@ -55,17 +55,16 @@ 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 new readonly Dictionary> EmptyKwargsDictionary = + private static readonly Dictionary> EmptyKwargsDictionary = new Dictionary>(); - // TODO: Check if this is needed: /// public ResultSet CallProcedure(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) => - CallProcedure(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); + CallProcedure(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); /// public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write) => - CallProcedure(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); + CallProcedure(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); /// public ResultSet CallProcedure(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write) diff --git a/src/NRedisStack/Graph/GraphCommandsAsync.cs b/src/NRedisStack/Graph/GraphCommandsAsync.cs index ab2b8c5f..8f06f338 100644 --- a/src/NRedisStack/Graph/GraphCommandsAsync.cs +++ b/src/NRedisStack/Graph/GraphCommandsAsync.cs @@ -9,7 +9,7 @@ namespace NRedisStack { public class GraphCommandsAsync : IGraphCommandsAsync { - IDatabaseAsync _db; + readonly IDatabaseAsync _db; public GraphCommandsAsync(IDatabaseAsync db) { @@ -56,16 +56,16 @@ public async Task RO_QueryAsync(string graphName, string query, long? return new ResultSet(await _db.ExecuteAsync(GraphCommandBuilder.RO_Query(graphName, query, timeout)), _graphCaches[graphName]); } - internal static readonly Dictionary> EmptyKwargsDictionary = + private static readonly Dictionary> EmptyKwargsDictionary = new Dictionary>(); /// - public async Task CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) => - await CallProcedureAsync(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); + public Task CallProcedureAsync(string graphName, string procedure, ProcedureMode procedureMode = ProcedureMode.Write) => + CallProcedureAsync(graphName, procedure, Enumerable.Empty(), EmptyKwargsDictionary, procedureMode); /// - public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write) => - await CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); + public Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, ProcedureMode procedureMode = ProcedureMode.Write) => + CallProcedureAsync(graphName, procedure, args, EmptyKwargsDictionary, procedureMode); /// public async Task CallProcedureAsync(string graphName, string procedure, IEnumerable args, Dictionary> kwargs, ProcedureMode procedureMode = ProcedureMode.Write) From 89c039fb162ad8d1e8cf48ba215f91f661ef829b Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:40:36 +0200 Subject: [PATCH 4/6] Add tests for CallProcedure and CallProcedureAsync --- tests/NRedisStack.Tests/Graph/GraphTests.cs | 86 +++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index 6355c15b..fdc26716 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -956,6 +956,49 @@ public void TestModulePrefixs() Assert.NotEqual(graph1.GetHashCode(), graph2.GetHashCode()); } + [Fact] + public void TestCallProcedureDbLabels() + { + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + + const string graphName = "social"; + + var graph = db.GRAPH(); + // Create empty graph, otherwise call procedure will throw exception + graph.Query(graphName, "RETURN 1"); + + var labels0 = graph.CallProcedure(graphName, "db.labels"); + Assert.Empty(labels0); + + graph.Query(graphName, "CREATE (:Person { name: 'Bob' })"); + + var labels1 = graph.CallProcedure(graphName, "db.labels"); + Assert.Single(labels1); + } + + [Fact] + public void TestCallProcedureReadOnly() + { + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + + const string graphName = "social"; + + var graph = db.GRAPH(); + // throws RedisServerException when executing a ReadOnly procedure against non-existing graph. + Assert.Throws(() => graph.CallProcedure(graphName, "db.labels", ProcedureMode.Read)); + + graph.Query(graphName, "CREATE (:Person { name: 'Bob' })"); + var procedureArgs = new List + { + "Person", + "name" + }; + // throws RedisServerException when executing a Write procedure with Read procedure mode. + Assert.Throws(() => graph.CallProcedure(graphName, "db.idx.fulltext.createNodeIndex", procedureArgs, ProcedureMode.Read)); + } + #endregion #region AsyncTests @@ -1886,6 +1929,49 @@ public async Task TestModulePrefixsAsync() Assert.NotEqual(graph1.GetHashCode(), graph2.GetHashCode()); } + [Fact] + public async Task TestCallProcedureDbLabelsAsync() + { + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + + const string graphName = "social"; + + var graph = db.GRAPH(); + // Create empty graph, otherwise call procedure will throw exception + await graph.QueryAsync(graphName, "RETURN 1"); + + var labels0 = await graph.CallProcedureAsync(graphName, "db.labels"); + Assert.Empty(labels0); + + await graph.QueryAsync(graphName, "CREATE (:Person { name: 'Bob' })"); + + var labels1 = await graph.CallProcedureAsync(graphName, "db.labels"); + Assert.Single(labels1); + } + + [Fact] + public async Task TestCallProcedureReadOnlyAsync() + { + var db = redisFixture.Redis.GetDatabase(); + db.Execute("FLUSHALL"); + + const string graphName = "social"; + + var graph = db.GRAPH(); + // throws RedisServerException when executing a ReadOnly procedure against non-existing graph. + await Assert.ThrowsAsync(() => graph.CallProcedureAsync(graphName, "db.labels", ProcedureMode.Read)); + + await graph.QueryAsync(graphName, "CREATE (:Person { name: 'Bob' })"); + var procedureArgs = new List + { + "Person", + "name" + }; + // throws RedisServerException when executing a Write procedure with Read procedure mode. + await Assert.ThrowsAsync(() => graph.CallProcedureAsync(graphName, "db.idx.fulltext.createNodeIndex", procedureArgs, ProcedureMode.Read)); + } + [Fact] public void TestParseInfinity() { From 34857ae9ff75842c91bdba1668430c6c0cc9ef04 Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Mon, 31 Jul 2023 19:44:05 +0200 Subject: [PATCH 5/6] Replace lambda with method call --- src/NRedisStack/Graph/GraphCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NRedisStack/Graph/GraphCommands.cs b/src/NRedisStack/Graph/GraphCommands.cs index 9bfd4db8..16894221 100644 --- a/src/NRedisStack/Graph/GraphCommands.cs +++ b/src/NRedisStack/Graph/GraphCommands.cs @@ -69,7 +69,7 @@ public ResultSet CallProcedure(string graphName, string procedure, IEnumerable public ResultSet CallProcedure(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(); From 08238a86f2975a8453f247c0ebd84322ad156bd2 Mon Sep 17 00:00:00 2001 From: haysch <36488481+haysch@users.noreply.github.com> Date: Mon, 31 Jul 2023 19:55:03 +0200 Subject: [PATCH 6/6] Trim trailing whitespace --- tests/NRedisStack.Tests/Graph/GraphTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/NRedisStack.Tests/Graph/GraphTests.cs b/tests/NRedisStack.Tests/Graph/GraphTests.cs index fdc26716..d539de78 100644 --- a/tests/NRedisStack.Tests/Graph/GraphTests.cs +++ b/tests/NRedisStack.Tests/Graph/GraphTests.cs @@ -966,7 +966,7 @@ public void TestCallProcedureDbLabels() var graph = db.GRAPH(); // Create empty graph, otherwise call procedure will throw exception - graph.Query(graphName, "RETURN 1"); + graph.Query(graphName, "RETURN 1"); var labels0 = graph.CallProcedure(graphName, "db.labels"); Assert.Empty(labels0); @@ -1939,7 +1939,7 @@ public async Task TestCallProcedureDbLabelsAsync() var graph = db.GRAPH(); // Create empty graph, otherwise call procedure will throw exception - await graph.QueryAsync(graphName, "RETURN 1"); + await graph.QueryAsync(graphName, "RETURN 1"); var labels0 = await graph.CallProcedureAsync(graphName, "db.labels"); Assert.Empty(labels0);