Skip to content

Commit edd16ff

Browse files
authored
Adds support for IN TRANSACTIONS (#430)
Fixes #429
1 parent 08fef22 commit edd16ff

File tree

6 files changed

+75
-3
lines changed

6 files changed

+75
-3
lines changed

Neo4jClient.Tests/Cypher/CypherFluentQueryCallTests.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,55 @@
88

99
namespace Neo4jClient.Tests.Cypher
1010
{
11-
11+
public class CypherFluentQueryInTransactionsTests : IClassFixture<CultureInfoSetupFixture>
12+
{
13+
private static IRawGraphClient GraphClient_44
14+
{
15+
get
16+
{
17+
var client = Substitute.For<IRawGraphClient>();
18+
client.CypherCapabilities.Returns(CypherCapabilities.Cypher44);
19+
return client;
20+
}
21+
}
22+
23+
[Fact]
24+
public void AddsInTransactionsWithNoRows_WhenRowsNotSpecified()
25+
{
26+
var client = GraphClient_44;
27+
var query = new CypherFluentQuery(client)
28+
.Call("{arlo()}")
29+
.InTransactions()
30+
.Query;
31+
32+
Assert.Equal("CALL {arlo()}\r\nIN TRANSACTIONS", query.QueryText);
33+
}
34+
35+
[Fact]
36+
public void AddsInTransactionsWithRows_WhenRowsSpecified()
37+
{
38+
var client = GraphClient_44;
39+
var query = new CypherFluentQuery(client)
40+
.Call("{arlo()}")
41+
.InTransactions(1000)
42+
.Query;
43+
44+
Assert.Equal("CALL {arlo()}\r\nIN TRANSACTIONS OF 1000 ROWS", query.QueryText);
45+
}
46+
47+
[Fact]
48+
public void AddsInTransactionsWithNoRows_WhenRowsAreNull()
49+
{
50+
var client = GraphClient_44;
51+
var query = new CypherFluentQuery(client)
52+
.Call("{arlo()}")
53+
.InTransactions(null)
54+
.Query;
55+
56+
Assert.Equal("CALL {arlo()}\r\nIN TRANSACTIONS", query.QueryText);
57+
}
58+
}
59+
1260
public class CypherFluentQueryCallTests : IClassFixture<CultureInfoSetupFixture>
1361
{
1462
private class Foo

Neo4jClient/BoltGraphClient.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,12 @@ public async Task ConnectAsync(NeoServerConfiguration configuration = null)
285285
var version = record["versions"].As<List<object>>();
286286
ServerVersion = RootApiResponse.GetVersion(version?.First()?.ToString());
287287

288-
if (ServerVersion > new Version(3, 0))
288+
if (ServerVersion >= new Version(3, 0))
289289
CypherCapabilities = CypherCapabilities.Cypher30;
290290
if(ServerVersion >= new Version(4,0))
291291
CypherCapabilities = CypherCapabilities.Cypher40;
292+
if(ServerVersion >= new Version(4,4))
293+
CypherCapabilities = CypherCapabilities.Cypher44;
292294
}
293295

294296
await session.CloseAsync().ConfigureAwait(false);

Neo4jClient/Cypher/CypherCapabilities.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public CypherCapabilities(CypherCapabilities cypherCapabilities)
1414
SupportsStoredProcedures = cypherCapabilities.SupportsStoredProcedures;
1515
SupportsHasFunction = cypherCapabilities.SupportsHasFunction;
1616
SupportsMultipleTenancy = cypherCapabilities.SupportsMultipleTenancy;
17+
SupportsStoredProceduresWithTransactionalBatching = cypherCapabilities.SupportsStoredProceduresWithTransactionalBatching;
1718
}
1819

1920
public static readonly CypherCapabilities Cypher19 = new CypherCapabilities
@@ -34,7 +35,7 @@ public CypherCapabilities(CypherCapabilities cypherCapabilities)
3435
public static readonly CypherCapabilities Cypher23 = new CypherCapabilities(Cypher226) {SupportsStartsWith = true};
3536
public static readonly CypherCapabilities Cypher30 = new CypherCapabilities(Cypher23) { SupportsStoredProcedures = true, SupportsHasFunction = false };
3637
public static readonly CypherCapabilities Cypher40 = new CypherCapabilities(Cypher30) { SupportsMultipleTenancy = true, SupportsShow = true };
37-
38+
public static readonly CypherCapabilities Cypher44 = new CypherCapabilities(Cypher40) { SupportsStoredProceduresWithTransactionalBatching = true };
3839
public static readonly CypherCapabilities Default = Cypher20;
3940

4041
/// <summary>
@@ -46,6 +47,7 @@ public CypherCapabilities(CypherCapabilities cypherCapabilities)
4647
public bool SupportsPropertySuffixesForControllingNullComparisons { get; set; }
4748
public bool SupportsNullComparisonsWithIsOperator { get; set; }
4849
public bool SupportsStartsWith { get; set; }
50+
public bool SupportsStoredProceduresWithTransactionalBatching { get; set; }
4951

5052
/// <summary>
5153
/// Cypher 3.0 provides support for Stored Procedures via the CALL keyword.

Neo4jClient/Cypher/CypherFluentQuery.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ public ICypherFluentQuery Call<T>(Func<ICypherFluentQuery<T>> subQuery)
6262
return Call($"{{ {query.QueryText} }}", query.QueryParameters);
6363
}
6464

65+
public ICypherFluentQuery InTransactions(int? rows = null)
66+
{
67+
if (!Client.CypherCapabilities.SupportsStoredProceduresWithTransactionalBatching)
68+
throw new InvalidOperationException("IN TRANSACTIONS not supported in Neo4j versions older than 4.4");
69+
70+
return Mutate(w =>
71+
{
72+
w.AppendClause($"IN TRANSACTIONS{(rows.HasValue ? $" OF {rows.Value} ROWS" : string.Empty)}{Environment.NewLine}");
73+
});
74+
}
75+
6576

6677

6778
public ICypherFluentQuery Read

Neo4jClient/Cypher/ICypherFluentQuery.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ public partial interface ICypherFluentQuery
7777
/// <exception cref="InvalidOperationException">Thrown if an attempt is made to call this against a server version prior to 3.0.</exception>
7878
ICypherFluentQuery Call<T>(Func<ICypherFluentQuery<T>> subQuery);
7979

80+
/// <summary>
81+
/// [Neo4j 4.4+] Batches subqueries
82+
/// </summary>
83+
/// <param name="rows"></param>
84+
/// <returns></returns>
85+
ICypherFluentQuery InTransactions(int? rows = null);
86+
8087
/// <summary>
8188
/// [Neo4j 3.0+] Yields the values from the response of a <see cref="Call"/> method
8289
/// </summary>

Neo4jClient/GraphClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ void StopTimerAndNotifyCompleted()
119119

120120
if (version >= new Version(4, 0))
121121
CypherCapabilities = CypherCapabilities.Cypher40;
122+
if(ServerVersion >= new Version(4,4))
123+
CypherCapabilities = CypherCapabilities.Cypher44;
122124
}
123125
catch (AggregateException ex)
124126
{

0 commit comments

Comments
 (0)