Skip to content

Commit 26e002d

Browse files
Interfaces and final touches.
1 parent 3aaea62 commit 26e002d

9 files changed

Lines changed: 285 additions & 358 deletions

ArrayPoolExtensions.cs

Lines changed: 0 additions & 67 deletions
This file was deleted.

ExpressiveCommandBase.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,9 +824,8 @@ void I() => ExecuteReader(reader =>
824824
var ordinalValues = columns.Select(c => c.Ordinal).ToArray();
825825
deferred(new QueryResult<IEnumerable<object[]>>(
826826
ordinalValues,
827-
columns.Select(c => c.Name).ToArray(),
827+
columns.Select(c => c.Name),
828828
reader.AsEnumerable(ordinalValues)));
829-
830829
});
831830

832831
if (synchronousExecution) I();

Extensions.ConnectionFactory.cs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,9 @@ public static async Task<T> OpenAsync<TConn, T>(this IDbConnectionFactory<TConn>
272272

273273
using (var conn = connectionFactory.Create())
274274
{
275-
var c = conn as DbConnection;
276-
if (c == null) conn.Open();
277-
else await c.OpenAsync();
278-
return await action(conn).ConfigureAwait(false);
275+
if (conn is DbConnection c) await c.OpenAsync();
276+
else conn.Open();
277+
return await action(conn).ConfigureAwait(false);
279278
}
280279
}
281280

@@ -294,10 +293,9 @@ public static async Task OpenAsync<TConn>(this IDbConnectionFactory<TConn> conne
294293

295294
using (var conn = connectionFactory.Create())
296295
{
297-
var c = conn as DbConnection;
298-
if (c == null) conn.Open();
299-
else await c.OpenAsync();
300-
await action(conn).ConfigureAwait(false);
296+
if (conn is DbConnection c) await c.OpenAsync();
297+
else conn.Open();
298+
await action(conn).ConfigureAwait(false);
301299
}
302300
}
303301

@@ -318,10 +316,9 @@ public static async Task<T> OpenAsync<TConn, T>(this Func<TConn> connectionFacto
318316

319317
using (var conn = connectionFactory())
320318
{
321-
var c = conn as DbConnection;
322-
if (c == null) conn.Open();
323-
else await c.OpenAsync();
324-
return await action(conn).ConfigureAwait(false);
319+
if (conn is DbConnection c) await c.OpenAsync();
320+
else conn.Open();
321+
return await action(conn).ConfigureAwait(false);
325322
}
326323
}
327324

@@ -340,15 +337,12 @@ public static async Task OpenAsync<TConn>(this Func<TConn> connectionFactory, Fu
340337

341338
using (var conn = connectionFactory())
342339
{
343-
var c = conn as DbConnection;
344-
if (c == null) conn.Open();
345-
else await c.OpenAsync();
346-
await action(conn).ConfigureAwait(false);
340+
if (conn is DbConnection c) await c.OpenAsync();
341+
else conn.Open();
342+
await action(conn).ConfigureAwait(false);
347343
}
348344
}
349345

350-
351-
352346
/// <summary>
353347
/// Creates an ExpressiveDbCommand for subsequent configuration and execution.
354348
/// </summary>

Extensions.Results.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public static IEnumerable<T> Results<T>(this IDataReader reader, IEnumerable<(st
2929
var columns = reader.GetMatchingOrdinals(x.ColumnNames, true);
3030

3131
return x.AsDequeueingEnumerable(RetrieveInternal(reader,
32-
columns.Select(c => c.Ordinal).ToArray(),
33-
columns.Select(c => c.Name).ToArray(), readStarted: true));
32+
columns.Select(c => c.Ordinal),
33+
columns.Select(c => c.Name), readStarted: true));
3434
}
3535

3636
/// <summary>
@@ -111,8 +111,10 @@ public static IEnumerable<T> Results<T>(this IDbCommand command, IEnumerable<Key
111111
var columns = reader.GetMatchingOrdinals(x.ColumnNames, true);
112112

113113
return x.AsDequeueingEnumerable(await RetrieveAsyncInternal(reader, token,
114-
columns.Select(c => c.Ordinal).ToArray(),
115-
columns.Select(c => c.Name).ToArray(), readStarted: true, useReadAsync: useReadAsync));
114+
columns.Select(c => c.Ordinal),
115+
columns.Select(c => c.Name),
116+
readStarted: true,
117+
useReadAsync: useReadAsync));
116118
}
117119

118120
/// <summary>

Extensions.Retrieve.cs

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,11 @@ namespace Open.Database.Extensions
1313
public static partial class Extensions
1414
{
1515

16-
static QueryResult<Queue<object[]>> RetrieveInternal(this IDataReader reader, int[] ordinals, string[] columnNames = null, bool readStarted = false)
16+
static QueryResult<Queue<object[]>> RetrieveInternal(this IDataReader reader, IEnumerable<int> ordinals, IEnumerable<string> columnNames = null, bool readStarted = false)
1717
{
18-
var fieldCount = ordinals.Length;
19-
if (columnNames == null) columnNames = ordinals.Select(reader.GetName).ToArray();
20-
else if (columnNames.Length != fieldCount) throw new ArgumentException("Mismatched array lengths of ordinals and names.");
21-
18+
var o = ordinals as IList<int> ?? ordinals.ToArray();
2219
return new QueryResult<Queue<object[]>>(
23-
ordinals,
24-
columnNames,
20+
o, columnNames as IList<string> ?? columnNames.ToArray(),
2521
new Queue<object[]>(AsEnumerableInternal(reader, ordinals, readStarted)));
2622
}
2723

@@ -35,8 +31,7 @@ public static QueryResult<Queue<object[]>> Retrieve(this IDataReader reader)
3531
{
3632
var names = reader.GetNames();
3733
return new QueryResult<Queue<object[]>>(
38-
Enumerable.Range(0, names.Length).ToArray(),
39-
names,
34+
Enumerable.Range(0, names.Length), names,
4035
new Queue<object[]>(AsEnumerable(reader)));
4136
}
4237

@@ -48,7 +43,7 @@ public static QueryResult<Queue<object[]>> Retrieve(this IDataReader reader)
4843
/// <param name="ordinals">The ordinals to request from the reader for each record.</param>
4944
/// <returns>The QueryResult that contains all the results and the column mappings.</returns>
5045
public static QueryResult<Queue<object[]>> Retrieve(this IDataReader reader, IEnumerable<int> ordinals)
51-
=> RetrieveInternal(reader, ordinals.ToArray());
46+
=> RetrieveInternal(reader, ordinals);
5247

5348
/// <summary>
5449
/// Iterates all records within the current result set using an IDataReader and returns the desired results.
@@ -71,8 +66,9 @@ public static QueryResult<Queue<object[]>> Retrieve(this IDataReader reader, int
7166
public static QueryResult<Queue<object[]>> Retrieve(this IDataReader reader, IEnumerable<string> columnNames)
7267
{
7368
var columns = reader.GetOrdinalMapping(columnNames);
74-
var ordinalValues = columns.Select(c => c.Ordinal).ToArray();
75-
return RetrieveInternal(reader, ordinalValues, columns.Select(c => c.Name).ToArray());
69+
return RetrieveInternal(reader,
70+
columns.Select(c => c.Ordinal),
71+
columns.Select(c => c.Name));
7672
}
7773

7874
/// <summary>
@@ -162,29 +158,35 @@ public static async Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbData
162158
if (!useReadAsync) token.ThrowIfCancellationRequested();
163159

164160
return new QueryResult<Queue<object[]>>(
165-
Enumerable.Range(0, names.Length).ToArray(),
161+
Enumerable.Range(0, names.Length),
166162
names,
167163
buffer);
168164
}
169165

170-
static async Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbDataReader reader, CancellationToken token, int[] ordinals, string[] columnNames = null, bool readStarted = false, bool useReadAsync = true)
166+
static async Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbDataReader reader, CancellationToken token, IEnumerable<int> ordinals, IEnumerable<string> columnNames = null, bool readStarted = false, bool useReadAsync = true)
171167
{
172-
var fieldCount = ordinals.Length;
173-
if (columnNames == null) columnNames = ordinals.Select(reader.GetName).ToArray();
174-
else if (columnNames.Length != fieldCount) throw new ArgumentException("Mismatched array lengths of ordinals and names.");
168+
var buffer
169+
= new Queue<object[]>();
170+
171+
var result
172+
= new QueryResult<Queue<object[]>>(
173+
ordinals,
174+
columnNames ?? ordinals.Select(reader.GetName),
175+
buffer);
176+
177+
var fieldCount = result.ColumnCount;
178+
var o = result.Ordinals;
175179

176180
Func<IDataRecord, object[]> handler;
177181
if (fieldCount == 0) handler = record => Array.Empty<object>();
178182
else handler = record =>
179183
{
180184
var row = new object[fieldCount];
181185
for (var i = 0; i < fieldCount; i++)
182-
row[i] = reader.GetValue(ordinals[i]);
186+
row[i] = reader.GetValue(o[i]);
183187
return row;
184188
};
185189

186-
var buffer = new Queue<object[]>();
187-
188190
if (readStarted)
189191
buffer.Enqueue(handler(reader));
190192

@@ -194,13 +196,9 @@ static async Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbDataRead
194196
if (!useReadAsync)
195197
token.ThrowIfCancellationRequested();
196198

197-
return new QueryResult<Queue<object[]>>(
198-
ordinals,
199-
columnNames,
200-
buffer);
199+
return result;
201200
}
202201

203-
204202
/// <summary>
205203
/// Asynchronously enumerates all the remaining values of the current result set of a data reader.
206204
/// DBNull values are left unchanged (retained).
@@ -211,7 +209,7 @@ static async Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbDataRead
211209
/// <param name="useReadAsync">If true (default) will iterate the results using .ReadAsync() otherwise will only Execute the reader asynchronously and then use .Read() to iterate the results but still allowing cancellation.</param>
212210
/// <returns>The QueryResult that contains a buffer block of the results and the column mappings.</returns>
213211
public static Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbDataReader reader, IEnumerable<int> ordinals, CancellationToken token = default, bool useReadAsync = true)
214-
=> RetrieveAsyncInternal(reader, token, ordinals as int[] ?? ordinals.ToArray(), useReadAsync: useReadAsync);
212+
=> RetrieveAsyncInternal(reader, token, ordinals, useReadAsync: useReadAsync);
215213

216214
/// <summary>
217215
/// Asynchronously enumerates all the remaining values of the current result set of a data reader.
@@ -250,11 +248,9 @@ public static Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbDataReader
250248
{
251249
// Validate columns first.
252250
var columns = reader.GetOrdinalMapping(columnNames, normalizeColumnOrder);
253-
254251
return RetrieveAsyncInternal(reader, token,
255-
256-
columns.Select(c => c.Ordinal).ToArray(),
257-
columns.Select(c => c.Name).ToArray(), useReadAsync: useReadAsync);
252+
columns.Select(c => c.Ordinal),
253+
columns.Select(c => c.Name), useReadAsync: useReadAsync);
258254
}
259255

260256
/// <summary>
@@ -291,7 +287,7 @@ public static Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbDataReader
291287
public static Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbCommand command, CancellationToken token = default, bool useReadAsync = true)
292288
=> command.ExecuteReaderAsync(reader => RetrieveAsync(reader, token, useReadAsync), CommandBehavior.SequentialAccess, token);
293289

294-
static Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbCommand command, CancellationToken token, int[] ordinals, string[] columnNames = null, bool useReadAsync = true)
290+
static Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbCommand command, CancellationToken token, IEnumerable<int> ordinals, IEnumerable<string> columnNames = null, bool useReadAsync = true)
295291
=> command.ExecuteReaderAsync(reader => RetrieveAsyncInternal(reader, token, ordinals, columnNames, useReadAsync: useReadAsync), token: token);
296292

297293
/// <summary>
@@ -304,7 +300,7 @@ static Task<QueryResult<Queue<object[]>>> RetrieveAsyncInternal(DbCommand comman
304300
/// <param name="useReadAsync">If true (default) will iterate the results using .ReadAsync() otherwise will only Execute the reader asynchronously and then use .Read() to iterate the results but still allowing cancellation.</param>
305301
/// <returns>The QueryResult that contains a buffer block of the results and the column mappings.</returns>
306302
public static Task<QueryResult<Queue<object[]>>> RetrieveAsync(this DbCommand command, IEnumerable<int> ordinals, CancellationToken token = default, bool useReadAsync = true)
307-
=> RetrieveAsyncInternal(command, token, ordinals as int[] ?? ordinals.ToArray(), useReadAsync: useReadAsync);
303+
=> RetrieveAsyncInternal(command, token, ordinals, useReadAsync: useReadAsync);
308304

309305
/// <summary>
310306
/// Asynchronously enumerates all the remaining values of the current result set of a data reader.

Extensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1193,7 +1193,7 @@ public static async Task ForEachAsync(this DbCommand command,
11931193
if (handler == null) throw new ArgumentNullException(nameof(handler));
11941194
Contract.EndContractBlock();
11951195

1196-
var state = await command.Connection.EnsureOpenAsync(t);
1196+
var state = await command.Connection.EnsureOpenAsync(token);
11971197
if (state == ConnectionState.Closed) behavior |= CommandBehavior.CloseConnection;
11981198
using (var reader = await command.ExecuteReaderAsync(behavior, token))
11991199
{

Open.Database.Extensions.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<Description>Useful set of utilities and abstractions for simplifying modern data-access operations and ensuring DI compatibility.</Description>
1212
<RepositoryUrl>https://github.com/electricessence/Open.Database.Extensions</RepositoryUrl>
1313
<RepositoryType>git</RepositoryType>
14-
<Version>5.13.3</Version>
15-
<AssemblyVersion>5.13.3.0</AssemblyVersion>
16-
<FileVersion>5.13.3.0</FileVersion>
14+
<Version>5.14.0</Version>
15+
<AssemblyVersion>5.14.0.0</AssemblyVersion>
16+
<FileVersion>5.14.0.0</FileVersion>
1717
<PackageReleaseNotes>Reduced array allocation.</PackageReleaseNotes>
1818
<LangVersion>latest</LangVersion>
1919
</PropertyGroup>

0 commit comments

Comments
 (0)