From d3f962446736dfd81ac96197172048b825870b73 Mon Sep 17 00:00:00 2001 From: Carl Berg Date: Mon, 20 Feb 2023 14:09:24 +0100 Subject: [PATCH] Geography parameter handling (#25) * Added custom handling for geography parameters * Bumped version * Tweaking setting of udt type * Added geography integration tests --- .../Scripts/Migrations/1.0.0/01.Schema.sql | 6 ++++ DataDude.Tests/DataDude.Tests.csproj | 1 + DataDude.Tests/Inserts/InstructionTests.cs | 26 +++++++++++++++++ DataDude/DataDude.csproj | 2 +- DataDude/Database/DataDudeDbParameter.cs | 28 +++++++++++-------- .../Instructions/IInstructionDecorator.cs | 2 +- .../Insert/Insertion/RowInsertHandler.cs | 2 +- 7 files changed, 53 insertions(+), 14 deletions(-) diff --git a/DataDude.Tests/Core/Scripts/Migrations/1.0.0/01.Schema.sql b/DataDude.Tests/Core/Scripts/Migrations/1.0.0/01.Schema.sql index ff5b4c8..acf2187 100644 --- a/DataDude.Tests/Core/Scripts/Migrations/1.0.0/01.Schema.sql +++ b/DataDude.Tests/Core/Scripts/Migrations/1.0.0/01.Schema.sql @@ -82,6 +82,12 @@ CREATE TABLE Test_Nullable_Text_Data_Type( ) GO +CREATE TABLE Test_Geography_Data( + Id INT IDENTITY PRIMARY KEY, + Position GEOGRAPHY NULL, +) +GO + CREATE TRIGGER People.EmployeeUpdatedAt ON People.Employee AFTER UPDATE AS BEGIN UPDATE People.Employee SET People.Employee.UpdatedAt = GETDATE() diff --git a/DataDude.Tests/DataDude.Tests.csproj b/DataDude.Tests/DataDude.Tests.csproj index 1f93104..015451b 100644 --- a/DataDude.Tests/DataDude.Tests.csproj +++ b/DataDude.Tests/DataDude.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/DataDude.Tests/Inserts/InstructionTests.cs b/DataDude.Tests/Inserts/InstructionTests.cs index 3f2b4ef..ee829cb 100644 --- a/DataDude.Tests/Inserts/InstructionTests.cs +++ b/DataDude.Tests/Inserts/InstructionTests.cs @@ -4,6 +4,7 @@ using DataDude.Instructions.Insert; using DataDude.Instructions.Insert.Insertion; using DataDude.Tests.Core; +using Microsoft.SqlServer.Types; using Shouldly; using Xunit; @@ -345,5 +346,30 @@ public async Task Split_Inserts_Keeps_Track_Of_Previously_Inserted_Data() var officeOccupancies = await connection.QueryAsync("SELECT * FROM People.OfficeOccupancy"); officeOccupancies.ShouldContain(x => true, 2, "Should contain two occupancies"); } + + [Fact] + public async Task Can_Insert_Geography_Data() + { + using var connection = Fixture.CreateNewConnection(); + var position = SqlGeography.Point(50, 11, 4326); + + var dude = new Dude(); + await dude + .Insert("Test_Geography_Data", + new { Position = position }, + new { Position = (SqlGeography)null }) + .Go(connection); + + var geography_data = (await connection.QueryAsync<(decimal? Lat, decimal? Long)>("SELECT Position.Lat, Position.Long FROM Test_Geography_Data ORDER BY Id")).ToList(); + geography_data.ShouldSatisfyAllConditions( + positions => positions[0].ShouldSatisfyAllConditions( + position => position.Lat.ShouldBe(50), + position => position.Long.ShouldBe(11)), + positions => positions[1].ShouldSatisfyAllConditions( + position => position.Lat.ShouldBeNull(), + position => position.Long.ShouldBeNull())); + + + } } } diff --git a/DataDude/DataDude.csproj b/DataDude/DataDude.csproj index 09a0896..1e31b01 100644 --- a/DataDude/DataDude.csproj +++ b/DataDude/DataDude.csproj @@ -4,7 +4,7 @@ netstandard2.1 9.0 enable - 0.8.0-preview.1 + 0.8.0-preview.2 true true snupkg diff --git a/DataDude/Database/DataDudeDbParameter.cs b/DataDude/Database/DataDudeDbParameter.cs index a8a3712..cf92957 100644 --- a/DataDude/Database/DataDudeDbParameter.cs +++ b/DataDude/Database/DataDudeDbParameter.cs @@ -1,31 +1,37 @@ using System; using System.Data; using System.Data.Common; +using System.Reflection; +using DataDude.Instructions.Insert; +using DataDude.Schema; namespace DataDude.Core { public struct DataDudeDbParameter { - public DataDudeDbParameter(string name, object? value, DbType? dbType) + public DataDudeDbParameter(ColumnInformation column, ColumnValue? value) { - Name = name; - Value = value; - DbType = dbType; + Column = column; + ColumnValue = value; } - public string Name { get; } - public object? Value { get; } - public DbType? DbType { get; } + public ColumnInformation Column { get; } + public ColumnValue? ColumnValue { get; } public void AddParameterTo(DbCommand cmd) { var param = cmd.CreateParameter(); - param.ParameterName = $"@{Name}"; - param.Value = Value ?? DBNull.Value; + param.ParameterName = $"@{Column.Name}"; + param.Value = ColumnValue?.Value ?? DBNull.Value; param.Direction = ParameterDirection.Input; - if (DbType is { }) + + if (ColumnValue?.DbType is { } dbType) { - param.DbType = DbType.Value; + param.DbType = dbType; + } + else if (Column is { DataType: "geography" } && param.GetType().GetProperty("UdtTypeName") is PropertyInfo udtProperty) + { + udtProperty.SetValue(param, "geography"); } cmd.Parameters.Add(param); diff --git a/DataDude/Instructions/IInstructionDecorator.cs b/DataDude/Instructions/IInstructionDecorator.cs index 965e2a1..a209526 100644 --- a/DataDude/Instructions/IInstructionDecorator.cs +++ b/DataDude/Instructions/IInstructionDecorator.cs @@ -3,7 +3,7 @@ namespace DataDude.Instructions { /// - /// + /// Intercept context before and after instructions have been executed /// public interface IInstructionDecorator { diff --git a/DataDude/Instructions/Insert/Insertion/RowInsertHandler.cs b/DataDude/Instructions/Insert/Insertion/RowInsertHandler.cs index ddf48d8..eb3b8e2 100644 --- a/DataDude/Instructions/Insert/Insertion/RowInsertHandler.cs +++ b/DataDude/Instructions/Insert/Insertion/RowInsertHandler.cs @@ -23,7 +23,7 @@ protected internal (string columns, string values, IReadOnlyList