• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 23278216331

19 Mar 2026 03:19AM UTC coverage: 57.398% (+0.7%) from 56.658%
23278216331

push

github

pwelter34
Enable nullable and improve source generators

1403 of 3069 branches covered (45.72%)

Branch coverage included in aggregate %.

527 of 907 new or added lines in 58 files covered. (58.1%)

22 existing lines in 10 files now uncovered.

4288 of 6846 relevant lines covered (62.64%)

330.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.36
/src/FluentCommand.Generators/DataReaderFactoryWriter.cs
1
using FluentCommand.Generators.Models;
2

3
namespace FluentCommand.Generators;
4

5
public static class DataReaderFactoryWriter
6
{
7
    public static string Generate(EntityClass entityClass)
8
    {
9
        if (entityClass == null)
1!
10
            throw new ArgumentNullException(nameof(entityClass));
×
11

12
        var codeBuilder = new IndentedStringBuilder();
1✔
13
        codeBuilder
1✔
14
            .AppendLine("// <auto-generated />")
1✔
15
            .AppendLine("#nullable enable")
1✔
16
            .AppendLine()
1✔
17
            .AppendLine("using global::FluentCommand.Extensions;")
1✔
18
            .AppendLine();
1✔
19

20
        codeBuilder
1✔
21
            .Append("namespace ")
1✔
22
            .AppendLine(entityClass.EntityNamespace)
1✔
23
            .AppendLine("{")
1✔
24
            .IncrementIndent();
1✔
25

26
        codeBuilder
1✔
27
            .AppendLine("/// <summary>")
1✔
28
            .AppendLine("/// Extension methods for FluentCommand")
1✔
29
            .AppendLine("/// </summary>")
1✔
30
            .Append("public static partial class ")
1✔
31
            .Append(entityClass.EntityName)
1✔
32
            .AppendLine("DataReaderExtensions")
1✔
33
            .AppendLine("{")
1✔
34
            .IncrementIndent();
1✔
35

36
        WriteQueryEntity(codeBuilder, entityClass);
1✔
37

38
        WriteQuerySingleEntity(codeBuilder, entityClass);
1✔
39

40
        WriteQueryEntityTask(codeBuilder, entityClass);
1✔
41

42
        WriteQuerySingleEntityTask(codeBuilder, entityClass);
1✔
43

44
        WriteEntityFactory(codeBuilder, entityClass);
1✔
45

46
        codeBuilder
1✔
47
            .DecrementIndent()
1✔
48
            .AppendLine("}") // class
1✔
49
            .DecrementIndent()
1✔
50
            .AppendLine("}"); // namespace
1✔
51

52
        return codeBuilder.ToString();
1✔
53
    }
54

55
    private static void WriteQuerySingleEntityTask(IndentedStringBuilder codeBuilder, EntityClass entity)
56
    {
57
        // public static Task<Entity> QuerySingleEntityAsync(this IDataQueryAsync dataQuery) => QuerySingleAsync(dataQuery, EntityFactory);
58
        codeBuilder
1✔
59
            .AppendLine("/// <summary>")
1✔
60
            .Append("/// Executes the query and returns the first row in the result as a <see cref=\"T:")
1✔
61
            .Append(entity.FullyQualified)
1✔
62
            .AppendLine("\"/> object.")
1✔
63
            .AppendLine("/// </summary>")
1✔
64
            .AppendLine("/// <param name=\"dataQuery\">The <see cref=\"T:FluentCommand.IDataQueryAsync\"/> for this extension method.</param>")
1✔
65
            .AppendLine("/// <param name=\"cancellationToken\">The cancellation instruction.</param>")
1✔
66
            .AppendLine("/// <returns>")
1✔
67
            .Append("/// A instance of <see cref=\"T:")
1✔
68
            .Append(entity.FullyQualified)
1✔
69
            .AppendLine("\"/>  if row exists; otherwise null.")
1✔
70
            .AppendLine("/// </returns>")
1✔
71
            .Append("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"")
1✔
72
            .Append(ThisAssembly.Product)
1✔
73
            .Append("\", \"")
1✔
74
            .Append(ThisAssembly.InformationalVersion)
1✔
75
            .AppendLine("\")]")
1✔
76
            .Append("public static global::System.Threading.Tasks.Task<")
1✔
77
            .Append(entity.FullyQualified)
1✔
78
            .Append("?> QuerySingle")
1✔
79
            .AppendLine("Async<TEntity>(")
1✔
80
            .IncrementIndent()
1✔
81
            .AppendLine("this global::FluentCommand.IDataQueryAsync dataQuery,")
1✔
82
            .AppendLine("global::System.Threading.CancellationToken cancellationToken = default)")
1✔
83
            .Append("where TEntity : ")
1✔
84
            .AppendLine(entity.FullyQualified)
1✔
85
            .DecrementIndent()
1✔
86
            .AppendLine("{")
1✔
87
            .IncrementIndent()
1✔
88
            .Append("return dataQuery.QuerySingleAsync<")
1✔
89
            .Append(entity.FullyQualified)
1✔
90
            .AppendLine(">(")
1✔
91
            .IncrementIndent()
1✔
92
            .Append("factory: ")
1✔
93
            .Append(entity.EntityName)
1✔
94
            .Append("DataReaderExtensions.")
1✔
95
            .Append(entity.EntityName)
1✔
96
            .AppendLine("Factory,")
1✔
97
            .AppendLine("commandBehavior: global::System.Data.CommandBehavior.SequentialAccess |")
1✔
98
            .AppendLine("                 global::System.Data.CommandBehavior.SingleResult |")
1✔
99
            .AppendLine("                 global::System.Data.CommandBehavior.SingleRow,")
1✔
100
            .AppendLine("cancellationToken: cancellationToken);")
1✔
101
            .DecrementIndent()
1✔
102
            .DecrementIndent()
1✔
103
            .AppendLine("}")
1✔
104
            .AppendLine();
1✔
105
    }
1✔
106

107
    private static void WriteQueryEntityTask(IndentedStringBuilder codeBuilder, EntityClass entity)
108
    {
109
        // public static Task<IEnumerable<Entity>> QueryEntityAsync(this IDataQueryAsync dataQuery) => QueryAsync(dataQuery, EntityFactory);
110
        codeBuilder
1✔
111
            .AppendLine("/// <summary>")
1✔
112
            .Append("/// Executes the command against the connection and converts the results to <see cref=\"T:")
1✔
113
            .Append(entity.FullyQualified)
1✔
114
            .AppendLine("\"/> objects.")
1✔
115
            .AppendLine("/// </summary>")
1✔
116
            .AppendLine("/// <param name=\"dataQuery\">The <see cref=\"T:FluentCommand.IDataQueryAsync\"/> for this extension method.</param>")
1✔
117
            .AppendLine("/// <param name=\"cancellationToken\">The cancellation instruction.</param>")
1✔
118
            .AppendLine("/// <returns>")
1✔
119
            .Append("/// An <see cref=\"T:System.Collections.Generic.IEnumerable`1\" /> of <see cref=\"T:")
1✔
120
            .Append(entity.FullyQualified)
1✔
121
            .AppendLine("\"/> objects.")
1✔
122
            .AppendLine("/// </returns>")
1✔
123
            .Append("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"")
1✔
124
            .Append(ThisAssembly.Product)
1✔
125
            .Append("\", \"")
1✔
126
            .Append(ThisAssembly.InformationalVersion)
1✔
127
            .AppendLine("\")]")
1✔
128
            .Append("public static global::System.Threading.Tasks.Task<global::System.Collections.Generic.IEnumerable<")
1✔
129
            .Append(entity.FullyQualified)
1✔
130
            .AppendLine(">> QueryAsync<TEntity>(")
1✔
131
            .IncrementIndent()
1✔
132
            .AppendLine("this global::FluentCommand.IDataQueryAsync dataQuery,")
1✔
133
            .AppendLine("global::System.Threading.CancellationToken cancellationToken = default)")
1✔
134
            .Append("where TEntity : ")
1✔
135
            .AppendLine(entity.FullyQualified)
1✔
136
            .DecrementIndent()
1✔
137
            .AppendLine("{")
1✔
138
            .IncrementIndent()
1✔
139
            .Append("return dataQuery.QueryAsync<")
1✔
140
            .Append(entity.FullyQualified)
1✔
141
            .AppendLine(">(")
1✔
142
            .IncrementIndent()
1✔
143
            .Append("factory: ")
1✔
144
            .Append(entity.EntityName)
1✔
145
            .Append("DataReaderExtensions.")
1✔
146
            .Append(entity.EntityName)
1✔
147
            .AppendLine("Factory,")
1✔
148
            .AppendLine("commandBehavior: global::System.Data.CommandBehavior.SequentialAccess |")
1✔
149
            .AppendLine("                 global::System.Data.CommandBehavior.SingleResult,")
1✔
150
            .AppendLine("cancellationToken: cancellationToken);")
1✔
151
            .DecrementIndent()
1✔
152
            .DecrementIndent()
1✔
153
            .AppendLine("}")
1✔
154
            .AppendLine();
1✔
155
    }
1✔
156

157
    private static void WriteQuerySingleEntity(IndentedStringBuilder codeBuilder, EntityClass entity)
158
    {
159
        // public static Entity QuerySingleEntity(this IDataQuery dataQuery) => QuerySingle(dataQuery, EntityFactory);
160
        codeBuilder
1✔
161
            .AppendLine("/// <summary>")
1✔
162
            .Append("/// Executes the query and returns the first row in the result as a <see cref=\"T:")
1✔
163
            .Append(entity.FullyQualified)
1✔
164
            .AppendLine("\"/> object.")
1✔
165
            .AppendLine("/// </summary>")
1✔
166
            .AppendLine("/// <param name=\"dataQuery\">The <see cref=\"T:FluentCommand.IDataQuery\"/> for this extension method.</param>")
1✔
167
            .AppendLine("/// <returns>")
1✔
168
            .Append("/// A instance of <see cref=\"T:")
1✔
169
            .Append(entity.FullyQualified)
1✔
170
            .AppendLine("\"/>  if row exists; otherwise null.")
1✔
171
            .AppendLine("/// </returns>")
1✔
172
            .Append("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"")
1✔
173
            .Append(ThisAssembly.Product)
1✔
174
            .Append("\", \"")
1✔
175
            .Append(ThisAssembly.InformationalVersion)
1✔
176
            .AppendLine("\")]")
1✔
177
            .Append("public static ")
1✔
178
            .Append(entity.FullyQualified)
1✔
179
            .AppendLine("? QuerySingle<TEntity>(")
1✔
180
            .IncrementIndent()
1✔
181
            .AppendLine("this global::FluentCommand.IDataQuery dataQuery)")
1✔
182
            .Append("where TEntity : ")
1✔
183
            .AppendLine(entity.FullyQualified)
1✔
184
            .DecrementIndent()
1✔
185
            .AppendLine("{")
1✔
186
            .IncrementIndent()
1✔
187
            .Append("return dataQuery.QuerySingle<")
1✔
188
            .Append(entity.FullyQualified)
1✔
189
            .AppendLine(">(")
1✔
190
            .IncrementIndent()
1✔
191
            .Append("factory: ")
1✔
192
            .Append(entity.EntityName)
1✔
193
            .Append("DataReaderExtensions.")
1✔
194
            .Append(entity.EntityName)
1✔
195
            .AppendLine("Factory,")
1✔
196
            .AppendLine("commandBehavior: global::System.Data.CommandBehavior.SequentialAccess |")
1✔
197
            .AppendLine("                 global::System.Data.CommandBehavior.SingleResult |")
1✔
198
            .AppendLine("                 global::System.Data.CommandBehavior.SingleRow);")
1✔
199
            .DecrementIndent()
1✔
200
            .DecrementIndent()
1✔
201
            .AppendLine("}")
1✔
202
            .AppendLine();
1✔
203
    }
1✔
204

205
    private static void WriteQueryEntity(IndentedStringBuilder codeBuilder, EntityClass entity)
206
    {
207
        // public static IEnumerable<Entity> QueryEntity(this IDataQuery dataQuery) => Query(dataQuery, EntityFactory);
208
        codeBuilder
1✔
209
            .AppendLine("/// <summary>")
1✔
210
            .Append("/// Executes the command against the connection and converts the results to <see cref=\"T:")
1✔
211
            .Append(entity.FullyQualified)
1✔
212
            .AppendLine("\"/> objects.")
1✔
213
            .AppendLine("/// </summary>")
1✔
214
            .AppendLine("/// <param name=\"dataQuery\">The <see cref=\"T:FluentCommand.IDataQuery\"/> for this extension method.</param>")
1✔
215
            .AppendLine("/// <returns>")
1✔
216
            .Append("/// An <see cref=\"T:System.Collections.Generic.IEnumerable`1\" /> of <see cref=\"T:")
1✔
217
            .Append(entity.FullyQualified)
1✔
218
            .AppendLine("\"/> objects.")
1✔
219
            .AppendLine("/// </returns>")
1✔
220
            .Append("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"")
1✔
221
            .Append(ThisAssembly.Product)
1✔
222
            .Append("\", \"")
1✔
223
            .Append(ThisAssembly.InformationalVersion)
1✔
224
            .AppendLine("\")]")
1✔
225
            .Append("public static global::System.Collections.Generic.IEnumerable<")
1✔
226
            .Append(entity.FullyQualified)
1✔
227
            .AppendLine("> Query<TEntity>(")
1✔
228
            .IncrementIndent()
1✔
229
            .AppendLine("this global::FluentCommand.IDataQuery dataQuery)")
1✔
230
            .Append("where TEntity : ")
1✔
231
            .AppendLine(entity.FullyQualified)
1✔
232
            .DecrementIndent()
1✔
233
            .AppendLine("{")
1✔
234
            .IncrementIndent()
1✔
235
            .Append("return dataQuery.Query<")
1✔
236
            .Append(entity.FullyQualified)
1✔
237
            .AppendLine(">(")
1✔
238
            .IncrementIndent()
1✔
239
            .Append("factory: ")
1✔
240
            .Append(entity.EntityName)
1✔
241
            .Append("DataReaderExtensions.")
1✔
242
            .Append(entity.EntityName)
1✔
243
            .AppendLine("Factory,")
1✔
244
            .AppendLine("commandBehavior: global::System.Data.CommandBehavior.SequentialAccess |")
1✔
245
            .AppendLine("                 global::System.Data.CommandBehavior.SingleResult);")
1✔
246
            .DecrementIndent()
1✔
247
            .DecrementIndent()
1✔
248
            .AppendLine("}")
1✔
249
            .AppendLine();
1✔
250
    }
1✔
251

252
    private static void WriteEntityFactory(IndentedStringBuilder codeBuilder, EntityClass entity)
253
    {
254
        codeBuilder
1✔
255
            .AppendLine("/// <summary>")
1✔
256
            .Append("/// A factory for creating <see cref=\"T:")
1✔
257
            .Append(entity.FullyQualified)
1✔
258
            .AppendLine("\"/> objects from the current row in the specified <paramref name=\"dataRecord\"/>.")
1✔
259
            .AppendLine("/// </summary>")
1✔
260
            .AppendLine("/// <param name=\"dataRecord\">The open <see cref=\"T:System.Data.IDataReader\"/> to get the object from.</param>")
1✔
261
            .AppendLine("/// <returns>")
1✔
262
            .Append("/// A instance of <see cref=\"")
1✔
263
            .Append(entity.FullyQualified)
1✔
264
            .AppendLine("\"/>  having property names set that match the field names in the <paramref name=\"dataRecord\"/>.")
1✔
265
            .AppendLine("/// </returns>")
1✔
266
            .Append("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"")
1✔
267
            .Append(ThisAssembly.Product)
1✔
268
            .Append("\", \"")
1✔
269
            .Append(ThisAssembly.InformationalVersion)
1✔
270
            .AppendLine("\")]")
1✔
271
            .Append("public static ")
1✔
272
            .Append(entity.FullyQualified)
1✔
273
            .Append(" ")
1✔
274
            .Append(entity.EntityName)
1✔
275
            .AppendLine("Factory(this global::System.Data.IDataReader dataRecord)")
1✔
276
            .AppendLine("{")
1✔
277
            .IncrementIndent()
1✔
278
            .AppendLine("if (dataRecord == null)")
1✔
279
            .IncrementIndent()
1✔
280
            .AppendLine("throw new global::System.ArgumentNullException(nameof(dataRecord));")
1✔
281
            .DecrementIndent()
1✔
282
            .AppendLine();
1✔
283

284
        foreach (var entityProperty in entity.Properties)
12✔
285
        {
286
            if (entityProperty.IsNotMapped)
5✔
287
                continue;
288

289
            var aliasType = GetAliasMap(entityProperty.PropertyType);
5✔
290
            var fieldName = CamelCase(entityProperty.PropertyName);
5✔
291

292
            // local variable
293
            codeBuilder
5✔
294
                .Append(aliasType)
5✔
295
                .Append(" v_")
5✔
296
                .Append(fieldName)
5✔
297
                .Append(" = default")
5✔
298
                .AppendIf("!", _ => !entityProperty.PropertyType.EndsWith("?"))
5✔
299
                .AppendLine(";");
5✔
300
        }
301

302
        codeBuilder
1✔
303
            .AppendLine()
1✔
304
            .AppendLine("for (var __index = 0; __index < dataRecord.FieldCount; __index++)")
1✔
305
            .AppendLine("{")
1✔
306
            .IncrementIndent()
1✔
307
            .AppendLine("if (dataRecord.IsDBNull(__index))")
1✔
308
            .IncrementIndent()
1✔
309
            .AppendLine(" continue;")
1✔
310
            .DecrementIndent()
1✔
311
            .AppendLine();
1✔
312

313
        codeBuilder
1✔
314
            .AppendLine("var __name = dataRecord.GetName(__index);")
1✔
315
            .AppendLine("switch (__name)")
1✔
316
            .AppendLine("{")
1✔
317
            .IncrementIndent();
1✔
318

319
        foreach (var entityProperty in entity.Properties)
12✔
320
        {
321
            if (entityProperty.IsNotMapped)
5✔
322
                continue;
323

324
            var fieldName = CamelCase(entityProperty.PropertyName);
5✔
325

326
            codeBuilder
5✔
327
                .Append("case \"")
5✔
328
                .Append(entityProperty.ColumnName)
5✔
329
                .AppendLine("\":");
5✔
330

331
            if (string.IsNullOrEmpty(entityProperty.ConverterName))
5!
332
            {
333
                var readerName = GetReaderName(entityProperty.PropertyType);
5✔
334

335
                codeBuilder
5✔
336
                    .IncrementIndent()
5✔
337
                    .Append("v_")
5✔
338
                    .Append(fieldName)
5✔
339
                    .Append(" = dataRecord.")
5✔
340
                    .Append(readerName)
5✔
341
                    .AppendLine("(__index);")
5✔
342
                    .AppendLine("break;")
5✔
343
                    .DecrementIndent();
5✔
344
            }
345
            else
346
            {
347
                // create converter via singleton helper
348
                codeBuilder
×
349
                    .IncrementIndent()
×
350
                    .Append("var c_")
×
351
                    .Append(fieldName)
×
352
                    .Append(" = global::FluentCommand.Internal.Singleton<")
×
NEW
353
                    .Append(entityProperty.ConverterName!)
×
354
                    .AppendLine(">.Current")
×
355
                    .IncrementIndent()
×
356
                    .Append("as global::FluentCommand.IDataFieldConverter<")
×
357
                    .Append(entityProperty.PropertyType)
×
358
                    .AppendLine(">;")
×
359
                    .DecrementIndent()
×
360
                    .AppendLine();
×
361

362
                // read via converter instance
363
                codeBuilder
×
364
                    .Append("v_")
×
365
                    .Append(fieldName)
×
366
                    .Append(" = c_")
×
367
                    .Append(fieldName)
×
368
                    .AppendLine(".ReadValue(dataRecord, __index);")
×
369
                    .AppendLine("break;")
×
370
                    .DecrementIndent();
×
371
            }
372
        }
373

374
        codeBuilder
1✔
375
            .DecrementIndent()
1✔
376
            .AppendLine("}") // switch
1✔
377
            .DecrementIndent()
1✔
378
            .AppendLine("}") // for
1✔
379
            .AppendLine();
1✔
380

381
        if (entity.InitializationMode == InitializationMode.Constructor)
1!
382
            WriteReturnConstructor(codeBuilder, entity);
×
383
        else
384
            WriteReturnObjectInitializer(codeBuilder, entity);
1✔
385

386
        codeBuilder
1✔
387
            .DecrementIndent()
1✔
388
            .AppendLine("}") // method
1✔
389
            .AppendLine();
1✔
390
    }
1✔
391

392
    private static void WriteReturnConstructor(IndentedStringBuilder codeBuilder, EntityClass entity)
393
    {
394
        codeBuilder
×
395
            .Append("return new ")
×
396
            .Append(entity.FullyQualified)
×
397
            .AppendLine("(")
×
398
            .IncrementIndent();
×
399

NEW
400
        var mappedProperties = entity.Properties.Where(p => !p.IsNotMapped).ToList();
×
401
        var index = 0;
×
NEW
402
        var count = mappedProperties.Count;
×
403

NEW
404
        foreach (var entityProperty in mappedProperties)
×
405
        {
406
            var fieldName = CamelCase(entityProperty.PropertyName);
×
407
            codeBuilder
×
NEW
408
                .Append(entityProperty.ParameterName!)
×
409
                .Append(": ")
×
410
                .Append(" v_")
×
411
                .Append(fieldName);
×
412

413
            if (++index == count)
×
414
                codeBuilder.AppendLine();
×
415
            else
416
                codeBuilder.AppendLine(",");
×
417
        }
418

419
        codeBuilder
×
420
            .DecrementIndent()
×
421
            .AppendLine(");"); // new
×
422
    }
×
423

424
    private static void WriteReturnObjectInitializer(IndentedStringBuilder codeBuilder, EntityClass entity)
425
    {
426
        codeBuilder
1✔
427
            .Append("return new ")
1✔
428
            .AppendLine(entity.FullyQualified)
1✔
429
            .AppendLine("{")
1✔
430
            .IncrementIndent();
1✔
431

432
        var mappedProperties = entity.Properties.Where(p => !p.IsNotMapped).ToList();
6✔
433
        var index = 0;
1✔
434
        var count = mappedProperties.Count;
1✔
435

436
        foreach (var entityProperty in mappedProperties)
12✔
437
        {
438
            var fieldName = CamelCase(entityProperty.PropertyName);
5✔
439
            codeBuilder
5✔
440
                .Append(entityProperty.PropertyName)
5✔
441
                .Append(" = ")
5✔
442
                .Append(" v_")
5✔
443
                .Append(fieldName);
5✔
444

445
            if (++index == count)
5✔
446
                codeBuilder.AppendLine();
1✔
447
            else
448
                codeBuilder.AppendLine(",");
4✔
449
        }
450

451
        codeBuilder
1✔
452
            .DecrementIndent()
1✔
453
            .AppendLine("};"); // new
1✔
454
    }
1✔
455

456
    private static string GetAliasMap(string type)
457
    {
458
        return type switch
5!
459
        {
5✔
460
            "System.Boolean" => "bool",
1✔
461
            "System.Byte" => "byte",
×
462
            "System.Byte[]" => "byte[]",
1✔
463
            "System.Char" => "char",
×
464
            "System.Decimal" => "decimal",
×
465
            "System.Double" => "double",
×
466
            "System.Single" => "float",
×
467
            "System.Int16" => "short",
×
468
            "System.Int32" => "int",
1✔
469
            "System.Int64" => "long",
×
470
            "System.String" => "string",
1✔
471
            _ => type,
1✔
472
        };
5✔
473
    }
474

475
    private static string GetReaderName(string propertyType)
476
    {
477
        // remove nullable
478
        var type = propertyType.EndsWith("?") ? propertyType.Substring(0, propertyType.Length - 1) : propertyType;
5!
479

480
        return type switch
5!
481
        {
5✔
482
            "System.Boolean" => "GetBoolean",
1✔
483
            "System.Byte" => "GetByte",
×
484
            "System.Byte[]" => "GetBytes",
1✔
485
            "System.Char" => "GetChar",
×
486
            "System.DateTime" => "GetDateTime",
×
487
            "System.DateTimeOffset" => "GetDateTimeOffset",
1✔
488
            "System.Decimal" => "GetDecimal",
×
489
            "System.Double" => "GetDouble",
×
490
            "System.Guid" => "GetGuid",
×
491
            "System.Single" => "GetFloat",
×
492
            "System.Int16" => "GetInt16",
×
493
            "System.Int32" => "GetInt32",
1✔
494
            "System.Int64" => "GetInt64",
×
495
            "System.String" => "GetString",
1✔
496
            "bool" => "GetBoolean",
×
497
            "byte" => "GetByte",
×
498
            "byte[]" => "GetBytes",
×
499
            "char" => "GetChar",
×
500
            "decimal" => "GetDecimal",
×
501
            "double" => "GetDouble",
×
502
            "float" => "GetFloat",
×
503
            "short" => "GetInt16",
×
504
            "int" => "GetInt32",
×
505
            "long" => "GetInt64",
×
506
            "string" => "GetString",
×
507
            "FluentCommand.ConcurrencyToken" => "GetBytes",
×
508
            _ => $"GetValue<{type}>"
×
509
        };
5✔
510
    }
511

512
    private static string CamelCase(string name)
513
    {
514
        if (string.IsNullOrEmpty(name) || !char.IsUpper(name[0]))
15!
515
            return name;
×
516

517
        char[] chars = name.ToCharArray();
15✔
518
        FixCasing(chars);
15✔
519

520
        return new string(chars);
15✔
521
    }
522

523
    private static void FixCasing(Span<char> chars)
524
    {
525
        for (int i = 0; i < chars.Length; i++)
60✔
526
        {
527
            if (i == 1 && !char.IsUpper(chars[i]))
30✔
528
                break;
529

530
            bool hasNext = (i + 1 < chars.Length);
15✔
531

532
            // Stop when next char is already lowercase.
533
            if (i > 0 && hasNext && !char.IsUpper(chars[i + 1]))
15!
534
            {
535
                // If the next char is a space, lowercase current char before exiting.
536
                if (chars[i + 1] == ' ')
×
537
                    chars[i] = char.ToLowerInvariant(chars[i]);
×
538

539
                break;
×
540
            }
541

542
            chars[i] = char.ToLowerInvariant(chars[i]);
15✔
543
        }
544
    }
15✔
545
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc