Skip to content

Commit e443f71

Browse files
authored
Upgrade to SDK 3.9 (#387)
Motivation ---------- Ensure compatibility with the modern approach to AsyncEnumerable extensions found in .NET 10. Modifications ------------- - Upgrade to the latest version of the Couchbase SDK, which uses System.Linq.Async 7.0.0 - Address deprecation of the ToEnumerable extension - Upgrade some related packages
1 parent 6b63364 commit e443f71

4 files changed

Lines changed: 49 additions & 8 deletions

File tree

Src/Couchbase.Linq.IntegrationTests/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"couchbase": {
33
"connectionString": "couchbase://localhost",
44
"username": "Administrator",
5-
"password": "password"
5+
"password": "password",
6+
"enableDnsSrvResolution": false
67
}
78
}

Src/Couchbase.Linq.UnitTests/Couchbase.Linq.UnitTests.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
</ItemGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
14-
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
15-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
16-
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
13+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.3" />
14+
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.3" />
15+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
16+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.3" />
1717
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
1818
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
1919
<PackageReference Include="Moq" Version="4.20.72" />

Src/Couchbase.Linq/Couchbase.Linq.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
1616
<RootNamespace>Couchbase.Linq</RootNamespace>
1717
<AssemblyName>Couchbase.Linq</AssemblyName>
18+
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
1819

1920
<GenerateDocumentationFile>true</GenerateDocumentationFile>
2021
<IncludeSymbols>true</IncludeSymbols>
@@ -33,8 +34,8 @@
3334
</PropertyGroup>
3435

3536
<ItemGroup>
36-
<PackageReference Include="CouchbaseNetClient" Version="3.6.4" />
37-
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
37+
<PackageReference Include="CouchbaseNetClient" Version="3.9.0" />
38+
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
3839
<PackageReference Include="Remotion.Linq" Version="2.2.0" />
3940
</ItemGroup>
4041

Src/Couchbase.Linq/Execution/ClusterQueryExecutor.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,46 @@ public IEnumerable<T> ExecuteCollection<T>(QueryModel queryModel)
106106
/// <returns>List of objects returned by the request.</returns>
107107
public IEnumerable<T> ExecuteCollection<T>(string statement, LinqQueryOptions queryOptions)
108108
{
109-
return ExecuteCollectionAsync<T>(statement, queryOptions).ToEnumerable();
109+
// This sync-over-async pattern is not ideal, but necessary for compatibility
110+
var asyncEnumerable = ExecuteCollectionAsync<T>(statement, queryOptions);
111+
112+
var enumerator = asyncEnumerable.GetAsyncEnumerator();
113+
try
114+
{
115+
while (BlockingWait(enumerator.MoveNextAsync()))
116+
{
117+
yield return enumerator.Current;
118+
}
119+
}
120+
finally
121+
{
122+
BlockingWait(enumerator.DisposeAsync());
123+
}
124+
}
125+
126+
private static void BlockingWait(ValueTask task)
127+
{
128+
if (task.IsCompleted)
129+
{
130+
// Avoid allocating a Task unnecessarily if the ValueTask is already completed
131+
task.GetAwaiter().GetResult();
132+
return;
133+
}
134+
135+
// ValueTask must be converted to Task to safely await the result if it is not completed
136+
task.AsTask().GetAwaiter().GetResult();
137+
}
138+
139+
private static T BlockingWait<T>(ValueTask<T> task)
140+
{
141+
if (task.IsCompleted)
142+
{
143+
// Avoid allocating a Task unnecessarily if the ValueTask is already completed
144+
return task.GetAwaiter().GetResult();
145+
}
146+
147+
// ValueTask must be converted to Task to safely await the result if it is not completed
148+
return task.AsTask().GetAwaiter().GetResult();
110149
}
111150

112151
public IAsyncEnumerable<T> ExecuteCollectionAsync<T>(QueryModel queryModel, CancellationToken cancellationToken = default)

0 commit comments

Comments
 (0)