Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/conventions.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# applied automatically by https://github.com/Faithlife/RepoConventionsApplier (DO NOT REMOVE THIS LINE)
conventions:
- path: Faithlife/CodingGuidelines/conventions/faithlife-auto-apply-conventions
- path: Faithlife/CodingGuidelines/conventions/dotnet-common
- path: Faithlife/CodingGuidelines/conventions/faithlife-dotnet-library-build
- path: Faithlife/CodingGuidelines/conventions/faithlife-dotnet-library-workflow
- path: Faithlife/CodingGuidelines/conventions/faithlife-license-mit
- path: Faithlife/CodingGuidelines/conventions/faithlife-dotnet-library

pull-request:
reviewers:
Expand Down
21 changes: 13 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
.vs/
.idea/
# DO NOT EDIT: gitignore-common convention
.DS_Store
Thumbs.db
*.log
# END DO NOT EDIT

# DO NOT EDIT: gitignore-dotnet convention
artifacts/
bin/
obj/
release/
# END DO NOT EDIT

# DO NOT EDIT: gitignore-ide convention
.vs/
.idea/
*.cache
*.log
*.ncrunchproject
*.ncrunchsolution
*.user
launchSettings.json
nCrunchTemp*
*.userprefs
_ReSharper*
.DS_Store
# END DO NOT EDIT
2 changes: 2 additions & 0 deletions DapperUtility.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
</Folder>
<Folder Name="/Solution Items/.github/">
<File Path=".github/conventions.yml" />
<File Path=".github/lsp.json" />
</Folder>
<Folder Name="/Solution Items/.github/workflows/">
<File Path=".github/workflows/ci.yml" />
<File Path=".github/workflows/copilot-setup-steps.yml" />
</Folder>
<Project Path="src/Faithlife.Utility.Dapper/Faithlife.Utility.Dapper.csproj" />
<Project Path="tests/Faithlife.Utility.Dapper.Tests/Faithlife.Utility.Dapper.Tests.csproj" />
Expand Down
27 changes: 14 additions & 13 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
<PropertyGroup>
<VersionPrefix>2.0.0</VersionPrefix>
<PackageValidationBaselineVersion>2.0.0</PackageValidationBaselineVersion>
<LangVersion>12.0</LangVersion>
<Nullable>disable</Nullable>
<NoWarn>$(NoWarn);1591;1998;NU1507;NU5105</NoWarn>
<GitHubOrganization>Faithlife</GitHubOrganization>
<RepositoryName>DapperUtility</RepositoryName>
</PropertyGroup>

<!-- DO NOT EDIT: faithlife-dotnet-library-props convention -->
<PropertyGroup>
<LangVersion>14.0</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);1591;1998;NU1507;NU5105</NoWarn>
<NeutralLanguage>en-US</NeutralLanguage>
<DebugType>embedded</DebugType>
<GitHubOrganization>Faithlife</GitHubOrganization>
<RepositoryName>DapperUtility</RepositoryName>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/$(GitHubOrganization)/$(RepositoryName)</PackageProjectUrl>
<PackageReleaseNotes>https://github.com/$(GitHubOrganization)/$(RepositoryName)/blob/master/ReleaseNotes.md</PackageReleaseNotes>
<RepositoryUrl>https://github.com/$(GitHubOrganization)/$(RepositoryName).git</RepositoryUrl>
<RepositoryUrl>https://github.com/$(GitHubOrganization)/$(RepositoryName)</RepositoryUrl>
<Authors>Faithlife</Authors>
<Copyright>Copyright $(Authors)</Copyright>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-all</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
Expand All @@ -31,11 +33,10 @@
<EnableStrictModeForCompatibleFrameworksInPackageValidation>true</EnableStrictModeForCompatibleFrameworksInPackageValidation>
<EnableStrictModeForCompatibleTfms>true</EnableStrictModeForCompatibleTfms>
<DisablePackageBaselineValidation Condition=" $(PackageValidationBaselineVersion) == $(VersionPrefix) or $(PackageValidationBaselineVersion) == '0.0.0' ">true</DisablePackageBaselineValidation>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAuditLevel>low</NuGetAuditLevel>
</PropertyGroup>

<PropertyGroup Condition=" '$(BuildNumber)' != '' ">
<AssemblyVersion>$(VersionPrefix).$(BuildNumber)</AssemblyVersion>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<!-- END DO NOT EDIT -->

</Project>
12 changes: 9 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<Project>
<!-- DO NOT EDIT: faithlife-dotnet-library-props/properties convention -->
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<CentralPackageFloatingVersionsEnabled>true</CentralPackageFloatingVersionsEnabled>
</PropertyGroup>
<!-- END DO NOT EDIT -->
<ItemGroup>
<PackageVersion Include="Dapper" Version="2.1.35" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
Expand All @@ -10,9 +14,11 @@
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.1" />
<PackageVersion Include="XmlDocMarkdown.Core" Version="2.9.0" />
</ItemGroup>
<!-- DO NOT EDIT: faithlife-dotnet-library-props/analyzers convention -->
<ItemGroup>
<GlobalPackageReference Include="Faithlife.Analyzers" Version="1.5.0" />
<GlobalPackageReference Include="NUnit.Analyzers" Version="4.2.0" />
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<GlobalPackageReference Include="Faithlife.Analyzers" Version="1.*" />
<GlobalPackageReference Include="NUnit.Analyzers" Version="4.*" />
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.*-*" />
</ItemGroup>
<!-- END DO NOT EDIT -->
</Project>
2 changes: 1 addition & 1 deletion nuget.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
38 changes: 19 additions & 19 deletions src/Faithlife.Utility.Dapper/BulkInsertUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ public static class BulkInsertUtility
/// <summary>
/// Efficiently inserts multiple rows, in batches as necessary.
/// </summary>
public static int BulkInsert<TInsert>(this IDbConnection connection, string sql, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null)
public static int BulkInsert<TInsert>(this IDbConnection connection, string sql, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null)
{
return connection.BulkInsert(sql, (object) null, insertParams, transaction, batchSize);
return connection.BulkInsert(sql, (object?) null, insertParams, transaction, batchSize);
}

/// <summary>
/// Efficiently inserts multiple rows, in batches as necessary.
/// </summary>
public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, string sql, TCommon commonParam, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null)
public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, string sql, TCommon? commonParam, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null)
{
int rowCount = 0;
foreach (var commandDefinition in GetBulkInsertCommands(sql, commonParam, insertParams, transaction, batchSize))
Expand All @@ -35,15 +35,15 @@ public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, st
/// <summary>
/// Efficiently inserts multiple rows, in batches as necessary.
/// </summary>
public static Task<int> BulkInsertAsync<TInsert>(this IDbConnection connection, string sql, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
public static Task<int> BulkInsertAsync<TInsert>(this IDbConnection connection, string sql, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
{
return connection.BulkInsertAsync(sql, (object) null, insertParams, transaction, batchSize, cancellationToken);
return connection.BulkInsertAsync(sql, (object?) null, insertParams, transaction, batchSize, cancellationToken);
}

/// <summary>
/// Efficiently inserts multiple rows, in batches as necessary.
/// </summary>
public static async Task<int> BulkInsertAsync<TCommon, TInsert>(this IDbConnection connection, string sql, TCommon commonParam, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
public static async Task<int> BulkInsertAsync<TCommon, TInsert>(this IDbConnection connection, string sql, TCommon? commonParam, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
{
int rowCount = 0;
foreach (var commandDefinition in GetBulkInsertCommands(sql, commonParam, insertParams, transaction, batchSize, cancellationToken))
Expand All @@ -54,15 +54,15 @@ public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, st
/// <summary>
/// Gets the Dapper <c>CommandDefinition</c>s used by <c>BulkInsert</c> and <c>BulkInsertAsync</c>.
/// </summary>
public static IEnumerable<CommandDefinition> GetBulkInsertCommands<TInsert>(string sql, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
public static IEnumerable<CommandDefinition> GetBulkInsertCommands<TInsert>(string sql, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
{
return GetBulkInsertCommands(sql, (object) null, insertParams, transaction, batchSize, cancellationToken);
return GetBulkInsertCommands(sql, (object?) null, insertParams, transaction, batchSize, cancellationToken);
}

/// <summary>
/// Gets the Dapper <c>CommandDefinition</c>s used by <c>BulkInsert</c> and <c>BulkInsertAsync</c>.
/// </summary>
public static IEnumerable<CommandDefinition> GetBulkInsertCommands<TCommon, TInsert>(string sql, TCommon commonParam, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
public static IEnumerable<CommandDefinition> GetBulkInsertCommands<TCommon, TInsert>(string sql, TCommon? commonParam, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (sql == null)
throw new ArgumentNullException(nameof(sql));
Expand All @@ -81,7 +81,7 @@ public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, st
return YieldBulkInsertCommands(valuesClauseMatches[0], sql, commonParam, insertParams, transaction, batchSize, cancellationToken);
}

private static IEnumerable<CommandDefinition> YieldBulkInsertCommands<TCommon, TInsert>(Match valuesClauseMatch, string sql, TCommon commonParam, IEnumerable<TInsert> insertParams, IDbTransaction transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
private static IEnumerable<CommandDefinition> YieldBulkInsertCommands<TCommon, TInsert>(Match valuesClauseMatch, string sql, TCommon? commonParam, IEnumerable<TInsert> insertParams, IDbTransaction? transaction = null, int? batchSize = null, CancellationToken cancellationToken = default(CancellationToken))
{
// identify SQL parts
Group tupleMatch = valuesClauseMatch.Groups[1];
Expand All @@ -91,7 +91,7 @@ public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, st

// get common names and values
string[] commonNames = ParamExtractor<TCommon>.GetNames();
object[] commonValues = ParamExtractor<TCommon>.GetValues(commonParam);
object?[] commonValues = ParamExtractor<TCommon>.GetValues(commonParam);

// get insert names and find insert parameters in tuple
string[] insertNames = ParamExtractor<TInsert>.GetNames();
Expand All @@ -106,9 +106,9 @@ public static int BulkInsert<TCommon, TInsert>(this IDbConnection connection, st
Math.Max(1, (maxParamsPerBatch - commonNames.Length) / Math.Max(1, insertNames.Length));

// insert one batch at a time
string batchSql = null;
string? batchSql = null;
int lastBatchCount = 0;
StringBuilder batchSqlBuilder = null;
StringBuilder? batchSqlBuilder = null;
foreach (var insertParamBatch in EnumerateBatches(insertParams, actualBatchSize))
{
// build the SQL for the batch
Expand Down Expand Up @@ -167,9 +167,9 @@ private static class ParamExtractor<T>
{
public static string[] GetNames() => s_names;

public static object[] GetValues(T param)
public static object?[] GetValues(T? param)
{
var values = new object[s_getters.Length];
var values = new object?[s_getters.Length];
if (param != null)
{
for (int index = 0; index < values.Length; index++)
Expand All @@ -183,7 +183,7 @@ static ParamExtractor()
#pragma warning restore CA1810
{
var names = new List<string>();
var getters = new List<Func<T, object>>();
var getters = new List<Func<T, object?>>();
foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
var getter = TryCreateGetter(property);
Expand All @@ -197,7 +197,7 @@ static ParamExtractor()
s_getters = [.. getters];
}

private static Func<T, object> TryCreateGetter(PropertyInfo property)
private static Func<T, object?>? TryCreateGetter(PropertyInfo property)
{
var getMethod = property.GetGetMethod();
var ownerType = property.DeclaringType;
Expand All @@ -215,11 +215,11 @@ private static Func<T, object> TryCreateGetter(PropertyInfo property)
generator.Emit(OpCodes.Box, property.PropertyType);
generator.Emit(OpCodes.Ret);

return (Func<T, object>) dynamicGetMethod.CreateDelegate(typeof(Func<T, object>));
return (Func<T, object?>) dynamicGetMethod.CreateDelegate(typeof(Func<T, object?>));
}

private static readonly string[] s_names;
private static readonly Func<T, object>[] s_getters;
private static readonly Func<T, object?>[] s_getters;
}

private static IEnumerable<IReadOnlyList<T>> EnumerateBatches<T>(IEnumerable<T> items, int batchSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<IsPackable>true</IsPackable>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RewritePackageReadmeLinks>true</RewritePackageReadmeLinks>
</PropertyGroup>

<ItemGroup>
Expand Down
14 changes: 7 additions & 7 deletions tests/Faithlife.Utility.Dapper.Tests/BulkInsertUtilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public void NullSql_Throws()
{
Assert.Throws<ArgumentNullException>(() =>
{
BulkInsertUtility.GetBulkInsertCommands(null, new[] { new { foo = 1 } });
BulkInsertUtility.GetBulkInsertCommands(null!, new[] { new { foo = 1 } });
});
}

Expand All @@ -29,7 +29,7 @@ public void NullInsertParams_Throws()
{
Assert.Throws<ArgumentNullException>(() =>
{
BulkInsertUtility.GetBulkInsertCommands("VALUES (@foo)...", default(object[]));
BulkInsertUtility.GetBulkInsertCommands("VALUES (@foo)...", default(object[])!);
});
}

Expand Down Expand Up @@ -84,7 +84,7 @@ public void MinimalInsert()
var commands = BulkInsertUtility.GetBulkInsertCommands("INSERT INTO t (foo)VALUES(@foo)...;", new[] { new { foo = 1 } }).ToList();
commands.Count.Should().Be(1);
commands[0].CommandText.Should().Be("INSERT INTO t (foo)VALUES(@foo_0);");
var parameters = (DynamicParameters) commands[0].Parameters;
var parameters = (DynamicParameters) commands[0].Parameters!;
parameters.ParameterNames.Single().Should().Be("foo_0");
((SqlMapper.IParameterLookup) parameters)["foo_0"].Should().Be(1);
}
Expand Down Expand Up @@ -112,7 +112,7 @@ public void CommonAndInsertedParameters()
var commands = BulkInsertUtility.GetBulkInsertCommands("VALUES (@a, @b, @c, @d)...", new { a = 1, b = 2 }, new[] { new { c = 3, d = 4 }, new { c = 5, d = 6 } }).ToList();
commands.Count.Should().Be(1);
commands[0].CommandText.Should().Be("VALUES (@a, @b, @c_0, @d_0),(@a, @b, @c_1, @d_1)");
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters;
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters!;
parameters["a"].Should().Be(1);
parameters["b"].Should().Be(2);
parameters["c_0"].Should().Be(3);
Expand All @@ -129,7 +129,7 @@ public void EightRowsInThreeBatches()
commands[0].CommandText.Should().Be("VALUES(@foo_0),(@foo_1),(@foo_2)");
commands[1].CommandText.Should().Be("VALUES(@foo_0),(@foo_1),(@foo_2)");
commands[2].CommandText.Should().Be("VALUES(@foo_0),(@foo_1)");
((SqlMapper.IParameterLookup) commands[2].Parameters)["foo_1"].Should().Be(7);
((SqlMapper.IParameterLookup) commands[2].Parameters!)["foo_1"].Should().Be(7);
}

[Fact]
Expand Down Expand Up @@ -177,7 +177,7 @@ public void NoParameterNameValidation()
var commands = BulkInsertUtility.GetBulkInsertCommands("VALUES (@a, @b, @c, @d)...", new { e = 1, f = 2 }, new[] { new { g = 3, h = 4 }, new { g = 5, h = 6 } }).ToList();
commands.Count.Should().Be(1);
commands[0].CommandText.Should().Be("VALUES (@a, @b, @c, @d),(@a, @b, @c, @d)");
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters;
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters!;
parameters["e"].Should().Be(1);
parameters["f"].Should().Be(2);
parameters["g_0"].Should().Be(3);
Expand All @@ -192,7 +192,7 @@ public void ComplexValues()
var commands = BulkInsertUtility.GetBulkInsertCommands("VALUES (@a + (@d * @c) -\r\n\t@d)...", new { a = 1, b = 2 }, new[] { new { c = 3, d = 4 }, new { c = 5, d = 6 } }).ToList();
commands.Count.Should().Be(1);
commands[0].CommandText.Should().Be("VALUES (@a + (@d_0 * @c_0) -\r\n\t@d_0),(@a + (@d_1 * @c_1) -\r\n\t@d_1)");
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters;
var parameters = (SqlMapper.IParameterLookup) commands[0].Parameters!;
parameters["a"].Should().Be(1);
parameters["b"].Should().Be(2);
parameters["c_0"].Should().Be(3);
Expand Down
Loading