From bc7acb9600374bbe539192cd34775edb76742f6a Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:09:15 -0500 Subject: [PATCH 01/40] Update to .Net Standard 2.1, adjust CI accordingly --- .github/workflows/dotnet-core.yml | 28 +++++++++++-------- FAnsiSql/FAnsi.csproj | 2 +- .../FAnsi.Implementations.MicrosoftSQL.csproj | 2 +- .../FAnsi.Implementations.MySql.csproj | 2 +- .../FAnsi.Implementations.Oracle.csproj | 2 +- .../FAnsi.Implementations.PostgreSql.csproj | 2 +- NuGet/FAnsi.NuGet.csproj | 2 +- NuGet/FAnsi.NuGet.nuspec | 6 ++-- Tests/FAnsiTests/FAnsiTests.csproj | 2 +- 9 files changed, 26 insertions(+), 22 deletions(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 6a6b14be..67315139 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -11,7 +11,7 @@ env: jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 services: postgres: image: postgres:latest @@ -26,25 +26,29 @@ jobs: - 5432:5432 steps: + - name: Disable write flush for CI runs + run: apt-get install -y libeatmydata - uses: actions/checkout@v2 + - uses: actions/cache@v3 + with: + path: ~/.nuget/packages - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.301 - - name: Add MSFT code signing key - run: wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - - - name: Add MSFT package repo - run: sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/18.04/mssql-server-2019.list)" - - name: MySQL + dotnet-version: 6.0.x + - name: Install Sql Server + run: | + wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - + sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/18.04/mssql-server-2019.list)" + sudo apt-get install -y --no-install-recommends postgresql mssql-tools mssql-server + sudo -E /opt/mssql/bin/mssql-conf -n setup accept-eula + - name: Start MySQL run: | sed -i'' -e 's/Password=;/Password=pgpass4291;/' Tests/FAnsiTests/TestDatabases.xml sudo mkdir -p /var/run/mysqld sudo chown mysql:mysql /var/run/mysqld sudo mysqld_safe --port=3306 --skip-grant-tables & - - name: Install Sql Server - run: sudo apt-get install -y --no-install-recommends postgresql mssql-tools mssql-server - - name: Configure Sql Server - run: sudo -E /opt/mssql/bin/mssql-conf -n setup accept-eula + run: - name: Install dependencies run: dotnet restore - name: Build @@ -54,7 +58,7 @@ jobs: - name: Pack run: | mkdir -p NuGet/bin - ln -sf Release/netstandard2.0 NuGet/bin/ + ln -sf Release/netstandard2.1 NuGet/bin/ dotnet pack NuGet/FAnsi.NuGet.csproj -c Release --include-source --include-symbols --nologo -p:NuspecFile=`pwd`/NuGet/FAnsi.NuGet.nuspec -p:NuspecProperties=Version=$(fgrep AssemblyInformationalVersion SharedAssemblyInfo.cs|cut -d'"' -f2)\;configuration=Release -p:SymbolPackageFormat=snupkg - name: Nuget push if: contains(github.ref,'refs/tags/') diff --git a/FAnsiSql/FAnsi.csproj b/FAnsiSql/FAnsi.csproj index d9b2c4ae..13f3421c 100644 --- a/FAnsiSql/FAnsi.csproj +++ b/FAnsiSql/FAnsi.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.1 HIC.FAnsiSql Health Informatics Centre, University of Dundee HIC.FAnsiSql diff --git a/Implementations/FAnsi.Implementations.MicrosoftSQL/FAnsi.Implementations.MicrosoftSQL.csproj b/Implementations/FAnsi.Implementations.MicrosoftSQL/FAnsi.Implementations.MicrosoftSQL.csproj index 00172e22..e2519589 100644 --- a/Implementations/FAnsi.Implementations.MicrosoftSQL/FAnsi.Implementations.MicrosoftSQL.csproj +++ b/Implementations/FAnsi.Implementations.MicrosoftSQL/FAnsi.Implementations.MicrosoftSQL.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.1 SqlServerImplementation SqlServerImplementation Copyright © 2019 diff --git a/Implementations/FAnsi.Implementations.MySql/FAnsi.Implementations.MySql.csproj b/Implementations/FAnsi.Implementations.MySql/FAnsi.Implementations.MySql.csproj index aa5fda08..83c0bf8f 100644 --- a/Implementations/FAnsi.Implementations.MySql/FAnsi.Implementations.MySql.csproj +++ b/Implementations/FAnsi.Implementations.MySql/FAnsi.Implementations.MySql.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.1 FAnsi.Implementations.MySql FAnsi.Implementations.MySql Copyright © 2019 diff --git a/Implementations/FAnsi.Implementations.Oracle/FAnsi.Implementations.Oracle.csproj b/Implementations/FAnsi.Implementations.Oracle/FAnsi.Implementations.Oracle.csproj index cd69a477..5218005f 100644 --- a/Implementations/FAnsi.Implementations.Oracle/FAnsi.Implementations.Oracle.csproj +++ b/Implementations/FAnsi.Implementations.Oracle/FAnsi.Implementations.Oracle.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.1 FAnsi.Implementations.Oracle FAnsi.Implementations.Oracle Copyright © 2019 diff --git a/Implementations/FAnsi.Implementations.PostgreSql/FAnsi.Implementations.PostgreSql.csproj b/Implementations/FAnsi.Implementations.PostgreSql/FAnsi.Implementations.PostgreSql.csproj index 20cf1bd6..a8250ef1 100644 --- a/Implementations/FAnsi.Implementations.PostgreSql/FAnsi.Implementations.PostgreSql.csproj +++ b/Implementations/FAnsi.Implementations.PostgreSql/FAnsi.Implementations.PostgreSql.csproj @@ -2,7 +2,7 @@ CS1591 - netstandard2.0 + netstandard2.1 diff --git a/NuGet/FAnsi.NuGet.csproj b/NuGet/FAnsi.NuGet.csproj index a0c680a0..0682e5c8 100644 --- a/NuGet/FAnsi.NuGet.csproj +++ b/NuGet/FAnsi.NuGet.csproj @@ -2,7 +2,7 @@ NuGet NuGet - netstandard2.0 + netstandard2.1 HIC.FAnsiSql Health Informatics Centre, University of Dundee HIC.FAnsiSql diff --git a/NuGet/FAnsi.NuGet.nuspec b/NuGet/FAnsi.NuGet.nuspec index 1c4026a2..2585c565 100644 --- a/NuGet/FAnsi.NuGet.nuspec +++ b/NuGet/FAnsi.NuGet.nuspec @@ -24,8 +24,8 @@ - - - + + + diff --git a/Tests/FAnsiTests/FAnsiTests.csproj b/Tests/FAnsiTests/FAnsiTests.csproj index 344d54da..3206ae29 100644 --- a/Tests/FAnsiTests/FAnsiTests.csproj +++ b/Tests/FAnsiTests/FAnsiTests.csproj @@ -1,6 +1,6 @@  - netcoreapp3.1 + net6.0 FAnsiSqlTests FAnsiSqlTests Copyright © 2019 From 9de0dd3c42341137df272f632c599e9b3e4e971d Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:09:58 -0500 Subject: [PATCH 02/40] YAML fixup --- .github/workflows/dotnet-core.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 67315139..19fc4eff 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -48,7 +48,6 @@ jobs: sudo mkdir -p /var/run/mysqld sudo chown mysql:mysql /var/run/mysqld sudo mysqld_safe --port=3306 --skip-grant-tables & - run: - name: Install dependencies run: dotnet restore - name: Build From 20adc78a103d9ab7fa62b7432048d78185276592 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:11:44 -0500 Subject: [PATCH 03/40] Sudo fixup --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 19fc4eff..a8f7c2be 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Disable write flush for CI runs - run: apt-get install -y libeatmydata + run: sudo apt-get install -y libeatmydata - uses: actions/checkout@v2 - uses: actions/cache@v3 with: From 056fd0aec5dcfa829f714f51b2ef73f30c675e41 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:13:57 -0500 Subject: [PATCH 04/40] Package name fix --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index a8f7c2be..3aea9d2f 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Disable write flush for CI runs - run: sudo apt-get install -y libeatmydata + run: sudo apt-get install -y libeatmydata1 - uses: actions/checkout@v2 - uses: actions/cache@v3 with: From 288b9981b344e0f5ce0432a4e344b6c037c001e6 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:15:26 -0500 Subject: [PATCH 05/40] Cache key fix --- .github/workflows/dotnet-core.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 3aea9d2f..af52bd85 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -31,6 +31,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/cache@v3 with: + key: ${{ runner.os }} path: ~/.nuget/packages - name: Setup .NET Core uses: actions/setup-dotnet@v1 From 8a9aed5faf070c6558f38b2a42cf90b3b8df48d6 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:18:50 -0500 Subject: [PATCH 06/40] Stick to Ubuntu 20.04 for now for MSSQL support --- .github/workflows/dotnet-core.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index af52bd85..fb7b6077 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -11,7 +11,7 @@ env: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-20.04 services: postgres: image: postgres:latest @@ -40,7 +40,7 @@ jobs: - name: Install Sql Server run: | wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - - sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/18.04/mssql-server-2019.list)" + sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)" sudo apt-get install -y --no-install-recommends postgresql mssql-tools mssql-server sudo -E /opt/mssql/bin/mssql-conf -n setup accept-eula - name: Start MySQL From 42820b61485066495c15810a7e7a3501263ff6ce Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:25:21 -0500 Subject: [PATCH 07/40] Adjust MySQL startup --- .github/workflows/dotnet-core.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index fb7b6077..cb8e60fe 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -46,15 +46,14 @@ jobs: - name: Start MySQL run: | sed -i'' -e 's/Password=;/Password=pgpass4291;/' Tests/FAnsiTests/TestDatabases.xml - sudo mkdir -p /var/run/mysqld - sudo chown mysql:mysql /var/run/mysqld - sudo mysqld_safe --port=3306 --skip-grant-tables & + sed -i'' -e 's/Pwd=;/Pwd=root;/' Tests/FAnsiTests/TestDatabases.xml + sudo service start mysql - name: Install dependencies - run: dotnet restore + run: dotnet restore --nologo - name: Build - run: dotnet build --configuration Release --no-restore + run: dotnet build --configuration Release --no-restore --nologo - name: Test - run: dotnet test --no-restore --verbosity normal + run: dotnet test --no-restore --verbosity normal --nologo - name: Pack run: | mkdir -p NuGet/bin From f2536a22108b228aff0d7b20634b50969cf90dd7 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:28:04 -0500 Subject: [PATCH 08/40] Adjust MySQL startup again --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index cb8e60fe..e8fdbe07 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -47,7 +47,7 @@ jobs: run: | sed -i'' -e 's/Password=;/Password=pgpass4291;/' Tests/FAnsiTests/TestDatabases.xml sed -i'' -e 's/Pwd=;/Pwd=root;/' Tests/FAnsiTests/TestDatabases.xml - sudo service start mysql + sudo systemctl start mysql.service - name: Install dependencies run: dotnet restore --nologo - name: Build From 0013b618d64e5892da86881c433c6cf04e8a0d1e Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Tue, 9 Aug 2022 11:33:57 -0500 Subject: [PATCH 09/40] Change MySQL SSL mode --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index e8fdbe07..d68a5a32 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -46,7 +46,7 @@ jobs: - name: Start MySQL run: | sed -i'' -e 's/Password=;/Password=pgpass4291;/' Tests/FAnsiTests/TestDatabases.xml - sed -i'' -e 's/Pwd=;/Pwd=root;/' Tests/FAnsiTests/TestDatabases.xml + sed -i'' -e 's/Pwd=;SslMode=None/Pwd=root;AllowPublicKeyRetrieval=True/' Tests/FAnsiTests/TestDatabases.xml sudo systemctl start mysql.service - name: Install dependencies run: dotnet restore --nologo From 48acbda600b9f88b74aee2a0a0a3980a009bf6bf Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 11 Aug 2022 12:00:18 -0500 Subject: [PATCH 10/40] Update LGTM .Net version --- lgtm.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lgtm.yml b/lgtm.yml index 684633a0..cd696eb4 100644 --- a/lgtm.yml +++ b/lgtm.yml @@ -2,4 +2,4 @@ extraction: csharp: index: dotnet: - version: 3.1.404 + version: 6.0.x From db1c61e381e9ebd3057f71e6ecd312b049774705 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 11 Aug 2022 12:08:14 -0500 Subject: [PATCH 11/40] Run tests v:q not v:n so I can find which test actually failed in 12000 lines of junk --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index ac6eb4a8..d0bb97a3 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -53,7 +53,7 @@ jobs: - name: Build run: dotnet build --configuration Release --no-restore --nologo - name: Test - run: dotnet test --no-restore --verbosity normal --nologo + run: dotnet test --no-restore --verbosity quiet --nologo - name: Pack run: | mkdir -p NuGet/bin From 77c9c8aaa50d463ef4da863178826e1f5774737e Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 11 Aug 2022 12:31:56 -0500 Subject: [PATCH 12/40] Adjust test log syntax --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index d0bb97a3..eea43e60 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -53,7 +53,7 @@ jobs: - name: Build run: dotnet build --configuration Release --no-restore --nologo - name: Test - run: dotnet test --no-restore --verbosity quiet --nologo + run: dotnet test --no-restore --logger "console;verbosity=normal" --nologo - name: Pack run: | mkdir -p NuGet/bin From 4e4ca37744c3e9ac10ff28578f765c634bcfa1ac Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 11 Aug 2022 12:37:22 -0500 Subject: [PATCH 13/40] Try verbosity minimal --- .github/workflows/dotnet-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index eea43e60..b4497dd8 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -53,7 +53,7 @@ jobs: - name: Build run: dotnet build --configuration Release --no-restore --nologo - name: Test - run: dotnet test --no-restore --logger "console;verbosity=normal" --nologo + run: dotnet test --no-restore --logger "console;verbosity=minimal" --nologo - name: Pack run: | mkdir -p NuGet/bin From 4ff53ddb0d4e8c61d2b17e51ed6a4e1b895abe55 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Thu, 11 Aug 2022 12:45:46 -0500 Subject: [PATCH 14/40] Add extra SQL diagnostics on errors --- .../CalendarWithPivotAggregationTests.cs | 130 ++++++++++-------- 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs index 824c335c..564afe64 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs @@ -6,26 +6,33 @@ using System.Collections.Generic; using System.Data; -namespace FAnsiTests.Aggregation +namespace FAnsiTests.Aggregation; + +class CalendarWithPivotAggregationTests:AggregationTests { - class CalendarWithPivotAggregationTests:AggregationTests + [TestCase(DatabaseType.MicrosoftSQLServer)] + [TestCase(DatabaseType.MySql)] + public void Test_Calendar_WithPivot(DatabaseType type) { - [TestCase(DatabaseType.MicrosoftSQLServer)] - [TestCase(DatabaseType.MySql)] - public void Test_Calendar_WithPivot(DatabaseType type) + string sql=null!; + try { var tbl = GetTestTable(type); var svr = tbl.Database.Server; var lines = new List(); lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine("EventDate,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("Category", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Pivot }); //tell it which the pivot + lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }); + lines.Add(new CustomLine("EventDate,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.Axis }); //tell it which the axis are + lines.Add(new CustomLine("Category", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.Pivot }); //tell it which the pivot lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine("EventDate,", QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + lines.Add(new CustomLine("EventDate,", QueryComponent.GroupBy) + { Role = CustomLineRole.Axis }); //tell it which the axis are lines.Add(new CustomLine("Category", QueryComponent.GroupBy) { Role = CustomLineRole.Pivot }); var axis = new QueryAxis() @@ -36,19 +43,18 @@ public void Test_Calendar_WithPivot(DatabaseType type) }; - var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); + sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - using (var con = svr.GetConnection()) - { - con.Open(); + using var con = svr.GetConnection(); + con.Open(); - var da = svr.GetDataAdapter(sql, con); - DataTable dt = new DataTable(); - da.Fill(dt); + var da = svr.GetDataAdapter(sql, con); + DataTable dt = new DataTable(); + da.Fill(dt); - //pivot columns should ordered by sum of pivot values (T has the highest followed by E...) + //pivot columns should ordered by sum of pivot values (T has the highest followed by E...) - /*joinDt T E&, %a' mp;E F G + /*joinDt T E&, %a' mp;E F G 2001 3 1 0 1 2002 2 1 2 0 2003 2 0 0 0 @@ -61,45 +67,53 @@ public void Test_Calendar_WithPivot(DatabaseType type) 2010 0 0 0 0 */ - Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data - - StringAssert.AreEqualIgnoringCase("joinDt", dt.Columns[0].ColumnName); - StringAssert.AreEqualIgnoringCase("T", dt.Columns[1].ColumnName); - StringAssert.AreEqualIgnoringCase("E&, %a' mp;E", dt.Columns[2].ColumnName); - StringAssert.AreEqualIgnoringCase("F", dt.Columns[3].ColumnName); - StringAssert.AreEqualIgnoringCase("G", dt.Columns[4].ColumnName); - - Assert.AreEqual(2001, dt.Rows[0][0]); - Assert.AreEqual(3, dt.Rows[0][1]); - Assert.AreEqual(1, dt.Rows[0][2]); - Assert.AreEqual(0, dt.Rows[0][3]); - Assert.AreEqual(1, dt.Rows[0][4]); - - Assert.AreEqual(2002, dt.Rows[1][0]); - Assert.AreEqual(2, dt.Rows[1][1]); - Assert.AreEqual(1, dt.Rows[1][2]); - Assert.AreEqual(2, dt.Rows[1][3]); - Assert.AreEqual(0, dt.Rows[1][4]); - - Assert.AreEqual(2003, dt.Rows[2][0]); - Assert.AreEqual(2, dt.Rows[2][1]); - Assert.AreEqual(0, dt.Rows[2][2]); - Assert.AreEqual(0, dt.Rows[2][3]); - Assert.AreEqual(0, dt.Rows[2][4]); - - Assert.AreEqual(2004, dt.Rows[3][0]); - Assert.AreEqual(0, dt.Rows[3][1] == DBNull.Value ? 0 : dt.Rows[3][1]); - Assert.AreEqual(0, dt.Rows[3][2] == DBNull.Value ? 0 : dt.Rows[3][1]); //null is permitted because this row doesn't have any matching records... peculiarity of MySql implementation but null=0 is ok for aggregates - Assert.AreEqual(0, dt.Rows[3][3] == DBNull.Value ? 0 : dt.Rows[3][1]); - Assert.AreEqual(0, dt.Rows[3][4] == DBNull.Value ? 0 : dt.Rows[3][1]); - - Assert.AreEqual(2005, dt.Rows[4][0]); - Assert.AreEqual(0, dt.Rows[4][1]); - Assert.AreEqual(1, dt.Rows[4][2]); - Assert.AreEqual(0, dt.Rows[4][3]); - Assert.AreEqual(0, dt.Rows[4][4]); - - } + Assert.AreEqual(10, + dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data + + StringAssert.AreEqualIgnoringCase("joinDt", dt.Columns[0].ColumnName); + StringAssert.AreEqualIgnoringCase("T", dt.Columns[1].ColumnName); + StringAssert.AreEqualIgnoringCase("E&, %a' mp;E", dt.Columns[2].ColumnName); + StringAssert.AreEqualIgnoringCase("F", dt.Columns[3].ColumnName); + StringAssert.AreEqualIgnoringCase("G", dt.Columns[4].ColumnName); + + Assert.AreEqual(2001, dt.Rows[0][0]); + Assert.AreEqual(3, dt.Rows[0][1]); + Assert.AreEqual(1, dt.Rows[0][2]); + Assert.AreEqual(0, dt.Rows[0][3]); + Assert.AreEqual(1, dt.Rows[0][4]); + + Assert.AreEqual(2002, dt.Rows[1][0]); + Assert.AreEqual(2, dt.Rows[1][1]); + Assert.AreEqual(1, dt.Rows[1][2]); + Assert.AreEqual(2, dt.Rows[1][3]); + Assert.AreEqual(0, dt.Rows[1][4]); + + Assert.AreEqual(2003, dt.Rows[2][0]); + Assert.AreEqual(2, dt.Rows[2][1]); + Assert.AreEqual(0, dt.Rows[2][2]); + Assert.AreEqual(0, dt.Rows[2][3]); + Assert.AreEqual(0, dt.Rows[2][4]); + + Assert.AreEqual(2004, dt.Rows[3][0]); + Assert.AreEqual(0, dt.Rows[3][1] == DBNull.Value ? 0 : dt.Rows[3][1]); + Assert.AreEqual(0, + dt.Rows[3][2] == DBNull.Value + ? 0 + : dt.Rows[3][ + 1]); //null is permitted because this row doesn't have any matching records... peculiarity of MySql implementation but null=0 is ok for aggregates + Assert.AreEqual(0, dt.Rows[3][3] == DBNull.Value ? 0 : dt.Rows[3][1]); + Assert.AreEqual(0, dt.Rows[3][4] == DBNull.Value ? 0 : dt.Rows[3][1]); + + Assert.AreEqual(2005, dt.Rows[4][0]); + Assert.AreEqual(0, dt.Rows[4][1]); + Assert.AreEqual(1, dt.Rows[4][2]); + Assert.AreEqual(0, dt.Rows[4][3]); + Assert.AreEqual(0, dt.Rows[4][4]); + } + catch (Exception e) + { + Console.Error.WriteLine($"SQL triggering error was: '{(sql ?? "None defined")}'"); + throw; } } -} +} \ No newline at end of file From b81e7beb6d2309f1d32146bc2fa8080e3e9a6b6f Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 12 Aug 2022 09:01:18 +0100 Subject: [PATCH 15/40] Add 'else 0' to case statement in MySql pivots --- .../Aggregation/MySqlAggregateHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index 93b2fcbd..a4cfeb66 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -288,7 +288,7 @@ order by {5} ); -/* Build case when x='fish' then 1 end as 'fish', case when x='cammel' then 1 end as 'cammel' etc*/ +/* Build case when x='fish' then 1 else 0 end as 'fish', case when x='cammel' then 1 end as 'cammel' etc*/ SET @columnsSelectCases = NULL; SELECT GROUP_CONCAT( From 0b62633b4654ad4a7849e7703b9a29f8016394cc Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 12 Aug 2022 09:10:17 +0100 Subject: [PATCH 16/40] Added else 0 in the sql code this time (previous commit affected only comment - oops) --- .../Aggregation/MySqlAggregateHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index a4cfeb66..8d90a676 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -293,7 +293,7 @@ order by SELECT GROUP_CONCAT( CONCAT( - '{0}(case when {1} = ''', REPLACE(pivotValues.piv,'\'','\\\''), ''' then {2} end) AS `', pivotValues.piv,'`' + '{0}(case when {1} = ''', REPLACE(pivotValues.piv,'\'','\\\''), ''' then {2} else 0 end) AS `', pivotValues.piv,'`' ) ) INTO @columnsSelectCases FROM From 1f793fcddb1a03d0c4802ad711c940d78ba7113f Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 12 Aug 2022 11:04:33 +0100 Subject: [PATCH 17/40] Replace triple single quotes with slashquote --- .../Aggregation/MySqlAggregateHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index 8d90a676..669d8fc0 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -288,12 +288,12 @@ order by {5} ); -/* Build case when x='fish' then 1 else 0 end as 'fish', case when x='cammel' then 1 end as 'cammel' etc*/ +/* Build case when x='fish' then 1 else null end as 'fish', case when x='cammel' then 1 end as 'cammel' etc*/ SET @columnsSelectCases = NULL; SELECT GROUP_CONCAT( CONCAT( - '{0}(case when {1} = ''', REPLACE(pivotValues.piv,'\'','\\\''), ''' then {2} else 0 end) AS `', pivotValues.piv,'`' + '{0}(case when {1} = \'', REPLACE(pivotValues.piv,'\'','\\\''), '\' then {2} else null end) AS `', pivotValues.piv,'`' ) ) INTO @columnsSelectCases FROM From 11caca630d4e7ea2861ad398754c7fad43f1ccdb Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 12 Aug 2022 11:55:01 +0100 Subject: [PATCH 18/40] Change 'GROUP BY' and 'ORDER BY' to use the join column alias instead of SQL --- .../Aggregation/MySqlAggregateHelper.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index 669d8fc0..b196d981 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -181,7 +181,7 @@ protected override string BuildPivotOnlyAggregate(AggregateCustomLineCollection { string part1 = GetPivotPart1(query); - string nonPivotColumnSql = nonPivotColumn.GetTextWithoutAlias(query.SyntaxHelper); + string joinAlias = nonPivotColumn.GetAliasFromText(query.SyntaxHelper); return string.Format(@" {0} @@ -213,7 +213,7 @@ ORDER BY //everything inclusive of FROM but stopping before GROUP BY query.SyntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert >= QueryComponent.FROM && c.LocationToInsert < QueryComponent.GroupBy))), - nonPivotColumnSql, + joinAlias, //any HAVING SQL query.SyntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert == QueryComponent.Having))) @@ -371,9 +371,9 @@ order by //SELECT // GROUP_CONCAT(DISTINCT // CONCAT( -// 'count(case when `test`.`biochemistry`.`hb_extract` = ''', +// 'count(case when `test`.`biochemistry`.`hb_extract` = \'', // b.`Pivot`, -// ''' then 1 end) AS `', +// \'' then 1 else null end) AS `', // b.`Pivot`,'`' // ) order by b.`CountName` desc // ) INTO @columns From 1b896508b8aa1bc5e8cd7636b4aedf202ffc9b1a Mon Sep 17 00:00:00 2001 From: tznind Date: Fri, 12 Aug 2022 12:10:44 +0100 Subject: [PATCH 19/40] Split Test_Calendar_WithPivot into easy and hard versions --- .../Aggregation/AggregationTests.cs | 40 +++++++++++++------ .../CalendarWithPivotAggregationTests.cs | 14 +++++-- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Tests/FAnsiTests/Aggregation/AggregationTests.cs b/Tests/FAnsiTests/Aggregation/AggregationTests.cs index 06d2dec6..9be28def 100644 --- a/Tests/FAnsiTests/Aggregation/AggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/AggregationTests.cs @@ -10,16 +10,24 @@ namespace FAnsiTests.Aggregation { class AggregationTests:DatabaseTests { - protected readonly Dictionary _testTables = new Dictionary(); - + protected readonly Dictionary _easyTables = new Dictionary(); + protected readonly Dictionary _hardTables = new Dictionary(); + [OneTimeSetUp] public void Setup() + { + SetupDatabaseTable(true, "AggregateDataBasedTestsEasy"); + + SetupDatabaseTable(false, "AggregateDataBasedTestsHard"); + } + + private void SetupDatabaseTable(bool easy, string name) { try { using (DataTable dt = new DataTable()) { - dt.TableName = "AggregateDataBasedTests"; + dt.TableName = name; dt.Columns.Add("EventDate"); dt.Columns.Add("Category"); @@ -38,21 +46,27 @@ public void Setup() dt.Rows.Add("2002-01-01", "F", "29"); dt.Rows.Add("2002-01-01", "F", "31"); - dt.Rows.Add("2001-01-01", "E&, %a' mp;E", "37"); - dt.Rows.Add("2002-01-01", "E&, %a' mp;E", "41"); - dt.Rows.Add("2005-01-01", "E&, %a' mp;E", "59"); //note there are no records in 2004 it is important for axis tests (axis involves you having to build a calendar table) + if(!easy) + { + dt.Rows.Add("2001-01-01", "E&, %a' mp;E", "37"); + dt.Rows.Add("2002-01-01", "E&, %a' mp;E", "41"); + dt.Rows.Add("2005-01-01", "E&, %a' mp;E", "59"); //note there are no records in 2004 it is important for axis tests (axis involves you having to build a calendar table) + } + dt.Rows.Add(null, "G", "47"); dt.Rows.Add("2001-01-01", "G", "53"); - + foreach (KeyValuePair kvp in TestConnectionStrings) { try { var db = GetTestDatabase(kvp.Key); var tbl = db.CreateTable("AggregateDataBasedTests", dt); - _testTables.Add(kvp.Key,tbl); + + var dic = easy ? _easyTables : _hardTables; + dic.Add(kvp.Key, tbl); } catch (Exception e) @@ -61,7 +75,7 @@ public void Setup() Console.WriteLine(e); } - + } } } @@ -152,12 +166,14 @@ protected void ConsoleWriteTable(DataTable dt) Console.Write(Environment.NewLine); } - protected DiscoveredTable GetTestTable(DatabaseType type) + protected DiscoveredTable GetTestTable(DatabaseType type, bool easy = false) { - if (!_testTables.ContainsKey(type)) + var dic = easy ? _easyTables : _hardTables; + + if (!dic.ContainsKey(type)) Assert.Inconclusive("No connection string found for Test database type {0}", type); - return _testTables[type]; + return dic[type]; } } diff --git a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs index 564afe64..035dbc2e 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs @@ -10,14 +10,16 @@ namespace FAnsiTests.Aggregation; class CalendarWithPivotAggregationTests:AggregationTests { - [TestCase(DatabaseType.MicrosoftSQLServer)] - [TestCase(DatabaseType.MySql)] - public void Test_Calendar_WithPivot(DatabaseType type) + [TestCase(DatabaseType.MicrosoftSQLServer,true)] + [TestCase(DatabaseType.MySql,true)] + [TestCase(DatabaseType.MicrosoftSQLServer, false)] + [TestCase(DatabaseType.MySql, false)] + public void Test_Calendar_WithPivot(DatabaseType type,bool easy) { string sql=null!; try { - var tbl = GetTestTable(type); + var tbl = GetTestTable(type,easy); var svr = tbl.Database.Server; var lines = new List(); @@ -70,6 +72,10 @@ public void Test_Calendar_WithPivot(DatabaseType type) Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data + // only validate hard output, we got rows on easy thats enough for now + if (easy) + return; + StringAssert.AreEqualIgnoringCase("joinDt", dt.Columns[0].ColumnName); StringAssert.AreEqualIgnoringCase("T", dt.Columns[1].ColumnName); StringAssert.AreEqualIgnoringCase("E&, %a' mp;E", dt.Columns[2].ColumnName); From 063c98e5cb13bbc1d4378bff0caab4e822e52846 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Sat, 13 Aug 2022 13:29:36 -0500 Subject: [PATCH 20/40] Comment and syntax tidy --- .../Aggregation/MySqlAggregateHelper.cs | 23 ++++++++----------- Tests/FAnsiTests/Table/BulkInsertTest.cs | 12 +++++----- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index b196d981..f0062068 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -64,19 +64,14 @@ dt DATE public override string GetDatePartOfColumn(AxisIncrement increment, string columnSql) { - switch (increment) + return increment switch { - case AxisIncrement.Day: - return "DATE(" + columnSql + ")"; - case AxisIncrement.Month: - return "DATE_FORMAT("+columnSql+",'%Y-%m')"; - case AxisIncrement.Year: - return "YEAR(" + columnSql + ")"; - case AxisIncrement.Quarter: - return "CONCAT(YEAR(" + columnSql + "),'Q',QUARTER(" + columnSql + "))"; - default: - throw new ArgumentOutOfRangeException("increment"); - } + AxisIncrement.Day => $"DATE({columnSql})", + AxisIncrement.Month => $"DATE_FORMAT({columnSql},'%Y-%m')", + AxisIncrement.Year => $"YEAR({columnSql})", + AxisIncrement.Quarter => $"CONCAT(YEAR({columnSql}),'Q',QUARTER({columnSql}))", + _ => throw new ArgumentOutOfRangeException(nameof(increment)) + }; } @@ -249,11 +244,11 @@ private static string GetPivotPart1(AggregateCustomLineCollection query) var axisColumnWithoutAlias = query.AxisSelect.GetTextWithoutAlias(query.SyntaxHelper); whereDateColumnNotNull += query.Lines.Any(l => l.LocationToInsert == QueryComponent.WHERE) ? "AND " : "WHERE "; - whereDateColumnNotNull += axisColumnWithoutAlias + " IS NOT NULL"; + whereDateColumnNotNull += $"{axisColumnWithoutAlias} IS NOT NULL"; } //work out how to order the pivot columns - string orderBy = countSqlWithoutAlias + " desc"; //default, order by the count(*) / sum(*) etc column desc + string orderBy = $"{countSqlWithoutAlias} desc"; //default, order by the count(*) / sum(*) etc column desc //theres an explicit topX so order by it verbatim instead var topXOrderByLine = diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index c4f65041..976cd4dd 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -436,7 +436,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas for (int i = 0; i < 30; i++) { - dt.Columns.Add("Column" + i); + dt.Columns.Add($"Column{i}"); } @@ -453,7 +453,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas Assert.AreEqual(numberOfRowsPerBatch, blk.Upload(dt)); //affected rows should match batch size } sw.Stop(); - Console.WriteLine("Time taken:" + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); dt.Rows.Clear(); @@ -469,7 +469,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas } sw.Stop(); - Console.WriteLine("Time taken:" + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); } @@ -501,15 +501,15 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas if(type != DatabaseType.MySql) StringAssert.Contains("cancel",ex.InnerException.Message); else - Console.WriteLine("MySql error was:" + ex.InnerException); + Console.WriteLine($"MySql error was:{ex.InnerException}"); } } - //Now lets test cancelling GetDataTable + //Now let's test cancelling GetDataTable using (var con = tbl.Database.Server.BeginNewTransactedConnection()) { - //give it 100 ms delay (simulates user cancelling not DbCommand.Timeout expiring) + //give it 300 ms delay (simulates user cancelling not DbCommand.Timeout expiring) using (cts = new CancellationTokenSource(300)) { //GetDataTable should have been cancelled at the database level From bd5b9bccdac32dc384b276a4f238853642e03a48 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Sat, 13 Aug 2022 14:12:43 -0500 Subject: [PATCH 21/40] Write to TestContext not Console, for less noisy tests when things pass --- .../Aggregation/AggregationTests.cs | 98 +++-- .../Aggregation/CalendarAggregationTests.cs | 403 +++++++++--------- .../CalendarWithPivotAggregationTests.cs | 2 +- Tests/FAnsiTests/CrossPlatformTests.cs | 30 +- .../Database/DiscoverTablesTests.cs | 4 +- Tests/FAnsiTests/DatabaseTests.cs | 2 +- Tests/FAnsiTests/Examples.cs | 20 +- Tests/FAnsiTests/Server/ServerTests.cs | 4 +- Tests/FAnsiTests/Table/BulkInsertTest.cs | 6 +- Tests/FAnsiTests/Table/UpdateTests.cs | 26 +- Tests/FAnsiTests/TestDatabases.xml | 6 +- .../TypeTranslation/DatatypeComputerTests.cs | 2 +- .../TypeTranslation/TypeTranslaterTests.cs | 3 +- 13 files changed, 297 insertions(+), 309 deletions(-) diff --git a/Tests/FAnsiTests/Aggregation/AggregationTests.cs b/Tests/FAnsiTests/Aggregation/AggregationTests.cs index 9be28def..7091f5c0 100644 --- a/Tests/FAnsiTests/Aggregation/AggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/AggregationTests.cs @@ -25,63 +25,61 @@ private void SetupDatabaseTable(bool easy, string name) { try { - using (DataTable dt = new DataTable()) - { - dt.TableName = name; + using DataTable dt = new DataTable(); + dt.TableName = name; - dt.Columns.Add("EventDate"); - dt.Columns.Add("Category"); - dt.Columns.Add("NumberInTrouble"); + dt.Columns.Add("EventDate"); + dt.Columns.Add("Category"); + dt.Columns.Add("NumberInTrouble"); - dt.Rows.Add("2001-01-01", "T", "7"); - dt.Rows.Add("2001-01-02", "T", "11"); - dt.Rows.Add("2001-01-01", "T", "49"); + dt.Rows.Add("2001-01-01", "T", "7"); + dt.Rows.Add("2001-01-02", "T", "11"); + dt.Rows.Add("2001-01-01", "T", "49"); - dt.Rows.Add("2002-02-01", "T", "13"); - dt.Rows.Add("2002-03-02", "T", "17"); - dt.Rows.Add("2003-01-01", "T", "19"); - dt.Rows.Add("2003-04-02", "T", "23"); + dt.Rows.Add("2002-02-01", "T", "13"); + dt.Rows.Add("2002-03-02", "T", "17"); + dt.Rows.Add("2003-01-01", "T", "19"); + dt.Rows.Add("2003-04-02", "T", "23"); - dt.Rows.Add("2002-01-01", "F", "29"); - dt.Rows.Add("2002-01-01", "F", "31"); + dt.Rows.Add("2002-01-01", "F", "29"); + dt.Rows.Add("2002-01-01", "F", "31"); - if(!easy) - { - dt.Rows.Add("2001-01-01", "E&, %a' mp;E", "37"); - dt.Rows.Add("2002-01-01", "E&, %a' mp;E", "41"); - dt.Rows.Add("2005-01-01", "E&, %a' mp;E", "59"); //note there are no records in 2004 it is important for axis tests (axis involves you having to build a calendar table) - } - + if (!easy) + { + dt.Rows.Add("2001-01-01", "E&, %a' mp;E", "37"); + dt.Rows.Add("2002-01-01", "E&, %a' mp;E", "41"); + dt.Rows.Add("2005-01-01", "E&, %a' mp;E", "59"); //note there are no records in 2004 it is important for axis tests (axis involves you having to build a calendar table) + } - dt.Rows.Add(null, "G", "47"); - dt.Rows.Add("2001-01-01", "G", "53"); + dt.Rows.Add(null, "G", "47"); + dt.Rows.Add("2001-01-01", "G", "53"); - foreach (KeyValuePair kvp in TestConnectionStrings) - { - try - { - var db = GetTestDatabase(kvp.Key); - var tbl = db.CreateTable("AggregateDataBasedTests", dt); - var dic = easy ? _easyTables : _hardTables; - dic.Add(kvp.Key, tbl); + foreach (var (key, _) in TestConnectionStrings) + { + try + { + var db = GetTestDatabase(key); + var tbl = db.CreateTable("AggregateDataBasedTests", dt); - } - catch (Exception e) - { - Console.WriteLine("Could not setup test database for DatabaseType " + kvp.Key); - Console.WriteLine(e); + var dic = easy ? _easyTables : _hardTables; + dic.Add(key, tbl); - } + } + catch (Exception e) + { + TestContext.WriteLine($"Could not setup test database for DatabaseType {key}"); + TestContext.WriteLine(e); } + } } catch (Exception e) { - Console.WriteLine(e); + TestContext.WriteLine(e); throw; } } @@ -129,7 +127,7 @@ protected bool IsMatch(DataRow r, object[] cells) protected void ConsoleWriteTable(DataTable dt) { - Console.WriteLine("--- DebugTable(" + dt.TableName + ") ---"); + TestContext.WriteLine($"--- DebugTable({dt.TableName}) ---"); int zeilen = dt.Rows.Count; int spalten = dt.Columns.Count; @@ -137,33 +135,33 @@ protected void ConsoleWriteTable(DataTable dt) for (int i = 0; i < dt.Columns.Count; i++) { string s = dt.Columns[i].ToString(); - Console.Write(String.Format("{0,-20} | ", s)); + TestContext.Write($"{s,-20} | "); } - Console.Write(Environment.NewLine); + TestContext.Write(Environment.NewLine); for (int i = 0; i < dt.Columns.Count; i++) { - Console.Write("---------------------|-"); + TestContext.Write("---------------------|-"); } - Console.Write(Environment.NewLine); + TestContext.Write(Environment.NewLine); // Data for (int i = 0; i < zeilen; i++) { DataRow row = dt.Rows[i]; - //Console.WriteLine("{0} {1} ", row[0], row[1]); + //TestContext.WriteLine("{0} {1} ", row[0], row[1]); for (int j = 0; j < spalten; j++) { string s = row[j].ToString(); - if (s.Length > 20) s = s.Substring(0, 17) + "..."; - Console.Write(String.Format("{0,-20} | ", s)); + if (s.Length > 20) s = $"{s[..17]}..."; + TestContext.Write($"{s,-20} | "); } - Console.Write(Environment.NewLine); + TestContext.Write(Environment.NewLine); } for (int i = 0; i < dt.Columns.Count; i++) { - Console.Write("---------------------|-"); + TestContext.Write("---------------------|-"); } - Console.Write(Environment.NewLine); + TestContext.Write(Environment.NewLine); } protected DiscoveredTable GetTestTable(DatabaseType type, bool easy = false) diff --git a/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs index 61da142f..64f37e2b 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarAggregationTests.cs @@ -20,16 +20,19 @@ public void Test_Calendar_Year(DatabaseType type) var eventDate = tbl.DiscoverColumn("EventDate"); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are - - var axis = new QueryAxis() + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }, + new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; + + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = "'2010-01-01'", @@ -38,42 +41,36 @@ public void Test_Calendar_Year(DatabaseType type) var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - Console.WriteLine("About to send SQL:" + Environment.NewLine + sql); - - using (var con = svr.GetConnection()) - { - con.Open(); - - using (var da = svr.GetDataAdapter(sql, con)) - { - using (DataTable dt = new DataTable()) - { - da.Fill(dt); - - Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data - Assert.AreEqual(2001, dt.Rows[0][0]); - Assert.AreEqual(5, dt.Rows[0][1]); - Assert.AreEqual(2002, dt.Rows[1][0]); - Assert.AreEqual(5, dt.Rows[1][1]); - Assert.AreEqual(2003, dt.Rows[2][0]); - Assert.AreEqual(2, dt.Rows[2][1]); - Assert.AreEqual(2004, dt.Rows[3][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); - Assert.AreEqual(2005, dt.Rows[4][0]); - Assert.AreEqual(1, dt.Rows[4][1]); - Assert.AreEqual(2006, dt.Rows[5][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); - Assert.AreEqual(2007, dt.Rows[6][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); - Assert.AreEqual(2008, dt.Rows[7][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); - Assert.AreEqual(2009, dt.Rows[8][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); - Assert.AreEqual(2010, dt.Rows[9][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); - } - } - } + TestContext.WriteLine($"About to send SQL:{Environment.NewLine}{sql}"); + + using var con = svr.GetConnection(); + con.Open(); + + using var da = svr.GetDataAdapter(sql, con); + using DataTable dt = new DataTable(); + da.Fill(dt); + + Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data + Assert.AreEqual(2001, dt.Rows[0][0]); + Assert.AreEqual(5, dt.Rows[0][1]); + Assert.AreEqual(2002, dt.Rows[1][0]); + Assert.AreEqual(5, dt.Rows[1][1]); + Assert.AreEqual(2003, dt.Rows[2][0]); + Assert.AreEqual(2, dt.Rows[2][1]); + Assert.AreEqual(2004, dt.Rows[3][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); + Assert.AreEqual(2005, dt.Rows[4][0]); + Assert.AreEqual(1, dt.Rows[4][1]); + Assert.AreEqual(2006, dt.Rows[5][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); + Assert.AreEqual(2007, dt.Rows[6][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); + Assert.AreEqual(2008, dt.Rows[7][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); + Assert.AreEqual(2009, dt.Rows[8][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); + Assert.AreEqual(2010, dt.Rows[9][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] @@ -83,16 +80,18 @@ public void Test_Calendar_Quarter(DatabaseType type) var svr = tbl.Database.Server; var col = tbl.DiscoverColumn("EventDate"); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, + new CustomLine(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; - var axis = new QueryAxis() + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = "'2010-01-01'", @@ -102,23 +101,19 @@ public void Test_Calendar_Quarter(DatabaseType type) var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - using (var con = svr.GetConnection()) - { - con.Open(); + using var con = svr.GetConnection(); + con.Open(); - using(var da = svr.GetDataAdapter(sql, con)) - using (DataTable dt = new DataTable()) - { - da.Fill(dt); + using var da = svr.GetDataAdapter(sql, con); + using DataTable dt = new DataTable(); + da.Fill(dt); - ConsoleWriteTable(dt); + ConsoleWriteTable(dt); - Assert.AreEqual(37, dt.Rows.Count); // 4 quarters per year between 2001 and 2009 + 2010Q1 + Assert.AreEqual(37, dt.Rows.Count); // 4 quarters per year between 2001 and 2009 + 2010Q1 - AssertHasRow(dt, "2001Q1", 5); - AssertHasRow(dt, "2001Q2", null); - } - } + AssertHasRow(dt, "2001Q1", 5); + AssertHasRow(dt, "2001Q2", null); } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] @@ -129,16 +124,19 @@ public void Test_Calendar_Month(DatabaseType type) var syntax = tbl.GetQuerySyntaxHelper(); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine(syntax.EnsureWrapped("EventDate"), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(syntax.EnsureWrapped("EventDate"), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }, + new CustomLine(syntax.EnsureWrapped("EventDate"), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(syntax.EnsureWrapped("EventDate"), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; - var axis = new QueryAxis() + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = "'2010-01-01'", @@ -148,25 +146,19 @@ public void Test_Calendar_Month(DatabaseType type) var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - using (var con = svr.GetConnection()) - { - con.Open(); + using var con = svr.GetConnection(); + con.Open(); - using (var da = svr.GetDataAdapter(sql, con)) - { - using (DataTable dt = new DataTable()) - { - da.Fill(dt); + using var da = svr.GetDataAdapter(sql, con); + using DataTable dt = new DataTable(); + da.Fill(dt); - ConsoleWriteTable(dt); + ConsoleWriteTable(dt); - Assert.AreEqual(109, dt.Rows.Count); // 109 months between 2001 and 2010 (inclusive) + Assert.AreEqual(109, dt.Rows.Count); // 109 months between 2001 and 2010 (inclusive) - AssertHasRow(dt,"2001-01",5); - AssertHasRow(dt, "2001-02", null); - } - } - } + AssertHasRow(dt,"2001-01",5); + AssertHasRow(dt, "2001-02", null); } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] @@ -176,16 +168,19 @@ public void Test_Calendar_Day(DatabaseType type) var svr = tbl.Database.Server; var col = tbl.DiscoverColumn("EventDate"); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }, + new CustomLine(col.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(col.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; - var axis = new QueryAxis() + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = "'2010-01-01'", @@ -195,23 +190,21 @@ public void Test_Calendar_Day(DatabaseType type) var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - using (var con = svr.GetConnection()) - { - con.Open(); + using var con = svr.GetConnection(); + con.Open(); - var da = svr.GetDataAdapter(sql, con); - DataTable dt = new DataTable(); - da.Fill(dt); + var da = svr.GetDataAdapter(sql, con); + DataTable dt = new DataTable(); + da.Fill(dt); - ConsoleWriteTable(dt); + ConsoleWriteTable(dt); - Assert.AreEqual(3288, dt.Rows.Count); // 109 months between 2001 and 2010 (inclusive) + Assert.AreEqual(3288, dt.Rows.Count); // 109 months between 2001 and 2010 (inclusive) - AssertHasRow(dt, new DateTime(2001,1,1), 4); - AssertHasRow(dt, new DateTime(2001, 1, 2), 1); - AssertHasRow(dt, new DateTime(2001, 1, 3), null); - dt.Dispose(); - } + AssertHasRow(dt, new DateTime(2001,1,1), 4); + AssertHasRow(dt, new DateTime(2001, 1, 2), 1); + AssertHasRow(dt, new DateTime(2001, 1, 3), null); + dt.Dispose(); } @@ -222,16 +215,19 @@ public void Test_Calendar_ToToday(DatabaseType type) var svr = tbl.Database.Server; var eventDate = tbl.DiscoverColumn("EventDate"); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }, + new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; - var axis = new QueryAxis() + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = tbl.GetQuerySyntaxHelper().GetScalarFunctionSql(MandatoryScalarFunctions.GetTodaysDate), @@ -241,46 +237,40 @@ public void Test_Calendar_ToToday(DatabaseType type) var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - Console.WriteLine(sql); - - using (var con = svr.GetConnection()) - { - con.Open(); - - using (var da = svr.GetDataAdapter(sql, con)) - { - using (DataTable dt = new DataTable()) - { - da.Fill(dt); - - Assert.GreaterOrEqual(dt.Rows.Count, 19); //there are 19 years between 2001 and 2019 (use greater than because we don't want test to fail in 2020) - Assert.AreEqual(2001, dt.Rows[0][0]); - Assert.AreEqual(5, dt.Rows[0][1]); - Assert.AreEqual(2002, dt.Rows[1][0]); - Assert.AreEqual(5, dt.Rows[1][1]); - Assert.AreEqual(2003, dt.Rows[2][0]); - Assert.AreEqual(2, dt.Rows[2][1]); - Assert.AreEqual(2004, dt.Rows[3][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); - Assert.AreEqual(2005, dt.Rows[4][0]); - Assert.AreEqual(1, dt.Rows[4][1]); - Assert.AreEqual(2006, dt.Rows[5][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); - Assert.AreEqual(2007, dt.Rows[6][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); - Assert.AreEqual(2008, dt.Rows[7][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); - Assert.AreEqual(2009, dt.Rows[8][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); - Assert.AreEqual(2010, dt.Rows[9][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); - - //should go up to this year - Assert.AreEqual(DateTime.Now.Year, dt.Rows[dt.Rows.Count - 1][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); - } - } - } + TestContext.WriteLine(sql); + + using var con = svr.GetConnection(); + con.Open(); + + using var da = svr.GetDataAdapter(sql, con); + using DataTable dt = new DataTable(); + da.Fill(dt); + + Assert.GreaterOrEqual(dt.Rows.Count, 19); //there are 19 years between 2001 and 2019 (use greater than because we don't want test to fail in 2020) + Assert.AreEqual(2001, dt.Rows[0][0]); + Assert.AreEqual(5, dt.Rows[0][1]); + Assert.AreEqual(2002, dt.Rows[1][0]); + Assert.AreEqual(5, dt.Rows[1][1]); + Assert.AreEqual(2003, dt.Rows[2][0]); + Assert.AreEqual(2, dt.Rows[2][1]); + Assert.AreEqual(2004, dt.Rows[3][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); + Assert.AreEqual(2005, dt.Rows[4][0]); + Assert.AreEqual(1, dt.Rows[4][1]); + Assert.AreEqual(2006, dt.Rows[5][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); + Assert.AreEqual(2007, dt.Rows[6][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); + Assert.AreEqual(2008, dt.Rows[7][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); + Assert.AreEqual(2009, dt.Rows[8][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); + Assert.AreEqual(2010, dt.Rows[9][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); + + //should go up to this year + Assert.AreEqual(DateTime.Now.Year, dt.Rows[dt.Rows.Count - 1][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); } /// @@ -294,16 +284,19 @@ public void Test_Calendar_SELECTColumnOrder_CountAfterAxisColumn(DatabaseType ty var svr = tbl.Database.Server; var eventDate = tbl.DiscoverColumn("EventDate"); - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName() +",", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("count(*) as MyCount", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis }); //tell it which the axis are + var lines = new List + { + new CustomLine("SELECT", QueryComponent.SELECT), + new CustomLine($"{eventDate.GetFullyQualifiedName()},", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.Axis }, //tell it which the axis are + new CustomLine("count(*) as MyCount", QueryComponent.QueryTimeColumn) { Role = CustomLineRole.CountFunction }, + new CustomLine("FROM ", QueryComponent.FROM), + new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new CustomLine("GROUP BY", QueryComponent.GroupBy), + new CustomLine(eventDate.GetFullyQualifiedName(), QueryComponent.GroupBy) { Role = CustomLineRole.Axis } //tell it which the axis are + }; - var axis = new QueryAxis() + var axis = new QueryAxis { StartDate = "'2001-01-01'", EndDate = "'2010-01-01'", @@ -313,42 +306,36 @@ public void Test_Calendar_SELECTColumnOrder_CountAfterAxisColumn(DatabaseType ty var sql = svr.GetQuerySyntaxHelper().AggregateHelper.BuildAggregate(lines, axis); - Console.WriteLine(sql); - - using (var con = svr.GetConnection()) - { - con.Open(); - - using (var da = svr.GetDataAdapter(sql, con)) - { - using (DataTable dt = new DataTable()) - { - da.Fill(dt); - - Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data - Assert.AreEqual(2001, dt.Rows[0][0]); - Assert.AreEqual(5, dt.Rows[0][1]); - Assert.AreEqual(2002, dt.Rows[1][0]); - Assert.AreEqual(5, dt.Rows[1][1]); - Assert.AreEqual(2003, dt.Rows[2][0]); - Assert.AreEqual(2, dt.Rows[2][1]); - Assert.AreEqual(2004, dt.Rows[3][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); - Assert.AreEqual(2005, dt.Rows[4][0]); - Assert.AreEqual(1, dt.Rows[4][1]); - Assert.AreEqual(2006, dt.Rows[5][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); - Assert.AreEqual(2007, dt.Rows[6][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); - Assert.AreEqual(2008, dt.Rows[7][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); - Assert.AreEqual(2009, dt.Rows[8][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); - Assert.AreEqual(2010, dt.Rows[9][0]); - Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); - } - } - } + TestContext.WriteLine(sql); + + using var con = svr.GetConnection(); + con.Open(); + + using var da = svr.GetDataAdapter(sql, con); + using DataTable dt = new DataTable(); + da.Fill(dt); + + Assert.AreEqual(10, dt.Rows.Count); //there are 10 years between 2001 and 2010 even though not all years are represented in the data + Assert.AreEqual(2001, dt.Rows[0][0]); + Assert.AreEqual(5, dt.Rows[0][1]); + Assert.AreEqual(2002, dt.Rows[1][0]); + Assert.AreEqual(5, dt.Rows[1][1]); + Assert.AreEqual(2003, dt.Rows[2][0]); + Assert.AreEqual(2, dt.Rows[2][1]); + Assert.AreEqual(2004, dt.Rows[3][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[3][1]); + Assert.AreEqual(2005, dt.Rows[4][0]); + Assert.AreEqual(1, dt.Rows[4][1]); + Assert.AreEqual(2006, dt.Rows[5][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[5][1]); + Assert.AreEqual(2007, dt.Rows[6][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[6][1]); + Assert.AreEqual(2008, dt.Rows[7][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[7][1]); + Assert.AreEqual(2009, dt.Rows[8][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[8][1]); + Assert.AreEqual(2010, dt.Rows[9][0]); + Assert.AreEqual(DBNull.Value, dt.Rows[9][1]); } } } diff --git a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs index 035dbc2e..dab17ed8 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs @@ -118,7 +118,7 @@ public void Test_Calendar_WithPivot(DatabaseType type,bool easy) } catch (Exception e) { - Console.Error.WriteLine($"SQL triggering error was: '{(sql ?? "None defined")}'"); + TestContext.Error.WriteLine($"SQL triggering error was: '{(sql ?? "None defined")}'"); throw; } } diff --git a/Tests/FAnsiTests/CrossPlatformTests.cs b/Tests/FAnsiTests/CrossPlatformTests.cs index 8a06da3e..7693c2a2 100644 --- a/Tests/FAnsiTests/CrossPlatformTests.cs +++ b/Tests/FAnsiTests/CrossPlatformTests.cs @@ -343,13 +343,16 @@ public void ForeignKeyCreationTest(DatabaseType type) { con.Open(); - var cmd = tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (100,'chucky')", con); + var cmd = tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (100,'chucky')", con); //violation of fk Assert.That(() => cmd.ExecuteNonQuery(), Throws.Exception); - tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (1,'chucky')", con).ExecuteNonQuery(); - tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (1,'chucky2')", con).ExecuteNonQuery(); + tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,'chucky')", con).ExecuteNonQuery(); + tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,'chucky2')", con).ExecuteNonQuery(); } Assert.AreEqual(2,tblParent.GetRowCount()); @@ -359,7 +362,7 @@ public void ForeignKeyCreationTest(DatabaseType type) { con.Open(); - var cmd = tblParent.Database.Server.GetCommand("DELETE FROM " + tblParent.GetFullyQualifiedName(), con); + var cmd = tblParent.Database.Server.GetCommand($"DELETE FROM {tblParent.GetFullyQualifiedName()}", con); cmd.ExecuteNonQuery(); } @@ -418,13 +421,16 @@ public void ForeignKeyCreationTest_TwoColumns(DatabaseType type, bool cascadeDel { con.Open(); - var cmd = tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (1,3,'chucky')", con); + var cmd = tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,3,'chucky')", con); //violation of fk Assert.That(() => cmd.ExecuteNonQuery(), Throws.Exception); - tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (1,2,'chucky')", con).ExecuteNonQuery(); - tblParent.Database.Server.GetCommand("INSERT INTO " + tblChild.GetFullyQualifiedName() + " VALUES (1,2,'chucky2')", con).ExecuteNonQuery(); + tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,2,'chucky')", con).ExecuteNonQuery(); + tblParent.Database.Server.GetCommand( + $"INSERT INTO {tblChild.GetFullyQualifiedName()} VALUES (1,2,'chucky2')", con).ExecuteNonQuery(); } Assert.AreEqual(1, tblParent.GetRowCount()); @@ -433,7 +439,7 @@ public void ForeignKeyCreationTest_TwoColumns(DatabaseType type, bool cascadeDel using (var con = tblParent.Database.Server.GetConnection()) { con.Open(); - var cmd = tblParent.Database.Server.GetCommand("DELETE FROM " + tblParent.GetFullyQualifiedName(), con); + var cmd = tblParent.Database.Server.GetCommand($"DELETE FROM {tblParent.GetFullyQualifiedName()}", con); if (cascadeDelete) { @@ -1003,7 +1009,7 @@ public void CreateTable_DefaultTest_Guid(DatabaseType type) var databaseValue = (string)dt2.Rows.Cast().Single()["MyGuid"]; Assert.IsNotNull(databaseValue); - Console.WriteLine(databaseValue); + TestContext.WriteLine(databaseValue); } [TestCaseSource(typeof(All),nameof(All.DatabaseTypes))] @@ -1308,7 +1314,7 @@ public void DateTimeTypeDeciderPerformance() foreach(string f in DateTimeTypeDecider.DateFormatsDM) { var val = dt.ToString(f); - Console.WriteLine(val); + TestContext.WriteLine(val); d.Parse(val); } @@ -1317,7 +1323,7 @@ public void DateTimeTypeDeciderPerformance() foreach(string f in DateTimeTypeDecider.TimeFormats) { var t = dt.ToString(f); - Console.WriteLine(t); + TestContext.WriteLine(t); d.Parse(t); } @@ -1326,7 +1332,7 @@ public void DateTimeTypeDeciderPerformance() //12s sw.Stop(); - Console.WriteLine(sw.ElapsedMilliseconds + " ms"); + TestContext.WriteLine($"{sw.ElapsedMilliseconds} ms"); } } } diff --git a/Tests/FAnsiTests/Database/DiscoverTablesTests.cs b/Tests/FAnsiTests/Database/DiscoverTablesTests.cs index 8a83b9b9..f76a4476 100644 --- a/Tests/FAnsiTests/Database/DiscoverTablesTests.cs +++ b/Tests/FAnsiTests/Database/DiscoverTablesTests.cs @@ -127,7 +127,7 @@ private void DropBadTable(DiscoveredDatabase db,bool ignoreFailure) if (!ignoreFailure) throw; - Console.WriteLine("Drop table failed, this is expected, since FAnsi won't see this dodgy table name we can't drop it as normal before tests"); + TestContext.WriteLine("Drop table failed, this is expected, since FAnsi won't see this dodgy table name we can't drop it as normal before tests"); } } } @@ -179,7 +179,7 @@ private void DropBadView(DiscoveredDatabase db, bool ignoreFailure) if (!ignoreFailure) throw; - Console.WriteLine("Drop view failed, this is expected, since FAnsi won't see this dodgy table name we can't drop it as normal before tests"); + TestContext.WriteLine("Drop view failed, this is expected, since FAnsi won't see this dodgy table name we can't drop it as normal before tests"); } } diff --git a/Tests/FAnsiTests/DatabaseTests.cs b/Tests/FAnsiTests/DatabaseTests.cs index ef8ae504..d8abdf8a 100644 --- a/Tests/FAnsiTests/DatabaseTests.cs +++ b/Tests/FAnsiTests/DatabaseTests.cs @@ -81,7 +81,7 @@ public void CheckFiles() } catch (Exception exception) { - Console.WriteLine(exception); + TestContext.WriteLine(exception); throw; } diff --git a/Tests/FAnsiTests/Examples.cs b/Tests/FAnsiTests/Examples.cs index 82b1b026..0da4376c 100644 --- a/Tests/FAnsiTests/Examples.cs +++ b/Tests/FAnsiTests/Examples.cs @@ -82,18 +82,16 @@ public void Example_TableCreation() var table = database.CreateTable("MyTable", dt); //Table has 2 rows in it - Console.WriteLine("Table {0} has {1} rows" ,table.GetFullyQualifiedName(), table.GetRowCount()); - Console.WriteLine("Column Name is of type {0}", table.DiscoverColumn("Name").DataType.SQLType); - Console.WriteLine("Column DateOfBirth is of type {0}", table.DiscoverColumn("DateOfBirth").DataType.SQLType); + TestContext.WriteLine("Table {0} has {1} rows" ,table.GetFullyQualifiedName(), table.GetRowCount()); + TestContext.WriteLine("Column Name is of type {0}", table.DiscoverColumn("Name").DataType.SQLType); + TestContext.WriteLine("Column DateOfBirth is of type {0}", table.DiscoverColumn("DateOfBirth").DataType.SQLType); - using (DbConnection con = server.GetConnection()) - { - con.Open(); - using(DbCommand cmd = server.GetCommand("Select * from " + table.GetFullyQualifiedName(), con)) - using(DbDataReader r = cmd.ExecuteReader()) - while (r.Read()) - Console.WriteLine(string.Join(",", r["Name"],r["DateOfBirth"])); - } + using DbConnection con = server.GetConnection(); + con.Open(); + using DbCommand cmd = server.GetCommand($"Select * from {table.GetFullyQualifiedName()}", con); + using DbDataReader r = cmd.ExecuteReader(); + while (r.Read()) + TestContext.WriteLine(string.Join(",", r["Name"],r["DateOfBirth"])); //Drop the table afterwards table.Drop(); diff --git a/Tests/FAnsiTests/Server/ServerTests.cs b/Tests/FAnsiTests/Server/ServerTests.cs index 40550db4..c9ba61a6 100644 --- a/Tests/FAnsiTests/Server/ServerTests.cs +++ b/Tests/FAnsiTests/Server/ServerTests.cs @@ -31,7 +31,7 @@ public void Server_RespondsWithinTime(DatabaseType type) { var server = GetTestServer(type); - Assert.IsTrue(server.RespondsWithinTime(3,out Exception ex)); + Assert.IsTrue(server.RespondsWithinTime(3,out _)); } /// @@ -219,7 +219,7 @@ public void TestServer_GetVersion(DatabaseType dbType) var db = GetTestDatabase(dbType, false); var ver = db.Server.GetVersion(); - Console.WriteLine("Version:" + ver); + TestContext.WriteLine($"Version:{ver}"); Assert.IsNotNull(ver); Assert.Greater(ver.Major,0); diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index 976cd4dd..75e42125 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -453,7 +453,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas Assert.AreEqual(numberOfRowsPerBatch, blk.Upload(dt)); //affected rows should match batch size } sw.Stop(); - Console.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); + TestContext.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); dt.Rows.Clear(); @@ -469,7 +469,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas } sw.Stop(); - Console.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); + TestContext.WriteLine($"Time taken:{sw.ElapsedMilliseconds}ms"); } @@ -501,7 +501,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas if(type != DatabaseType.MySql) StringAssert.Contains("cancel",ex.InnerException.Message); else - Console.WriteLine($"MySql error was:{ex.InnerException}"); + TestContext.WriteLine($"MySql error was:{ex.InnerException}"); } } diff --git a/Tests/FAnsiTests/Table/UpdateTests.cs b/Tests/FAnsiTests/Table/UpdateTests.cs index ab81f1d9..31823fba 100644 --- a/Tests/FAnsiTests/Table/UpdateTests.cs +++ b/Tests/FAnsiTests/Table/UpdateTests.cs @@ -57,25 +57,23 @@ public void Test_UpdateTableFromJoin(DatabaseType dbType) string sql = updateHelper.BuildUpdate(tbl1, tbl2, queryLines); - Console.WriteLine("UPDATE Sql:" + sql); + TestContext.WriteLine($"UPDATE Sql:{sql}"); - using (var con = db.Server.GetConnection()) - { - con.Open(); + using var con = db.Server.GetConnection(); + con.Open(); - DbCommand cmd = db.Server.GetCommand(sql, con); - int affectedRows = cmd.ExecuteNonQuery(); + DbCommand cmd = db.Server.GetCommand(sql, con); + int affectedRows = cmd.ExecuteNonQuery(); - Assert.AreEqual(1,affectedRows); + Assert.AreEqual(1,affectedRows); - //Frank should have got a new high score of 900 - cmd = db.Server.GetCommand($"SELECT {highScore} from {tbl1.GetFullyQualifiedName()} WHERE {name} = 'Frank'", con); - Assert.AreEqual(900,cmd.ExecuteScalar()); + //Frank should have got a new high score of 900 + cmd = db.Server.GetCommand($"SELECT {highScore} from {tbl1.GetFullyQualifiedName()} WHERE {name} = 'Frank'", con); + Assert.AreEqual(900,cmd.ExecuteScalar()); - //Dave should have his old score of 100 - cmd = db.Server.GetCommand($"SELECT {highScore} from {tbl1.GetFullyQualifiedName()} WHERE {name} = 'Dave'", con); - Assert.AreEqual(100, cmd.ExecuteScalar()); - } + //Dave should have his old score of 100 + cmd = db.Server.GetCommand($"SELECT {highScore} from {tbl1.GetFullyQualifiedName()} WHERE {name} = 'Dave'", con); + Assert.AreEqual(100, cmd.ExecuteScalar()); } } diff --git a/Tests/FAnsiTests/TestDatabases.xml b/Tests/FAnsiTests/TestDatabases.xml index 33ce80b8..93eedca9 100644 --- a/Tests/FAnsiTests/TestDatabases.xml +++ b/Tests/FAnsiTests/TestDatabases.xml @@ -5,20 +5,20 @@ MicrosoftSQLServer - server=localhost;User Id=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=true + Data Source=(LocalDb)\MSSQLLocalDB MySql - server=127.0.0.1;Uid=root;Pwd=;SslMode=None + server=127.0.0.1;Uid=root;Pwd=root;AllowPublicKeyRetrieval=True PostgreSql User ID=postgres;Password=;Host=127.0.0.1;Port=5432 +--> diff --git a/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs b/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs index 169f23c8..67b12dd7 100644 --- a/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs +++ b/Tests/FAnsiTests/TypeTranslation/DatatypeComputerTests.cs @@ -238,7 +238,7 @@ public void TestGuesser_DateTime_EnglishWithTime() Guesser t = new Guesser(); Console.WriteLine(CultureInfo.CurrentCulture.EnglishName); - Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.MonthDayPattern); + TestContext.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.MonthDayPattern); t.AdjustToCompensateForValue(GetCultureSpecificDate() + " 11:10"); t.AdjustToCompensateForValue(null); diff --git a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs index ae359929..b252800c 100644 --- a/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs +++ b/Tests/FAnsiTests/TypeTranslation/TypeTranslaterTests.cs @@ -243,7 +243,8 @@ private void RunKnownTypeTest(DatabaseType type, string sqlType, Type expectedTy Assert.AreEqual(tBefore, tAfter,"We asked to create a '{0}', DBMS created a '{1}'. FAnsi decided that '{0}' is '{2}' and that '{1}' is '{3}'",sqlType,col.DataType.SQLType,tBefore,tAfter); if(!string.Equals(col.DataType.SQLType,sqlType,StringComparison.CurrentCultureIgnoreCase)) - Console.WriteLine("{0} created a '{1}' when asked to create a '{2}'",type,col.DataType.SQLType,sqlType); + TestContext.WriteLine("{0} created a '{1}' when asked to create a '{2}'", type, + col.DataType.SQLType, sqlType); } finally From 4ce62d8f5832639c30dce8485dfd0892ddc7072b Mon Sep 17 00:00:00 2001 From: James A Sutherland <> Date: Sat, 13 Aug 2022 14:23:51 -0500 Subject: [PATCH 22/40] No LocalDB in CI, use SQL creds instead --- Tests/FAnsiTests/TestDatabases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FAnsiTests/TestDatabases.xml b/Tests/FAnsiTests/TestDatabases.xml index 93eedca9..90cb5b02 100644 --- a/Tests/FAnsiTests/TestDatabases.xml +++ b/Tests/FAnsiTests/TestDatabases.xml @@ -5,7 +5,7 @@ MicrosoftSQLServer - Data Source=(LocalDb)\MSSQLLocalDB + Data Source=localhost;Integrated Security=false;User ID=sa;Password=YourStrong!Passw0rd; MySql From 9ff20a80b7a6938b5e798286ac97be5b0a4312fe Mon Sep 17 00:00:00 2001 From: James A Sutherland <> Date: Sat, 13 Aug 2022 14:31:06 -0500 Subject: [PATCH 23/40] Disable MSSQL cert checks --- Tests/FAnsiTests/TestDatabases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FAnsiTests/TestDatabases.xml b/Tests/FAnsiTests/TestDatabases.xml index 90cb5b02..a057ab72 100644 --- a/Tests/FAnsiTests/TestDatabases.xml +++ b/Tests/FAnsiTests/TestDatabases.xml @@ -5,7 +5,7 @@ MicrosoftSQLServer - Data Source=localhost;Integrated Security=false;User ID=sa;Password=YourStrong!Passw0rd; + Data Source=localhost;Encrypt=true;TrustServerCertificate=true;Integrated Security=false;User ID=sa;Password=YourStrong!Passw0rd; MySql From d5cdeaab7eea4b3c8b81444c61a50143883f0ca6 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Sat, 13 Aug 2022 14:58:14 -0500 Subject: [PATCH 24/40] Avoid escaping newlines when combining lines for MySQL --- .../Aggregation/MySqlAggregateHelper.cs | 2 +- .../CalendarWithPivotAggregationTests.cs | 32 +++++++++-------- Tests/FAnsiTests/Table/BulkInsertTest.cs | 34 +++++++------------ 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs index f0062068..4a78a8fa 100644 --- a/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs +++ b/Implementations/FAnsi.Implementations.MySql/Aggregation/MySqlAggregateHelper.cs @@ -168,7 +168,7 @@ ORDER BY query.SyntaxHelper.Escape(GetDatePartOfColumn(query.Axis.AxisIncrement,axisColumnWithoutAlias)), //the order by (should be count so that heavy populated columns come first) - query.SyntaxHelper.Escape(string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert >= QueryComponent.FROM && c.LocationToInsert <= QueryComponent.WHERE))) + string.Join(Environment.NewLine, query.Lines.Where(c => c.LocationToInsert >= QueryComponent.FROM && c.LocationToInsert <= QueryComponent.WHERE).Select(x=> query.SyntaxHelper.Escape(x.Text))) ); } diff --git a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs index dab17ed8..90cd31aa 100644 --- a/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs +++ b/Tests/FAnsiTests/Aggregation/CalendarWithPivotAggregationTests.cs @@ -22,20 +22,22 @@ public void Test_Calendar_WithPivot(DatabaseType type,bool easy) var tbl = GetTestTable(type,easy); var svr = tbl.Database.Server; - var lines = new List(); - lines.Add(new CustomLine("SELECT", QueryComponent.SELECT)); - lines.Add(new CustomLine("count(*) as MyCount,", QueryComponent.QueryTimeColumn) - { Role = CustomLineRole.CountFunction }); - lines.Add(new CustomLine("EventDate,", QueryComponent.QueryTimeColumn) - { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("Category", QueryComponent.QueryTimeColumn) - { Role = CustomLineRole.Pivot }); //tell it which the pivot - lines.Add(new CustomLine("FROM ", QueryComponent.FROM)); - lines.Add(new CustomLine(tbl.GetFullyQualifiedName(), QueryComponent.FROM)); - lines.Add(new CustomLine("GROUP BY", QueryComponent.GroupBy)); - lines.Add(new CustomLine("EventDate,", QueryComponent.GroupBy) - { Role = CustomLineRole.Axis }); //tell it which the axis are - lines.Add(new CustomLine("Category", QueryComponent.GroupBy) { Role = CustomLineRole.Pivot }); + var lines = new List + { + new("SELECT", QueryComponent.SELECT), + new("count(*) as MyCount,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.CountFunction }, + new("EventDate,", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.Axis }, //tell it which the axis are + new("Category", QueryComponent.QueryTimeColumn) + { Role = CustomLineRole.Pivot }, //tell it which the pivot + new("FROM ", QueryComponent.FROM), + new(tbl.GetFullyQualifiedName(), QueryComponent.FROM), + new("GROUP BY", QueryComponent.GroupBy), + new("EventDate,", QueryComponent.GroupBy) + { Role = CustomLineRole.Axis }, //tell it which the axis are + new("Category", QueryComponent.GroupBy) { Role = CustomLineRole.Pivot } + }; var axis = new QueryAxis() { @@ -116,7 +118,7 @@ public void Test_Calendar_WithPivot(DatabaseType type,bool easy) Assert.AreEqual(0, dt.Rows[4][3]); Assert.AreEqual(0, dt.Rows[4][4]); } - catch (Exception e) + catch (Exception) { TestContext.Error.WriteLine($"SQL triggering error was: '{(sql ?? "None defined")}'"); throw; diff --git a/Tests/FAnsiTests/Table/BulkInsertTest.cs b/Tests/FAnsiTests/Table/BulkInsertTest.cs index 75e42125..2054d894 100644 --- a/Tests/FAnsiTests/Table/BulkInsertTest.cs +++ b/Tests/FAnsiTests/Table/BulkInsertTest.cs @@ -1,12 +1,10 @@ using System; using System.Collections.Generic; using System.Data; -using System.Data.Common; using System.Diagnostics; using System.Linq; using System.Threading; using FAnsi; -using FAnsi.Connections; using FAnsi.Discovery; using FAnsi.Discovery.QuerySyntax; using FAnsi.Exceptions; @@ -488,34 +486,28 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas Assert.IsFalse(tbl.DiscoverColumns().Any(c=>c.IsPrimaryKey)); - CancellationTokenSource cts; using (var con = tbl.Database.Server.BeginNewTransactedConnection()) { //give it 100 ms delay (simulates user cancelling not DbCommand.Timeout expiring) - using (cts = new CancellationTokenSource(100)) - { - //creation should have been cancelled at the database level - var ex = Assert.Throws(()=>tbl.CreatePrimaryKey(con.ManagedTransaction,cts.Token,50000,bobCol)); - - //MySql seems to be throwing null reference inside ExecuteNonQueryAsync. No idea why but it is still cancelled - if(type != DatabaseType.MySql) - StringAssert.Contains("cancel",ex.InnerException.Message); - else - TestContext.WriteLine($"MySql error was:{ex.InnerException}"); - } + using var cts = new CancellationTokenSource(100); + //creation should have been cancelled at the database level + var ex = Assert.Throws(()=>tbl.CreatePrimaryKey(con.ManagedTransaction,cts.Token,50000,bobCol)); + //MySql seems to be throwing null reference inside ExecuteNonQueryAsync. No idea why but it is still cancelled + if(type != DatabaseType.MySql) + StringAssert.Contains("cancel",ex?.InnerException?.Message); + else + TestContext.WriteLine($"MySql error was:{ex?.InnerException?.Message}"); } //Now let's test cancelling GetDataTable using (var con = tbl.Database.Server.BeginNewTransactedConnection()) { //give it 300 ms delay (simulates user cancelling not DbCommand.Timeout expiring) - using (cts = new CancellationTokenSource(300)) - { - //GetDataTable should have been cancelled at the database level - Assert.Throws(()=>tbl.GetDataTable(new DatabaseOperationArgs(con.ManagedTransaction,cts.Token,50000))); - tbl.GetDataTable(new DatabaseOperationArgs(con.ManagedTransaction,default(CancellationToken),50000)); - } + using var cts = new CancellationTokenSource(300); + //GetDataTable should have been cancelled at the database level + Assert.Throws(()=>tbl.GetDataTable(new DatabaseOperationArgs(con.ManagedTransaction,cts.Token,50000))); + tbl.GetDataTable(new DatabaseOperationArgs(con.ManagedTransaction,default(CancellationToken),50000)); } @@ -523,7 +515,7 @@ public void UnmatchedColumnsBulkInsertTest_UsesDefaultValues_TwoLargeBatches_Pas Assert.IsFalse(tbl.DiscoverColumns().Any(c=>c.IsPrimaryKey)); //now give it a bit longer to create it - using(cts = new CancellationTokenSource(50000000)) + using(var cts = new CancellationTokenSource(50000000)) tbl.CreatePrimaryKey(null, cts.Token, 50000, bobCol); bobCol = tbl.DiscoverColumn("bob"); From c070f9b601f19c2d15197a599c67794cd2d9f1b2 Mon Sep 17 00:00:00 2001 From: James A Sutherland Date: Fri, 26 Aug 2022 08:31:15 -0500 Subject: [PATCH 25/40] Update TestDatabases.xml --- Tests/FAnsiTests/TestDatabases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/FAnsiTests/TestDatabases.xml b/Tests/FAnsiTests/TestDatabases.xml index a057ab72..36689774 100644 --- a/Tests/FAnsiTests/TestDatabases.xml +++ b/Tests/FAnsiTests/TestDatabases.xml @@ -9,7 +9,7 @@ MySql - server=127.0.0.1;Uid=root;Pwd=root;AllowPublicKeyRetrieval=True + server=127.0.0.1;Uid=root;Pwd=root;AllowPublicKeyRetrieval=True;ConvertZeroDateTime=true