diff --git a/ETLBox/ETLBox.csproj b/ETLBox/ETLBox.csproj
index 36f3ee39..b848968c 100644
--- a/ETLBox/ETLBox.csproj
+++ b/ETLBox/ETLBox.csproj
@@ -30,19 +30,19 @@
-
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
diff --git a/ETLBox/src/Definitions/ConnectionManager/DataTypeConverter.cs b/ETLBox/src/Definitions/ConnectionManager/DataTypeConverter.cs
index 793ab5d8..2c5879be 100644
--- a/ETLBox/src/Definitions/ConnectionManager/DataTypeConverter.cs
+++ b/ETLBox/src/Definitions/ConnectionManager/DataTypeConverter.cs
@@ -165,5 +165,24 @@ public static string TryGetDBSpecificType(string dbSpecificTypeName, ConnectionM
return dbSpecificTypeName;
}
}
+
+ public static DateTimeKind? GetNETDateTimeKind(string dbSpecificTypeName)
+ {
+ switch (dbSpecificTypeName)
+ {
+ case "date":
+ case "datetime":
+ case "smalldatetime":
+ case "datetime2":
+ case "time":
+ case "timestamp":
+ return DateTimeKind.Unspecified;
+ case "timetz":
+ case "timestamptz":
+ return DateTimeKind.Utc;
+ default:
+ return null;
+ }
+ }
}
}
diff --git a/ETLBox/src/Definitions/ConnectionManager/DbConnectionManager.cs b/ETLBox/src/Definitions/ConnectionManager/DbConnectionManager.cs
index dbc393a5..7fd10501 100644
--- a/ETLBox/src/Definitions/ConnectionManager/DbConnectionManager.cs
+++ b/ETLBox/src/Definitions/ConnectionManager/DbConnectionManager.cs
@@ -108,7 +108,10 @@ public IDbCommand CreateCommand(string commandText, IEnumerable
{
var newPar = cmd.CreateParameter();
newPar.ParameterName = par.Name;
- newPar.DbType = par.DBType;
+ newPar.DbType = ConnectionManagerType == ConnectionManagerType.Postgres && par.DBType == DbType.DateTime
+ ? DbType.DateTime2 // TODO: Move this hack to more appropriate place
+ // (fix for https://www.npgsql.org/doc/release-notes/6.0.html#major-changes-to-timestamp-mapping in NpgSql 6.0+)
+ : par.DBType;
newPar.Value = par.Value;
cmd.Parameters.Add(newPar);
}
diff --git a/ETLBox/src/Definitions/Database/TableColumn.cs b/ETLBox/src/Definitions/Database/TableColumn.cs
index 8a274d20..1d97c815 100644
--- a/ETLBox/src/Definitions/Database/TableColumn.cs
+++ b/ETLBox/src/Definitions/Database/TableColumn.cs
@@ -18,8 +18,9 @@ public class TableColumn : ITableColumn, IColumnMapping
public string DefaultValue { get; set; }
public string Collation { get; set; }
public string ComputedColumn { get; set; }
- public bool HasComputedColumn => !String.IsNullOrWhiteSpace(ComputedColumn);
+ public bool HasComputedColumn => !string.IsNullOrWhiteSpace(ComputedColumn);
public System.Type NETDataType => Type.GetType(DataTypeConverter.GetNETObjectTypeString(DataType));
+ public DateTimeKind? NETDateTimeKind => DataTypeConverter.GetNETDateTimeKind(DataType);
public string Comment { get; set; } //MySql only
public int? IdentitySeed { get; set; } //Sql Server only
diff --git a/TestConnectionManager/TestConnectionManager.csproj b/TestConnectionManager/TestConnectionManager.csproj
index 7d962f5a..0d15dc3a 100644
--- a/TestConnectionManager/TestConnectionManager.csproj
+++ b/TestConnectionManager/TestConnectionManager.csproj
@@ -9,10 +9,17 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/TestConnectionManager/default.config.json-template b/TestConnectionManager/default.config.json-template
index 2f02cdf5..bb254802 100644
--- a/TestConnectionManager/default.config.json-template
+++ b/TestConnectionManager/default.config.json-template
@@ -1,6 +1,6 @@
{
"DataFlow": {
- "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlow",
+ "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};TrustServerCertificate=true;User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlow",
"SqlOdbcConnectionString": "Driver={SQL Server};Server=${CFG_MSSQL_IP};Database=ETLBox_DataFlow;Uid=sa;Pwd=YourStrong@Passw0rd;",
"SQLiteConnectionString": "Data Source=.${CFG_PD}db${CFG_PD}SQLiteDataFlow.db;",
"AccessOdbcConnectionString": "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=.${CFG_PD}db${CFG_PD}AccessDataFlow.accdb",
@@ -9,18 +9,18 @@
"AzureSqlConnectionString": "Server=tcp:etlbox.database.windows.net,1433;Initial Catalog=etlbox;Persist Security Info=False;User ID=etlboxadmin;Password=ETLBoxPassw0rd!;"
},
"DataFlowSource": {
- "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlowSource",
+ "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};TrustServerCertificate=true;User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlowSource",
"SQLiteConnectionString": "Data Source=.${CFG_PD}db${CFG_PD}SQLiteDataFlowSource.db;",
"MySqlConnectionString": "Server=${CFG_MYSQL_IP};Database=ETLBox_DataFlowSource;Uid=root;Pwd=etlboxpassword;",
"PostgresConnectionString": "Server=${CFG_POSTGRES_IP};Database=ETLBox_DataFlowSource;User Id=postgres;Password=etlboxpassword;"
},
"DataFlowDestination": {
- "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlowDestination",
+ "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};TrustServerCertificate=true;User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_DataFlowDestination",
"SQLiteConnectionString": "Data Source=.${CFG_PD}db${CFG_PD}SQLiteDataFlowDestination.db;",
"MySqlConnectionString": "Server=${CFG_MYSQL_IP};Database=ETLBox_DataFlowDestination;Uid=root;Pwd=etlboxpassword;",
"PostgresConnectionString": "Server=${CFG_POSTGRES_IP};Database=ETLBox_DataFlowDestination;User Id=postgres;Password=etlboxpassword;"
},
"ConnectionManager": {
- "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_ConnectionManager"
+ "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};TrustServerCertificate=true;User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_ConnectionManager"
}
}
diff --git a/TestControlFlowTasks/TestControlFlowTasks.csproj b/TestControlFlowTasks/TestControlFlowTasks.csproj
index 881860b2..aa6ffc12 100644
--- a/TestControlFlowTasks/TestControlFlowTasks.csproj
+++ b/TestControlFlowTasks/TestControlFlowTasks.csproj
@@ -9,10 +9,17 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/TestControlFlowTasks/default.config.json-template b/TestControlFlowTasks/default.config.json-template
index af5693d1..92bba556 100644
--- a/TestControlFlowTasks/default.config.json-template
+++ b/TestControlFlowTasks/default.config.json-template
@@ -1,6 +1,6 @@
{
"ControlFlow": {
- "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_ControlFlow",
+ "SqlConnectionString": "Data Source=${CFG_MSSQL_IP};TrustServerCertificate=true;User Id=sa;Password=YourStrong@Passw0rd;Initial Catalog=ETLBox_ControlFlow",
"SSASConnectionString": "Data Source=.;Integrated Security=SSPI;Initial Catalog=ETLBox_ControlFlow",
"SQLiteConnectionString": "Data Source=.${CFG_PD}db${CFG_PD}SQLiteControlFlow.db;",
"AccessOdbcConnectionString": "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=.${CFG_PD}db${CFG_PD}AccessControlFlow.accdb",
diff --git a/TestControlFlowTasks/src/Postgres/TableDefinitionTests.cs b/TestControlFlowTasks/src/Postgres/TableDefinitionTests.cs
index f963d788..c53bfde5 100644
--- a/TestControlFlowTasks/src/Postgres/TableDefinitionTests.cs
+++ b/TestControlFlowTasks/src/Postgres/TableDefinitionTests.cs
@@ -62,11 +62,11 @@ tswithtimezone TIMESTAMPTZ
//Assert
Assert.Collection(result.Columns,
tc => Assert.True(tc.DataType == "date" && tc.NETDataType == typeof(DateTime)),
- tc => Assert.True(tc.DataType == "time" && tc.NETDataType == typeof(DateTime)),
- tc => Assert.True(tc.DataType == "timetz" && tc.NETDataType == typeof(DateTime)),
- tc => Assert.True(tc.DataType == "interval" && tc.NETDataType == typeof(String)),
- tc => Assert.True(tc.DataType == "timestamp" && tc.NETDataType == typeof(DateTime)),
- tc => Assert.True(tc.DataType == "timestamptz" && tc.NETDataType == typeof(DateTime))
+ tc => Assert.True(tc.DataType == "time" && tc.NETDataType == typeof(DateTime) && tc.NETDateTimeKind == DateTimeKind.Unspecified),
+ tc => Assert.True(tc.DataType == "timetz" && tc.NETDataType == typeof(DateTime) && tc.NETDateTimeKind == DateTimeKind.Utc),
+ tc => Assert.True(tc.DataType == "interval" && tc.NETDataType == typeof(String) && tc.NETDateTimeKind == null),
+ tc => Assert.True(tc.DataType == "timestamp" && tc.NETDataType == typeof(DateTime) && tc.NETDateTimeKind == DateTimeKind.Unspecified),
+ tc => Assert.True(tc.DataType == "timestamptz" && tc.NETDataType == typeof(DateTime) && tc.NETDateTimeKind == DateTimeKind.Utc)
);
}
diff --git a/TestControlFlowTasks/src/SqlTaskBulkInsertTests.cs b/TestControlFlowTasks/src/SqlTaskBulkInsertTests.cs
index 3fffc2f9..45b08ad0 100644
--- a/TestControlFlowTasks/src/SqlTaskBulkInsertTests.cs
+++ b/TestControlFlowTasks/src/SqlTaskBulkInsertTests.cs
@@ -1,82 +1,87 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
using ALE.ETLBox;
using ALE.ETLBox.ConnectionManager;
using ALE.ETLBox.ControlFlow;
using ALE.ETLBox.Helper;
-using ALE.ETLBox.Logging;
using ALE.ETLBoxTests.Fixtures;
-using System;
-using System.Collections.Generic;
using Xunit;
-namespace ALE.ETLBoxTests.ControlFlowTests
+namespace ALE.ETLBoxTests.ControlFlowTests;
+
+[Collection("ControlFlow")]
+public class SqlTaskBulkInsertTests
{
- [Collection("ControlFlow")]
- public class SqlTaskBulkInsertTests
+ public SqlTaskBulkInsertTests(ControlFlowDatabaseFixture dbFixture)
+ {
+ }
+
+ public static IEnumerable