From 49411c9dd0bae2e68810f0fcfb4deb4e47500ccb Mon Sep 17 00:00:00 2001 From: Carl Berg Date: Sat, 11 Mar 2023 16:52:43 +0100 Subject: [PATCH] Handling default values (including null) for most sql server data types (#29) --- DataDude.Tests/Inserts/InstructionTests.cs | 49 +++++++++++++++++++ DataDude/DataDude.csproj | 4 +- DataDude/DataDudeContext.cs | 28 +++++++---- DataDude/Instructions/Insert/InsertContext.cs | 1 + .../ValueProviders/BinaryValueProvider.cs | 2 +- .../ValueProviders/DateValueProvider.cs | 1 + .../ValueProviders/GuidValueProvider.cs | 18 +++++++ .../ValueProviders/NumericValueProvider.cs | 2 +- .../ValueProviders/StringValueProvider.cs | 2 +- .../ValueProviders/VersionValueProvider.cs | 2 +- 10 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 DataDude/Instructions/Insert/ValueProviders/GuidValueProvider.cs diff --git a/DataDude.Tests/Inserts/InstructionTests.cs b/DataDude.Tests/Inserts/InstructionTests.cs index 3f126e0..dace082 100644 --- a/DataDude.Tests/Inserts/InstructionTests.cs +++ b/DataDude.Tests/Inserts/InstructionTests.cs @@ -379,5 +379,54 @@ public async Task Can_Insert_Default_Date_Times() var rows = await connection.QueryAsync("SELECT SomeDate, SomeTime, SomeDateTime FROM Test_DateTime_Data"); rows.ShouldHaveSingleItem(); } + + [Theory] + [InlineData("bigint")] + [InlineData("bit")] + [InlineData("decimal")] + [InlineData("int")] + [InlineData("money")] + [InlineData("numeric")] + [InlineData("smallint")] + [InlineData("smallmoney")] + [InlineData("tinyint")] + [InlineData("float")] + [InlineData("real")] + [InlineData("date")] + [InlineData("datetime2")] + [InlineData("datetime")] + [InlineData("datetimeoffset")] + [InlineData("smalldatetime")] + [InlineData("time")] + [InlineData("char")] + [InlineData("text")] + [InlineData("varchar")] + [InlineData("nchar")] + [InlineData("ntext")] + [InlineData("nvarchar")] + [InlineData("binary")] + [InlineData("varbinary")] + [InlineData("image")] + [InlineData("uniqueidentifier")] + public async Task Can_Insert_Default_Values(string dataType) + { + using var connection = Fixture.CreateNewConnection(); + + var tableName = $"Test_{dataType}"; + await connection.ExecuteAsync($"" + + $""" + CREATE TABLE [{tableName}] + ( + Id INT PRIMARY KEY IDENTITY, + Value {dataType} NOT NULL, + NullableValue {dataType} NULL + ) + """); + + await new Dude().Insert(tableName).Go(connection); + + var rows = await connection.QueryAsync($"SELECT * FROM [{tableName}]"); + rows.ShouldHaveSingleItem(); + } } } diff --git a/DataDude/DataDude.csproj b/DataDude/DataDude.csproj index 4a298e8..75775ff 100644 --- a/DataDude/DataDude.csproj +++ b/DataDude/DataDude.csproj @@ -2,9 +2,9 @@ netstandard2.1 - 9.0 + 11.0 enable - 0.8.0-preview.4 + 0.8.0-preview.5 true true snupkg diff --git a/DataDude/DataDudeContext.cs b/DataDude/DataDudeContext.cs index 2f7ab97..caeaa6b 100644 --- a/DataDude/DataDudeContext.cs +++ b/DataDude/DataDudeContext.cs @@ -31,25 +31,35 @@ public DataDudeContext(ISchemaLoader schemaLoader) public static IDictionary TypeMappings { get; } = new Dictionary { ["bit"] = DbType.Boolean, + ["bigint"] = DbType.Int64, + ["binary"] = DbType.Binary, + ["char"] = DbType.String, ["date"] = DbType.Date, ["datetime"] = DbType.DateTime, ["datetime2"] = DbType.DateTime2, ["datetimeoffset"] = DbType.DateTimeOffset, ["decimal"] = DbType.Decimal, - ["numeric"] = DbType.Decimal, ["float"] = DbType.Double, - ["real"] = DbType.Double, - ["uniqueidentifier"] = DbType.Guid, - ["smallint"] = DbType.Int16, + ["geography"] = DbType.String, ["int"] = DbType.Int32, - ["bigint"] = DbType.Int64, - ["variant"] = DbType.Object, - ["varbinary"] = DbType.Binary, - ["varchar"] = DbType.String, + ["image"] = DbType.Binary, + ["nchar"] = DbType.String, + ["ntext"] = DbType.String, ["nvarchar"] = DbType.String, + ["numeric"] = DbType.Decimal, + ["money"] = DbType.Decimal, + ["real"] = DbType.Double, + ["smalldatetime"] = DbType.DateTime, + ["smallint"] = DbType.Int16, + ["smallmoney"] = DbType.Decimal, ["text"] = DbType.String, - ["geography"] = DbType.String, + ["tinyint"] = DbType.Int16, + ["time"] = DbType.Time, ["timestamp"] = DbType.Binary, + ["uniqueidentifier"] = DbType.Guid, + ["varbinary"] = DbType.Binary, + ["varchar"] = DbType.String, + ["variant"] = DbType.Object, }; public ISchemaLoader SchemaLoader { get; } diff --git a/DataDude/Instructions/Insert/InsertContext.cs b/DataDude/Instructions/Insert/InsertContext.cs index 52f7659..1ba46c5 100644 --- a/DataDude/Instructions/Insert/InsertContext.cs +++ b/DataDude/Instructions/Insert/InsertContext.cs @@ -25,6 +25,7 @@ public InsertContext(DataDudeContext context) new DateValueProvider(), new BoolValueProvider(), new VersionValueProvider(), + new GuidValueProvider() }; public IList InsertRowHandlers { get; } = new List diff --git a/DataDude/Instructions/Insert/ValueProviders/BinaryValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/BinaryValueProvider.cs index 7015a5d..3c49b7b 100644 --- a/DataDude/Instructions/Insert/ValueProviders/BinaryValueProvider.cs +++ b/DataDude/Instructions/Insert/ValueProviders/BinaryValueProvider.cs @@ -6,7 +6,7 @@ public class BinaryValueProvider : ValueProvider { protected override ColumnValue? GetDefaultValue(ColumnInformation column, ColumnValue value) { - if (column.DataType is "varbinary") + if (column.DataType is "binary" or "image" or "varbinary") { return new ColumnValue(new byte[0]); } diff --git a/DataDude/Instructions/Insert/ValueProviders/DateValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/DateValueProvider.cs index 9f5fd08..c6461fe 100644 --- a/DataDude/Instructions/Insert/ValueProviders/DateValueProvider.cs +++ b/DataDude/Instructions/Insert/ValueProviders/DateValueProvider.cs @@ -10,6 +10,7 @@ public class DateValueProvider : ValueProvider return column.DataType switch { "date" or "datetime" or "datetime2" => new ColumnValue(new DateTime(1753, 1, 1, 12, 0, 0)), + "smalldatetime" => new ColumnValue(new DateTime(1900, 1, 1, 12, 0, 0)), "datetimeoffset" => new ColumnValue(new DateTimeOffset(1753, 1, 1, 12, 0, 0, TimeSpan.Zero)), "time" => new ColumnValue(TimeSpan.Zero), _ => null diff --git a/DataDude/Instructions/Insert/ValueProviders/GuidValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/GuidValueProvider.cs new file mode 100644 index 0000000..d4dddc5 --- /dev/null +++ b/DataDude/Instructions/Insert/ValueProviders/GuidValueProvider.cs @@ -0,0 +1,18 @@ +using System; +using DataDude.Schema; + +namespace DataDude.Instructions.Insert.ValueProviders +{ + public class GuidValueProvider : ValueProvider + { + protected override ColumnValue? GetDefaultValue(ColumnInformation column, ColumnValue value) + { + if (column.DataType is "uniqueidentifier") + { + return new ColumnValue(Guid.NewGuid()); + } + + return null; + } + } +} diff --git a/DataDude/Instructions/Insert/ValueProviders/NumericValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/NumericValueProvider.cs index bc4a569..3c66c7d 100644 --- a/DataDude/Instructions/Insert/ValueProviders/NumericValueProvider.cs +++ b/DataDude/Instructions/Insert/ValueProviders/NumericValueProvider.cs @@ -6,7 +6,7 @@ public class NumericValueProvider : ValueProvider { protected override ColumnValue? GetDefaultValue(ColumnInformation column, ColumnValue value) { - if (column.DataType is "int" or "smallint" or "bigint" or "decimal" or "numeric" or "real" or "float") + if (column.DataType is "int" or "smallint" or "tinyint" or "bigint" or "decimal" or "numeric" or "money" or "smallmoney" or "real" or "float") { return new ColumnValue(0); } diff --git a/DataDude/Instructions/Insert/ValueProviders/StringValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/StringValueProvider.cs index cc36c94..f65571b 100644 --- a/DataDude/Instructions/Insert/ValueProviders/StringValueProvider.cs +++ b/DataDude/Instructions/Insert/ValueProviders/StringValueProvider.cs @@ -6,7 +6,7 @@ public class StringValueProvider : ValueProvider { protected override ColumnValue? GetDefaultValue(ColumnInformation column, ColumnValue value) { - if (column.DataType is "varchar" or "nvarchar" or "text") + if (column.DataType is "char" or "varchar" or "nchar" or "ntext" or "nvarchar" or "text") { return new ColumnValue(string.Empty); } diff --git a/DataDude/Instructions/Insert/ValueProviders/VersionValueProvider.cs b/DataDude/Instructions/Insert/ValueProviders/VersionValueProvider.cs index 6f8405b..72ecb7b 100644 --- a/DataDude/Instructions/Insert/ValueProviders/VersionValueProvider.cs +++ b/DataDude/Instructions/Insert/ValueProviders/VersionValueProvider.cs @@ -6,7 +6,7 @@ public class VersionValueProvider : ValueProvider { protected override ColumnValue? GetDefaultValue(ColumnInformation column, ColumnValue value) { - if (column.DataType is "timestamp") + if (column.DataType is "timestamp" or "rowversion") { return ColumnValue.Ignore; }