Skip to content

Commit c7a16ba

Browse files
Fixes implemented
1 parent 8269297 commit c7a16ba

37 files changed

Lines changed: 386 additions & 314 deletions

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,6 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case
219219

220220
# RCS1123: Add parentheses when necessary.
221221
dotnet_diagnostic.RCS1123.severity = silent
222+
223+
# Only available in .NET 8
224+
dotnet_diagnostic.CA1510.severity = silent

Open.Database.Extensions.sln

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Open.Database.Extensions.Co
1717
EndProject
1818
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B4ADB121-1900-4CB4-905C-A7B1F640BA8A}"
1919
EndProject
20+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3194AC1F-55DE-4EAE-BDC6-4E427B034CFF}"
21+
ProjectSection(SolutionItems) = preProject
22+
.editorconfig = .editorconfig
23+
EndProjectSection
24+
EndProject
2025
Global
2126
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2227
Debug|Any CPU = Debug|Any CPU

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ The provided expressive command classes allow for an expressive means to append
1515

1616
Extensions are provided to create commands from connection factories.
1717

18+
## 8.0 Release Notes
19+
20+
- All `.ConfigureAwait(false)` are now `.ConfigureAwait(false)` as they should be.
21+
The caller will need to `.ConfigureAwait(false)` if they need to resume on the calling context.
22+
- Added `Open.Database.Extensions.MSSqlClient` for `Microsoft.Data.SqlClient` support.
23+
- .NET 8.0 added to targets to ensure potential compliation and performance improvements are available.
24+
- Improved nullable integrity.
25+
1826
### Example
1927

2028
```cs

Source/Channel/AsChannel.cs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ public static ChannelReader<object[]> AsChannel(this IDataReader reader,
4242
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
4343
/// <param name="cancellationToken">An optional cancellation token.</param>
4444
/// <returns>The channel reader containing the results.</returns>
45-
public static ChannelReader<object?[]> AsChannel(this IDataReader reader,
45+
public static ChannelReader<object[]> AsChannel(this IDataReader reader,
4646
bool singleReader,
47-
ArrayPool<object?> arrayPool,
47+
ArrayPool<object> arrayPool,
4848
CancellationToken cancellationToken = default)
4949
{
5050
if (reader is null) throw new ArgumentNullException(nameof(reader));
5151
if (arrayPool is null) throw new ArgumentNullException(nameof(arrayPool));
5252
Contract.EndContractBlock();
5353

54-
var channel = CreateChannel<object?[]>(-1, singleReader);
54+
var channel = CreateChannel<object[]>(-1, singleReader);
5555
_ = ToChannel(reader, channel.Writer, true, arrayPool, cancellationToken);
5656
return channel.Reader;
5757
}
@@ -153,16 +153,16 @@ public static ChannelReader<object[]> AsChannel(this IDbCommand command,
153153
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
154154
/// <param name="cancellationToken">An optional cancellation token.</param>
155155
/// <returns>The channel reader containing the results.</returns>
156-
public static ChannelReader<object?[]> AsChannel(this IDbCommand command,
156+
public static ChannelReader<object[]> AsChannel(this IDbCommand command,
157157
bool singleReader,
158-
ArrayPool<object?> arrayPool,
158+
ArrayPool<object> arrayPool,
159159
CancellationToken cancellationToken = default)
160160
{
161161
if (command is null) throw new ArgumentNullException(nameof(command));
162162
if (arrayPool is null) throw new ArgumentNullException(nameof(arrayPool));
163163
Contract.EndContractBlock();
164164

165-
var channel = CreateChannel<object?[]>(-1, singleReader);
165+
var channel = CreateChannel<object[]>(-1, singleReader);
166166
_ = ToChannel(command, channel.Writer, true, arrayPool, cancellationToken);
167167
return channel.Reader;
168168
}
@@ -261,15 +261,15 @@ public static ChannelReader<object[]> AsChannel(this IExecuteReader command,
261261
/// <param name="singleReader">True will cause the resultant reader to optimize for the assumption that no concurrent read operations will occur.</param>
262262
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
263263
/// <returns>The channel reader containing the results.</returns>
264-
public static ChannelReader<object?[]> AsChannel(this IExecuteReader command,
264+
public static ChannelReader<object[]> AsChannel(this IExecuteReader command,
265265
bool singleReader,
266-
ArrayPool<object?> arrayPool)
266+
ArrayPool<object> arrayPool)
267267
{
268268
if (command is null) throw new ArgumentNullException(nameof(command));
269269
if (arrayPool is null) throw new ArgumentNullException(nameof(arrayPool));
270270
Contract.EndContractBlock();
271271

272-
var channel = CreateChannel<object?[]>(-1, singleReader);
272+
var channel = CreateChannel<object[]>(-1, singleReader);
273273
_ = ToChannel(command, channel.Writer, true, arrayPool);
274274
return channel.Reader;
275275
}
@@ -336,7 +336,8 @@ public static ChannelReader<T> AsChannel<T>(this IExecuteReader command,
336336
return channel.Reader;
337337
}
338338

339-
#if NETSTANDARD2_1
339+
#if NETSTANDARD2_0
340+
#else
340341
/// <summary>
341342
/// Asynchronously iterates an DbDataReader and writes each record as an array to an unbound channel.
342343
/// Iterates an DbDataReader through the transform function and writes each record to an unbound channel.
@@ -367,16 +368,16 @@ public static ChannelReader<object[]> AsChannelAsync(this DbDataReader reader,
367368
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
368369
/// <param name="cancellationToken">An optional cancellation token.</param>
369370
/// <returns>The channel reader containing the results.</returns>
370-
public static ChannelReader<object?[]> AsChannelAsync(this DbDataReader reader,
371+
public static ChannelReader<object[]> AsChannelAsync(this DbDataReader reader,
371372
bool singleReader,
372-
ArrayPool<object?> arrayPool,
373+
ArrayPool<object> arrayPool,
373374
CancellationToken cancellationToken = default)
374375
{
375376
if (reader is null) throw new ArgumentNullException(nameof(reader));
376377
if (arrayPool is null) throw new ArgumentNullException(nameof(arrayPool));
377378
Contract.EndContractBlock();
378379

379-
var channel = CreateChannel<object?[]>(-1, singleReader);
380+
var channel = CreateChannel<object[]>(-1, singleReader);
380381
_ = ToChannelAsync(reader, channel.Writer, true, arrayPool, cancellationToken);
381382
return channel.Reader;
382383
}
@@ -478,16 +479,16 @@ public static ChannelReader<object[]> AsChannelAsync(this DbCommand command,
478479
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
479480
/// <param name="cancellationToken">An optional cancellation token.</param>
480481
/// <returns>The channel reader containing the results.</returns>
481-
public static ChannelReader<object?[]> AsChannelAsync(this DbCommand command,
482+
public static ChannelReader<object[]> AsChannelAsync(this DbCommand command,
482483
bool singleReader,
483-
ArrayPool<object?> arrayPool,
484+
ArrayPool<object> arrayPool,
484485
CancellationToken cancellationToken = default)
485486
{
486487
if (command is null) throw new ArgumentNullException(nameof(command));
487488
if (arrayPool is null) throw new ArgumentNullException(nameof(arrayPool));
488489
Contract.EndContractBlock();
489490

490-
var channel = CreateChannel<object?[]>(-1, singleReader);
491+
var channel = CreateChannel<object[]>(-1, singleReader);
491492
_ = ToChannelAsync(command, channel.Writer, true, arrayPool, cancellationToken);
492493
return channel.Reader;
493494
}
@@ -586,14 +587,14 @@ public static ChannelReader<object[]> AsChannelAsync(this IExecuteReaderAsync co
586587
/// <param name="singleReader">True will cause the resultant reader to optimize for the assumption that no concurrent read operations will occur.</param>
587588
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
588589
/// <returns>The channel reader containing the results.</returns>
589-
public static ChannelReader<object?[]> AsChannelAsync(this IExecuteReaderAsync command,
590+
public static ChannelReader<object[]> AsChannelAsync(this IExecuteReaderAsync command,
590591
bool singleReader,
591-
ArrayPool<object?> arrayPool)
592+
ArrayPool<object> arrayPool)
592593
{
593594
if (command is null) throw new ArgumentNullException(nameof(command));
594595
Contract.EndContractBlock();
595596

596-
var channel = CreateChannel<object?[]>(-1, singleReader);
597+
var channel = CreateChannel<object[]>(-1, singleReader);
597598
_ = ToChannelAsync(command, channel.Writer, true, arrayPool);
598599
return channel.Reader;
599600
}

Source/Channel/Open.Database.Extensions.Channel.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<RootNamespace>Open.Database.Extensions</RootNamespace>
5-
<TargetFrameworks>netstandard2.0; netstandard2.1</TargetFrameworks>
5+
<TargetFrameworks>netstandard2.0; netstandard2.1; net8.0</TargetFrameworks>
66
<LangVersion>latest</LangVersion>
77
<Nullable>enable</Nullable>
88
<Authors>electricessence</Authors>
@@ -27,7 +27,7 @@
2727
</PropertyGroup>
2828

2929
<ItemGroup>
30-
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
30+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
3131
<PackageReference Include="Open.ChannelExtensions" Version="6.2.2" />
3232
</ItemGroup>
3333

Source/Channel/ToChannel.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ public static ValueTask<long> ToChannel(this IDataReader reader,
5050
/// <param name="cancellationToken">An optional cancellation token.</param>
5151
/// <returns>The number of records processed.</returns>
5252
public static ValueTask<long> ToChannel(this IDataReader reader,
53-
ChannelWriter<object?[]> target,
53+
ChannelWriter<object[]> target,
5454
bool complete,
55-
ArrayPool<object?> arrayPool,
55+
ArrayPool<object> arrayPool,
5656
CancellationToken cancellationToken = default)
5757
{
5858
if (reader is null) throw new ArgumentNullException(nameof(reader));
@@ -149,6 +149,7 @@ public static async ValueTask<long> ToChannel(this IDbCommand command,
149149
{
150150
if (command is null) throw new ArgumentNullException(nameof(command));
151151
if (target is null) throw new ArgumentNullException(nameof(target));
152+
if(command.Connection is null) throw new InvalidOperationException("Command has no connection.");
152153
Contract.EndContractBlock();
153154

154155
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -187,13 +188,14 @@ public static async ValueTask<long> ToChannel(this IDbCommand command,
187188
/// <param name="cancellationToken">An optional cancellation token.</param>
188189
/// <returns>The number of records processed.</returns>
189190
public static async ValueTask<long> ToChannel(this IDbCommand command,
190-
ChannelWriter<object?[]> target,
191+
ChannelWriter<object[]> target,
191192
bool complete,
192-
ArrayPool<object?> arrayPool,
193+
ArrayPool<object> arrayPool,
193194
CancellationToken cancellationToken = default)
194195
{
195196
if (command is null) throw new ArgumentNullException(nameof(command));
196197
if (target is null) throw new ArgumentNullException(nameof(target));
198+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
197199
Contract.EndContractBlock();
198200

199201
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -240,6 +242,7 @@ public static async ValueTask<long> ToChannel<T>(this IDbCommand command,
240242
if (command is null) throw new ArgumentNullException(nameof(command));
241243
if (target is null) throw new ArgumentNullException(nameof(target));
242244
if (transform is null) throw new ArgumentNullException(nameof(transform));
245+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
243246
Contract.EndContractBlock();
244247

245248
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -288,6 +291,7 @@ public static async ValueTask<long> ToChannel<T>(this IDbCommand command,
288291
{
289292
if (command is null) throw new ArgumentNullException(nameof(command));
290293
if (target is null) throw new ArgumentNullException(nameof(target));
294+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
291295
Contract.EndContractBlock();
292296

293297
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -335,6 +339,7 @@ public static async ValueTask<long> ToChannel<T>(this IDbCommand command,
335339
{
336340
if (command is null) throw new ArgumentNullException(nameof(command));
337341
if (target is null) throw new ArgumentNullException(nameof(target));
342+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
338343
Contract.EndContractBlock();
339344

340345
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -412,9 +417,9 @@ public static async ValueTask<long> ToChannel(this IExecuteReader command,
412417
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
413418
/// <returns>The number of records processed.</returns>
414419
public static async ValueTask<long> ToChannel(this IExecuteReader command,
415-
ChannelWriter<object?[]> target,
420+
ChannelWriter<object[]> target,
416421
bool complete,
417-
ArrayPool<object?> arrayPool)
422+
ArrayPool<object> arrayPool)
418423
{
419424
if (command is null) throw new ArgumentNullException(nameof(command));
420425
if (target is null) throw new ArgumentNullException(nameof(target));
@@ -573,7 +578,8 @@ public static async ValueTask<long> ToChannel<T>(this IExecuteReader command,
573578
}
574579
}
575580

576-
#if NETSTANDARD2_1
581+
#if NETSTANDARD2_0
582+
#else
577583
/// <summary>
578584
/// Asynchronously iterates an DbDataReader and writes each record as an array to the channel.
579585
/// </summary>
@@ -606,9 +612,9 @@ public static ValueTask<long> ToChannelAsync(this DbDataReader reader,
606612
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
607613
/// <param name="cancellationToken">An optional cancellation token.</param>
608614
public static ValueTask<long> ToChannelAsync(this DbDataReader reader,
609-
ChannelWriter<object?[]> target,
615+
ChannelWriter<object[]> target,
610616
bool complete,
611-
ArrayPool<object?> arrayPool,
617+
ArrayPool<object> arrayPool,
612618
CancellationToken cancellationToken = default)
613619
{
614620
if (reader is null) throw new ArgumentNullException(nameof(reader));
@@ -702,6 +708,7 @@ public static async ValueTask<long> ToChannelAsync(this DbCommand command,
702708
{
703709
if (command is null) throw new ArgumentNullException(nameof(command));
704710
if (target is null) throw new ArgumentNullException(nameof(target));
711+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
705712
Contract.EndContractBlock();
706713

707714
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -740,13 +747,14 @@ public static async ValueTask<long> ToChannelAsync(this DbCommand command,
740747
/// <param name="cancellationToken">An optional cancellation token.</param>
741748
/// <returns>The number of records processed.</returns>
742749
public static async ValueTask<long> ToChannelAsync(this DbCommand command,
743-
ChannelWriter<object?[]> target,
750+
ChannelWriter<object[]> target,
744751
bool complete,
745-
ArrayPool<object?> arrayPool,
752+
ArrayPool<object> arrayPool,
746753
CancellationToken cancellationToken = default)
747754
{
748755
if (command is null) throw new ArgumentNullException(nameof(command));
749756
if (target is null) throw new ArgumentNullException(nameof(target));
757+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
750758
Contract.EndContractBlock();
751759

752760
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -794,6 +802,7 @@ public static async ValueTask<long> ToChannelAsync<T>(this DbCommand command,
794802
if (command is null) throw new ArgumentNullException(nameof(command));
795803
if (target is null) throw new ArgumentNullException(nameof(target));
796804
if (transform is null) throw new ArgumentNullException(nameof(transform));
805+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
797806
Contract.EndContractBlock();
798807

799808
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -839,6 +848,7 @@ public static async ValueTask<long> ToChannelAsync<T>(this DbCommand command,
839848
{
840849
if (command is null) throw new ArgumentNullException(nameof(command));
841850
if (target is null) throw new ArgumentNullException(nameof(target));
851+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
842852
Contract.EndContractBlock();
843853

844854
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -886,6 +896,7 @@ public static async ValueTask<long> ToChannelAsync<T>(this DbCommand command,
886896
{
887897
if (command is null) throw new ArgumentNullException(nameof(command));
888898
if (target is null) throw new ArgumentNullException(nameof(target));
899+
if (command.Connection is null) throw new InvalidOperationException("Command has no connection.");
889900
Contract.EndContractBlock();
890901

891902
if (!command.Connection.State.HasFlag(ConnectionState.Open))
@@ -965,9 +976,9 @@ public static async ValueTask<long> ToChannelAsync(this IExecuteReaderAsync comm
965976
/// <param name="arrayPool">The array pool to acquire buffers from.</param>
966977
/// <returns>The number of records processed.</returns>
967978
public static async ValueTask<long> ToChannelAsync(this IExecuteReaderAsync command,
968-
ChannelWriter<object?[]> target,
979+
ChannelWriter<object[]> target,
969980
bool complete,
970-
ArrayPool<object?> arrayPool)
981+
ArrayPool<object> arrayPool)
971982
{
972983
if (command is null) throw new ArgumentNullException(nameof(command));
973984
if (target is null) throw new ArgumentNullException(nameof(target));

Source/Channel/Transformer.cs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@
1212

1313
namespace Open.Database.Extensions;
1414

15-
internal class Transformer<T> : Core.Transformer<T>
15+
/// <summary>Constructs a <see cref="Transformer{T}"/>.</summary>
16+
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
17+
internal class Transformer<T>(IEnumerable<(string Field, string? Column)>? fieldMappingOverrides = null)
18+
: Core.Transformer<T>(fieldMappingOverrides)
1619
where T : new()
1720
{
18-
/// <summary>Constructs a <see cref="Transformer{T}"/>.</summary>
19-
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
20-
public Transformer(IEnumerable<(string Field, string? Column)>? fieldMappingOverrides = null)
21-
: base(fieldMappingOverrides)
22-
{
23-
}
24-
2521
/// <summary>
2622
/// Static utility for creating a Transformer <typeparamref name="T"/>.
2723
/// </summary>
28-
/// <param name="fieldMappingOverrides"></param>
24+
/// <param name="fieldMappingOverrides">An optional override map of field names to column names where the keys are the property names, and values are the column names.</param>
2925
public static new Transformer<T> Create(IEnumerable<(string Field, string? Column)>? fieldMappingOverrides = null)
3026
=> new(fieldMappingOverrides);
3127

@@ -49,7 +45,7 @@ internal async ValueTask<long> PipeResultsTo(IDataReader reader, ChannelWriter<T
4945
var processor = new Processor(this, names);
5046
var transform = processor.Transform;
5147

52-
var channel = ChannelDbExtensions.CreateChannel<object?[]>(MaxArrayBuffer, true);
48+
var channel = ChannelDbExtensions.CreateChannel<object[]>(MaxArrayBuffer, true);
5349
var writer = channel.Writer;
5450

5551
var piped = channel
@@ -85,7 +81,8 @@ internal async ValueTask<long> PipeResultsTo(IDataReader reader, ChannelWriter<T
8581
.ToChannel(writer, false, LocalPool, cancellationToken).ConfigureAwait(false);
8682
}
8783

88-
#if NETSTANDARD2_1
84+
#if NETSTANDARD2_0
85+
#else
8986
/// <summary>
9087
/// Transforms the results from the reader by first buffering the results and if/when the buffer size is reached, the results are transformed to a channel for reading.
9188
/// </summary>
@@ -106,7 +103,7 @@ internal ValueTask<long> PipeResultsToAsync(DbDataReader reader, ChannelWriter<T
106103
var processor = new Processor(this, names);
107104
var transform = processor.Transform;
108105

109-
var channel = ChannelDbExtensions.CreateChannel<object?[]>(MaxArrayBuffer, true);
106+
var channel = ChannelDbExtensions.CreateChannel<object[]>(MaxArrayBuffer, true);
110107
var writer = channel.Writer;
111108

112109
var piped = channel

0 commit comments

Comments
 (0)