diff --git a/Build/build-scripts.ps1 b/Build/build-scripts.ps1 index d5999cae..2cb17547 100644 --- a/Build/build-scripts.ps1 +++ b/Build/build-scripts.ps1 @@ -81,9 +81,74 @@ function Wait-Mssql($connectionString) { Start-Sleep -Seconds 1 } } + + $connection.Open() } finally { $connection.Dispose() } } +function Start-Pgsql { + $npgsqldll = Join-Path $env:USERPROFILE ".nuget\packages\npgsql\4.0.11\lib\netstandard2.0\Npgsql.dll" + Add-Type -Path $npgsqldll + + $containerId = exec { + docker run ` + -d ` + -p 5432 ` + sqldatabase/postgres:13.3 + } + + $ip = exec { + docker inspect ` + --format "{{.NetworkSettings.Networks.bridge.IPAddress}}" ` + $containerId + } + + $port = exec { + docker inspect ` + --format "{{(index (index .NetworkSettings.Ports \""5432/tcp\"") 0).HostPort}}" ` + $containerId + } + + $builder = New-Object -TypeName Npgsql.NpgsqlConnectionStringBuilder + $builder["Database"] = "sqldatabasetest" + $builder["Username"] = "postgres" + $builder["Password"] = "qwerty" + $builder["Timeout"] = 5 + + $builder.Host = "localhost" + $builder.Port = $port.ToString() + $connectionString = $builder.ToString() + + $builder.Host = $ip.ToString() + $builder.Port = 5432 + $remoteConnectionString = $builder.ToString() + + return @{ + containerId = $containerId + connectionString = $connectionString + remoteConnectionString = $remoteConnectionString + } +} + +function Wait-Pgsql($connectionString) { + $connection = New-Object -TypeName Npgsql.NpgsqlConnection -ArgumentList $connectionString + try { + for ($i = 0; $i -lt 20; $i++) { + try { + $connection.Open() + return + } + catch { + Start-Sleep -Seconds 1 + } + } + + $connection.Open() + } + finally { + $connection.Dispose() + } +} diff --git a/Build/build-tasks.it-linux.ps1 b/Build/build-tasks.it-linux.ps1 index 6b3f1bd5..1a6c2534 100644 --- a/Build/build-tasks.it-linux.ps1 +++ b/Build/build-tasks.it-linux.ps1 @@ -1,20 +1,21 @@ param( - $settings, - $targetFramework, - $image + $settings + , $targetFramework + , $database + , $image ) -task Test RunMssql, UnZip, RunTest +task Test StartDatabase, UnZip, RunTest . .\build-scripts.ps1 -$mssqlContainerId = "" +$containerId = "" $connectionString = "" $remoteConnectionString = "" $tempDir = Join-Path $settings.bin ([Guid]::NewGuid().ToString()) Enter-Build { - Write-Output "$image" + Write-Output "$database on $targetFramework on $image" } task UnZip { @@ -24,10 +25,10 @@ task UnZip { Expand-Archive -Path $package -DestinationPath $tempDir } -task RunMssql { - $info = Start-Mssql +task StartDatabase { + $info = & "Start-$database" - $script:mssqlContainerId = $info.containerId + $script:containerId = $info.containerId $script:remoteConnectionString = $info.remoteConnectionString $script:connectionString = $info.connectionString @@ -35,10 +36,10 @@ task RunMssql { } task RunTest { - Wait-Mssql $info.connectionString + & "Wait-$database" $connectionString $app = $tempDir + ":/app" - $test = $settings.integrationTests + ":/test" + $test = (Join-Path $settings.integrationTests $database) + ":/test" exec { docker run --rm ` @@ -57,7 +58,7 @@ Exit-Build { Remove-Item -Path $tempDir -Force -Recurse } - if ($mssqlContainerId) { - exec { docker container rm -f $mssqlContainerId } | Out-Null + if ($containerId) { + exec { docker container rm -f $containerId } | Out-Null } } \ No newline at end of file diff --git a/Build/build-tasks.it-ps-core.ps1 b/Build/build-tasks.it-ps-core.ps1 index 5c725a84..8140595e 100644 --- a/Build/build-tasks.it-ps-core.ps1 +++ b/Build/build-tasks.it-ps-core.ps1 @@ -1,32 +1,33 @@ param( - $settings, - $image + $settings + , $database + , $image ) -task Test RunMssql, RunTest +task Test StartDatabase, RunTest . .\build-scripts.ps1 -$mssqlContainerId = "" +$containerId = "" $connectionString = "" Enter-Build { - Write-Output "$image" + Write-Output "$database on $image" } -task RunMssql { - $info = Start-Mssql +task StartDatabase { + $info = & "Start-$database" - $script:mssqlContainerId = $info.containerId + $script:containerId = $info.containerId $script:connectionString = $info.remoteConnectionString Write-Output $connectionString - Wait-Mssql $info.connectionString + & "Wait-$database" $info.connectionString } task RunTest { $app = $settings.artifactsPowerShell + ":/root/.local/share/powershell/Modules/SqlDatabase" - $test = $settings.integrationTests + ":/test" + $test = (Join-Path $settings.integrationTests $database) + ":/test" exec { docker run --rm ` @@ -39,7 +40,7 @@ task RunTest { } Exit-Build { - if ($mssqlContainerId) { - exec { docker container rm -f $mssqlContainerId } | Out-Null + if ($containerId) { + exec { docker container rm -f $containerId } | Out-Null } } \ No newline at end of file diff --git a/Build/build-tasks.it-ps-desktop.ps1 b/Build/build-tasks.it-ps-desktop.ps1 index 294f133a..97a656ab 100644 --- a/Build/build-tasks.it-ps-desktop.ps1 +++ b/Build/build-tasks.it-ps-desktop.ps1 @@ -2,12 +2,14 @@ param( $settings ) -task Test RunMssql, CopyModule, PublishModule, RunTest +task Test RunContainers, CopyModule, PublishModule, RunTest . .\build-scripts.ps1 $mssqlContainerId = "" -$connectionString = "" +$mssqlConnectionString = "" +$pgsqlContainerId = "" +$pgsqlConnectionString = "" $testDir = Join-Path ([Environment]::GetFolderPath("MyDocuments")) "WindowsPowerShell\modules\SqlDatabase" task CopyModule { @@ -25,23 +27,30 @@ task PublishModule { exec { powershell -NoLogo -Command "$command" } } -task RunMssql { +task RunContainers { $info = Start-Mssql - $script:mssqlContainerId = $info.containerId - $script:connectionString = $info.connectionString + $script:mssqlConnectionString = $info.connectionString + Write-Output $mssqlConnectionString - Write-Output $connectionString + $info = Start-Pgsql + $script:pgsqlContainerId = $info.containerId + $script:pgsqlConnectionString = $info.connectionString + Write-Output $pgsqlConnectionString } task RunTest { - Wait-Mssql $connectionString - - $env:connectionString = $connectionString + Wait-Mssql $mssqlConnectionString + Wait-Pgsql $pgsqlConnectionString - $testScript = Join-Path $settings.integrationTests "TestPowerShell.ps1" + $env:connectionString = $mssqlConnectionString + $testScript = Join-Path $settings.integrationTests "MsSql\TestPowerShell.ps1" $command = ". $testScript" + exec { powershell -NoLogo -Command "$command" } + $env:connectionString = $pgsqlConnectionString + $testScript = Join-Path $settings.integrationTests "PgSql\TestPowerShell.ps1" + $command = ". $testScript" exec { powershell -NoLogo -Command "$command" } } @@ -50,7 +59,5 @@ Exit-Build { Remove-Item -Path $testDir -Force -Recurse } - if ($mssqlContainerId) { - exec { docker container rm -f $mssqlContainerId } | Out-Null - } + exec { docker container rm -f $mssqlContainerId $pgsqlContainerId } | Out-Null } \ No newline at end of file diff --git a/Build/build-tasks.it-tool-linux.ps1 b/Build/build-tasks.it-tool-linux.ps1 index a01d1c24..ad7f1ad6 100644 --- a/Build/build-tasks.it-tool-linux.ps1 +++ b/Build/build-tasks.it-tool-linux.ps1 @@ -1,34 +1,35 @@ param( - $settings, - $image + $settings + , $database + , $image ) -task Test RunMssql, RunTest +task Test StartDatabase, RunTest . .\build-scripts.ps1 -$mssqlContainerId = "" +$containerId = "" $connectionString = "" Enter-Build { - Write-Output "$image" + Write-Output "$database on $image" } -task RunMssql { - $info = Start-Mssql +task StartDatabase { + $info = & "Start-$database" - $script:mssqlContainerId = $info.containerId + $script:containerId = $info.containerId $script:connectionString = $info.remoteConnectionString Write-Output $connectionString - Wait-Mssql $info.connectionString + & "Wait-$database" $info.connectionString } task RunTest { $packageVersion = $settings.version $packageName = "SqlDatabase.GlobalTool.$packageVersion.nupkg" $app = (Join-Path $settings.artifacts $packageName) + ":/app/$packageName" - $test = $settings.integrationTests + ":/test" + $test = (Join-Path $settings.integrationTests $database) + ":/test" exec { docker run --rm ` @@ -44,7 +45,7 @@ task RunTest { } Exit-Build { - if ($mssqlContainerId) { - exec { docker container rm -f $mssqlContainerId } | Out-Null + if ($containerId) { + exec { docker container rm -f $containerId } | Out-Null } } \ No newline at end of file diff --git a/Build/build-tasks.it-win.ps1 b/Build/build-tasks.it-win.ps1 index ad2609b7..70a4a607 100644 --- a/Build/build-tasks.it-win.ps1 +++ b/Build/build-tasks.it-win.ps1 @@ -1,13 +1,14 @@ param( - $settings, - $targetFramework + $settings + , $targetFramework + , $database ) -task Test RunMssql, UnZip, RunTest +task Test StartDatabase, UnZip, RunTest . .\build-scripts.ps1 -$mssqlContainerId = "" +$containerId = "" $connectionString = "" $tempDir = Join-Path $settings.bin ([Guid]::NewGuid().ToString()) @@ -22,20 +23,21 @@ task UnZip { Expand-Archive -Path $package -DestinationPath $tempDir } -task RunMssql { - $info = Start-Mssql +task StartDatabase { + $info = & "Start-$database" - $script:mssqlContainerId = $info.containerId + $script:containerId = $info.containerId $script:connectionString = $info.connectionString Write-Output $connectionString } task RunTest { - Wait-Mssql $info.connectionString + & "Wait-$database" $connectionString $app = Join-Path $tempDir "SqlDatabase.exe" - $script = Join-Path $settings.integrationTests "Test.ps1" + $script = (Join-Path $settings.integrationTests $database) + $script = Join-Path $script "Test.ps1" & $script $app $connectionString } @@ -45,7 +47,7 @@ Exit-Build { Remove-Item -Path $tempDir -Force -Recurse } - if ($mssqlContainerId) { - exec { docker container rm -f $mssqlContainerId } | Out-Null + if ($containerId) { + exec { docker container rm -f $containerId } | Out-Null } } \ No newline at end of file diff --git a/Build/build-tasks.ps1 b/Build/build-tasks.ps1 index 0d774f23..5f2a2abd 100644 --- a/Build/build-tasks.ps1 +++ b/Build/build-tasks.ps1 @@ -72,13 +72,7 @@ task PackPoweShellModule { # copy ThirdPartyNotices Copy-Item -Path (Join-Path $settings.bin "ThirdPartyNotices.txt") -Destination $dest - # copy net452 - $net45Dest = Join-Path $dest "net452" - $net45Source = Join-Path $settings.bin "SqlDatabase\net452" - New-Item -Path $net45Dest -ItemType Directory | Out-Null - Copy-Item -Path (Join-Path $net45Source "SqlDatabase.exe") -Destination $net45Dest - Copy-Item -Path (Join-Path $net45Source "SqlDatabase.pdb") -Destination $net45Dest - Copy-Item -Path (Join-Path $net45Source "System.Management.Automation.dll") -Destination $net45Dest + Get-ChildItem $dest -Include *.pdb -Recurse | Remove-Item } task PackNuget452 PackPoweShellModule, { @@ -116,8 +110,8 @@ task PackManualDownload PackGlobalTool, PackPoweShellModule, { # netcoreapp2.2 build does not create .exe, copy it from netcoreapp3.1 $exe = Join-Path $settings.bin "SqlDatabase\netcoreapp3.1\publish\SqlDatabase.exe" - $destination = Join-Path $out "SqlDatabase.$packageVersion-netcore22.zip" - $source = Join-Path $settings.bin "SqlDatabase\netcoreapp2.2\publish\*" + $destination = Join-Path $out "SqlDatabase.$packageVersion-netcore21.zip" + $source = Join-Path $settings.bin "SqlDatabase\netcoreapp2.1\publish\*" Compress-Archive -Path $source, $exe, $lic, $thirdParty -DestinationPath $destination $destination = Join-Path $out "SqlDatabase.$packageVersion-netcore31.zip" @@ -130,12 +124,14 @@ task PackManualDownload PackGlobalTool, PackPoweShellModule, { } task UnitTest { - Build-Parallel @( + $builds = @( @{ File = "build-tasks.unit-test.ps1"; Task = "Test"; settings = $settings; targetFramework = "net472" } - @{ File = "build-tasks.unit-test.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcoreapp2.2" } + @{ File = "build-tasks.unit-test.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcoreapp2.1" } @{ File = "build-tasks.unit-test.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcoreapp3.1" } @{ File = "build-tasks.unit-test.ps1"; Task = "Test"; settings = $settings; targetFramework = "net5.0" } - ) + ) + + Build-Parallel $builds -MaximumBuilds 4 } task InitializeIntegrationTest { @@ -145,7 +141,8 @@ task InitializeIntegrationTest { } Copy-Item -Path (Join-Path $settings.sources "SqlDatabase.Test\IntegrationTests") -Destination $dest -Force -Recurse - Copy-Item -Path (Join-Path $settings.bin "Tests\net472\2.1_2.2.*") -Destination (Join-Path $dest "Upgrade") -Force -Recurse + Copy-Item -Path (Join-Path $settings.bin "Tests\net472\2.1_2.2.*") -Destination (Join-Path $dest "MsSql\Upgrade") -Force + Copy-Item -Path (Join-Path $settings.bin "Tests\net472\2.1_2.2.*") -Destination (Join-Path $dest "PgSql\Upgrade") -Force # fix unix line endings $test = $dest + ":/test" @@ -153,43 +150,70 @@ task InitializeIntegrationTest { docker run --rm ` -v $test ` mcr.microsoft.com/dotnet/core/sdk:3.1 ` - bash -c "sed -i 's/\r//g' /test/TestGlobalTool.sh /test/Test.sh" + bash -c "sed -i 's/\r//g' test/MsSql/TestGlobalTool.sh test/MsSql/Test.sh test/PgSql/TestGlobalTool.sh /test/PgSql/Test.sh" } } task IntegrationTest { $builds = @( + # powershell desktop @{ File = "build-tasks.it-ps-desktop.ps1"; Task = "Test"; settings = $settings } - - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.1.0-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.1.1-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.1.2-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.1.3-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.2.0-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.2.1-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:6.2.4-alpine-3.8" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.0.0-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.0.1-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.0.2-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.0.3-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.1.0-ubuntu-18.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.1.2-ubuntu-20.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.2.0-preview.2-ubuntu-20.04" } - @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; image = "mcr.microsoft.com/powershell:7.2.0-preview.4-ubuntu-20.04" } - - @{ File = "build-tasks.it-tool-linux.ps1"; Task = "Test"; settings = $settings; image = "sqldatabase/dotnet_pwsh:2.2-sdk" } - @{ File = "build-tasks.it-tool-linux.ps1"; Task = "Test"; settings = $settings; image = "sqldatabase/dotnet_pwsh:3.1-sdk" } - @{ File = "build-tasks.it-tool-linux.ps1"; Task = "Test"; settings = $settings; image = "sqldatabase/dotnet_pwsh:5.0-sdk" } - - @{ File = "build-tasks.it-linux.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcore22"; image = "sqldatabase/dotnet_pwsh:2.2-runtime" } - @{ File = "build-tasks.it-linux.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcore31"; image = "sqldatabase/dotnet_pwsh:3.1-runtime" } - @{ File = "build-tasks.it-linux.ps1"; Task = "Test"; settings = $settings; targetFramework = "net50"; image = "sqldatabase/dotnet_pwsh:5.0-runtime" } - - @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = "net452" } - @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcore22" } - @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = "netcore31" } - @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = "net50" } ) + + # powershell core + $testCases = $( + "mcr.microsoft.com/powershell:6.1.0-ubuntu-18.04" + , "mcr.microsoft.com/powershell:6.1.1-alpine-3.8" + , "mcr.microsoft.com/powershell:6.1.2-alpine-3.8" + , "mcr.microsoft.com/powershell:6.1.3-alpine-3.8" + , "mcr.microsoft.com/powershell:6.2.0-alpine-3.8" + , "mcr.microsoft.com/powershell:6.2.1-alpine-3.8" + , "mcr.microsoft.com/powershell:6.2.4-alpine-3.8" + , "mcr.microsoft.com/powershell:7.0.0-ubuntu-18.04" + , "mcr.microsoft.com/powershell:7.0.1-ubuntu-18.04" + , "mcr.microsoft.com/powershell:7.0.2-ubuntu-18.04" + , "mcr.microsoft.com/powershell:7.0.3-ubuntu-18.04" + , "mcr.microsoft.com/powershell:7.1.0-ubuntu-18.04" + , "mcr.microsoft.com/powershell:7.1.2-ubuntu-20.04" + , "mcr.microsoft.com/powershell:7.2.0-preview.2-ubuntu-20.04" + , "mcr.microsoft.com/powershell:7.2.0-preview.4-ubuntu-20.04") + foreach ($case in $testCases) { + $builds += @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; database = "MsSql"; image = $case } + $builds += @{ File = "build-tasks.it-ps-core.ps1"; Task = "Test"; settings = $settings; database = "PgSql"; image = $case } + } + + # sdk tool + $testCases = $( + "sqldatabase/dotnet_pwsh:2.1-sdk" + , "sqldatabase/dotnet_pwsh:3.1-sdk" + , "sqldatabase/dotnet_pwsh:5.0-sdk") + foreach ($case in $testCases) { + $builds += @{ File = "build-tasks.it-tool-linux.ps1"; Task = "Test"; settings = $settings; database = "MsSql"; image = $case } + $builds += @{ File = "build-tasks.it-tool-linux.ps1"; Task = "Test"; settings = $settings; database = "PgSql"; image = $case } + } + + # .net runtime linux + $testCases = $( + @{ targetFramework = "netcore21"; image = "sqldatabase/dotnet_pwsh:2.1-runtime" } + , @{ targetFramework = "netcore31"; image = "sqldatabase/dotnet_pwsh:3.1-runtime" } + , @{ targetFramework = "net50"; image = "sqldatabase/dotnet_pwsh:5.0-runtime" } + ) + foreach ($case in $testCases) { + $builds += @{ File = "build-tasks.it-linux.ps1"; Task = "Test"; settings = $settings; targetFramework = $case.targetFramework; database = "MsSql"; image = $case.image } + $builds += @{ File = "build-tasks.it-linux.ps1"; Task = "Test"; settings = $settings; targetFramework = $case.targetFramework; database = "PgSql"; image = $case.image } + } + + # .net runtime windows + $testCases = $( + "net452" + , "netcore21" + , "netcore31" + , "net50" + ) + foreach ($case in $testCases) { + $builds += @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = $case; database = "MsSql" } + $builds += @{ File = "build-tasks.it-win.ps1"; Task = "Test"; settings = $settings; targetFramework = $case; database = "PgSql" } + } Build-Parallel $builds -MaximumBuilds 4 } \ No newline at end of file diff --git a/Build/build-tasks.unit-test.ps1 b/Build/build-tasks.unit-test.ps1 index d468e5fe..691ffc6a 100644 --- a/Build/build-tasks.unit-test.ps1 +++ b/Build/build-tasks.unit-test.ps1 @@ -3,35 +3,50 @@ param( $targetFramework ) -task Test RunMssql, UpdateConfig, RunTests +task Test RunContainers, UpdateConfig, RunTests . .\build-scripts.ps1 $mssqlContainerId = "empty" -$connectionString = "empty" +$mssqlConnectionString = "empty" +$pgsqlContainerId = "empty" +$pgsqlConnectionString = "empty" $testDir = Join-Path (Join-Path $settings.bin "Tests") $targetFramework Enter-Build { Write-Output "$testDir" } -task RunMssql { +task RunContainers { $info = Start-Mssql - $script:mssqlContainerId = $info.containerId - $script:connectionString = $info.connectionString + $script:mssqlConnectionString = $info.connectionString + Write-Output $mssqlConnectionString + + $info = Start-Pgsql + $script:pgsqlContainerId = $info.containerId + $script:pgsqlConnectionString = $info.connectionString + Write-Output $pgsqlConnectionString - Write-Output $connectionString - Wait-Mssql $connectionString + Wait-Mssql $mssqlConnectionString + Wait-Pgsql $pgsqlConnectionString } + task UpdateConfig { $configFiles = Get-ChildItem -Path $testDir -Filter *.dll.config foreach ($configFile in $configFiles) { [xml]$config = Get-Content $configFile - $node = $config.SelectSingleNode("configuration/connectionStrings/add[@name = 'test']") + + $node = $config.SelectSingleNode("configuration/connectionStrings/add[@name = 'mssql']") + if ($node) { + $node.Attributes["connectionString"].InnerText = $mssqlConnectionString + $config.Save($configFile) + } + + $node = $config.SelectSingleNode("configuration/connectionStrings/add[@name = 'pgsql']") if ($node) { - $node.Attributes["connectionString"].InnerText = $connectionString + $node.Attributes["connectionString"].InnerText = $pgsqlConnectionString $config.Save($configFile) } } @@ -52,5 +67,5 @@ task RunTests { Exit-Build { - exec { docker container rm -f $mssqlContainerId } | Out-Null + exec { docker container rm -f $mssqlContainerId $pgsqlContainerId } | Out-Null } \ No newline at end of file diff --git a/Build/create-images-tasks.ps1 b/Build/create-images-tasks.ps1 index eab2226b..04ff7a17 100644 --- a/Build/create-images-tasks.ps1 +++ b/Build/create-images-tasks.ps1 @@ -1,12 +1,13 @@ -task Default BuildDotnetSdk22 ` - , BuildDotnetRuntime22 ` +task Default BuildDotnetSdk21 ` + , BuildDotnetRuntime21 ` , BuildDotnetSdk31 ` , BuildDotnetRuntime31 ` , BuildDotnetSdk50 ` , BuildDotnetRuntime50 ` - , BuildDatabase + , BuildMsSqlDatabase ` + , BuildPgSqlDatabase -task BuildDatabase { +task BuildMsSqlDatabase { $context = Join-Path $PSScriptRoot "..\Sources\SqlDatabase.Test\Docker" exec { docker build ` @@ -16,20 +17,30 @@ task BuildDatabase { } } -task BuildDotnetSdk22 { +task BuildPgSqlDatabase { + $context = Join-Path $PSScriptRoot "..\Sources\SqlDatabase.Test\Docker" + exec { + docker build ` + -f image-postgres-133.dockerfile ` + -t sqldatabase/postgres:13.3 ` + $context + } +} + +task BuildDotnetSdk21 { exec { docker build ` - -f image-dotnet-sdk-2.2.dockerfile ` - -t sqldatabase/dotnet_pwsh:2.2-sdk ` + -f image-dotnet-sdk-2.1.dockerfile ` + -t sqldatabase/dotnet_pwsh:2.1-sdk ` . } } -task BuildDotnetRuntime22 { +task BuildDotnetRuntime21 { exec { docker build ` - -f image-dotnet-runtime-2.2.dockerfile ` - -t sqldatabase/dotnet_pwsh:2.2-runtime ` + -f image-dotnet-runtime-2.1.dockerfile ` + -t sqldatabase/dotnet_pwsh:2.1-runtime ` . } } diff --git a/Build/image-dotnet-runtime-2.2.dockerfile b/Build/image-dotnet-runtime-2.1.dockerfile similarity index 89% rename from Build/image-dotnet-runtime-2.2.dockerfile rename to Build/image-dotnet-runtime-2.1.dockerfile index 6609c060..f64aae23 100644 --- a/Build/image-dotnet-runtime-2.2.dockerfile +++ b/Build/image-dotnet-runtime-2.1.dockerfile @@ -1,4 +1,4 @@ -FROM microsoft/dotnet:2.2-runtime +FROM microsoft/dotnet:2.1-runtime RUN curl -L https://github.com/PowerShell/PowerShell/releases/download/v6.2.7/powershell_6.2.7-1.debian.9_amd64.deb --output powershell_6.2.7-1.debian.9_amd64.deb && \ dpkg -i powershell_6.2.7-1.debian.9_amd64.deb && \ diff --git a/Build/image-dotnet-sdk-2.2.dockerfile b/Build/image-dotnet-sdk-2.1.dockerfile similarity index 90% rename from Build/image-dotnet-sdk-2.2.dockerfile rename to Build/image-dotnet-sdk-2.1.dockerfile index e216a01c..f9276744 100644 --- a/Build/image-dotnet-sdk-2.2.dockerfile +++ b/Build/image-dotnet-sdk-2.1.dockerfile @@ -1,4 +1,4 @@ -FROM microsoft/dotnet:2.2-sdk +FROM microsoft/dotnet:2.1-sdk RUN curl -L https://github.com/PowerShell/PowerShell/releases/download/v6.2.7/powershell_6.2.7-1.debian.9_amd64.deb --output powershell_6.2.7-1.debian.9_amd64.deb && \ dpkg -i powershell_6.2.7-1.debian.9_amd64.deb && \ diff --git a/Build/image-mssql-2017.dockerfile b/Build/image-mssql-2017.dockerfile index 68686927..24069fc1 100644 --- a/Build/image-mssql-2017.dockerfile +++ b/Build/image-mssql-2017.dockerfile @@ -4,11 +4,11 @@ ENV ACCEPT_EULA=Y \ SA_PASSWORD=P@ssw0rd \ MSSQL_PID=Express -COPY CreateDatabase.sql /db/ +COPY mssql.create-database.sql /db/ RUN /opt/mssql/bin/sqlservr & \ sleep 20 && \ - /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P P@ssw0rd -l 300 -i /db/CreateDatabase.sql && \ + /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P P@ssw0rd -l 300 -i /db/mssql.create-database.sql && \ ls /var/opt/mssql/data/ && \ pkill sqlservr diff --git a/Build/image-postgres-133.dockerfile b/Build/image-postgres-133.dockerfile new file mode 100644 index 00000000..903ac9c8 --- /dev/null +++ b/Build/image-postgres-133.dockerfile @@ -0,0 +1,5 @@ +FROM postgres:13.3-alpine + +ENV POSTGRES_PASSWORD=qwerty + +COPY pgsql.create-database.sql /docker-entrypoint-initdb.d/ \ No newline at end of file diff --git a/Build/third-party-libraries/configuration/third-party-notices-template.txt b/Build/third-party-libraries/configuration/third-party-notices-template.txt index 16ae942f..9d40365f 100644 --- a/Build/third-party-libraries/configuration/third-party-notices-template.txt +++ b/Build/third-party-libraries/configuration/third-party-notices-template.txt @@ -11,7 +11,7 @@ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION {%- if package.Copyright -%} Copyright: {{package.Copyright}} {%- endif -%} - License: {{package.License.FullName}}, full text can be found at{% for i in package.License.HRefs %} {{i}}{% endfor %} or in{% for i in package.License.FileNames %} {{i}}{% endfor %} + License: {{package.License.FullName}}, full text can be found at{% for i in package.License.HRefs %} {{i}}{% endfor %} {%- if package.ThirdPartyNotices -%} {{package.ThirdPartyNotices}} diff --git a/Build/third-party-libraries/licenses/postgresql/index.json b/Build/third-party-libraries/licenses/postgresql/index.json new file mode 100644 index 00000000..fd5bb3de --- /dev/null +++ b/Build/third-party-libraries/licenses/postgresql/index.json @@ -0,0 +1,9 @@ +{ + "Code": "PostgreSQL", + "FullName": "PostgreSQL License", + "RequiresApproval": false, + "RequiresThirdPartyNotices": false, + "HRef": "https://spdx.org/licenses/PostgreSQL", + "FileName": "license.txt", + "Dependencies": [] +} \ No newline at end of file diff --git a/Build/third-party-libraries/licenses/postgresql/license.txt b/Build/third-party-libraries/licenses/postgresql/license.txt new file mode 100644 index 00000000..f5775a4c --- /dev/null +++ b/Build/third-party-libraries/licenses/postgresql/license.txt @@ -0,0 +1,12 @@ +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2010, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. diff --git a/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/index.json b/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/index.json index efb43d11..7a09813f 100644 --- a/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/readme.md b/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/readme.md index 8a6bead6..380d23ef 100644 --- a/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/castle.core/4.4.0/readme.md @@ -3,7 +3,7 @@ Castle.Core [4.4.0](https://www.nuget.org/packages/Castle.Core/4.4.0) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [Apache-2.0](../../../../licenses/apache-2.0) diff --git a/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/index.json b/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/index.json index 66ce807f..c792d8d5 100644 --- a/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/index.json +++ b/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/readme.md b/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/readme.md index 9e6cf9dd..821559d7 100644 --- a/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/dapper.strongname/2.0.78/readme.md @@ -3,7 +3,7 @@ Dapper.StrongName [2.0.78](https://www.nuget.org/packages/Dapper.StrongName/2.0. Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [Apache-2.0](../../../../licenses/apache-2.0) diff --git a/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/index.json b/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/index.json index 03b901fa..0c12e0b2 100644 --- a/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/index.json +++ b/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/readme.md b/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/readme.md index 16dd4066..ddac9530 100644 --- a/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/diffengine/6.4.9/readme.md @@ -3,7 +3,7 @@ DiffEngine [6.4.9](https://www.nuget.org/packages/DiffEngine/6.4.9) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/index.json b/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/index.json index 05e8c1cb..f8e9cef5 100644 --- a/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/index.json +++ b/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/readme.md b/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/readme.md index d5860427..c1b669b1 100644 --- a/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/emptyfiles/2.3.3/readme.md @@ -3,7 +3,7 @@ EmptyFiles [2.3.3](https://www.nuget.org/packages/EmptyFiles/2.3.3) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/index.json index 15376626..9d07bd3b 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/readme.md index cac144f4..837f64ba 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.codecoverage/16.9.4/readme.md @@ -3,7 +3,7 @@ Microsoft.CodeCoverage [16.9.4](https://www.nuget.org/packages/Microsoft.CodeCov Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/index.json index 173f502b..ed452b63 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/readme.md index 0d8a3195..d3339eb2 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0/readme.md @@ -3,7 +3,7 @@ Microsoft.DotNet.InternalAbstractions [1.0.0](https://www.nuget.org/packages/Mic Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/index.json index 18c0bf72..89119799 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/readme.md index 5ae55f1d..19fb0a89 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.net.test.sdk/16.9.4/readme.md @@ -3,7 +3,7 @@ Microsoft.NET.Test.Sdk [16.9.4](https://www.nuget.org/packages/Microsoft.NET.Tes Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/index.json similarity index 96% rename from Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/index.json rename to Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/index.json index 7f31c8ce..88c9c1dd 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/package-LICENSE.txt b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/package-LICENSE.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/package-LICENSE.txt rename to Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/package-LICENSE.txt diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/package.nuspec b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/package.nuspec new file mode 100644 index 00000000..343e83f1 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/package.nuspec @@ -0,0 +1,121 @@ + + + + Microsoft.NETCore.App + 2.1.0 + Microsoft.NETCore.App + Microsoft + microsoft,dotnetframework + false + https://github.com/dotnet/core-setup/blob/master/LICENSE.TXT + https://dot.net/ + http://go.microsoft.com/fwlink/?LinkID=288859 + A set of .NET API's that are included in the default .NET Core application model. +caa7b7e2bad98e56a687fb5cbaf60825500800f7 +When using NuGet 3.x this package requires at least version 3.4. + https://go.microsoft.com/fwlink/?LinkID=799417 + © Microsoft Corporation. All rights reserved. + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/readme.md similarity index 77% rename from Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/readme.md rename to Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/readme.md index c0f56d0a..c7b4e97e 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/readme.md @@ -1,9 +1,9 @@ -Microsoft.NETCore.App [2.2.0](https://www.nuget.org/packages/Microsoft.NETCore.App/2.2.0) +Microsoft.NETCore.App [2.1.0](https://www.nuget.org/packages/Microsoft.NETCore.App/2.1.0) -------------------- Used by: SqlDatabase -Target frameworks: net452, net472, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net472, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) @@ -13,7 +13,7 @@ License: [MIT](../../../../licenses/mit) Description ----------- A set of .NET API's that are included in the default .NET Core application model. -1249f08feda72b116c7e6e4e9a390671883c797d +caa7b7e2bad98e56a687fb5cbaf60825500800f7 When using NuGet 3.x this package requires at least version 3.4. Remarks diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/remarks.md b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/remarks.md similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/remarks.md rename to Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/remarks.md diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/third-party-notices.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/third-party-notices.txt rename to Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.1.0/third-party-notices.txt diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/package.nuspec b/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/package.nuspec deleted file mode 100644 index cced4f0d..00000000 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.netcore.app/2.2.0/package.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - Microsoft.NETCore.App - 2.2.0 - Microsoft.NETCore.App - Microsoft - microsoft,dotnetframework - false - https://github.com/dotnet/core-setup/blob/master/LICENSE.TXT - https://dot.net/ - http://go.microsoft.com/fwlink/?LinkID=288859 - A set of .NET API's that are included in the default .NET Core application model. -1249f08feda72b116c7e6e4e9a390671883c797d -When using NuGet 3.x this package requires at least version 3.4. - https://go.microsoft.com/fwlink/?LinkID=799417 - © Microsoft Corporation. All rights reserved. - true - - - - - - - - - - \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/index.json index a17a7bba..08a6c5d0 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/readme.md index 3e61ed34..57289300 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4/readme.md @@ -3,7 +3,7 @@ Microsoft.TestPlatform.ObjectModel [16.9.4](https://www.nuget.org/packages/Micro Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/index.json index d190d80d..0b25eb36 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/readme.md index 01c0e607..ab321b4d 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.testplatform.testhost/16.9.4/readme.md @@ -3,7 +3,7 @@ Microsoft.TestPlatform.TestHost [16.9.4](https://www.nuget.org/packages/Microsof Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/index.json index ed93092e..4be18516 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/readme.md index 087edfad..aa73ffa0 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.win32.registry/4.5.0/readme.md @@ -3,7 +3,7 @@ Microsoft.Win32.Registry [4.5.0](https://www.nuget.org/packages/Microsoft.Win32. Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/index.json index ff915420..1c007617 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/readme.md index 6e10ea0f..8e296c50 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/6.2.7/readme.md @@ -3,7 +3,7 @@ Microsoft.WSMan.Runtime [6.2.7](https://www.nuget.org/packages/Microsoft.WSMan.R Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/index.json index ff915420..1c007617 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/readme.md index c512b89a..cba905db 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.0.5/readme.md @@ -3,7 +3,7 @@ Microsoft.WSMan.Runtime [7.0.5](https://www.nuget.org/packages/Microsoft.WSMan.R Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/index.json b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/index.json index 86ccee66..5ab6a77c 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/index.json +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/readme.md b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/readme.md index c5cb6b3b..aaeb3ea2 100644 --- a/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/microsoft.wsman.runtime/7.1.2/readme.md @@ -3,7 +3,7 @@ Microsoft.WSMan.Runtime [7.1.2](https://www.nuget.org/packages/Microsoft.WSMan.R Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/index.json b/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/index.json index ca8f4e93..e5b7c883 100644 --- a/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/readme.md b/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/readme.md index 2fed2db4..f8c46660 100644 --- a/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/moq/4.16.1/readme.md @@ -3,7 +3,7 @@ Moq [4.16.1](https://www.nuget.org/packages/Moq/4.16.1) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [BSD-3-Clause](../../../../licenses/bsd-3-clause) diff --git a/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/index.json b/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/index.json index 356aae31..48a44b18 100644 --- a/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/index.json +++ b/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/readme.md b/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/readme.md index 367e0d23..6388a23d 100644 --- a/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/netstandard.library/2.0.3/readme.md @@ -3,7 +3,7 @@ NETStandard.Library [2.0.3](https://www.nuget.org/packages/NETStandard.Library/2 Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/index.json b/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/index.json index 07925c48..2037a02b 100644 --- a/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/readme.md b/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/readme.md index c971a418..847d82c2 100644 --- a/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/newtonsoft.json/13.0.1/readme.md @@ -3,7 +3,7 @@ Newtonsoft.Json [13.0.1](https://www.nuget.org/packages/Newtonsoft.Json/13.0.1) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/index.json b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/index.json new file mode 100644 index 00000000..8deb81ef --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/index.json @@ -0,0 +1,45 @@ +{ + "License": { + "Code": "PostgreSQL", + "Status": "AutomaticallyApproved" + }, + "UsedBy": [ + { + "Name": "SqlDatabase", + "InternalOnly": false, + "TargetFrameworks": [ + "netcoreapp2.1", + "netcoreapp3.1", + "net5.0", + "net452", + "netstandard2.0" + ], + "Dependencies": [ + { + "Name": "System.Runtime.CompilerServices.Unsafe", + "Version": "4.5.2" + } + ] + } + ], + "Licenses": [ + { + "Subject": "package", + "Code": "PostgreSQL", + "HRef": "https://licenses.nuget.org/PostgreSQL", + "Description": null + }, + { + "Subject": "repository", + "Code": "PostgreSQL", + "HRef": "git://github.com/npgsql/npgsql", + "Description": null + }, + { + "Subject": "project", + "Code": null, + "HRef": "http://www.npgsql.org/", + "Description": "License should be verified on http://www.npgsql.org/" + } + ] +} \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/package.nuspec b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/package.nuspec new file mode 100644 index 00000000..a2a9cd1f --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/package.nuspec @@ -0,0 +1,37 @@ + + + + Npgsql + 4.0.11 + Shay Rojansky,Yoh Deadfall,Austin Drenski,Emil Lenngren,Francisco Figueiredo Jr.,Kenji Uno + Shay Rojansky,Yoh Deadfall,Austin Drenski,Emil Lenngren,Francisco Figueiredo Jr.,Kenji Uno + false + PostgreSQL + https://licenses.nuget.org/PostgreSQL + http://www.npgsql.org/ + Npgsql is the open source .NET data provider for PostgreSQL. + Copyright 2019 © The Npgsql Development Team + npgsql postgresql postgres ado ado.net database sql + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/readme.md b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/readme.md new file mode 100644 index 00000000..6e83cc84 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/readme.md @@ -0,0 +1,30 @@ +Npgsql [4.0.11](https://www.nuget.org/packages/Npgsql/4.0.11) +-------------------- + +Used by: SqlDatabase + +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 + +License: [PostgreSQL](../../../../licenses/postgresql) + +- package license: [PostgreSQL](https://licenses.nuget.org/PostgreSQL) +- repository license: [PostgreSQL](git://github.com/npgsql/npgsql) +- project license: [Unknown](http://www.npgsql.org/) , License should be verified on http://www.npgsql.org/ + +Description +----------- +Npgsql is the open source .NET data provider for PostgreSQL. + +Remarks +----------- +no remarks + + +Dependencies 1 +----------- + +|Name|Version| +|----------|:----| +|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2)|4.5.2| + +*This page was generated by a tool.* \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/remarks.md b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/remarks.md similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/remarks.md rename to Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/remarks.md diff --git a/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/repository-LICENSE b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/repository-LICENSE new file mode 100644 index 00000000..b102b0e3 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/repository-LICENSE @@ -0,0 +1,17 @@ +Copyright (c) 2002-2021, Npgsql + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL NPGSQL BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +Npgsql HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +NPGSQL SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND Npgsql +HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, +OR MODIFICATIONS. diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/third-party-notices.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/third-party-notices.txt rename to Build/third-party-libraries/packages/nuget.org/npgsql/4.0.11/third-party-notices.txt diff --git a/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/index.json b/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/index.json index ec3787df..691d794f 100644 --- a/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/readme.md b/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/readme.md index fb0c74ed..fca3bfc9 100644 --- a/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/nuget.frameworks/5.0.0/readme.md @@ -3,7 +3,7 @@ NuGet.Frameworks [5.0.0](https://www.nuget.org/packages/NuGet.Frameworks/5.0.0%2 Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [Apache-2.0](../../../../licenses/apache-2.0) diff --git a/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/index.json b/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/index.json index dae89141..5f283814 100644 --- a/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/readme.md b/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/readme.md index b554aa1b..f1b96aaa 100644 --- a/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/nunit/3.13.1/readme.md @@ -3,7 +3,7 @@ NUnit [3.13.1](https://www.nuget.org/packages/NUnit/3.13.1) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/index.json b/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/index.json index 059f316b..ba9f90cc 100644 --- a/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/readme.md b/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/readme.md index a4c1ba8c..0a6712e2 100644 --- a/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/nunit3testadapter/3.17.0/readme.md @@ -3,7 +3,7 @@ NUnit3TestAdapter [3.17.0](https://www.nuget.org/packages/NUnit3TestAdapter/3.17 Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/index.json b/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/index.json index 91ab4139..4a2478d9 100644 --- a/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/readme.md b/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/readme.md index 61ca46e0..0d24a8b1 100644 --- a/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/powershellstandard.library/5.1.0/readme.md @@ -3,7 +3,7 @@ PowerShellStandard.Library [5.1.0](https://www.nuget.org/packages/PowerShellStan Used by: SqlDatabase -Target frameworks: net452, net472, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net472, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/index.json b/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/index.json index befc8666..fdf607ea 100644 --- a/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/index.json +++ b/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/readme.md b/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/readme.md index 881dfe1a..0a68b0ae 100644 --- a/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/shouldly/4.0.3/readme.md @@ -3,7 +3,7 @@ Shouldly [4.0.3](https://www.nuget.org/packages/Shouldly/4.0.3) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [BSD-2-Clause](../../../../licenses/bsd-2-clause) diff --git a/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/index.json b/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/index.json index cd6f444e..9911c827 100644 --- a/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/index.json +++ b/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/readme.md b/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/readme.md index fc568653..3957a22e 100644 --- a/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/stylecop.analyzers.unstable/1.2.0.333/readme.md @@ -3,7 +3,7 @@ StyleCop.Analyzers.Unstable [1.2.0.333](https://www.nuget.org/packages/StyleCop. Used by: SqlDatabase internal -Target frameworks: net452, net472, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net472, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/readme.md index 90674f6c..a998b65b 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.appcontext/4.1.0/readme.md @@ -3,7 +3,7 @@ System.AppContext [4.1.0](https://www.nuget.org/packages/System.AppContext/4.1.0 Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/readme.md index 006b67e8..60a51643 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.4.0/readme.md @@ -3,7 +3,7 @@ System.Buffers [4.4.0](https://www.nuget.org/packages/System.Buffers/4.4.0) Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/index.json b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/index.json index cf5ff9ee..382a9b54 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/readme.md b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/readme.md index 144c332f..0ec1f1b3 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.buffers/4.5.1/readme.md @@ -3,7 +3,7 @@ System.Buffers [4.5.1](https://www.nuget.org/packages/System.Buffers/4.5.1) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/index.json index 39f87c94..6a62a378 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/readme.md index 4ec215e7..9ea88387 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.collections.nongeneric/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Collections.NonGeneric [4.3.0](https://www.nuget.org/packages/System.Coll Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/index.json index def3298c..58af373c 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/readme.md index 8327e40a..7e16dffb 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.collections.specialized/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Collections.Specialized [4.3.0](https://www.nuget.org/packages/System.Col Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/index.json index 39f87c94..6a62a378 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/readme.md index 90e2f9fe..11a373f2 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.eventbasedasync/4.3.0/readme.md @@ -3,7 +3,7 @@ System.ComponentModel.EventBasedAsync [4.3.0](https://www.nuget.org/packages/Sys Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/index.json index 14c1c1f6..b6c1e6c6 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/readme.md index 3c0b0d2e..73ae92df 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.primitives/4.3.0/readme.md @@ -3,7 +3,7 @@ System.ComponentModel.Primitives [4.3.0](https://www.nuget.org/packages/System.C Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/index.json index 0399ae33..544be632 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/readme.md index 34894824..fd9aeadd 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel.typeconverter/4.3.0/readme.md @@ -3,7 +3,7 @@ System.ComponentModel.TypeConverter [4.3.0](https://www.nuget.org/packages/Syste Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/readme.md index b11a1b0e..1da84558 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.componentmodel/4.3.0/readme.md @@ -3,7 +3,7 @@ System.ComponentModel [4.3.0](https://www.nuget.org/packages/System.ComponentMod Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/index.json index 48133d99..214b48c4 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/readme.md index eeb956eb..5b4c7a4a 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.configuration.configurationmanager/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Configuration.ConfigurationManager [4.5.0](https://www.nuget.org/packages Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/index.json b/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/index.json index 66cb0ede..3953b474 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/readme.md b/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/readme.md index 8c3d8f49..a9fa0ba6 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.data.sqlclient/4.5.1/readme.md @@ -3,7 +3,7 @@ System.Data.SqlClient [4.5.1](https://www.nuget.org/packages/System.Data.SqlClie Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/readme.md index e811fb97..3032b33e 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.diagnostics.diagnosticsource/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Diagnostics.DiagnosticSource [4.5.0](https://www.nuget.org/packages/Syste Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/index.json index fcf4cc80..0dd49c10 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/readme.md index 52987346..c802b600 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.dynamic.runtime/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Dynamic.Runtime [4.3.0](https://www.nuget.org/packages/System.Dynamic.Run Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/readme.md index 83b022cb..af4d7ada 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.io.filesystem.primitives/4.3.0/readme.md @@ -3,7 +3,7 @@ System.IO.FileSystem.Primitives [4.3.0](https://www.nuget.org/packages/System.IO Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/index.json index 65d347b5..442dc52d 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/readme.md index b7c65661..38ecd9b6 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.linq.expressions/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Linq.Expressions [4.3.0](https://www.nuget.org/packages/System.Linq.Expre Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/readme.md index 1d3212dc..bb17d419 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.linq/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Linq [4.3.0](https://www.nuget.org/packages/System.Linq/4.3.0) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/index.json b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/index.json similarity index 84% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/index.json rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/index.json index ddf80c74..00a64e95 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", @@ -19,13 +19,9 @@ "Name": "System.Buffers", "Version": "4.4.0" }, - { - "Name": "System.Numerics.Vectors", - "Version": "4.4.0" - }, { "Name": "System.Runtime.CompilerServices.Unsafe", - "Version": "4.5.0" + "Version": "4.5.2" } ] } diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/package-LICENSE.txt b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/package-LICENSE.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/package-LICENSE.txt rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/package-LICENSE.txt diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/package.nuspec b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/package.nuspec similarity index 65% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/package.nuspec rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/package.nuspec index ec3aaa1f..eee52259 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/package.nuspec +++ b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/package.nuspec @@ -2,7 +2,7 @@ System.Memory - 4.5.1 + 4.5.3 System.Memory Microsoft microsoft,dotnetframework @@ -22,73 +22,79 @@ System.Buffers.ReadOnlySequence System.Buffers.Text.Utf8Parser System.Buffers.Text.Utf8Formatter -7ee84596d92e178bce54c986df31ccc52479e772 +c6cf790234e063b855fcdb50f3fb1b3cfac73275 When using NuGet 3.x this package requires at least version 3.4. https://go.microsoft.com/fwlink/?LinkID=799421 - © Microsoft Corporation. All rights reserved. + © Microsoft Corporation. All rights reserved. true - - + + - - + + - - + + - - - + + + - + - - - + + + + + + + + + - - - + + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/readme.md b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/readme.md similarity index 75% rename from Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/readme.md rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/readme.md index af789cff..62d36493 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.1/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/readme.md @@ -1,9 +1,9 @@ -System.Memory [4.5.1](https://www.nuget.org/packages/System.Memory/4.5.1) +System.Memory [4.5.3](https://www.nuget.org/packages/System.Memory/4.5.3) -------------------- Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) @@ -24,7 +24,7 @@ System.Buffers.ReadOnlySequence System.Buffers.Text.Utf8Parser System.Buffers.Text.Utf8Formatter -7ee84596d92e178bce54c986df31ccc52479e772 +c6cf790234e063b855fcdb50f3fb1b3cfac73275 When using NuGet 3.x this package requires at least version 3.4. Remarks @@ -32,13 +32,12 @@ Remarks no remarks -Dependencies 3 +Dependencies 2 ----------- |Name|Version| |----------|:----| |[System.Buffers](../../../../packages/nuget.org/system.buffers/4.4.0)|4.4.0| -|[System.Numerics.Vectors](../../../../packages/nuget.org/system.numerics.vectors/4.4.0)|4.4.0| -|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0)|4.5.0| +|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2)|4.5.2| *This page was generated by a tool.* \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/remarks.md b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/remarks.md similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/remarks.md rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/remarks.md diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/third-party-notices.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/third-party-notices.txt rename to Build/third-party-libraries/packages/nuget.org/system.memory/4.5.3/third-party-notices.txt diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/index.json b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/index.json index 5a631783..c35b4742 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/readme.md b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/readme.md index f8e1a692..963c6681 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.memory/4.5.4/readme.md @@ -3,7 +3,7 @@ System.Memory [4.5.4](https://www.nuget.org/packages/System.Memory/4.5.4) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/readme.md index d5125ac4..566c1bba 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.4.0/readme.md @@ -3,7 +3,7 @@ System.Numerics.Vectors [4.4.0](https://www.nuget.org/packages/System.Numerics.V Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/index.json index cf5ff9ee..382a9b54 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/readme.md index fa1b0872..a600eb56 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.numerics.vectors/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Numerics.Vectors [4.5.0](https://www.nuget.org/packages/System.Numerics.V Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/index.json index 39f87c94..6a62a378 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/readme.md index e3a9a242..648ee567 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.objectmodel/4.3.0/readme.md @@ -3,7 +3,7 @@ System.ObjectModel [4.3.0](https://www.nuget.org/packages/System.ObjectModel/4.3 Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/index.json index cf5ff9ee..382a9b54 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/readme.md index eed14d8c..52c056a2 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.reflection.metadata/1.6.0/readme.md @@ -3,7 +3,7 @@ System.Reflection.Metadata [1.6.0](https://www.nuget.org/packages/System.Reflect Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/readme.md index ae433825..9152b598 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.reflection.typeextensions/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Reflection.TypeExtensions [4.3.0](https://www.nuget.org/packages/System.R Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/index.json similarity index 96% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/index.json rename to Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/package-LICENSE.txt b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/package-LICENSE.txt similarity index 100% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/package-LICENSE.txt rename to Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/package-LICENSE.txt diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/package.nuspec b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/package.nuspec similarity index 88% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/package.nuspec rename to Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/package.nuspec index 8235d41b..a8481f68 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/package.nuspec +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/package.nuspec @@ -2,7 +2,7 @@ System.Runtime.CompilerServices.Unsafe - 4.5.0 + 4.5.2 System.Runtime.CompilerServices.Unsafe Microsoft microsoft,dotnetframework @@ -15,10 +15,10 @@ Commonly Used Types: System.Runtime.CompilerServices.Unsafe -30ab651fcb4354552bd4891619a0bdd81e0ebdbf +02b11eeee1fbc5f3ef43a1452fe07efd25fa1715 When using NuGet 3.x this package requires at least version 3.4. https://go.microsoft.com/fwlink/?LinkID=799421 - © Microsoft Corporation. All rights reserved. + © Microsoft Corporation. All rights reserved. true @@ -28,7 +28,6 @@ When using NuGet 3.x this package requires at least version 3.4. - diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/readme.md similarity index 74% rename from Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/readme.md rename to Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/readme.md index 5a5463a6..0719ceea 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/readme.md @@ -1,9 +1,9 @@ -System.Runtime.CompilerServices.Unsafe [4.5.0](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/4.5.0) +System.Runtime.CompilerServices.Unsafe [4.5.2](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/4.5.2) -------------------- Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) @@ -17,7 +17,7 @@ Provides the System.Runtime.CompilerServices.Unsafe class, which provides generi Commonly Used Types: System.Runtime.CompilerServices.Unsafe -30ab651fcb4354552bd4891619a0bdd81e0ebdbf +02b11eeee1fbc5f3ef43a1452fe07efd25fa1715 When using NuGet 3.x this package requires at least version 3.4. Remarks diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/remarks.md b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/remarks.md new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2/third-party-notices.txt new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/index.json b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/index.json index cf5ff9ee..382a9b54 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/readme.md b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/readme.md index 3988e243..116cee73 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3/readme.md @@ -3,7 +3,7 @@ System.Runtime.CompilerServices.Unsafe [4.5.3](https://www.nuget.org/packages/Sy Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/index.json index 39f87c94..6a62a378 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/readme.md index 6a0a6e2a..0a128c5f 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Runtime.InteropServices.RuntimeInformation [4.3.0](https://www.nuget.org/ Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/index.json index ff5bfc39..df83ee35 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/readme.md index 5cfe63a1..643745ae 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.runtime.loader/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Runtime.Loader [4.3.0](https://www.nuget.org/packages/System.Runtime.Load Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/index.json index 40145b17..adff3590 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/readme.md index a8a224e1..440e43f8 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.security.accesscontrol/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Security.AccessControl [4.5.0](https://www.nuget.org/packages/System.Secu Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/readme.md index 29ee1242..62d6de63 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.security.cryptography.protecteddata/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Security.Cryptography.ProtectedData [4.5.0](https://www.nuget.org/package Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/index.json index 23e8eac3..0794360f 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/readme.md index 06d46c68..db949f63 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.security.permissions/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Security.Permissions [4.5.0](https://www.nuget.org/packages/System.Securi Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/index.json index 4518b6a9..f3706740 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", diff --git a/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/readme.md index 0ab2632e..49fb2f0b 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.security.principal.windows/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Security.Principal.Windows [4.5.0](https://www.nuget.org/packages/System. Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/index.json index d557df70..c82a1ea9 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": false, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net452", @@ -17,7 +17,7 @@ "Dependencies": [ { "Name": "System.Runtime.CompilerServices.Unsafe", - "Version": "4.5.0" + "Version": "4.5.2" } ] } diff --git a/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/readme.md index ac66fa30..d120054f 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.text.encoding.codepages/4.5.0/readme.md @@ -3,7 +3,7 @@ System.Text.Encoding.CodePages [4.5.0](https://www.nuget.org/packages/System.Tex Used by: SqlDatabase -Target frameworks: net452, net5.0, netcoreapp2.2, netcoreapp3.1, netstandard2.0 +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 License: [MIT](../../../../licenses/mit) @@ -30,6 +30,6 @@ Dependencies 1 |Name|Version| |----------|:----| -|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0)|4.5.0| +|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2)|4.5.2| *This page was generated by a tool.* \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/readme.md index 1eaa17ae..3aefca8b 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.text.regularexpressions/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Text.RegularExpressions [4.3.0](https://www.nuget.org/packages/System.Tex Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/index.json b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/index.json new file mode 100644 index 00000000..c82a1ea9 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/index.json @@ -0,0 +1,39 @@ +{ + "License": { + "Code": "MIT", + "Status": "AutomaticallyApproved" + }, + "UsedBy": [ + { + "Name": "SqlDatabase", + "InternalOnly": false, + "TargetFrameworks": [ + "netcoreapp2.1", + "netcoreapp3.1", + "net5.0", + "net452", + "netstandard2.0" + ], + "Dependencies": [ + { + "Name": "System.Runtime.CompilerServices.Unsafe", + "Version": "4.5.2" + } + ] + } + ], + "Licenses": [ + { + "Subject": "package", + "Code": "MIT", + "HRef": "https://github.com/dotnet/corefx/blob/master/LICENSE.TXT", + "Description": null + }, + { + "Subject": "project", + "Code": null, + "HRef": "https://dot.net/", + "Description": "License should be verified on https://dot.net/" + } + ] +} \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package-LICENSE.txt b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package-LICENSE.txt new file mode 100644 index 00000000..984713a4 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package-LICENSE.txt @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package.nuspec b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package.nuspec new file mode 100644 index 00000000..672cf34a --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/package.nuspec @@ -0,0 +1,56 @@ + + + + System.Threading.Tasks.Extensions + 4.5.2 + System.Threading.Tasks.Extensions + Microsoft + microsoft,dotnetframework + false + https://github.com/dotnet/corefx/blob/master/LICENSE.TXT + https://dot.net/ + http://go.microsoft.com/fwlink/?LinkID=288859 + Provides additional types that simplify the work of writing concurrent and asynchronous code. + +Commonly Used Types: +System.Threading.Tasks.ValueTask<TResult> + +99ce22c306b07f99ddae60f443d23a983ae78f7b + https://go.microsoft.com/fwlink/?LinkID=799421 + © Microsoft Corporation. All rights reserved. + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/readme.md b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/readme.md new file mode 100644 index 00000000..cbbe5480 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/readme.md @@ -0,0 +1,34 @@ +System.Threading.Tasks.Extensions [4.5.2](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.5.2) +-------------------- + +Used by: SqlDatabase + +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 + +License: [MIT](../../../../licenses/mit) + +- package license: [MIT](https://github.com/dotnet/corefx/blob/master/LICENSE.TXT) +- project license: [Unknown](https://dot.net/) , License should be verified on https://dot.net/ + +Description +----------- +Provides additional types that simplify the work of writing concurrent and asynchronous code. + +Commonly Used Types: +System.Threading.Tasks.ValueTask + +99ce22c306b07f99ddae60f443d23a983ae78f7b + +Remarks +----------- +no remarks + + +Dependencies 1 +----------- + +|Name|Version| +|----------|:----| +|[System.Runtime.CompilerServices.Unsafe](../../../../packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2)|4.5.2| + +*This page was generated by a tool.* \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/remarks.md b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/remarks.md new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.2/third-party-notices.txt new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/index.json b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/index.json index 809b8b5b..96a2ee4f 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/readme.md b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/readme.md index 9f18bab3..69e07ea3 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.tasks.extensions/4.5.4/readme.md @@ -3,7 +3,7 @@ System.Threading.Tasks.Extensions [4.5.4](https://www.nuget.org/packages/System. Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [MIT](../../../../licenses/mit) diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/readme.md index 5d0fc2cb..480bd44a 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.threading.thread/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Threading.Thread [4.3.0](https://www.nuget.org/packages/System.Threading. Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/index.json index 0397d25c..cb053ee5 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/readme.md index ac794ae8..969ae5bc 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.threading/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Threading [4.3.0](https://www.nuget.org/packages/System.Threading/4.3.0) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/index.json new file mode 100644 index 00000000..f3706740 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/index.json @@ -0,0 +1,33 @@ +{ + "License": { + "Code": "MIT", + "Status": "AutomaticallyApproved" + }, + "UsedBy": [ + { + "Name": "SqlDatabase", + "InternalOnly": false, + "TargetFrameworks": [ + "netcoreapp2.1", + "netcoreapp3.1", + "net5.0", + "net452", + "netstandard2.0" + ] + } + ], + "Licenses": [ + { + "Subject": "package", + "Code": "MIT", + "HRef": "https://github.com/dotnet/corefx/blob/master/LICENSE.TXT", + "Description": null + }, + { + "Subject": "project", + "Code": null, + "HRef": "https://dot.net/", + "Description": "License should be verified on https://dot.net/" + } + ] +} \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package-LICENSE.txt b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package-LICENSE.txt new file mode 100644 index 00000000..984713a4 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package-LICENSE.txt @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package.nuspec b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package.nuspec new file mode 100644 index 00000000..b0629162 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/package.nuspec @@ -0,0 +1,58 @@ + + + + System.ValueTuple + 4.5.0 + System.ValueTuple + Microsoft + microsoft,dotnetframework + false + https://github.com/dotnet/corefx/blob/master/LICENSE.TXT + https://dot.net/ + http://go.microsoft.com/fwlink/?LinkID=288859 + Provides the System.ValueTuple structs, which implement the underlying types for tuples in C# and Visual Basic. + +Commonly Used Types: +System.ValueTuple +System.ValueTuple<T1> +System.ValueTuple<T1, T2> +System.ValueTuple<T1, T2, T3> +System.ValueTuple<T1, T2, T3, T4> +System.ValueTuple<T1, T2, T3, T4, T5> +System.ValueTuple<T1, T2, T3, T4, T5, T6> +System.ValueTuple<T1, T2, T3, T4, T5, T6, T7> +System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> + +30ab651fcb4354552bd4891619a0bdd81e0ebdbf +When using NuGet 3.x this package requires at least version 3.4. + https://go.microsoft.com/fwlink/?LinkID=799421 + © Microsoft Corporation. All rights reserved. + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/readme.md new file mode 100644 index 00000000..f5db75f6 --- /dev/null +++ b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/readme.md @@ -0,0 +1,40 @@ +System.ValueTuple [4.5.0](https://www.nuget.org/packages/System.ValueTuple/4.5.0) +-------------------- + +Used by: SqlDatabase + +Target frameworks: net452, net5.0, netcoreapp2.1, netcoreapp3.1, netstandard2.0 + +License: [MIT](../../../../licenses/mit) + +- package license: [MIT](https://github.com/dotnet/corefx/blob/master/LICENSE.TXT) +- project license: [Unknown](https://dot.net/) , License should be verified on https://dot.net/ + +Description +----------- +Provides the System.ValueTuple structs, which implement the underlying types for tuples in C# and Visual Basic. + +Commonly Used Types: +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple +System.ValueTuple + +30ab651fcb4354552bd4891619a0bdd81e0ebdbf +When using NuGet 3.x this package requires at least version 3.4. + +Remarks +----------- +no remarks + + +Dependencies 0 +----------- + + +*This page was generated by a tool.* \ No newline at end of file diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/remarks.md b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/remarks.md new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/third-party-notices.txt b/Build/third-party-libraries/packages/nuget.org/system.valuetuple/4.5.0/third-party-notices.txt new file mode 100644 index 00000000..e69de29b diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/index.json index c187fa19..a279bbc4 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/readme.md index a809e2c1..d4193a70 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.readerwriter/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Xml.ReaderWriter [4.3.0](https://www.nuget.org/packages/System.Xml.Reader Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/index.json index 0d845ce4..a722c5f1 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/readme.md index 79dcfd06..de85b563 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xmldocument/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Xml.XmlDocument [4.3.0](https://www.nuget.org/packages/System.Xml.XmlDocu Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/index.json index 9c027619..d1c598c7 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/readme.md index 4cf36e86..85597cb7 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath.xmldocument/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Xml.XPath.XmlDocument [4.3.0](https://www.nuget.org/packages/System.Xml.X Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/index.json b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/index.json index 0d845ce4..a722c5f1 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/index.json +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/index.json @@ -8,7 +8,7 @@ "Name": "SqlDatabase", "InternalOnly": true, "TargetFrameworks": [ - "netcoreapp2.2", + "netcoreapp2.1", "netcoreapp3.1", "net5.0", "net472" diff --git a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/readme.md b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/readme.md index 75310ff5..4793f028 100644 --- a/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/readme.md +++ b/Build/third-party-libraries/packages/nuget.org/system.xml.xpath/4.3.0/readme.md @@ -3,7 +3,7 @@ System.Xml.XPath [4.3.0](https://www.nuget.org/packages/System.Xml.XPath/4.3.0) Used by: SqlDatabase internal -Target frameworks: net472, net5.0, netcoreapp2.2, netcoreapp3.1 +Target frameworks: net472, net5.0, netcoreapp2.1, netcoreapp3.1 License: [ms-net-library](../../../../licenses/ms-net-library) diff --git a/Build/third-party-libraries/readme.md b/Build/third-party-libraries/readme.md index 5471942f..8bc7eb9a 100644 --- a/Build/third-party-libraries/readme.md +++ b/Build/third-party-libraries/readme.md @@ -6,12 +6,13 @@ Licenses |[Apache-2.0](licenses/apache-2.0)|no|no|3| |[BSD-2-Clause](licenses/bsd-2-clause)|no|no|1| |[BSD-3-Clause](licenses/bsd-3-clause)|no|no|1| -|[MIT](licenses/mit)|no|no|36| +|[MIT](licenses/mit)|no|no|38| |[ms-net-library](licenses/ms-net-library)|no|no|22| +|[PostgreSQL](licenses/postgresql)|no|no|1| -Packages 63 +Packages 66 -------- |Name|Version|Source|License|Used by| @@ -23,7 +24,7 @@ Packages 63 |[Microsoft.CodeCoverage](packages/nuget.org/microsoft.codecoverage/16.9.4)|16.9.4|[nuget.org](https://www.nuget.org/packages/Microsoft.CodeCoverage/16.9.4)|[MIT](licenses/mit)|SqlDatabase internal| |[Microsoft.DotNet.InternalAbstractions](packages/nuget.org/microsoft.dotnet.internalabstractions/1.0.0)|1.0.0|[nuget.org](https://www.nuget.org/packages/Microsoft.DotNet.InternalAbstractions/1.0.0)|[MIT](licenses/mit)|SqlDatabase internal| |[Microsoft.NET.Test.Sdk](packages/nuget.org/microsoft.net.test.sdk/16.9.4)|16.9.4|[nuget.org](https://www.nuget.org/packages/Microsoft.NET.Test.Sdk/16.9.4)|[MIT](licenses/mit)|SqlDatabase internal| -|[Microsoft.NETCore.App](packages/nuget.org/microsoft.netcore.app/2.2.0)|2.2.0|[nuget.org](https://www.nuget.org/packages/Microsoft.NETCore.App/2.2.0)|[MIT](licenses/mit)|SqlDatabase| +|[Microsoft.NETCore.App](packages/nuget.org/microsoft.netcore.app/2.1.0)|2.1.0|[nuget.org](https://www.nuget.org/packages/Microsoft.NETCore.App/2.1.0)|[MIT](licenses/mit)|SqlDatabase| |[Microsoft.TestPlatform.ObjectModel](packages/nuget.org/microsoft.testplatform.objectmodel/16.9.4)|16.9.4|[nuget.org](https://www.nuget.org/packages/Microsoft.TestPlatform.ObjectModel/16.9.4)|[MIT](licenses/mit)|SqlDatabase internal| |[Microsoft.TestPlatform.TestHost](packages/nuget.org/microsoft.testplatform.testhost/16.9.4)|16.9.4|[nuget.org](https://www.nuget.org/packages/Microsoft.TestPlatform.TestHost/16.9.4)|[MIT](licenses/mit)|SqlDatabase internal| |[Microsoft.Win32.Registry](packages/nuget.org/microsoft.win32.registry/4.5.0)|4.5.0|[nuget.org](https://www.nuget.org/packages/Microsoft.Win32.Registry/4.5.0)|[MIT](licenses/mit)|SqlDatabase| @@ -33,6 +34,7 @@ Packages 63 |[Moq](packages/nuget.org/moq/4.16.1)|4.16.1|[nuget.org](https://www.nuget.org/packages/Moq/4.16.1)|[BSD-3-Clause](licenses/bsd-3-clause)|SqlDatabase internal| |[NETStandard.Library](packages/nuget.org/netstandard.library/2.0.3)|2.0.3|[nuget.org](https://www.nuget.org/packages/NETStandard.Library/2.0.3)|[MIT](licenses/mit)|SqlDatabase| |[Newtonsoft.Json](packages/nuget.org/newtonsoft.json/13.0.1)|13.0.1|[nuget.org](https://www.nuget.org/packages/Newtonsoft.Json/13.0.1)|[MIT](licenses/mit)|SqlDatabase internal| +|[Npgsql](packages/nuget.org/npgsql/4.0.11)|4.0.11|[nuget.org](https://www.nuget.org/packages/Npgsql/4.0.11)|[PostgreSQL](licenses/postgresql)|SqlDatabase| |[NuGet.Frameworks](packages/nuget.org/nuget.frameworks/5.0.0)|5.0.0|[nuget.org](https://www.nuget.org/packages/NuGet.Frameworks/5.0.0%2b42a8779499c1d1ed2488c2e6b9e2ee6ff6107766)|[Apache-2.0](licenses/apache-2.0)|SqlDatabase internal| |[NUnit](packages/nuget.org/nunit/3.13.1)|3.13.1|[nuget.org](https://www.nuget.org/packages/NUnit/3.13.1)|[MIT](licenses/mit)|SqlDatabase internal| |[NUnit3TestAdapter](packages/nuget.org/nunit3testadapter/3.17.0)|3.17.0|[nuget.org](https://www.nuget.org/packages/NUnit3TestAdapter/3.17.0)|[MIT](licenses/mit)|SqlDatabase internal| @@ -55,14 +57,14 @@ Packages 63 |[System.IO.FileSystem.Primitives](packages/nuget.org/system.io.filesystem.primitives/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.IO.FileSystem.Primitives/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Linq](packages/nuget.org/system.linq/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Linq/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Linq.Expressions](packages/nuget.org/system.linq.expressions/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Linq.Expressions/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| -|[System.Memory](packages/nuget.org/system.memory/4.5.1)|4.5.1|[nuget.org](https://www.nuget.org/packages/System.Memory/4.5.1)|[MIT](licenses/mit)|SqlDatabase| +|[System.Memory](packages/nuget.org/system.memory/4.5.3)|4.5.3|[nuget.org](https://www.nuget.org/packages/System.Memory/4.5.3)|[MIT](licenses/mit)|SqlDatabase| |[System.Memory](packages/nuget.org/system.memory/4.5.4)|4.5.4|[nuget.org](https://www.nuget.org/packages/System.Memory/4.5.4)|[MIT](licenses/mit)|SqlDatabase internal| |[System.Numerics.Vectors](packages/nuget.org/system.numerics.vectors/4.4.0)|4.4.0|[nuget.org](https://www.nuget.org/packages/System.Numerics.Vectors/4.4.0)|[MIT](licenses/mit)|SqlDatabase| |[System.Numerics.Vectors](packages/nuget.org/system.numerics.vectors/4.5.0)|4.5.0|[nuget.org](https://www.nuget.org/packages/System.Numerics.Vectors/4.5.0)|[MIT](licenses/mit)|SqlDatabase internal| |[System.ObjectModel](packages/nuget.org/system.objectmodel/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.ObjectModel/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Reflection.Metadata](packages/nuget.org/system.reflection.metadata/1.6.0)|1.6.0|[nuget.org](https://www.nuget.org/packages/System.Reflection.Metadata/1.6.0)|[MIT](licenses/mit)|SqlDatabase internal| |[System.Reflection.TypeExtensions](packages/nuget.org/system.reflection.typeextensions/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Reflection.TypeExtensions/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| -|[System.Runtime.CompilerServices.Unsafe](packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.0)|4.5.0|[nuget.org](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/4.5.0)|[MIT](licenses/mit)|SqlDatabase| +|[System.Runtime.CompilerServices.Unsafe](packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.2)|4.5.2|[nuget.org](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/4.5.2)|[MIT](licenses/mit)|SqlDatabase| |[System.Runtime.CompilerServices.Unsafe](packages/nuget.org/system.runtime.compilerservices.unsafe/4.5.3)|4.5.3|[nuget.org](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/4.5.3)|[MIT](licenses/mit)|SqlDatabase internal| |[System.Runtime.InteropServices.RuntimeInformation](packages/nuget.org/system.runtime.interopservices.runtimeinformation/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Runtime.InteropServices.RuntimeInformation/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Runtime.Loader](packages/nuget.org/system.runtime.loader/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Runtime.Loader/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase| @@ -73,8 +75,10 @@ Packages 63 |[System.Text.Encoding.CodePages](packages/nuget.org/system.text.encoding.codepages/4.5.0)|4.5.0|[nuget.org](https://www.nuget.org/packages/System.Text.Encoding.CodePages/4.5.0)|[MIT](licenses/mit)|SqlDatabase| |[System.Text.RegularExpressions](packages/nuget.org/system.text.regularexpressions/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Text.RegularExpressions/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Threading](packages/nuget.org/system.threading/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Threading/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| +|[System.Threading.Tasks.Extensions](packages/nuget.org/system.threading.tasks.extensions/4.5.2)|4.5.2|[nuget.org](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.5.2)|[MIT](licenses/mit)|SqlDatabase| |[System.Threading.Tasks.Extensions](packages/nuget.org/system.threading.tasks.extensions/4.5.4)|4.5.4|[nuget.org](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.5.4)|[MIT](licenses/mit)|SqlDatabase internal| |[System.Threading.Thread](packages/nuget.org/system.threading.thread/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Threading.Thread/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| +|[System.ValueTuple](packages/nuget.org/system.valuetuple/4.5.0)|4.5.0|[nuget.org](https://www.nuget.org/packages/System.ValueTuple/4.5.0)|[MIT](licenses/mit)|SqlDatabase| |[System.Xml.ReaderWriter](packages/nuget.org/system.xml.readerwriter/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Xml.ReaderWriter/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Xml.XmlDocument](packages/nuget.org/system.xml.xmldocument/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Xml.XmlDocument/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| |[System.Xml.XPath](packages/nuget.org/system.xml.xpath/4.3.0)|4.3.0|[nuget.org](https://www.nuget.org/packages/System.Xml.XPath/4.3.0)|[ms-net-library](licenses/ms-net-library)|SqlDatabase internal| diff --git a/Examples/CSharpMirationStep/SqlDatabaseScript.cs b/Examples/CSharpMirationStep/SqlDatabaseScript.MsSql.cs similarity index 62% rename from Examples/CSharpMirationStep/SqlDatabaseScript.cs rename to Examples/CSharpMirationStep/SqlDatabaseScript.MsSql.cs index 2b3d8a73..337a0268 100644 --- a/Examples/CSharpMirationStep/SqlDatabaseScript.cs +++ b/Examples/CSharpMirationStep/SqlDatabaseScript.MsSql.cs @@ -2,21 +2,22 @@ using System.Collections.Generic; using System.Data; -namespace SqlDatabaseCustomScript +namespace SqlDatabaseCustomScript.MsSql { public /*sealed*/ class SqlDatabaseScript /*: IDisposable*/ { + /// + /// MSSQL server demo + /// public void Execute(IDbCommand command, IReadOnlyDictionary variables) { Console.WriteLine("start execution"); - command.CommandText = string.Format("print 'current database name is {0}'", variables["DatabaseName"]); - command.ExecuteNonQuery(); - - command.CommandText = string.Format("print 'version from {0}'", variables["CurrentVersion"]); - command.ExecuteNonQuery(); - - command.CommandText = string.Format("print 'version to {0}'", variables["TargetVersion"]); + command.CommandText = string.Format( + "print 'upgrade database {0} from version {1} to {2}'", + variables["DatabaseName"], + variables["CurrentVersion"], + variables["TargetVersion"]); command.ExecuteNonQuery(); command.CommandText = "create table dbo.DemoTable (Id INT)"; diff --git a/Examples/CSharpMirationStep/SqlDatabaseScript.PgSql.cs b/Examples/CSharpMirationStep/SqlDatabaseScript.PgSql.cs new file mode 100644 index 00000000..82de2415 --- /dev/null +++ b/Examples/CSharpMirationStep/SqlDatabaseScript.PgSql.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Data; + +namespace SqlDatabaseCustomScript.PgSql +{ + public /*sealed*/ class SqlDatabaseScript /*: IDisposable*/ + { + /// + /// PostgreSQL server demo + /// + public void Execute(IDbCommand command, IReadOnlyDictionary variables) + { + Console.WriteLine("start execution"); + + command.CommandText = string.Format( + @" +DO $$ +BEGIN +RAISE NOTICE 'upgrade database {0} from version {1} to {2}'; +END +$$;", + variables["DatabaseName"], + variables["CurrentVersion"], + variables["TargetVersion"]); + command.ExecuteNonQuery(); + + command.CommandText = "create table public.demo_table (id integer)"; + command.ExecuteNonQuery(); + + command.CommandText = @" +DO $$ +BEGIN +RAISE NOTICE 'drop table demo_table'; +END +$$;"; + command.ExecuteNonQuery(); + + command.CommandText = "drop table public.demo_table"; + command.ExecuteNonQuery(); + + Console.WriteLine("finish execution"); + } + } +} diff --git a/Examples/CSharpMirationStep/readme.md b/Examples/CSharpMirationStep/readme.md index 60421269..94cf1865 100644 --- a/Examples/CSharpMirationStep/readme.md +++ b/Examples/CSharpMirationStep/readme.md @@ -2,16 +2,19 @@ ========================================== Any assembly script is + - .exe or .dll for target framework is 4.5.2+ -- .dll for .net core 2.2/3.1 or .net5.0 +- .dll for .net core 2.1/3.1 or .net5.0 - has exactly one class with script implementation This project is an example of script implementation. The build output is 2.1_2.2.dll with target framework 4.5.2. -Due to the current dependencies, 2.1_2.2.dll works well on .net core 2.2/3.1 and .net 5.0. +Due to the current dependencies, 2.1_2.2.dll works well on .net core 2.1/3.1 and .net 5.0. ## Script source + Method [SqlDatabaseScript.Execute](SqlDatabaseScript.cs) implements a logic of script + ```C# namespace SqlDatabaseCustomScript { @@ -46,14 +49,17 @@ namespace SqlDatabaseCustomScript ``` Use -* method`s parameter "IDbCommand command" to affect database -* Console.WriteLine() to write something into output/log + +- method`s parameter "IDbCommand command" to affect database +- Console.WriteLine() to write something into output/log ## Runtime .NET desktop -At runtime the assembly will be loaded into private application domain with -* ApplicationBase: temporary directory -* ConfigurationFile: current [SqlDatabase.exe.config](../ConfigurationFile) -* Location of assembly: ApplicationBase, temporary directory + +At runtime the assembly will be loaded into A private application domain with + +- ApplicationBase: temporary directory +- Location of assembly: ApplicationBase, temporary directory + ```C# public class SqlDatabaseScript { @@ -66,18 +72,22 @@ At runtime the assembly will be loaded into private application domain with } } ``` -Instance of migration step will be resolved via reflection: Activator.CreateInstance(typeof(SqlDatabaseScript)) + +Instance of migration step will be resolved via reflection: `Activator.CreateInstance(typeof(SqlDatabaseScript))` After the migration step is finished or failed -- instance of SqlDatabaseScript will be disposed (if IDisposable) + +- instance of SqlDatabaseScript will be disposed (if `IDisposable`) - the domain will be unloaded - temporary directory will be deleted ## Runtime .NET Core -At runtime the assembly will be loaded into the current application domain. -* ApplicationBase: is a directory of SqlDatabase -* ConfigurationFile: current [SqlDatabase.exe.config](../ConfigurationFile) -* Script assembly has no location: + +At runtime the assembly will be loaded into the current application domain (`AssemblyLoadContext.Default`). + +- ApplicationBase: is a directory of SqlDatabase +- Script assembly has no location: + ```C# public class SqlDatabaseScript { @@ -90,25 +100,31 @@ At runtime the assembly will be loaded into the current application domain. } } ``` -Instance of migration step will be resolved via reflection: Activator.CreateInstance(typeof(SqlDatabaseScript)) + +Instance of migration step will be resolved via reflection: `Activator.CreateInstance(typeof(SqlDatabaseScript))` After the migration step is finished or failed -- instance of SqlDatabaseScript will be disposed (if IDisposable) + +- instance of SqlDatabaseScript will be disposed (if `IDisposable`) ## Resolving SqlDatabaseScript.Execute -The assembly must contain exactly one "public class SqlDatabaseScript", namespace doesn't matter. -Class SqlDatabaseScript must contain instance method "public void Execute(...)". + +The assembly must contain exactly one `public class SqlDatabaseScript`, namespace doesn't matter. +Class `SqlDatabaseScript` must contain instance method `public void Execute(...)`. Supported signatures of Execute method -* void Execute(IDbCommand command, IReadOnlyDictionary variables) -* void Execute(IReadOnlyDictionary variables, IDbCommand command) -* void Execute(IDbCommand command) -* void Execute(IDbConnection connection) + +- void Execute(IDbCommand command, IReadOnlyDictionary variables) +- void Execute(IReadOnlyDictionary variables, IDbCommand command) +- void Execute(IDbCommand command) +- void Execute(IDbConnection connection) Names *SqlDatabaseScript* and *Execute* are configurable. ## Configuration -name of class SqlDatabaseScript and method Execute can be changed in the [SqlDatabase.exe.config](../ConfigurationFile): + +name of class `SqlDatabaseScript` and method `Execute` can be changed in the [configuration file](../ConfigurationFile): + ```xml diff --git a/Examples/ConfigurationFile/README.md b/Examples/ConfigurationFile/README.md index dfbc49bb..7a730cc1 100644 --- a/Examples/ConfigurationFile/README.md +++ b/Examples/ConfigurationFile/README.md @@ -1,21 +1,13 @@ Configuration file ================== -By default the current configuration file is [SqlDatabase.exe.config](SqlDatabase.exe.config). It can be changed in a CLI +By default the current configuration file is [SqlDatabase.dll.config](SqlDatabase.dll.config). The file is located in the installation folder. It can be changed in CLI + ```bash $ SqlDatabase ... -configuration=path\to\sql-database.config ``` - - -- [getCurrentVersion](#getCurrentVersion) -- [setCurrentVersion](#setCurrentVersion) -- [Example (get/set)CurrentVersion](#Example-(get/set)CurrentVersion) -- [assemblyScript](#assemblyScript) -- [variables](#variables) - - - +## File example ```xml @@ -24,59 +16,93 @@ $ SqlDatabase ... -configuration=path\to\sql-database.config type="SqlDatabase.Configuration.AppConfiguration, SqlDatabase"/> - + - + + + + + + + + + + + + + + + + + + ``` ## getCurrentVersion + An sql script to determine the current version of database, see [database upgrade](../MigrationStepsFolder). -Default value: + +Default value for MSSQL Server (sqlDatabase/mssql/@getCurrentVersion): + ```sql SELECT value from sys.fn_listextendedproperty('version', default, default, default, default, default, default) ``` +Default value for PostgreSQL (sqlDatabase/pgsql/@getCurrentVersion): + +```sql +SELECT version FROM public.version WHERE module_name = 'database' +``` + +Warn: SqlDatabase does not validate the provided script, please make sure that script is working before running SqlDatabase. + ## setCurrentVersion + An sql script to update the current version of database, see [database upgrade](../MigrationStepsFolder). -Default value: + +Default value for MSSQL Server (sqlDatabase/mssql/@setCurrentVersion): + ```sql EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'{{TargetVersion}}' ``` -## Example (get/set)CurrentVersion -The example shows an alternative how to store database version: +Default value for PostgreSQL (sqlDatabase/pgsql/@setCurrentVersion): + ```sql -CREATE TABLE dbo.Version -( - Name NVARCHAR(30) NOT NULL PRIMARY KEY - ,Version NVARCHAR(30) NOT NULL -) -GO +UPDATE public.version SET version='{{TargetVersion}}' WHERE module_name = 'database' ``` -```xml - -``` +Warn: SqlDatabase does not validate the provided script, please make sure that script is working before running SqlDatabase. ## assemblyScript + A configuration of [.NET Assembly scripts](../CSharpMirationStep). * className - a script class name, default value is *SqlDatabaseScript* -* methodName - a method, entry point of *SqlDatabaseScript* +* methodName - a method, entry point of *SqlDatabaseScript*, default value is *Execute* example + ```C# namespace { @@ -90,6 +116,7 @@ namespace } } ``` + ```xml ``` ## variables + +sections + +* sqlDatabase/variables +* sqlDatabase/mssql/variables +* sqlDatabase/pgsql/variables + A list of variables in format + ```xml ``` -by default the list is empty. + +by default all lists are empty. example + ```xml @@ -117,6 +154,7 @@ example ``` + ```sql -- script file *.sql PRINT 'drop table {{SchemaName}}.{{TableName}}' diff --git a/Examples/ConfigurationFile/SqlDatabase.dll.config b/Examples/ConfigurationFile/SqlDatabase.dll.config new file mode 100644 index 00000000..2072c732 --- /dev/null +++ b/Examples/ConfigurationFile/SqlDatabase.dll.config @@ -0,0 +1,55 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Examples/ConfigurationFile/SqlDatabase.exe.config b/Examples/ConfigurationFile/SqlDatabase.exe.config deleted file mode 100644 index ef3f4505..00000000 --- a/Examples/ConfigurationFile/SqlDatabase.exe.config +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Examples/CreateDatabaseFolder/README.md b/Examples/CreateDatabaseFolder/README.md index 444aedc5..2af69786 100644 --- a/Examples/CreateDatabaseFolder/README.md +++ b/Examples/CreateDatabaseFolder/README.md @@ -23,7 +23,7 @@ CLI |:--|:----------| |-database|set connection string to target database| |-from|a path to a folder or zip archive with sql scripts or path to a sql script file. Repeat -from to setup several sources.| -|-configuration|a path to application configuration file. Default is current [SqlDatabase.exe.config](../ConfigurationFile)| +|-configuration|a path to application [configuration file](../ConfigurationFile).| |-log|optional path to log file| |-var|set a variable in format "=var[name of variable]=[value of variable]"| |-whatIf|shows what would happen if the command runs. The command is not run| @@ -105,7 +105,12 @@ Predefined variables |:--|:----------| |DatabaseName|the target database name| -Sql script example +Opening a connection +======================== + +Before starting any step SqlDatabase checks if a database, provided in the connection string, exists. If database does not exists the connection will be targeted to `master` for MSSQL and `postgres` for PostgreSQL. + +MSSQL Server script example ================== File name 01_database/02_Create.sql @@ -139,10 +144,25 @@ ALTER DATABASE [MyDatabase] SET ALLOW_SNAPSHOT_ISOLATION ON GO ``` +PostgreSQL script example +================== + +Extract database creation into separate file: + +```sql +CREATE DATABASE {{DatabaseName}}; +``` + +Database properties into a second file: + +```sql +CREATE EXTENSION citext; +``` + .ps1 script example ============================= -File name 01_database/02_Create.ps1, see details [here](../PowerShellScript). +File name 01_database/02_Create.ps1, see details about powershell scripts [here](../PowerShellScript). ```powershell param ( @@ -166,10 +186,27 @@ $Command.ExecuteNonQuery() Write-Information "finish execution" ``` +.ps1 script example how to drop existing database on PostgreSQL +============================= + +```powershell +param ( + $Command, + $Variables +) + +$Command.Connection.ChangeDatabase("postgres"); + +Write-Information ("drop " + $Variables.DatabaseName) + +$Command.CommandText = ("DROP DATABASE {0} WITH (FORCE)" -f $Variables.DatabaseName) +$Command.ExecuteNonQuery() +``` + Assembly script example ======================= -File name 01_database/02_Create.dll, see details [here](../CSharpMirationStep). +File name 01_database/02_Create.dll, see details about assembly scripts [here](../CSharpMirationStep). ```C# namespace diff --git a/Examples/ExecuteScriptsFolder/README.md b/Examples/ExecuteScriptsFolder/README.md index b890288e..da8ab9bb 100644 --- a/Examples/ExecuteScriptsFolder/README.md +++ b/Examples/ExecuteScriptsFolder/README.md @@ -4,18 +4,18 @@ ```bash $ SqlDatabase execute ^ "-database=Data Source=server;Initial Catalog=database;Integrated Security=True" ^ - -from=c:\Scripts\script.sql ^ + -from=c:\SqlDatabase\Examples\ExecuteScriptsFolder ^ -varVariable1=value1 ^ -varVariable2=value2 PS> Execute-SqlDatabase ` -database "Data Source=server;Initial Catalog=database;Integrated Security=True" ` - -from c:\Scripts\script.sql ` + -from c:\SqlDatabase\Examples\ExecuteScriptsFolder ` -var Variable1=value1,Variable2=value2 ` -InformationAction Continue ``` -execute script from file "c:\Scripts\script.sql" on *[MyDatabase]* on server *[MyServer]* with "Variable1=value1" and "Variable2=value2" +execute script from folder "c:\SqlDatabase\Examples\ExecuteScriptsFolder" on *[MyDatabase]* on server *[MyServer]* with "Variable1=value1" and "Variable2=value2" CLI === @@ -25,7 +25,7 @@ CLI |-database|set connection string to target database| |-from|a path to a folder or zip archive with sql scripts or path to a sql script file. Repeat -from to setup several sources.| |-fromSql|an sql script text. Repeat -fromSql to setup several scripts.| -|-configuration|a path to application configuration file. Default is current [SqlDatabase.exe.config](../ConfigurationFile)| +|-configuration|a path to application [configuration file](../ConfigurationFile).| |-log|optional path to log file| |-var|set a variable in format "=var[name of variable]=[value of variable]"| |-whatIf|shows what would happen if the command runs. The command is not run| @@ -107,7 +107,12 @@ Predefined variables |:--|:----------| |DatabaseName|the target database name| -Sql script example +Opening a connection +======================== + +Before starting any step SqlDatabase checks if a database, provided in the connection string, exists. If database does not exists the connection will be targeted to `master` for MSSQL and `postgres` for PostgreSQL. + +MSSQL Server script example ============================= File name 02_demo.Department.sql @@ -130,10 +135,31 @@ CREATE NONCLUSTERED INDEX IX_Department_Name ON demo.Department (Name) GO ``` +PostgreSQL script example +============================= + +```sql +DO $$ +BEGIN +RAISE NOTICE 'create table demo.department'; +END +$$; + +CREATE TABLE demo.department +( + id serial + ,name varchar(300) NOT NULL +); + +ALTER TABLE demo.department ADD CONSTRAINT pk_department PRIMARY KEY (Id); + +CREATE INDEX ix_department_name ON demo.department (name); +``` + .ps1 script example ============================= -File name 02_demo.Department.ps1, see details [here](../PowerShellScript). +File name 02_demo.Department.ps1, see details about powershell scripts [here](../PowerShellScript). ```powershell param ( @@ -162,7 +188,7 @@ $Command.ExecuteNonQuery() Assembly script example ======================= -File name 02_demo.Department.dll, see details [here](../CSharpMirationStep). +File name 02_demo.Department.dll, see details about assembly scripts [here](../CSharpMirationStep). ```C# namespace diff --git a/Examples/ExportData/README.md b/Examples/ExportData/README.md index 25c788b1..6c45bff3 100644 --- a/Examples/ExportData/README.md +++ b/Examples/ExportData/README.md @@ -56,9 +56,9 @@ CLI |-database|set connection string to target database| |-from|a path to a folder or zip archive with sql scripts or path to a sql script file. Repeat -from to setup several sources.| |-fromSql|an sql script to select export data. Repeat -fromSql to setup several scripts.| -|-toTable|setup "INSERT INTO" table name. Default is dbo.SqlDatabaseExport.| +|-toTable|setup "INSERT INTO" table name. Default is dbo.SqlDatabaseExport for MSSQL and public.sqldatabase_export for PostgreSQL.| |-toFile|write sql scripts into a file. By default write into standard output (console/information stream).| -|-configuration|a path to application configuration file. Default is current [SqlDatabase.exe.config](../ConfigurationFile)| +|-configuration|a path to application [configuration file](../ConfigurationFile).| |-log|optional path to log file| |-var|set a variable in format "=var[name of variable]=[value of variable]"| diff --git a/Examples/MigrationStepsFolder/Modularity/README.md b/Examples/MigrationStepsFolder/Modularity/README.md index 29129367..b2f3b2a9 100644 --- a/Examples/MigrationStepsFolder/Modularity/README.md +++ b/Examples/MigrationStepsFolder/Modularity/README.md @@ -20,20 +20,23 @@ A file name must be in the format "[module name]\_[version from]\_[version to].[ |File|Module name|Version from|Version to|Extension| |:--|:----------|:----------|:----------|:----------| -|moduleA_1.0_2.0.sql|moduleA|1.0|2.0|.sql| -|moduleA_2.1_2.2.exe|moduleA|2.1|2.2|.exe| -|moduleB_1.0_2.0.dll|moduleB|1.0|2.0|.dll| +|moduleA_1.0_2.0.sql|moduleA|1.0|2.0|.sql (text file with sql scripts)| +|moduleA_2.1_2.2.exe|moduleA|2.1|2.2|.exe (.net assembly with a script implementation)| +|moduleB_1.0_2.0.dll|moduleB|1.0|2.0|.dll (.net assembly with a script implementation)| +|moduleB_2.0_2.1.ps1|moduleB|2.0|2.1|.ps1 (text file with powershell script)| [Back to ToC](#table-of-contents) -Step dependencies +Step`s dependencies === -Dependencies are optional. They are are written as a special type of comment in the form "module dependency: [module name] [module version]". Module names are not case-sensitive. +Dependencies are optional. They are written as a special type of comment in the form "module dependency: [module name] [module version]". Module names case-insensitive. -#### .sql step -Once GO instruction has been processed, SqlDatabase no longer looks for dependencies. Therefore, all dependencies must be at the very top of a script. +#### MSSQL Server .sql step + +Once `GO` instruction has been processed, SqlDatabase no longer looks for dependencies. Therefore, all dependencies must be at the very top of a script. The following step depends on module A version 2.0 and module B version 1.0. + ```sql /* * module dependency: a 2.0 @@ -44,6 +47,7 @@ GO ``` The following step depends on module A version 2.0. + ```sql -- module dependency: a 2.0 GO @@ -51,6 +55,7 @@ GO ``` The following example is invalid: + ```sql /* module dependency: a 2.0 @@ -59,10 +64,44 @@ GO ... ``` -#### .dll or .exe step +#### PostgreSQL .sql step + +Once a line `;` has been processed, SqlDatabase no longer looks for dependencies. Therefore, all dependencies must be at the very top of a script. + +The following step depends on module A version 2.0 and module B version 1.0. + +```sql +/* +* module dependency: a 2.0 +* module dependency: b 1.0 +*/ +; +... +``` + +The following step depends on module A version 2.0. + +```sql +-- module dependency: a 2.0 +; +... +``` + +The following example is invalid: + +```sql +/* +module dependency: a 2.0 +*/ +; +... +``` + +#### .dll, .exe or .ps1 step Dependencies for this step can be defined in a separate text file with the same name. The text file must be the next to step file. Step moduleA_2.1_2.2.exe, text file moduleA_2.1_2.2.txt + ```txt /* * module dependency: b 2.0 @@ -72,6 +111,7 @@ Step moduleA_2.1_2.2.exe, text file moduleA_2.1_2.2.txt ``` Step moduleB_1.0_2.0.dll, text file moduleB_1.0_2.0.txt + ```txt -- module dependency: b 2.0 -- module dependency: c 1.0 @@ -84,20 +124,64 @@ Select/update a module version === Scripts for resolving and updating a module version are defined in the [configuration file](../../ConfigurationFile). -Default scripts must be changed in order to support modularity. Here is one possible example +Default scripts must be changed in order to support modularity. Few examples: + +#### MSSQL Server, store versions in the database properties + ```sql --- select current version +-- configuration: select current version SELECT value from sys.fn_listextendedproperty('version-{{ModuleName}}', default, default, default, default, default, default) --- update current version +-- configuration: update current version EXEC sys.sp_updateextendedproperty @name=N'version-{{ModuleName}}', @value=N'{{TargetVersion}}' ``` +#### MSSQL Server, store versions in a specific table + +```sql +-- a table +CREATE TABLE dbo.Version +( + ModuleName NVARCHAR(100) NOT NULL + , Version NVARCHAR(20) NOT NULL +) +GO +ALTER TABLE dbo.Version ADD CONSTRAINT PK_dbo_Version PRIMARY KEY CLUSTERED (ModuleName); + +-- configuration: select current version +SELECT Version FROM dbo.Version WHERE ModuleName = N'{{ModuleName}}' + +-- configuration: update current version +UPDATE dbo.Version SET Version = N'{{TargetVersion}}' WHERE ModuleName = N'{{ModuleName}}' +``` + +#### PostgreSQL, store versions in a specific table + +```sql +-- a table +CREATE TABLE public.version +( + module_name public.citext NOT NULL + , version varchar(20) NOT NULL +); + +ALTER TABLE public.version ADD CONSTRAINT pk_version PRIMARY KEY (module_name); + +-- configuration: select current version +SELECT version FROM public.version WHERE module_name = '{{ModuleName}}' + +-- configuration: update current version +UPDATE public.version SET version = '{{TargetVersion}}' WHERE module_name = '{{ModuleName}}' +``` + +Warn: SqlDatabase does not validate the provided script, please make sure that script is working before running SqlDatabase. + [Back to ToC](#table-of-contents) Execution === -In the current folder are migration steps for three modules *person*, *book* and *reader*. +In the current folder there are migration steps for three modules *person*, *book* and *reader*. + - [person_1.0_2.0.sql](person_1.0_2.0.sql) - creates a table "dbo.Person" - [book_1.0_2.0.sql](book_1.0_2.0.sql) - creates a table "dbo.Book", depends on person 2.0 - [reader_1.0_2.0.sql](reader_1.0_2.0.sql) - creates a table "dbo.BookComment", depends on person 2.0 and book 2.0 @@ -105,27 +189,28 @@ In the current folder are migration steps for three modules *person*, *book* and The folder structure does not matter, SqlDatabase analyzes all files and folders recursively. #### runtime -1. Load all migartion steps -2. Resolve the current version of modules: author 1.0, book 1.0 and reader 1.0 + +1. Load all migration steps +2. Resolve the current version of modules: imagine author is 1.0, book is 1.0 and reader is 1.0 3. Resolve migration step dependencies -4. build migration sequence: person 1.0 => 2.0; book 1.0 => 2.0; reader 1.0 => 2.0; +4. Build migration sequence: person 1.0 => 2.0; book 1.0 => 2.0; reader 1.0 => 2.0; 5. Execute each step one by one: ```sql /* person 1.0 => 2.0 */ execute person_1.0_2.0.sql --- update author`s version -EXEC sys.sp_updateextendedproperty @name=N'version-person', @value=N'2.0' +execute "update person module version to 2.0" +execute "check that person module version is 2.0" /* book 1.0 => 2.0 */ execute book_1.0_2.0.sql --- update book`s version -EXEC sys.sp_updateextendedproperty @name=N'version-book', @value=N'2.0' +execute "update book module version to 2.0" +execute "check that book module version is 2.0" /* reader 1.0 => 2.0 */ execute reader_1.0_2.0.sql --- update reader`s version -EXEC sys.sp_updateextendedproperty @name=N'version-reader', @value=N'2.0' +execute "update reader module version to 2.0" +execute "check that reader module version is 2.0" ``` -whatIf option diff --git a/Examples/MigrationStepsFolder/README.md b/Examples/MigrationStepsFolder/README.md index 1f2a19f0..4efee80f 100644 --- a/Examples/MigrationStepsFolder/README.md +++ b/Examples/MigrationStepsFolder/README.md @@ -26,7 +26,7 @@ CLI |-database|set connection string to target database| |-from|a path to a folder or zip archive with migration steps. Repeat -from to setup several sources.| |-transaction|set transaction mode (none, perStep). Option [none] is default, means no transactions. Option [perStep] means to use one transaction per each migration step| -|-configuration|a path to application configuration file. Default is current [SqlDatabase.exe.config](../ConfigurationFile)| +|-configuration|a path to application [configuration file](../ConfigurationFile).| |-log|optional path to log file| |-var|set a variable in format "=var[name of variable]=[value of variable]"| |-whatIf|shows what would happen if the command runs. The command is not run| @@ -96,7 +96,12 @@ Predefined variables |TargetVersion|the database version after execution of current migration step| |ModuleName|the module name of current migration step, empty string in case of straight forward upgrade| -Migration .sql step example +Opening a connection +======================== + +Before starting any step SqlDatabase checks if a database, provided in the connection string, exists. If database does not exists the connection will be targeted to `master` for MSSQL and `postgres` for PostgreSQL. + +Migration MSSQL Server .sql step example ============================= File name 2.0_2.1.sql @@ -118,10 +123,34 @@ ALTER TABLE dbo.Demo ADD CONSTRAINT PK_Demo PRIMARY KEY CLUSTERED (Id) GO ``` +Migration PostgreSQL .sql step example +============================= + +```sql +DO $$ +BEGIN +RAISE NOTICE 'create table demo'; +END +$$; + +CREATE TABLE public.demo +( + id integer NOT NULL +); + +DO $$ +BEGIN +RAISE NOTICE 'create primary key pk_demo'; +END +$$; + +ALTER TABLE public.demo ADD CONSTRAINT pk_demo PRIMARY KEY (id); +``` + Migration .ps1 step example ============================= -File name 2.0_2.1.ps1, see details [here](../PowerShellScript). +File name 2.0_2.1.ps1, see details about powershell scripts [here](../PowerShellScript). ```powershell param ( @@ -149,7 +178,7 @@ $Command.ExecuteNonQuery() Migration .dll step example ======================= -File name 2.1_2.2.dll, see details [here](../CSharpMirationStep). +File name 2.1_2.2.dll, see details about assembly scripts [here](../CSharpMirationStep). ```C# namespace diff --git a/Examples/MigrationStepsFolder/StraightForward/README.md b/Examples/MigrationStepsFolder/StraightForward/README.md index 01bb263d..09dc99c7 100644 --- a/Examples/MigrationStepsFolder/StraightForward/README.md +++ b/Examples/MigrationStepsFolder/StraightForward/README.md @@ -7,17 +7,70 @@ A file name must be in the format "[version from]\_[version to].[extension]", fo |File|Version from|Version to|Extension| |:--|:----------|:----------|:----------| -|1.0_2.0.sql|1.0|2.0|.sql| -|2.1_2.2.exe|2.1|2.2|.exe| -|1.0_2.0.dll|1.0|2.0|.dll| +|1.0_2.0.sql|1.0|2.0|.sql (text file with sql scripts)| +|2.0_2.1.exe|2.0|2.1|.exe (.net assembly with a script implementation)| +|2.1_2.2.dll|2.1|2.2|.dll (.net assembly with a script implementation)| +|2.2_3.0.ps1|2.2|3.0|.ps1 (text file with powershell script)| -Select/update a database version +Select/update a database version === Scripts for resolving and updating a database version are defined in the [configuration file](../../ConfigurationFile). +#### MSSQL Server, store versions in the database properties (default script) + +```sql +-- configuration: select current version +SELECT value FROM sys.fn_listextendedproperty('version', default, default, default, default, default, default) + +-- configuration: update current version +EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'{{TargetVersion}}' +``` + +#### MSSQL Server, store versions in a specific table + +```sql +-- a table +CREATE TABLE dbo.Version +( + ModuleName NVARCHAR(100) NOT NULL + , Version NVARCHAR(20) NOT NULL +) +GO +ALTER TABLE dbo.Version ADD CONSTRAINT PK_dbo_Version PRIMARY KEY CLUSTERED (ModuleName); + +-- configuration: select current version +SELECT Version FROM dbo.Version WHERE ModuleName = N'database' + +-- configuration: update current version +UPDATE dbo.Version SET Version = N'{{TargetVersion}}' WHERE ModuleName = N'database' +``` + +#### PostgreSQL, store versions in a specific table + +```sql +-- a table +CREATE TABLE public.version +( + module_name public.citext NOT NULL + , version varchar(20) NOT NULL +); + +ALTER TABLE public.version ADD CONSTRAINT pk_version PRIMARY KEY (module_name); + +-- configuration: select current version +SELECT version FROM public.version WHERE module_name = 'database' + +-- configuration: update current version +UPDATE public.version SET version = '{{TargetVersion}}' WHERE module_name = 'database' +``` + +Warn: SqlDatabase does not validate the provided script, please make sure that script is working before running SqlDatabase. + Execution === + In the current folder are migration steps + - [1.0_1.1.sql](1.0_1.1.sql) - creates a table "dbo.Person" - [1.1_2.0.sql](1.1_2.0.sql) - creates a table "dbo.Book" - [2.0_3.0.sql](2.0_3.0.sql) - creates a table "dbo.BookComment" @@ -25,26 +78,27 @@ In the current folder are migration steps The folder structure does not matter, SqlDatabase analyzes all files and folders recursively. #### runtime -1. Load all migartion steps -2. Resolve the current version of database: 1.0 -4. build migration sequence: 1.0 => 1.1; 1.1 => 2.0; 2.0 => 3.0 -5. Execute each step one by one: + +1. Load all migration steps +2. Resolve the current version of database: imagine is 1.0 +3. build migration sequence: 1.0 => 1.1; 1.1 => 2.0; 2.0 => 3.0 +4. Execute each step one by one: ```sql /* 1.0 => 1.1 */ execute 1.0_1.1.sql --- update database version -EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'1.1' +execute "update database version to 1.1" +execute "check that current version is 1.1" /* 1.1 => 2.0 */ execute 1.1_2.0.sql --- update database version -EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'2.0' +execute "update database version to 2.0" +execute "check that current version is 2.0" /* 2.0 => 3.0 */ execute 2.0_3.0.sql --- update database version -EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'3.0' +execute "update database version to 3.0" +execute "check that current version is 3.0" ``` -whatIf option diff --git a/Examples/PackageManagerConsole/SolutionScripts/SolutionScripts.csproj b/Examples/PackageManagerConsole/SolutionScripts/SolutionScripts.csproj index 6a8aab6b..b0c44127 100644 --- a/Examples/PackageManagerConsole/SolutionScripts/SolutionScripts.csproj +++ b/Examples/PackageManagerConsole/SolutionScripts/SolutionScripts.csproj @@ -10,7 +10,7 @@ - + diff --git a/Examples/PowerShellScript/readme.md b/Examples/PowerShellScript/readme.md index c7240be9..4feaf146 100644 --- a/Examples/PowerShellScript/readme.md +++ b/Examples/PowerShellScript/readme.md @@ -67,7 +67,7 @@ The version with which you run the module. Installed Powershell Desktop version. -### .net SDK tool for .net 5.0 or .net core 2.2/3.1 +### .net SDK tool for .net 5.0 or .net core 2.1/3.1 [![NuGet](https://img.shields.io/nuget/v/SqlDatabase.GlobalTool.svg?style=flat-square&label=nuget%20dotnet%20tool)](https://www.nuget.org/packages/SqlDatabase.GlobalTool/) @@ -75,7 +75,7 @@ Pre-installed Powershell Core is required, will be used by SqlDatabase as extern * SqlDatabase .net 5.0 can host Powershell Core versions below 7.2 * .net core 3.1 below 7.1 -* .net core 2.2 below 7.0 +* .net core 2.1 below 7.0 PowerShell location can be passed via command line: diff --git a/README.md b/README.md index 24dbf50e..8f7a852a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ SqlDatabase [![PowerShell Gallery](https://img.shields.io/powershellgallery/v/SqlDatabase.svg?style=flat-square)](https://www.powershellgallery.com/packages/SqlDatabase) [![GitHub release](https://img.shields.io/github/release/max-ieremenko/SqlDatabase.svg?style=flat-square&label=manual%20download)](https://github.com/max-ieremenko/SqlDatabase/releases) -Command-line tool and PowerShell module for SQL Server allows to execute scripts, database migrations and export data. +Command-line tool and PowerShell module for MSSQL Server and PostgreSQL allows to execute scripts, database migrations and export data. Table of Contents ----------------- @@ -14,14 +14,15 @@ Table of Contents - [Installation](#installation) +- [Target database type](#database-selection) - [Execute script(s) (file)](#execute-script) - [Export data from a database to sql script (file)](#export-data) - [Create a database](#create-database) - [Migrate an existing database](#upgrade-database) - [Scripts](#scripts) - [Variables](#variables) -- [VS Package manager console](#console) - [*.zip files](#zip-files) +- [VS Package manager console](#console) - [Examples](#examples) - [License](#license) @@ -32,9 +33,9 @@ Installation PowerShell module is compatible with Powershell Core 6.1+ and PowerShell Desktop 5.1. -Dotnet tool requires SDK .Net 5.0 or .Net Core 2.2/3.1. +.net tool requires SDK .Net 5.0 or .Net Core 2.1/3.1. -Command-line tool is compatible with .Net runtime 5.0, .Net Core runtime 2.2/3.1 and .Net Framework 4.5.2+. +Command-line tool is compatible with .net runtime 5.0, .net Core runtime 2.1/3.1 and .net Framework 4.5.2+. ### PowerShell, from gallery @@ -52,7 +53,7 @@ PS> Install-Module -Name SqlDatabase PS> Import-Module .\SqlDatabase.psm1 ``` -### Dotnet tool +### Dotnet sdk tool [![NuGet](https://img.shields.io/nuget/v/SqlDatabase.GlobalTool.svg?style=flat-square&label=nuget%20dotnet%20tool)](https://www.nuget.org/packages/SqlDatabase.GlobalTool/) @@ -62,7 +63,30 @@ $ dotnet tool install --global SqlDatabase.GlobalTool [Back to ToC](#table-of-contents) -Execute script(s) (file) +Target database type selection +-------------- + +The target database/server type is recognized automatically from provided connection string: + +here is target MSSQL Server: + +```bash +$ SqlDatabase [command] "-database=Data Source=server;Initial Catalog=database;Integrated Security=True" + +PS> *-SqlDatabase -database "Data Source=server;Initial Catalog=database;Integrated Security=True" +``` + +here is target PostgreSQL: + +```bash +$ SqlDatabase [command] "-database=Host=server;Username=postgres;Password=qwerty;Database=database" + +PS> *-SqlDatabase -database "Host=server;Username=postgres;Password=qwerty;Database=database" +``` + +[Back to ToC](#table-of-contents) + +Execute script(s) -------------- execute script from file "c:\Scripts\script.sql" on *[MyDatabase]* on server *[MyServer]* with "Variable1=value1" and "Variable2=value2" @@ -156,7 +180,7 @@ PS> Upgrade-SqlDatabase ` Scripts ------- -- *.sql* a text file with Sql Server scripts +- *.sql* a text file with sql scripts - *.ps1* a text file with PowerShell script, details are [here](Examples/PowerShellScript) - *.dll* or *.exe* an .NET assembly with a script implementation, details are [here](Examples/CSharpMirationStep) @@ -167,6 +191,7 @@ Variables In a sql text file any entry like *{{VariableName}}* or *$(VariableName)* is interpreted as variable and has to be changed (text replacement) with a value before script execution. The variable name is + - a word from characters a-z, A-Z, 0-9, including the _ (underscore) character - case insensitive @@ -183,7 +208,7 @@ DROP TABLE [{{Schema}}].[{{Table}}] $ SqlDatabase execute -from=script.sql -varSchema=dbo -varTable=Person PS> Execute-SqlDatabase -from script.sql -var Schema=dbo,Table=Person -InformationAction Continue -# output +# log output script.sql ... variable Schema was replaced with dbo variable Table was replaced with Person @@ -209,7 +234,7 @@ ALTER LOGIN [sa] WITH PASSWORD=N'{{_Password}}' $ SqlDatabase execute -from=script.sql -var_Password=P@ssw0rd PS> Execute-SqlDatabase -from script.sql -var _Password=P@ssw0rd -InformationAction Continue -# output +# log output script.sql ... variable _Password was replaced with [value is hidden] ``` @@ -221,56 +246,57 @@ ALTER LOGIN [sa] WITH PASSWORD=N'{{P@ssw0rd}}' A non defined variable`s value leads to an error and stops script execution process. -The variable value is resolving in the following order: +The variable value is resolved in the following order: 1. check command line -2. check environment variable (Environment.GetEnvironmentVariable()) +2. check environment variables (Environment.GetEnvironmentVariable()) 3. check [configuration file](Examples/ConfigurationFile) ### Predefined variables -- *DatabaseName* - the target database name (-database=...Initial Catalog=MyDatabase...) +- *DatabaseName* - the target database name, see connection string (-database=...Initial Catalog=MyDatabase...) - *CurrentVersion* - the database/module version before execution of a [migration step](Examples/MigrationStepsFolder) - *TargetVersion* - the database/module version after execution of a [migration step](Examples/MigrationStepsFolder) - *ModuleName* - the module name of current [migration step](Examples/MigrationStepsFolder), empty string in case of straight forward upgrade [Back to ToC](#table-of-contents) -VS Package manager console ------------------------------------------------- +*.zip files +------------------------------------ -To integrate SqlDatabase into the Visual studio package manager console please check this [example](Examples/PackageManagerConsole). +Parameters *-from* and *-configuration* in the command line interpret .zip files in the path as folders, for example + +- -from=c:\scripts.zip\archive\tables.zip\demo +- -from=c:\scripts.zip\archive\tables.zip\table1.sql +- -configuration=c:\scripts.zip\app.config [Back to ToC](#table-of-contents) -*.zip files ------------------------------------- -Parameters *-from* and *-configuration* in the command line interpret .zip files in the path as folders, for example +VS Package manager console +------------------------------------------------ -* -from=c:\scripts.zip\archive\tables.zip\demo -* -from=c:\scripts.zip\archive\tables.zip\table1.sql -* -configuration=c:\scripts.zip\app.config +For integrating SqlDatabase into the Visual studio package manager console please check this [example](Examples/PackageManagerConsole). [Back to ToC](#table-of-contents) Examples -------- -* [create ms sql server linux docker image](Examples/SqlServerDockerImage) -* [execute script(s)](Examples/ExecuteScriptsFolder) -* [export data](Examples/ExportData) -* [create a database](Examples/CreateDatabaseFolder) -* [upgrade an existing database](Examples/MigrationStepsFolder) -* [how to use SqlDatabase in the VS Package manager console](Examples/PackageManagerConsole) -* [configuration file](Examples/ConfigurationFile) -* [assembly script](Examples/CSharpMirationStep) +- [create ms sql server linux docker image](Examples/SqlServerDockerImage) +- [execute script(s)](Examples/ExecuteScriptsFolder) +- [export data](Examples/ExportData) +- [create a database](Examples/CreateDatabaseFolder) +- [upgrade an existing database](Examples/MigrationStepsFolder) +- [how to use SqlDatabase in the VS Package manager console](Examples/PackageManagerConsole) +- [configuration file](Examples/ConfigurationFile) +- [assembly script](Examples/CSharpMirationStep) [Back to ToC](#table-of-contents) License ------- -This tool is distributed under the [MIT](LICENSE) license. +This tool is distributed under the [MIT](LICENSE.md) license. [Back to ToC](#table-of-contents) \ No newline at end of file diff --git a/Sources/GlobalAssemblyInfo.cs b/Sources/GlobalAssemblyInfo.cs index 9e607bee..2d5c1c26 100644 --- a/Sources/GlobalAssemblyInfo.cs +++ b/Sources/GlobalAssemblyInfo.cs @@ -9,5 +9,5 @@ [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: AssemblyVersion("2.3.0.0")] -[assembly: AssemblyFileVersion("2.3.0.0")] +[assembly: AssemblyVersion("3.0.0.0")] +[assembly: AssemblyFileVersion("3.0.0.0")] diff --git a/Sources/SqlDatabase.Package/nuget/package.nuspec b/Sources/SqlDatabase.Package/nuget/package.nuspec index bf26c76d..4ad4723b 100644 --- a/Sources/SqlDatabase.Package/nuget/package.nuspec +++ b/Sources/SqlDatabase.Package/nuget/package.nuspec @@ -11,11 +11,11 @@ https://github.com/max-ieremenko/SqlDatabase/raw/master/icon-32.png icon-32.png false - Command-line tool and PowerShell module for SQL Server. - SqlDatabase is a tool for SQL Server, allows to execute scripts, database migrations and export data. + Command-line tool and PowerShell module for MSSQL Server and PostgreSQL. + SqlDatabase is a tool for MSSQL Server and PostgreSQL, allows to execute scripts, database migrations and export data. https://github.com/max-ieremenko/SqlDatabase/releases (C) 2018-2021 Max Ieremenko. - sqlserver sqlcmd migration-tool c-sharp command-line-tool miration-step sql-script sql-database database-migrations export-data + sqlserver postgresql sqlcmd migration-tool c-sharp command-line-tool miration-step sql-script sql-database database-migrations export-data diff --git a/Sources/SqlDatabase.PowerShell.Test/CreateCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/CreateCmdLetTest.cs index 1b5cfb29..1564ba2b 100644 --- a/Sources/SqlDatabase.PowerShell.Test/CreateCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/CreateCmdLetTest.cs @@ -14,7 +14,7 @@ public class CreateCmdLetTest : SqlDatabaseCmdLetTest [TestCase("Create-SqlDatabase")] public void BuildCommandLine(string commandName) { - var commandLines = InvokeCommand( + var commandLines = InvokeSqlDatabase( commandName, c => { @@ -56,7 +56,7 @@ public void BuildCommandLine(string commandName) [TestCase("Create-SqlDatabase")] public void BuildPipeCommandLine(string commandName) { - var commandLines = InvokeCommandPipeLine( + var commandLines = InvokeInvokeSqlDatabasePipeLine( commandName, c => c.Parameters.Add(nameof(CreateCmdLet.Database), "connection string"), "file 1", diff --git a/Sources/SqlDatabase.PowerShell.Test/ExecuteCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/ExecuteCmdLetTest.cs index b184452d..766c8873 100644 --- a/Sources/SqlDatabase.PowerShell.Test/ExecuteCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/ExecuteCmdLetTest.cs @@ -14,7 +14,7 @@ public class ExecuteCmdLetTest : SqlDatabaseCmdLetTest [TestCase("Execute-SqlDatabase")] public void BuildCommandLine(string commandName) { - var commandLines = InvokeCommand( + var commandLines = InvokeSqlDatabase( commandName, c => { @@ -61,7 +61,7 @@ public void BuildCommandLine(string commandName) [TestCase("Execute-SqlDatabase")] public void BuildPipeCommandLine(string commandName) { - var commandLines = InvokeCommandPipeLine( + var commandLines = InvokeInvokeSqlDatabasePipeLine( commandName, c => c.Parameters.Add(nameof(ExecuteCmdLet.Database), "connection string"), "file 1", diff --git a/Sources/SqlDatabase.PowerShell.Test/ExportCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/ExportCmdLetTest.cs index 73aa5047..5c2c68dc 100644 --- a/Sources/SqlDatabase.PowerShell.Test/ExportCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/ExportCmdLetTest.cs @@ -12,7 +12,7 @@ public class ExportCmdLetTest : SqlDatabaseCmdLetTest [Test] public void BuildCommandLine() { - var commandLines = InvokeCommand( + var commandLines = InvokeSqlDatabase( "Export-SqlDatabase", c => { diff --git a/Sources/SqlDatabase.PowerShell.Test/InfoCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/InfoCmdLetTest.cs new file mode 100644 index 00000000..c1ee26f5 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell.Test/InfoCmdLetTest.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.PowerShell.TestApi; + +namespace SqlDatabase.PowerShell +{ + [TestFixture] + public class InfoCmdLetTest : SqlDatabaseCmdLetTest + { + [Test] + public void ProcessRecord() + { + var actual = InvokeCommand("Show-SqlDatabaseInfo"); + + actual.Count.ShouldBe(1); + Console.WriteLine(actual[0]); + + actual[0].Properties["PSEdition"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["PSVersion"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["Version"].Value.ShouldBeOfType().ShouldNotBeNull(); + actual[0].Properties["FrameworkDescription"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["OSDescription"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["OSArchitecture"].Value.ShouldBeOfType(); + actual[0].Properties["ProcessArchitecture"].Value.ShouldBeOfType(); + actual[0].Properties["Location"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["WorkingDirectory"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + actual[0].Properties["DefaultConfigurationFile"].Value.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell.Test/Internal/DependencyResolverFactoryTest.cs b/Sources/SqlDatabase.PowerShell.Test/Internal/DependencyResolverFactoryTest.cs new file mode 100644 index 00000000..946d5228 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell.Test/Internal/DependencyResolverFactoryTest.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections; +using NUnit.Framework; +using Shouldly; + +namespace SqlDatabase.PowerShell.Internal +{ + [TestFixture] + public class DependencyResolverFactoryTest + { + [Test] + [TestCase("Desktop", typeof(PowerShellDesktopDependencyResolver))] + [TestCase(null, typeof(PowerShellDesktopDependencyResolver))] + [TestCase("Core", typeof(PowerShellCoreDependencyResolver))] + public void CreateProgram(string psEdition, Type expected) + { + var psVersionTable = new Hashtable(); + if (psEdition != null) + { + psVersionTable.Add("PSEdition", psEdition); + } + + var actual = DependencyResolverFactory.Create(new PSVersionTable(psVersionTable)); + + actual.ShouldBeOfType(expected); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/Internal/PowerShellCommandBaseTest.cs similarity index 65% rename from Sources/SqlDatabase.PowerShell.Test/SqlDatabaseCmdLetTest.cs rename to Sources/SqlDatabase.PowerShell.Test/Internal/PowerShellCommandBaseTest.cs index 52c8f8e0..eef69600 100644 --- a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/Internal/PowerShellCommandBaseTest.cs @@ -1,17 +1,17 @@ using NUnit.Framework; using SqlDatabase.Configuration; -namespace SqlDatabase.PowerShell +namespace SqlDatabase.PowerShell.Internal { [TestFixture] - public class SqlDatabaseCmdLetTest + public class PowerShellCommandBaseTest { [Test] public void AppendDefaultConfiguration() { var command = new GenericCommandLine(); - SqlDatabaseCmdLet.AppendDefaultConfiguration(command); + PowerShellCommandBase.AppendDefaultConfiguration(command); FileAssert.Exists(command.ConfigurationFile); } diff --git a/Sources/SqlDatabase.PowerShell.Test/OutputReaderTest.cs b/Sources/SqlDatabase.PowerShell.Test/OutputReaderTest.cs deleted file mode 100644 index 18deee4b..00000000 --- a/Sources/SqlDatabase.PowerShell.Test/OutputReaderTest.cs +++ /dev/null @@ -1,134 +0,0 @@ -using NUnit.Framework; -using Shouldly; - -namespace SqlDatabase.PowerShell -{ - [TestFixture] - public class OutputReaderTest - { - private OutputReader _sut; - - [SetUp] - public void BeforeEachTest() - { - _sut = new OutputReader(); - } - - [Test] - public void ReadInfo() - { - var line = NextLine("some text"); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe("some text"); - line.Value.IsError.ShouldBeFalse(); - } - - [Test] - public void ReadEmptyInfo() - { - var line = NextLine(string.Empty); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe(string.Empty); - line.Value.IsError.ShouldBeFalse(); - } - - [Test] - public void ReadError() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, "some error", OutputReader.SetForegroundColorToDefault); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe("some error"); - line.Value.IsError.ShouldBeTrue(); - } - - [Test] - public void ReadEmptyError() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, string.Empty, OutputReader.SetForegroundColorToDefault); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe(string.Empty); - line.Value.IsError.ShouldBeTrue(); - } - - [Test] - public void ReadMixed() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, "error 1"); - - line.HasValue.ShouldBeFalse(); - - line = NextLine("error 2", OutputReader.SetForegroundColorToDefault); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe("error 1\r\nerror 2"); - line.Value.IsError.ShouldBeTrue(); - - line = NextLine("message"); - - line.HasValue.ShouldBeTrue(); - line.Value.Text.ShouldBe("message"); - line.Value.IsError.ShouldBeFalse(); - } - - [Test] - public void BufferError() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, "line 1"); - line.HasValue.ShouldBeFalse(); - - line = NextLine("line 2"); - line.HasValue.ShouldBeFalse(); - - line = NextLine("line 3", OutputReader.SetForegroundColorToDefault); - - line.HasValue.ShouldBeTrue(); - line.Value.IsError.ShouldBeTrue(); - line.Value.Text.ShouldBe(@"line 1 -line 2 -line 3"); - } - - [Test] - public void FlushAfterInfo() - { - NextLine("some text"); - - _sut.Flush().HasValue.ShouldBeFalse(); - } - - [Test] - public void FlushAfterError() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, "some text", OutputReader.SetForegroundColorToDefault); - - line.HasValue.ShouldBeTrue(); - line.Value.IsError.ShouldBeTrue(); - - _sut.Flush().HasValue.ShouldBeFalse(); - } - - [Test] - public void FlushBufferedError() - { - var line = NextLine(OutputReader.SetForegroundColorToRed, "some text"); - - line.HasValue.ShouldBeFalse(); - - line = _sut.Flush(); - - line.HasValue.ShouldBeTrue(); - line.Value.IsError.ShouldBeTrue(); - line.Value.Text.ShouldBe("some text"); - } - - private OutputReader.Record? NextLine(params string[] values) - { - var line = string.Join(string.Empty, values); - return _sut.NextLine(line); - } - } -} diff --git a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramFactoryTest.cs b/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramFactoryTest.cs deleted file mode 100644 index ec8fd23b..00000000 --- a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramFactoryTest.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections; -using Moq; -using NUnit.Framework; -using Shouldly; - -namespace SqlDatabase.PowerShell -{ - [TestFixture] - public class SqlDatabaseProgramFactoryTest - { - [Test] - [TestCase("Desktop", typeof(SqlDatabaseProgramNet452))] - [TestCase(null, typeof(SqlDatabaseProgramNet452))] - [TestCase("Core", typeof(SqlDatabaseProgramNetCore))] - public void CreateProgram(string psEdition, Type expected) - { - var psVersionTable = new Hashtable(); - if (psEdition != null) - { - psVersionTable.Add("PSEdition", psEdition); - } - - var owner = new Mock(MockBehavior.Strict); - - var actual = SqlDatabaseProgramFactory.CreateProgram(new PSVersionTable(psVersionTable), owner.Object); - - actual.ShouldBeOfType(expected); - } - } -} diff --git a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramNet452Test.cs b/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramNet452Test.cs deleted file mode 100644 index ebe9dae7..00000000 --- a/Sources/SqlDatabase.PowerShell.Test/SqlDatabaseProgramNet452Test.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Moq; -using NUnit.Framework; -using Shouldly; -using SqlDatabase.Configuration; - -namespace SqlDatabase.PowerShell -{ - [TestFixture] - public class SqlDatabaseProgramNet452Test - { - private Mock _owner; - private IList _output; - private IList _outputErrors; - private SqlDatabaseProgramNet452 _sut; - - [SetUp] - public void BeforeEachTest() - { - _output = new List(); - _outputErrors = new List(); - - _owner = new Mock(MockBehavior.Strict); - _owner - .Setup(o => o.WriteLine(It.IsNotNull())) - .Callback(_output.Add); - _owner - .Setup(o => o.WriteErrorLine(It.IsNotNull())) - .Callback(_outputErrors.Add); - - _sut = new SqlDatabaseProgramNet452(_owner.Object); - } - - [Test] - public void EchoCommandLine() - { - var command = new GenericCommandLineBuilder() - .SetCommand(CommandLineFactory.CommandEcho) - .SetConfigurationFile("config file") - .SetConnection("connection") - .SetScripts("script 1") - .SetVariable("var1", "value 1\\") - .Build(); - - _sut.ExecuteCommand(command); - - foreach (var i in _output) - { - Console.WriteLine(i); - } - - _output.Count.ShouldBe(6); - - CommandLineParser.PreFormatOutputLogs(_output).ShouldBeTrue(); - var actual = new CommandLineParser().Parse(_output.ToArray()); - - actual.Args[0].IsPair.ShouldBe(false); - actual.Args[0].Value.ShouldBe(CommandLineFactory.CommandEcho); - - actual.Args[1].Key.ShouldBe("database"); - actual.Args[1].Value.ShouldBe("connection"); - - actual.Args[2].Key.ShouldBe("from"); - actual.Args[2].Value.ShouldBe("script 1"); - - actual.Args[3].Key.ShouldBe("configuration"); - actual.Args[3].Value.ShouldBe("config file"); - - actual.Args[4].Key.ShouldBe("varvar1"); - actual.Args[4].Value.ShouldBe("value 1\\"); - } - - [Test] - public void ValidateErrors() - { - var command = new GenericCommandLineBuilder() - .SetCommand("Unknown") - .SetConnection("Data Source=.;Initial Catalog=SqlDatabaseTest") - .SetScripts("script 1") - .Build(); - - _sut.ExecuteCommand(command); - - _owner.Verify(); - _outputErrors.Count.ShouldBe(1); - } - } -} diff --git a/Sources/SqlDatabase.PowerShell.Test/TestApi/SqlDatabaseCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/TestApi/SqlDatabaseCmdLetTest.cs index 31735274..2b16d07e 100644 --- a/Sources/SqlDatabase.PowerShell.Test/TestApi/SqlDatabaseCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/TestApi/SqlDatabaseCmdLetTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Management.Automation; using System.Management.Automation.Runspaces; @@ -8,6 +9,7 @@ using NUnit.Framework; using Shouldly; using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; using Command = System.Management.Automation.Runspaces.Command; namespace SqlDatabase.PowerShell.TestApi @@ -40,13 +42,13 @@ public void BeforeEachTest() .Callback(cmd => _commandLines.Add(cmd)); _commandLines.Clear(); - SqlDatabaseCmdLet.Program = program.Object; + PowerShellCommandBase.Program = program.Object; } [TearDown] public void AfterEachTest() { - SqlDatabaseCmdLet.Program = null; + PowerShellCommandBase.Program = null; foreach (var row in _powerShell.Streams.Information) { @@ -57,12 +59,20 @@ public void AfterEachTest() _runSpace?.Dispose(); } - protected GenericCommandLine[] InvokeCommand(string name, Action builder) + protected Collection InvokeCommand(string name) { - return InvokeCommandPipeLine(name, builder); + var command = new Command(name); + _powerShell.Commands.AddCommand(command); + + return _powerShell.Invoke(); + } + + protected GenericCommandLine[] InvokeSqlDatabase(string name, Action builder) + { + return InvokeInvokeSqlDatabasePipeLine(name, builder); } - protected GenericCommandLine[] InvokeCommandPipeLine(string name, Action builder, params object[] args) + protected GenericCommandLine[] InvokeInvokeSqlDatabasePipeLine(string name, Action builder, params object[] args) { _commandLines.Clear(); diff --git a/Sources/SqlDatabase.PowerShell.Test/UpgradeCmdLetTest.cs b/Sources/SqlDatabase.PowerShell.Test/UpgradeCmdLetTest.cs index 77a1818e..f7085180 100644 --- a/Sources/SqlDatabase.PowerShell.Test/UpgradeCmdLetTest.cs +++ b/Sources/SqlDatabase.PowerShell.Test/UpgradeCmdLetTest.cs @@ -14,7 +14,7 @@ public class UpgradeCmdLetTest : SqlDatabaseCmdLetTest [TestCase("Upgrade-SqlDatabase")] public void BuildCommandLine(string commandName) { - var commandLines = InvokeCommand( + var commandLines = InvokeSqlDatabase( commandName, c => { @@ -61,7 +61,7 @@ public void BuildCommandLine(string commandName) [TestCase("Upgrade-SqlDatabase")] public void BuildPipeCommandLine(string commandName) { - var commandLines = InvokeCommandPipeLine( + var commandLines = InvokeInvokeSqlDatabasePipeLine( commandName, c => c.Parameters.Add(nameof(UpgradeCmdLet.Database), "connection string"), "file 1", diff --git a/Sources/SqlDatabase.PowerShell/CmdLetLogger.cs b/Sources/SqlDatabase.PowerShell/CmdLetLogger.cs deleted file mode 100644 index 4c168c6e..00000000 --- a/Sources/SqlDatabase.PowerShell/CmdLetLogger.cs +++ /dev/null @@ -1,24 +0,0 @@ -using SqlDatabase.Log; - -namespace SqlDatabase.PowerShell -{ - internal sealed class CmdLetLogger : LoggerBase - { - private readonly ICmdlet _owner; - - public CmdLetLogger(ICmdlet owner) - { - _owner = owner; - } - - protected override void WriteError(string message) - { - _owner.WriteErrorLine(message); - } - - protected override void WriteInfo(string message) - { - _owner.WriteLine(message); - } - } -} diff --git a/Sources/SqlDatabase.PowerShell/CreateCmdLet.cs b/Sources/SqlDatabase.PowerShell/CreateCmdLet.cs index eeabf668..9a850883 100644 --- a/Sources/SqlDatabase.PowerShell/CreateCmdLet.cs +++ b/Sources/SqlDatabase.PowerShell/CreateCmdLet.cs @@ -1,16 +1,16 @@ using System.Management.Automation; using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; namespace SqlDatabase.PowerShell { [Cmdlet(VerbsCommon.New, "SqlDatabase")] [Alias(CommandLineFactory.CommandCreate + "-SqlDatabase")] - public sealed class CreateCmdLet : SqlDatabaseCmdLet + public sealed class CreateCmdLet : PSCmdlet { - public CreateCmdLet() - : base(CommandLineFactory.CommandCreate) - { - } + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Connection string to target database.")] + [Alias("d")] + public string Database { get; set; } [Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true, HelpMessage = "A path to a folder or zip archive with sql scripts or path to a sql script file. Repeat -from to setup several sources.")] [Alias("f")] @@ -23,13 +23,16 @@ public CreateCmdLet() [Parameter(Position = 4, HelpMessage = "Shows what would happen if the command runs. The command is not run.")] public SwitchParameter WhatIf { get; set; } - internal override void BuildCommandLine(GenericCommandLineBuilder cmd) - { - this.AppendFrom(From, cmd); + [Parameter(ValueFromRemainingArguments = true, HelpMessage = "Set a variable in format \"[name of variable]=[value of variable]\".")] + [Alias("v")] + public string[] Var { get; set; } - cmd - .SetConfigurationFile(this.RootPath(Configuration)) - .SetWhatIf(WhatIf); + [Parameter(HelpMessage = "Optional path to log file.")] + public string Log { get; set; } + + protected override void ProcessRecord() + { + new CreatePowerShellCommand(this).Execute(); } } } \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/ExecuteCmdLet.cs b/Sources/SqlDatabase.PowerShell/ExecuteCmdLet.cs index 68ac5779..39539d43 100644 --- a/Sources/SqlDatabase.PowerShell/ExecuteCmdLet.cs +++ b/Sources/SqlDatabase.PowerShell/ExecuteCmdLet.cs @@ -1,16 +1,16 @@ using System.Management.Automation; using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; namespace SqlDatabase.PowerShell { [Cmdlet(VerbsLifecycle.Invoke, "SqlDatabase")] [Alias(CommandLineFactory.CommandExecute + "-SqlDatabase")] - public sealed class ExecuteCmdLet : SqlDatabaseCmdLet + public sealed class ExecuteCmdLet : PSCmdlet { - public ExecuteCmdLet() - : base(CommandLineFactory.CommandExecute) - { - } + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Connection string to target database.")] + [Alias("d")] + public string Database { get; set; } [Parameter(Position = 2, ValueFromPipeline = true, HelpMessage = "A path to a folder or zip archive with sql scripts or path to a sql script file. Repeat -from to setup several sources.")] [Alias("f")] @@ -22,7 +22,7 @@ public ExecuteCmdLet() [Parameter(Position = 3, HelpMessage = "Transaction mode. Possible values: none, perStep. Default is none.")] [Alias("t")] - public TransactionMode Transaction { get; set; } + public PSTransactionMode Transaction { get; set; } [Parameter(Position = 4, HelpMessage = "A path to application configuration file. Default is current SqlDatabase.exe.config.")] [Alias("c")] @@ -31,22 +31,16 @@ public ExecuteCmdLet() [Parameter(Position = 5, HelpMessage = "Shows what would happen if the command runs. The command is not run.")] public SwitchParameter WhatIf { get; set; } - internal override void BuildCommandLine(GenericCommandLineBuilder cmd) + [Parameter(ValueFromRemainingArguments = true, HelpMessage = "Set a variable in format \"[name of variable]=[value of variable]\".")] + [Alias("v")] + public string[] Var { get; set; } + + [Parameter(HelpMessage = "Optional path to log file.")] + public string Log { get; set; } + + protected override void ProcessRecord() { - this.AppendFrom(From, cmd); - - if (FromSql != null && FromSql.Length > 0) - { - foreach (var from in FromSql) - { - cmd.SetInLineScript(from); - } - } - - cmd - .SetTransaction(Transaction) - .SetConfigurationFile(this.RootPath(Configuration)) - .SetWhatIf(WhatIf); + new ExecutePowerShellCommand(this).Execute(); } } } \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/ExportCmdLet.cs b/Sources/SqlDatabase.PowerShell/ExportCmdLet.cs index b81a5526..bf4e1295 100644 --- a/Sources/SqlDatabase.PowerShell/ExportCmdLet.cs +++ b/Sources/SqlDatabase.PowerShell/ExportCmdLet.cs @@ -1,15 +1,14 @@ using System.Management.Automation; -using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; namespace SqlDatabase.PowerShell { [Cmdlet(VerbsData.Export, "SqlDatabase")] - public sealed class ExportCmdLet : SqlDatabaseCmdLet + public sealed class ExportCmdLet : PSCmdlet { - public ExportCmdLet() - : base(CommandLineFactory.CommandExport) - { - } + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Connection string to target database.")] + [Alias("d")] + public string Database { get; set; } [Parameter(Position = 2, HelpMessage = "An sql script to select export data. Repeat -fromSql to setup several scripts.")] [Alias("s")] @@ -29,22 +28,16 @@ public ExportCmdLet() [Parameter(HelpMessage = "Setup \"INSERT INTO\" table name. Default is dbo.SqlDatabaseExport.")] public string ToTable { get; set; } - internal override void BuildCommandLine(GenericCommandLineBuilder cmd) + [Parameter(ValueFromRemainingArguments = true, HelpMessage = "Set a variable in format \"[name of variable]=[value of variable]\".")] + [Alias("v")] + public string[] Var { get; set; } + + [Parameter(HelpMessage = "Optional path to log file.")] + public string Log { get; set; } + + protected override void ProcessRecord() { - this.AppendFrom(From, cmd); - - if (FromSql != null && FromSql.Length > 0) - { - foreach (var from in FromSql) - { - cmd.SetInLineScript(from); - } - } - - cmd - .SetConfigurationFile(this.RootPath(Configuration)) - .SetExportToTable(ToTable) - .SetExportToFile(ToFile); + new ExportPowerShellCommand(this).Execute(); } } } \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/ICmdlet.cs b/Sources/SqlDatabase.PowerShell/ICmdlet.cs deleted file mode 100644 index 2a924cec..00000000 --- a/Sources/SqlDatabase.PowerShell/ICmdlet.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace SqlDatabase.PowerShell -{ - internal interface ICmdlet - { - void WriteErrorLine(string value); - - void WriteLine(string value); - } -} diff --git a/Sources/SqlDatabase.PowerShell/InfoCmdLet.cs b/Sources/SqlDatabase.PowerShell/InfoCmdLet.cs index 41a603ba..7bda9ee3 100644 --- a/Sources/SqlDatabase.PowerShell/InfoCmdLet.cs +++ b/Sources/SqlDatabase.PowerShell/InfoCmdLet.cs @@ -2,6 +2,7 @@ using System.Management.Automation; using System.Runtime.InteropServices; using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; namespace SqlDatabase.PowerShell { @@ -9,8 +10,18 @@ namespace SqlDatabase.PowerShell public sealed class InfoCmdLet : PSCmdlet { protected override void ProcessRecord() + { + using (var resolver = DependencyResolverFactory.Create(this)) + { + resolver.Initialize(); + WriteInfo(); + } + } + + private void WriteInfo() { var assembly = GetType().Assembly; + var location = Path.GetDirectoryName(assembly.Location); this.TryGetPSVersionTable(out var psVersionTable); @@ -23,9 +34,9 @@ protected override void ProcessRecord() RuntimeInformation.OSDescription, RuntimeInformation.OSArchitecture, RuntimeInformation.ProcessArchitecture, - Location = Path.GetDirectoryName(assembly.Location), + Location = location, WorkingDirectory = this.GetWorkingDirectory(), - DefaultConfigurationFile = ConfigurationManager.ResolveDefaultConfigurationFile() + DefaultConfigurationFile = ConfigurationManager.ResolveDefaultConfigurationFile(location) }); } } diff --git a/Sources/SqlDatabase.PowerShell/Internal/AssemblyCache.cs b/Sources/SqlDatabase.PowerShell/Internal/AssemblyCache.cs new file mode 100644 index 00000000..85f72da6 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/AssemblyCache.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class AssemblyCache : IDisposable + { + private readonly string[] _probingPaths; + private readonly IDictionary _assemblyByName; + + public AssemblyCache(params string[] probingPaths) + { + _probingPaths = new string[probingPaths.Length + 1]; + _probingPaths[0] = Path.GetDirectoryName(GetType().Assembly.Location); + for (var i = 0; i < probingPaths.Length; i++) + { + _probingPaths[i + 1] = probingPaths[i]; + } + + _assemblyByName = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + public Assembly Load(AssemblyName assemblyName, Func loader) + { + var fileName = assemblyName.Name + ".dll"; + if (_assemblyByName.TryGetValue(fileName, out var assembly)) + { + return assembly; + } + + assembly = TryFindAndLoad(fileName, loader); + _assemblyByName[fileName] = assembly; + return assembly; + } + + public void Dispose() + { + _assemblyByName.Clear(); + } + + private Assembly TryFindAndLoad(string fileName, Func loader) + { + for (var i = 0; i < _probingPaths.Length; i++) + { + var path = Path.Combine(_probingPaths[i], fileName); + if (File.Exists(path)) + { + return loader(path); + } + } + + return null; + } + } +} diff --git a/Sources/SqlDatabase.PowerShell/Internal/CmdLetLogger.cs b/Sources/SqlDatabase.PowerShell/Internal/CmdLetLogger.cs new file mode 100644 index 00000000..ceb0e9e0 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/CmdLetLogger.cs @@ -0,0 +1,30 @@ +using System; +using System.Management.Automation; +using SqlDatabase.Log; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class CmdLetLogger : LoggerBase + { + private readonly Cmdlet _cmdlet; + + public CmdLetLogger(Cmdlet cmdlet) + { + _cmdlet = cmdlet; + } + + protected override void WriteError(string message) + { + _cmdlet.WriteError(new ErrorRecord( + new InvalidOperationException(message), + null, + ErrorCategory.NotSpecified, + null)); + } + + protected override void WriteInfo(string message) + { + _cmdlet.WriteInformation(new InformationRecord(message, null)); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell/CmdletExtensions.cs b/Sources/SqlDatabase.PowerShell/Internal/CmdletExtensions.cs similarity index 97% rename from Sources/SqlDatabase.PowerShell/CmdletExtensions.cs rename to Sources/SqlDatabase.PowerShell/Internal/CmdletExtensions.cs index d8697be0..15277ce2 100644 --- a/Sources/SqlDatabase.PowerShell/CmdletExtensions.cs +++ b/Sources/SqlDatabase.PowerShell/Internal/CmdletExtensions.cs @@ -2,7 +2,7 @@ using System.Management.Automation; using SqlDatabase.Configuration; -namespace SqlDatabase.PowerShell +namespace SqlDatabase.PowerShell.Internal { internal static class CmdletExtensions { diff --git a/Sources/SqlDatabase.PowerShell/Internal/CreatePowerShellCommand.cs b/Sources/SqlDatabase.PowerShell/Internal/CreatePowerShellCommand.cs new file mode 100644 index 00000000..d4f43832 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/CreatePowerShellCommand.cs @@ -0,0 +1,36 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class CreatePowerShellCommand : PowerShellCommandBase + { + public CreatePowerShellCommand(CreateCmdLet cmdlet) + : base(cmdlet) + { + } + + public new CreateCmdLet Cmdlet => (CreateCmdLet)base.Cmdlet; + + protected override void BuildCommandLine(GenericCommandLineBuilder builder) + { + builder + .SetCommand(CommandLineFactory.CommandCreate) + .SetConnection(Cmdlet.Database) + .SetLogFileName(Cmdlet.RootPath(Cmdlet.Log)); + + if (Cmdlet.Var != null) + { + for (var i = 0; i < Cmdlet.Var.Length; i++) + { + builder.SetVariable(Cmdlet.Var[i]); + } + } + + Cmdlet.AppendFrom(Cmdlet.From, builder); + + builder + .SetConfigurationFile(Cmdlet.RootPath(Cmdlet.Configuration)) + .SetWhatIf(Cmdlet.WhatIf); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/Internal/DependencyResolverFactory.cs b/Sources/SqlDatabase.PowerShell/Internal/DependencyResolverFactory.cs new file mode 100644 index 00000000..dee89fd1 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/DependencyResolverFactory.cs @@ -0,0 +1,29 @@ +using System; +using System.Management.Automation; + +namespace SqlDatabase.PowerShell.Internal +{ + internal static class DependencyResolverFactory + { + public static IDependencyResolver Create(PSCmdlet cmdlet) + { + if (!cmdlet.TryGetPSVersionTable(out var psVersionTable)) + { + throw new PlatformNotSupportedException("$PSVersionTable is not defined."); + } + + return Create(psVersionTable); + } + + internal static IDependencyResolver Create(PSVersionTable psVersionTable) + { + // In PowerShell 4 and below, this variable does not exist + if (string.IsNullOrEmpty(psVersionTable.PSEdition) || "Desktop".Equals(psVersionTable.PSEdition, StringComparison.OrdinalIgnoreCase)) + { + return new PowerShellDesktopDependencyResolver(); + } + + return new PowerShellCoreDependencyResolver(); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell/Internal/ExecutePowerShellCommand.cs b/Sources/SqlDatabase.PowerShell/Internal/ExecutePowerShellCommand.cs new file mode 100644 index 00000000..14588671 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/ExecutePowerShellCommand.cs @@ -0,0 +1,45 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class ExecutePowerShellCommand : PowerShellCommandBase + { + public ExecutePowerShellCommand(ExecuteCmdLet cmdLet) + : base(cmdLet) + { + } + + public new ExecuteCmdLet Cmdlet => (ExecuteCmdLet)base.Cmdlet; + + protected override void BuildCommandLine(GenericCommandLineBuilder builder) + { + builder + .SetCommand(CommandLineFactory.CommandExecute) + .SetConnection(Cmdlet.Database) + .SetLogFileName(Cmdlet.RootPath(Cmdlet.Log)); + + if (Cmdlet.Var != null) + { + for (var i = 0; i < Cmdlet.Var.Length; i++) + { + builder.SetVariable(Cmdlet.Var[i]); + } + } + + Cmdlet.AppendFrom(Cmdlet.From, builder); + + if (Cmdlet.FromSql != null) + { + for (var i = 0; i < Cmdlet.FromSql.Length; i++) + { + builder.SetInLineScript(Cmdlet.FromSql[i]); + } + } + + builder + .SetTransaction((TransactionMode)Cmdlet.Transaction) + .SetConfigurationFile(Cmdlet.RootPath(Cmdlet.Configuration)) + .SetWhatIf(Cmdlet.WhatIf); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/Internal/ExportPowerShellCommand.cs b/Sources/SqlDatabase.PowerShell/Internal/ExportPowerShellCommand.cs new file mode 100644 index 00000000..1a8aacca --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/ExportPowerShellCommand.cs @@ -0,0 +1,45 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class ExportPowerShellCommand : PowerShellCommandBase + { + public ExportPowerShellCommand(ExportCmdLet cmdLet) + : base(cmdLet) + { + } + + public new ExportCmdLet Cmdlet => (ExportCmdLet)base.Cmdlet; + + protected override void BuildCommandLine(GenericCommandLineBuilder builder) + { + builder + .SetCommand(CommandLineFactory.CommandExport) + .SetConnection(Cmdlet.Database) + .SetLogFileName(Cmdlet.RootPath(Cmdlet.Log)); + + if (Cmdlet.Var != null) + { + for (var i = 0; i < Cmdlet.Var.Length; i++) + { + builder.SetVariable(Cmdlet.Var[i]); + } + } + + Cmdlet.AppendFrom(Cmdlet.From, builder); + + if (Cmdlet.FromSql != null) + { + for (var i = 0; i < Cmdlet.FromSql.Length; i++) + { + builder.SetInLineScript(Cmdlet.FromSql[i]); + } + } + + builder + .SetConfigurationFile(Cmdlet.RootPath(Cmdlet.Configuration)) + .SetExportToTable(Cmdlet.ToTable) + .SetExportToFile(Cmdlet.ToFile); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/Internal/IDependencyResolver.cs b/Sources/SqlDatabase.PowerShell/Internal/IDependencyResolver.cs new file mode 100644 index 00000000..a1be125d --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/IDependencyResolver.cs @@ -0,0 +1,9 @@ +using System; + +namespace SqlDatabase.PowerShell.Internal +{ + internal interface IDependencyResolver : IDisposable + { + void Initialize(); + } +} diff --git a/Sources/SqlDatabase.PowerShell/ISqlDatabaseProgram.cs b/Sources/SqlDatabase.PowerShell/Internal/ISqlDatabaseProgram.cs similarity index 78% rename from Sources/SqlDatabase.PowerShell/ISqlDatabaseProgram.cs rename to Sources/SqlDatabase.PowerShell/Internal/ISqlDatabaseProgram.cs index e003a153..06956368 100644 --- a/Sources/SqlDatabase.PowerShell/ISqlDatabaseProgram.cs +++ b/Sources/SqlDatabase.PowerShell/Internal/ISqlDatabaseProgram.cs @@ -1,6 +1,6 @@ using SqlDatabase.Configuration; -namespace SqlDatabase.PowerShell +namespace SqlDatabase.PowerShell.Internal { internal interface ISqlDatabaseProgram { diff --git a/Sources/SqlDatabase.PowerShell/PSVersionTable.cs b/Sources/SqlDatabase.PowerShell/Internal/PSVersionTable.cs similarity index 95% rename from Sources/SqlDatabase.PowerShell/PSVersionTable.cs rename to Sources/SqlDatabase.PowerShell/Internal/PSVersionTable.cs index 8c03742a..c4c68bd8 100644 --- a/Sources/SqlDatabase.PowerShell/PSVersionTable.cs +++ b/Sources/SqlDatabase.PowerShell/Internal/PSVersionTable.cs @@ -1,7 +1,7 @@ using System; using System.Collections; -namespace SqlDatabase.PowerShell +namespace SqlDatabase.PowerShell.Internal { internal readonly ref struct PSVersionTable { diff --git a/Sources/SqlDatabase.PowerShell/Internal/PowerShellCommandBase.cs b/Sources/SqlDatabase.PowerShell/Internal/PowerShellCommandBase.cs new file mode 100644 index 00000000..37309278 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/PowerShellCommandBase.cs @@ -0,0 +1,60 @@ +using System.IO; +using System.Management.Automation; +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal abstract class PowerShellCommandBase + { + protected PowerShellCommandBase(PSCmdlet cmdlet) + { + Cmdlet = cmdlet; + } + + public PSCmdlet Cmdlet { get; } + + // only for tests + internal static ISqlDatabaseProgram Program { get; set; } + + public void Execute() + { + using (var resolver = DependencyResolverFactory.Create(Cmdlet)) + { + resolver.Initialize(); + ExecuteCore(); + } + } + + internal static void AppendDefaultConfiguration(GenericCommandLine command) + { + if (string.IsNullOrEmpty(command.ConfigurationFile)) + { + var probingPath = Path.GetDirectoryName(typeof(PowerShellCommandBase).Assembly.Location); + command.ConfigurationFile = ConfigurationManager.ResolveDefaultConfigurationFile(probingPath); + } + } + + protected abstract void BuildCommandLine(GenericCommandLineBuilder builder); + + private void ExecuteCore() + { + var builder = new GenericCommandLineBuilder(); + BuildCommandLine(builder); + + var command = builder.Build(); + AppendDefaultConfiguration(command); + + ResolveProgram().ExecuteCommand(command); + } + + private ISqlDatabaseProgram ResolveProgram() + { + if (Program != null) + { + return Program; + } + + return new SqlDatabaseProgram(new CmdLetLogger(Cmdlet)); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell/Internal/PowerShellCoreDependencyResolver.cs b/Sources/SqlDatabase.PowerShell/Internal/PowerShellCoreDependencyResolver.cs new file mode 100644 index 00000000..dbab07ba --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/PowerShellCoreDependencyResolver.cs @@ -0,0 +1,38 @@ +using System.IO; +using System.Management.Automation; +using System.Reflection; +using System.Runtime.Loader; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class PowerShellCoreDependencyResolver : IDependencyResolver + { + private readonly AssemblyCache _cache; + + public PowerShellCoreDependencyResolver() + { + var psCore = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "ps-core"); + _cache = new AssemblyCache( + psCore, + Path.GetDirectoryName(typeof(PSCmdlet).Assembly.Location)); + } + + public void Initialize() + { + // Fail to load configuration from [SqlDatabase.exe.config]. + // ---> An error occurred creating the configuration section handler for sqlDatabase: Could not load file or assembly 'SqlDatabase, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. + AssemblyLoadContext.Default.Resolving += AssemblyResolving; + } + + public void Dispose() + { + AssemblyLoadContext.Default.Resolving -= AssemblyResolving; + _cache.Dispose(); + } + + private Assembly AssemblyResolving(AssemblyLoadContext context, AssemblyName assemblyName) + { + return _cache.Load(assemblyName, context.LoadFromAssemblyPath); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/Internal/PowerShellDesktopDependencyResolver.cs b/Sources/SqlDatabase.PowerShell/Internal/PowerShellDesktopDependencyResolver.cs new file mode 100644 index 00000000..17053b0d --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/PowerShellDesktopDependencyResolver.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Reflection; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class PowerShellDesktopDependencyResolver : IDependencyResolver + { + private readonly AssemblyCache _cache; + + public PowerShellDesktopDependencyResolver() + { + var psDesktop = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), "ps-desktop"); + _cache = new AssemblyCache(psDesktop); + } + + public void Initialize() + { + AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; + } + + public void Dispose() + { + AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve; + _cache.Dispose(); + } + + private Assembly AssemblyResolve(object sender, ResolveEventArgs args) + { + return _cache.Load(new AssemblyName(args.Name), Assembly.LoadFrom); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/Internal/SqlDatabaseProgram.cs b/Sources/SqlDatabase.PowerShell/Internal/SqlDatabaseProgram.cs new file mode 100644 index 00000000..a97b7c2d --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/SqlDatabaseProgram.cs @@ -0,0 +1,20 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class SqlDatabaseProgram : ISqlDatabaseProgram + { + private readonly ILogger _logger; + + public SqlDatabaseProgram(ILogger logger) + { + _logger = logger; + } + + public void ExecuteCommand(GenericCommandLine command) + { + var args = new GenericCommandLineBuilder(command).BuildArray(); + Program.Run(_logger, args); + } + } +} diff --git a/Sources/SqlDatabase.PowerShell/Internal/UpgradePowerShellCommand.cs b/Sources/SqlDatabase.PowerShell/Internal/UpgradePowerShellCommand.cs new file mode 100644 index 00000000..2d1c403d --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/Internal/UpgradePowerShellCommand.cs @@ -0,0 +1,38 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell.Internal +{ + internal sealed class UpgradePowerShellCommand : PowerShellCommandBase + { + public UpgradePowerShellCommand(UpgradeCmdLet cmdLet) + : base(cmdLet) + { + } + + public new UpgradeCmdLet Cmdlet => (UpgradeCmdLet)base.Cmdlet; + + protected override void BuildCommandLine(GenericCommandLineBuilder builder) + { + builder + .SetCommand(CommandLineFactory.CommandUpgrade) + .SetConnection(Cmdlet.Database) + .SetLogFileName(Cmdlet.RootPath(Cmdlet.Log)); + + if (Cmdlet.Var != null) + { + for (var i = 0; i < Cmdlet.Var.Length; i++) + { + builder.SetVariable(Cmdlet.Var[i]); + } + } + + Cmdlet.AppendFrom(Cmdlet.From, builder); + + builder + .SetConfigurationFile(Cmdlet.RootPath(Cmdlet.Configuration)) + .SetTransaction((TransactionMode)Cmdlet.Transaction) + .SetWhatIf(Cmdlet.WhatIf) + .SetFolderAsModuleName(Cmdlet.FolderAsModuleName); + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/OutputReader.cs b/Sources/SqlDatabase.PowerShell/OutputReader.cs deleted file mode 100644 index 8e177116..00000000 --- a/Sources/SqlDatabase.PowerShell/OutputReader.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Text; -using SqlDatabase.Log; - -namespace SqlDatabase.PowerShell -{ - internal sealed class OutputReader - { - internal const string SetForegroundColorToDefault = RedirectedConsoleLogger.SetForegroundColorToDefault; - internal const string SetForegroundColorToRed = RedirectedConsoleLogger.SetForegroundColorToRed; - - private readonly StringBuilder _errorBuffer = new StringBuilder(); - private bool _errorFlag; - - public Record? NextLine(string text) - { - var startFromRed = text.StartsWith(SetForegroundColorToRed, StringComparison.Ordinal); - var endWithDefault = text.EndsWith(SetForegroundColorToDefault, StringComparison.Ordinal); - - var message = text; - if (startFromRed) - { - message = message.Substring(SetForegroundColorToRed.Length); - } - - if (endWithDefault) - { - message = message.Substring(0, message.Length - SetForegroundColorToDefault.Length); - } - - var isError = _errorFlag || startFromRed; - - if (endWithDefault) - { - _errorFlag = false; - } - else if (startFromRed) - { - _errorFlag = true; - } - - if (isError) - { - if (_errorBuffer.Length > 0) - { - _errorBuffer.AppendLine(); - } - - _errorBuffer.Append(message); - - if (_errorFlag) - { - return null; - } - - var record = new Record(_errorBuffer.ToString(), true); - _errorBuffer.Clear(); - return record; - } - - return new Record(message, false); - } - - public Record? Flush() - { - if (_errorBuffer.Length == 0) - { - return null; - } - - return new Record(_errorBuffer.ToString(), true); - } - - public struct Record - { - public Record(string text, bool isError) - { - Text = text; - IsError = isError; - } - - public string Text { get; } - - public bool IsError { get; } - } - } -} diff --git a/Sources/SqlDatabase.PowerShell/PSTransactionMode.cs b/Sources/SqlDatabase.PowerShell/PSTransactionMode.cs new file mode 100644 index 00000000..42c4ba76 --- /dev/null +++ b/Sources/SqlDatabase.PowerShell/PSTransactionMode.cs @@ -0,0 +1,12 @@ +using SqlDatabase.Configuration; + +namespace SqlDatabase.PowerShell +{ + // do not load SqlDatabase.dll on Import-Module + public enum PSTransactionMode + { + None = TransactionMode.None, + + PerStep = TransactionMode.PerStep + } +} diff --git a/Sources/SqlDatabase.PowerShell/PowerShellCmdlet.cs b/Sources/SqlDatabase.PowerShell/PowerShellCmdlet.cs deleted file mode 100644 index de54e7b6..00000000 --- a/Sources/SqlDatabase.PowerShell/PowerShellCmdlet.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Management.Automation; - -namespace SqlDatabase.PowerShell -{ - internal sealed class PowerShellCmdlet : ICmdlet - { - private readonly PSCmdlet _cmdlet; - - public PowerShellCmdlet(PSCmdlet cmdlet) - { - ////var errorActionPreference = cmdlet.SessionState.PSVariable.GetValue("ErrorActionPreference"); - ////var informationPreference = cmdlet.SessionState.PSVariable.GetValue("InformationPreference"); - ////var warningPreference = cmdlet.SessionState.PSVariable.GetValue("WarningPreference"); - - _cmdlet = cmdlet; - } - - public void WriteErrorLine(string value) - { - _cmdlet.WriteError(new ErrorRecord( - new InvalidOperationException(value), - null, - ErrorCategory.NotSpecified, - null)); - } - - public void WriteLine(string value) - { - _cmdlet.WriteInformation(new InformationRecord(value, null)); - } - } -} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabase.PowerShell.csproj b/Sources/SqlDatabase.PowerShell/SqlDatabase.PowerShell.csproj index befa74db..c734f917 100644 --- a/Sources/SqlDatabase.PowerShell/SqlDatabase.PowerShell.csproj +++ b/Sources/SqlDatabase.PowerShell/SqlDatabase.PowerShell.csproj @@ -3,6 +3,7 @@ netstandard2.0 ..\..\bin\SqlDatabase.PowerShell + true @@ -22,4 +23,23 @@ - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabase.psd1 b/Sources/SqlDatabase.PowerShell/SqlDatabase.psd1 index 0813d227..912f164f 100644 Binary files a/Sources/SqlDatabase.PowerShell/SqlDatabase.psd1 and b/Sources/SqlDatabase.PowerShell/SqlDatabase.psd1 differ diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabaseCmdlet.cs b/Sources/SqlDatabase.PowerShell/SqlDatabaseCmdlet.cs deleted file mode 100644 index 6b440726..00000000 --- a/Sources/SqlDatabase.PowerShell/SqlDatabaseCmdlet.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Management.Automation; -using SqlDatabase.Configuration; - -namespace SqlDatabase.PowerShell -{ - public abstract class SqlDatabaseCmdLet : PSCmdlet - { - private readonly string _command; - - protected SqlDatabaseCmdLet(string command) - { - _command = command; - } - - [Parameter(Mandatory = true, Position = 1, HelpMessage = "Connection string to target database.")] - [Alias("d")] - public string Database { get; set; } - - [Parameter(ValueFromRemainingArguments = true, HelpMessage = "Set a variable in format \"[name of variable]=[value of variable]\".")] - [Alias("v")] - public string[] Var { get; set; } - - [Parameter(HelpMessage = "Optional path to log file.")] - public string Log { get; set; } - - // only for tests - internal static ISqlDatabaseProgram Program { get; set; } - - internal static void AppendDefaultConfiguration(GenericCommandLine command) - { - if (string.IsNullOrEmpty(command.ConfigurationFile)) - { - command.ConfigurationFile = ConfigurationManager.ResolveDefaultConfigurationFile(); - } - } - - internal virtual void BuildCommandLine(GenericCommandLineBuilder cmd) - { - } - - protected sealed override void ProcessRecord() - { - var cmd = new GenericCommandLineBuilder() - .SetCommand(_command) - .SetConnection(Database) - .SetLogFileName(this.RootPath(Log)); - - if (Var != null && Var.Length > 0) - { - for (var i = 0; i < Var.Length; i++) - { - cmd.SetVariable(Var[i]); - } - } - - BuildCommandLine(cmd); - - var command = cmd.Build(); - AppendDefaultConfiguration(command); - - ResolveProgram().ExecuteCommand(command); - } - - private ISqlDatabaseProgram ResolveProgram() - { - if (Program != null) - { - return Program; - } - - if (!this.TryGetPSVersionTable(out var psVersionTable)) - { - throw new PlatformNotSupportedException("$PSVersionTable is not defined."); - } - - return SqlDatabaseProgramFactory.CreateProgram(psVersionTable, new PowerShellCmdlet(this)); - } - } -} \ No newline at end of file diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramFactory.cs b/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramFactory.cs deleted file mode 100644 index 75a46540..00000000 --- a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace SqlDatabase.PowerShell -{ - internal static class SqlDatabaseProgramFactory - { - public static ISqlDatabaseProgram CreateProgram(PSVersionTable psVersionTable, ICmdlet owner) - { - // In PowerShell 4 and below, this variable does not exist - if (string.IsNullOrEmpty(psVersionTable.PSEdition) || "Desktop".Equals(psVersionTable.PSEdition, StringComparison.OrdinalIgnoreCase)) - { - return new SqlDatabaseProgramNet452(owner); - } - - return new SqlDatabaseProgramNetCore(owner); - } - } -} diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNet452.cs b/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNet452.cs deleted file mode 100644 index 58aaac98..00000000 --- a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNet452.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Diagnostics; -using System.IO; -using System.Linq; -using SqlDatabase.Configuration; - -namespace SqlDatabase.PowerShell -{ - internal sealed class SqlDatabaseProgramNet452 : ISqlDatabaseProgram - { - private readonly ICmdlet _owner; - private readonly ILogger _logger; - private readonly OutputReader _reader; - - public SqlDatabaseProgramNet452(ICmdlet owner) - { - _owner = owner; - _logger = new CmdLetLogger(owner); - _reader = new OutputReader(); - } - - public void ExecuteCommand(GenericCommandLine command) - { - command.PreFormatOutputLogs = true; - - bool hasErrors; - using (var process = CreateProcess(command)) - { - process.Start(); - - hasErrors = WaitForExit(process); - } - - if (hasErrors) - { - _owner.WriteErrorLine("Execution failed."); - } - } - - private static Process CreateProcess(GenericCommandLine command) - { - var assemblyLocation = typeof(Program).Assembly.Location; - - var sqlDatabase = Path.Combine(Path.GetDirectoryName(assemblyLocation), "net452", Path.GetFileNameWithoutExtension(assemblyLocation) + ".exe"); - if (!File.Exists(sqlDatabase)) - { - // debug - sqlDatabase = Path.Combine(Path.GetDirectoryName(assemblyLocation), Path.GetFileNameWithoutExtension(assemblyLocation) + ".exe"); - } - - var startInfo = new ProcessStartInfo - { - WorkingDirectory = Path.GetDirectoryName(sqlDatabase), - FileName = sqlDatabase, - UseShellExecute = false, - Arguments = string.Join(" ", new GenericCommandLineBuilder(command).BuildArray(true).Select(i => "\"" + i + "\"")), - RedirectStandardOutput = true, - CreateNoWindow = true - }; - - return new Process { StartInfo = startInfo }; - } - - private bool WaitForExit(Process process) - { - var hasErrors = false; - - string line; - while ((line = process.StandardOutput.ReadLine()) != null) - { - var record = _reader.NextLine(line); - if (record.HasValue) - { - if (record.Value.IsError) - { - hasErrors = true; - _logger.Error(record.Value.Text); - } - else - { - _logger.Info(record.Value.Text); - } - } - } - - process.WaitForExit(); - - var buffered = _reader.Flush(); - if (buffered.HasValue) - { - if (buffered.Value.IsError) - { - hasErrors = true; - _logger.Error(buffered.Value.Text); - } - else - { - _logger.Info(buffered.Value.Text); - } - } - - return process.ExitCode != 0 && !hasErrors; - } - } -} diff --git a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNetCore.cs b/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNetCore.cs deleted file mode 100644 index 9aaea4e1..00000000 --- a/Sources/SqlDatabase.PowerShell/SqlDatabaseProgramNetCore.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.Loader; -using SqlDatabase.Configuration; - -namespace SqlDatabase.PowerShell -{ - internal sealed class SqlDatabaseProgramNetCore : ISqlDatabaseProgram - { - private readonly ICmdlet _owner; - - public SqlDatabaseProgramNetCore(ICmdlet owner) - { - _owner = owner; - } - - public void ExecuteCommand(GenericCommandLine command) - { - var logger = new CmdLetLogger(_owner); - var args = new GenericCommandLineBuilder(command).BuildArray(false); - - // Fail to load configuration from [SqlDatabase.exe.config]. - // ---> An error occurred creating the configuration section handler for sqlDatabase: Could not load file or assembly 'SqlDatabase, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified. - AssemblyLoadContext.Default.Resolving += AssemblyResolving; - - try - { - Program.Run(logger, args); - } - finally - { - AssemblyLoadContext.Default.Resolving -= AssemblyResolving; - } - } - - private Assembly AssemblyResolving(AssemblyLoadContext context, AssemblyName assemblyName) - { - var token = assemblyName.GetPublicKeyToken(); - if (token == null || token.Length == 0) - { - var sqlDatabase = typeof(Program).Assembly; - if (sqlDatabase.GetName().Name.Equals(assemblyName.Name, StringComparison.OrdinalIgnoreCase)) - { - return sqlDatabase; - } - } - - return null; - } - } -} diff --git a/Sources/SqlDatabase.PowerShell/UpgradeCmdLet.cs b/Sources/SqlDatabase.PowerShell/UpgradeCmdLet.cs index 23641a15..e4003dce 100644 --- a/Sources/SqlDatabase.PowerShell/UpgradeCmdLet.cs +++ b/Sources/SqlDatabase.PowerShell/UpgradeCmdLet.cs @@ -1,16 +1,16 @@ using System.Management.Automation; using SqlDatabase.Configuration; +using SqlDatabase.PowerShell.Internal; namespace SqlDatabase.PowerShell { [Cmdlet(VerbsData.Update, "SqlDatabase")] [Alias(CommandLineFactory.CommandUpgrade + "-SqlDatabase")] - public sealed class UpgradeCmdLet : SqlDatabaseCmdLet + public sealed class UpgradeCmdLet : PSCmdlet { - public UpgradeCmdLet() - : base(CommandLineFactory.CommandUpgrade) - { - } + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Connection string to target database.")] + [Alias("d")] + public string Database { get; set; } [Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true, HelpMessage = "A path to a folder or zip archive with migration steps. Repeat -from to setup several sources.")] [Alias("f")] @@ -18,7 +18,7 @@ public UpgradeCmdLet() [Parameter(Position = 3, HelpMessage = "Transaction mode. Possible values: none, perStep. Default is none.")] [Alias("t")] - public TransactionMode Transaction { get; set; } + public PSTransactionMode Transaction { get; set; } [Parameter(Position = 4, HelpMessage = "A path to application configuration file. Default is current SqlDatabase.exe.config.")] [Alias("c")] @@ -30,15 +30,16 @@ public UpgradeCmdLet() [Parameter(Position = 6)] public SwitchParameter FolderAsModuleName { get; set; } - internal override void BuildCommandLine(GenericCommandLineBuilder cmd) - { - this.AppendFrom(From, cmd); + [Parameter(ValueFromRemainingArguments = true, HelpMessage = "Set a variable in format \"[name of variable]=[value of variable]\".")] + [Alias("v")] + public string[] Var { get; set; } - cmd - .SetConfigurationFile(this.RootPath(Configuration)) - .SetTransaction(Transaction) - .SetWhatIf(WhatIf) - .SetFolderAsModuleName(FolderAsModuleName); + [Parameter(HelpMessage = "Optional path to log file.")] + public string Log { get; set; } + + protected override void ProcessRecord() + { + new UpgradePowerShellCommand(this).Execute(); } } } \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/Commands/DatabaseCreateCommandTest.cs b/Sources/SqlDatabase.Test/Commands/DatabaseCreateCommandTest.cs index af26f8d1..ae223bf3 100644 --- a/Sources/SqlDatabase.Test/Commands/DatabaseCreateCommandTest.cs +++ b/Sources/SqlDatabase.Test/Commands/DatabaseCreateCommandTest.cs @@ -18,8 +18,13 @@ public class DatabaseCreateCommandTest [SetUp] public void BeforeEachTest() { + var adapter = new Mock(MockBehavior.Strict); + adapter + .Setup(a => a.GetUserFriendlyConnectionString()) + .Returns("greet"); + _database = new Mock(MockBehavior.Strict); - _database.SetupGet(d => d.ConnectionString).Returns(@"Data Source=unknownServer;Initial Catalog=unknownDatabase"); + _database.SetupGet(d => d.Adapter).Returns(adapter.Object); _database.Setup(d => d.GetServerVersion()).Returns("sql server 1.0"); _scriptSequence = new Mock(MockBehavior.Strict); diff --git a/Sources/SqlDatabase.Test/Commands/DatabaseExecuteCommandTest.cs b/Sources/SqlDatabase.Test/Commands/DatabaseExecuteCommandTest.cs index 71211ab4..e361cb1c 100644 --- a/Sources/SqlDatabase.Test/Commands/DatabaseExecuteCommandTest.cs +++ b/Sources/SqlDatabase.Test/Commands/DatabaseExecuteCommandTest.cs @@ -17,8 +17,13 @@ public class DatabaseExecuteCommandTest [SetUp] public void BeforeEachTest() { + var adapter = new Mock(MockBehavior.Strict); + adapter + .Setup(a => a.GetUserFriendlyConnectionString()) + .Returns("greet"); + _database = new Mock(MockBehavior.Strict); - _database.SetupGet(d => d.ConnectionString).Returns(@"Data Source=unknownServer;Initial Catalog=unknownDatabase"); + _database.SetupGet(d => d.Adapter).Returns(adapter.Object); _database.Setup(d => d.GetServerVersion()).Returns("sql server 1.0"); _scriptSequence = new Mock(MockBehavior.Strict); diff --git a/Sources/SqlDatabase.Test/Commands/DatabaseExportCommandTest.cs b/Sources/SqlDatabase.Test/Commands/DatabaseExportCommandTest.cs index 5fdce613..3c2bfa1d 100644 --- a/Sources/SqlDatabase.Test/Commands/DatabaseExportCommandTest.cs +++ b/Sources/SqlDatabase.Test/Commands/DatabaseExportCommandTest.cs @@ -1,9 +1,11 @@ using System; using System.Data; +using System.IO; using Moq; using NUnit.Framework; using SqlDatabase.Export; using SqlDatabase.Scripts; +using SqlDatabase.Scripts.MsSql; namespace SqlDatabase.Commands { @@ -18,8 +20,16 @@ public class DatabaseExportCommandTest [SetUp] public void BeforeEachTest() { + var adapter = new Mock(MockBehavior.Strict); + adapter + .Setup(a => a.GetUserFriendlyConnectionString()) + .Returns("host; database"); + adapter + .Setup(a => a.CreateSqlWriter(It.IsAny())) + .Returns(output => new MsSqlWriter(output)); + _database = new Mock(MockBehavior.Strict); - _database.SetupGet(d => d.ConnectionString).Returns(@"Data Source=unknownServer;Initial Catalog=unknownDatabase"); + _database.SetupGet(d => d.Adapter).Returns(adapter.Object); _database.Setup(d => d.GetServerVersion()).Returns("sql server 1.0"); _scriptSequence = new Mock(MockBehavior.Strict); @@ -35,7 +45,7 @@ public void BeforeEachTest() _exporter = new Mock(MockBehavior.Strict); _exporter - .SetupSet(e => e.Output = It.IsNotNull()); + .SetupProperty(e => e.Output); _exporter .SetupSet(e => e.Log = log.Object); diff --git a/Sources/SqlDatabase.Test/Commands/DatabaseUpgradeCommandTest.cs b/Sources/SqlDatabase.Test/Commands/DatabaseUpgradeCommandTest.cs index 2a167312..a5b8b7bd 100644 --- a/Sources/SqlDatabase.Test/Commands/DatabaseUpgradeCommandTest.cs +++ b/Sources/SqlDatabase.Test/Commands/DatabaseUpgradeCommandTest.cs @@ -17,8 +17,13 @@ public class DatabaseUpgradeCommandTest [SetUp] public void BeforeEachTest() { + var adapter = new Mock(MockBehavior.Strict); + adapter + .Setup(a => a.GetUserFriendlyConnectionString()) + .Returns("greet"); + _database = new Mock(MockBehavior.Strict); - _database.SetupGet(d => d.ConnectionString).Returns(@"Data Source=unknownServer;Initial Catalog=unknownDatabase"); + _database.SetupGet(d => d.Adapter).Returns(adapter.Object); _database.Setup(d => d.GetServerVersion()).Returns("sql server 1.0"); _scriptSequence = new Mock(MockBehavior.Strict); diff --git a/Sources/SqlDatabase.Test/Configuration/AppConfiguration.full.xml b/Sources/SqlDatabase.Test/Configuration/AppConfiguration.full.xml index c91bdc22..1e04d830 100644 --- a/Sources/SqlDatabase.Test/Configuration/AppConfiguration.full.xml +++ b/Sources/SqlDatabase.Test/Configuration/AppConfiguration.full.xml @@ -15,5 +15,21 @@ + + + + + + + + + + + + diff --git a/Sources/SqlDatabase.Test/Configuration/AppConfigurationTest.cs b/Sources/SqlDatabase.Test/Configuration/AppConfigurationTest.cs index 4a1a739e..5a31120d 100644 --- a/Sources/SqlDatabase.Test/Configuration/AppConfigurationTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/AppConfigurationTest.cs @@ -1,5 +1,6 @@ using System.Configuration; using NUnit.Framework; +using Shouldly; using SqlDatabase.TestApi; namespace SqlDatabase.Configuration @@ -7,60 +8,74 @@ namespace SqlDatabase.Configuration [TestFixture] public class AppConfigurationTest { - private TempDirectory _temp; - - [SetUp] - public void BeforeEachTest() - { - _temp = new TempDirectory(); - } - - [TearDown] - public void AfterEachTest() - { - _temp?.Dispose(); - } - [Test] public void LoadEmpty() { var configuration = LoadFromResource("AppConfiguration.empty.xml"); - Assert.IsNull(configuration); + + configuration.ShouldBeNull(); } [Test] public void LoadDefault() { var configuration = LoadFromResource("AppConfiguration.default.xml"); - Assert.IsNotNull(configuration); - Assert.That(configuration.GetCurrentVersionScript, Is.Not.Null.And.Not.Empty); - Assert.That(configuration.SetCurrentVersionScript, Is.Not.Null.And.Not.Empty); - Assert.That(configuration.AssemblyScript.ClassName, Is.Not.Null.And.Not.Empty); - Assert.That(configuration.AssemblyScript.MethodName, Is.Not.Null.And.Not.Empty); + configuration.ShouldNotBeNull(); + + configuration.GetCurrentVersionScript.ShouldBeNullOrEmpty(); + configuration.SetCurrentVersionScript.ShouldBeNullOrEmpty(); + + configuration.AssemblyScript.ClassName.ShouldBe("SqlDatabaseScript"); + configuration.AssemblyScript.MethodName.ShouldBe("Execute"); + + configuration.Variables.Count.ShouldBe(0); + + configuration.MsSql.GetCurrentVersionScript.ShouldBeNullOrEmpty(); + configuration.MsSql.GetCurrentVersionScript.ShouldBeNullOrEmpty(); + configuration.MsSql.Variables.Count.ShouldBe(0); + + configuration.PgSql.GetCurrentVersionScript.ShouldBeNullOrEmpty(); + configuration.PgSql.GetCurrentVersionScript.ShouldBeNullOrEmpty(); + configuration.PgSql.Variables.Count.ShouldBe(0); } [Test] public void LoadFull() { var configuration = LoadFromResource("AppConfiguration.full.xml"); - Assert.IsNotNull(configuration); - Assert.AreEqual("get-version", configuration.GetCurrentVersionScript); - Assert.AreEqual("set-version", configuration.SetCurrentVersionScript); - Assert.AreEqual("method-name", configuration.AssemblyScript.MethodName); - Assert.AreEqual("class-name", configuration.AssemblyScript.ClassName); + configuration.ShouldNotBeNull(); + + configuration.GetCurrentVersionScript.ShouldBe("get-version"); + configuration.SetCurrentVersionScript.ShouldBe("set-version"); + + configuration.AssemblyScript.ClassName.ShouldBe("class-name"); + configuration.AssemblyScript.MethodName.ShouldBe("method-name"); + + configuration.Variables.AllKeys.ShouldBe(new[] { "x", "y" }); + configuration.Variables["x"].Value.ShouldBe("1"); + configuration.Variables["y"].Value.ShouldBe("2"); + + configuration.MsSql.GetCurrentVersionScript.ShouldBe("get-mssql-version"); + configuration.MsSql.SetCurrentVersionScript.ShouldBe("set-mssql-version"); + configuration.MsSql.Variables.AllKeys.ShouldBe(new[] { "mssql1" }); + configuration.MsSql.Variables["mssql1"].Value.ShouldBe("10"); - CollectionAssert.AreEquivalent( - new[] { "x", "y" }, - configuration.Variables.AllKeys); + configuration.PgSql.GetCurrentVersionScript.ShouldBe("get-pgsql-version"); + configuration.PgSql.SetCurrentVersionScript.ShouldBe("set-pgsql-version"); + configuration.PgSql.Variables.AllKeys.ShouldBe(new[] { "pgsql1" }); + configuration.PgSql.Variables["pgsql1"].Value.ShouldBe("20"); } - private AppConfiguration LoadFromResource(string resourceName) + private static AppConfiguration LoadFromResource(string resourceName) { - var fileName = _temp.CopyFileFromResources(resourceName); - var configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = fileName }, ConfigurationUserLevel.None); - return (AppConfiguration)configuration.GetSection(AppConfiguration.SectionName); + using (var temp = new TempDirectory()) + { + var fileName = temp.CopyFileFromResources(resourceName); + var configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = fileName }, ConfigurationUserLevel.None); + return (AppConfiguration)configuration.GetSection(AppConfiguration.SectionName); + } } } } diff --git a/Sources/SqlDatabase.Test/Configuration/CommandLineBaseTest.cs b/Sources/SqlDatabase.Test/Configuration/CommandLineBaseTest.cs index bfdd3a89..e1c3add1 100644 --- a/Sources/SqlDatabase.Test/Configuration/CommandLineBaseTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/CommandLineBaseTest.cs @@ -1,10 +1,10 @@ using System; using System.Configuration; -using System.Data.SqlClient; using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.IO; +using SqlDatabase.TestApi; namespace SqlDatabase.Configuration { @@ -32,7 +32,7 @@ public void BeforeEachTest() _fs = new Mock(MockBehavior.Strict); _sut = new Mock { CallBase = true }.Object; - _sut.Connection = new SqlConnectionStringBuilder(); + _sut.ConnectionString = MsSqlQuery.ConnectionString; _sut.FileSystemFactory = _fs.Object; } @@ -42,8 +42,7 @@ public void CreateDatabase() var actual = _sut.CreateDatabase(_log.Object, _configurationManager.Object, TransactionMode.PerStep, true); actual.Log.ShouldBe(_log.Object); - actual.ConnectionString.ShouldNotBeNull(); - actual.Configuration.ShouldBe(_configuration); + actual.Adapter.ShouldNotBeNull(); actual.Transaction.ShouldBe(TransactionMode.PerStep); actual.WhatIf.ShouldBeTrue(); } diff --git a/Sources/SqlDatabase.Test/Configuration/CommandLineParserTest.cs b/Sources/SqlDatabase.Test/Configuration/CommandLineParserTest.cs index 71ad7380..dd34c5aa 100644 --- a/Sources/SqlDatabase.Test/Configuration/CommandLineParserTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/CommandLineParserTest.cs @@ -14,30 +14,14 @@ public void BeforeEachTest() _sut = new CommandLineParser(); } - [Test] - [TestCase("-preFormatOutputLogs", true)] - [TestCase("-preFormatOutputLogs=true", true)] - [TestCase("-preFormatOutputLogs=false", false)] - [TestCase("preFormatOutputLogs", false)] - [TestCase("preFormatOutputLogs=true", false)] - public void PreFormatOutputLogs(string input, bool expected) - { - CommandLineParser.PreFormatOutputLogs(new[] { input }).ShouldBe(expected); - } - [Test] [TestCase("-x=y", "x", "y", true)] - [TestCase("+-x=eQ==", "x", "y", true)] [TestCase("x=y", null, "x=y", true)] [TestCase("-x", "x", null, true)] [TestCase("-x=", "x", null, true)] [TestCase("-=x", null, null, false)] [TestCase("-=", null, null, false)] [TestCase("-", null, null, false)] - [TestCase("+-", null, null, false)] - [TestCase("+", null, null, false)] - [TestCase("+x=y", null, null, false)] - [TestCase("+-x=y", null, null, false)] public void SplitArg(string keyValue, string expectedKey, string expectedValue, bool isValid) { CommandLineParser.ParseArg(keyValue, out var actual).ShouldBe(isValid); @@ -92,25 +76,10 @@ public void Parse() actual[4].Value.ShouldBe("folder 2"); } - [Test] - public void ParseRemovePreFormatOutputLogs() - { - var actual = _sut - .Parse( - "execute", - "-preFormatOutputLogs") - .Args; - - actual.Count.ShouldBe(1); - - actual[0].IsPair.ShouldBeFalse(); - actual[0].Value.ShouldBe("execute"); - } - [Test] public void ParseFail() { - Assert.Throws(() => _sut.Parse("+")); + Assert.Throws(() => _sut.Parse("-")); } } } diff --git a/Sources/SqlDatabase.Test/Configuration/CreateCommandLineTest.cs b/Sources/SqlDatabase.Test/Configuration/CreateCommandLineTest.cs index 0f6bf6f5..1e0f0dad 100644 --- a/Sources/SqlDatabase.Test/Configuration/CreateCommandLineTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/CreateCommandLineTest.cs @@ -1,10 +1,10 @@ -using System.Data.SqlClient; -using Moq; +using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Commands; using SqlDatabase.IO; using SqlDatabase.Scripts; +using SqlDatabase.TestApi; namespace SqlDatabase.Configuration { @@ -45,9 +45,7 @@ public void Parse() _sut.Scripts.ShouldBe(new[] { folder.Object }); - _sut.Connection.ShouldNotBeNull(); - _sut.Connection.DataSource.ShouldBe("."); - _sut.Connection.InitialCatalog.ShouldBe("test"); + _sut.ConnectionString.ShouldBe("Data Source=.;Initial Catalog=test"); _sut.Variables.Keys.ShouldBe(new[] { "X", "Y" }); _sut.Variables["x"].ShouldBe("1 2 3"); @@ -66,7 +64,7 @@ public void Parse() public void CreateCommand() { _sut.WhatIf = true; - _sut.Connection = new SqlConnectionStringBuilder(); + _sut.ConnectionString = MsSqlQuery.ConnectionString; _sut.UsePowerShell = @"c:\PowerShell"; var actual = _sut diff --git a/Sources/SqlDatabase.Test/Configuration/ExecuteCommandLineTest.cs b/Sources/SqlDatabase.Test/Configuration/ExecuteCommandLineTest.cs index 9316d95a..c370b8b5 100644 --- a/Sources/SqlDatabase.Test/Configuration/ExecuteCommandLineTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/ExecuteCommandLineTest.cs @@ -1,10 +1,10 @@ -using System.Data.SqlClient; -using Moq; +using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Commands; using SqlDatabase.IO; using SqlDatabase.Scripts; +using SqlDatabase.TestApi; namespace SqlDatabase.Configuration { @@ -53,9 +53,7 @@ public void Parse() _sut.Scripts[0].ShouldBe(folder.Object); _sut.Scripts[1].ShouldBe(sql.Object); - _sut.Connection.ShouldNotBeNull(); - _sut.Connection.DataSource.ShouldBe("."); - _sut.Connection.InitialCatalog.ShouldBe("test"); + _sut.ConnectionString.ShouldBe("Data Source=.;Initial Catalog=test"); _sut.Variables.Keys.ShouldBe(new[] { "X", "Y" }); _sut.Variables["x"].ShouldBe("1 2 3"); @@ -76,7 +74,7 @@ public void Parse() public void CreateCommand() { _sut.WhatIf = true; - _sut.Connection = new SqlConnectionStringBuilder(); + _sut.ConnectionString = MsSqlQuery.ConnectionString; _sut.UsePowerShell = @"c:\PowerShell"; var actual = _sut diff --git a/Sources/SqlDatabase.Test/Configuration/ExportCommandLineTest.cs b/Sources/SqlDatabase.Test/Configuration/ExportCommandLineTest.cs index eb5a3c06..2e3ee741 100644 --- a/Sources/SqlDatabase.Test/Configuration/ExportCommandLineTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/ExportCommandLineTest.cs @@ -1,5 +1,4 @@ -using System.Data.SqlClient; -using System.IO; +using System.IO; using Moq; using NUnit.Framework; using Shouldly; @@ -50,8 +49,7 @@ public void Parse() _sut.Scripts[0].ShouldBe(sql.Object); _sut.Scripts[1].ShouldBe(folder.Object); - _sut.Connection?.DataSource.ShouldBe("."); - _sut.Connection?.InitialCatalog.ShouldBe("test"); + _sut.ConnectionString.ShouldBe("Data Source=.;Initial Catalog=test"); _sut.DestinationTableName.ShouldBe("dbo.ExportedData"); _sut.DestinationFileName.ShouldBe("file path"); } @@ -59,7 +57,7 @@ public void Parse() [Test] public void CreateCommand() { - _sut.Connection = new SqlConnectionStringBuilder(); + _sut.ConnectionString = MsSqlQuery.ConnectionString; _sut.DestinationTableName = "table 1"; var actual = _sut diff --git a/Sources/SqlDatabase.Test/Configuration/GenericCommandLineBuilderTest.cs b/Sources/SqlDatabase.Test/Configuration/GenericCommandLineBuilderTest.cs index 41278a45..66f7cbed 100644 --- a/Sources/SqlDatabase.Test/Configuration/GenericCommandLineBuilderTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/GenericCommandLineBuilderTest.cs @@ -16,9 +16,9 @@ public void BeforeEachTest() } [Test] - public void EscapedCommandLine() + public void BuildArray() { - var escapedArgs = _sut + var args = _sut .SetCommand("some command") .SetConnection("Data Source=.;Initial Catalog=SqlDatabaseTest") .SetScripts("file1") @@ -28,18 +28,16 @@ public void EscapedCommandLine() .SetVariable("var1", "value 1") .SetWhatIf(true) .SetFolderAsModuleName(true) - .SetPreFormatOutputLogs(true) .SetLogFileName("log file") - .BuildArray(true); + .BuildArray(); - foreach (var arg in escapedArgs) + foreach (var arg in args) { Console.WriteLine(arg); } - CommandLineParser.PreFormatOutputLogs(escapedArgs).ShouldBeTrue(); - CommandLineParser.GetLogFileName(escapedArgs).ShouldBe("log file"); - var actual = new CommandLineParser().Parse(escapedArgs); + CommandLineParser.GetLogFileName(args).ShouldBe("log file"); + var actual = new CommandLineParser().Parse(args); actual.Args.Count.ShouldBe(9); @@ -77,7 +75,7 @@ public void BuildArrayScripts() var actual = _sut .SetScripts("file1") .SetScripts("file2") - .BuildArray(false); + .BuildArray(); actual.Length.ShouldBe(4); actual[2].ShouldBe("-from=file1"); @@ -90,7 +88,7 @@ public void BuildArrayInLineScripts() var actual = _sut .SetInLineScript("file1") .SetInLineScript("file2") - .BuildArray(false); + .BuildArray(); actual.Length.ShouldBe(4); actual[2].ShouldBe("-fromSql=file1"); @@ -102,7 +100,7 @@ public void BuildArrayExportToTable() { var actual = _sut .SetExportToTable("name") - .BuildArray(false); + .BuildArray(); actual.Length.ShouldBe(3); actual[2].ShouldBe("-toTable=name"); @@ -113,7 +111,7 @@ public void BuildArrayExportToFile() { var actual = _sut .SetExportToFile("file name") - .BuildArray(false); + .BuildArray(); actual.Length.ShouldBe(3); actual[2].ShouldBe("-toFile=file name"); diff --git a/Sources/SqlDatabase.Test/Configuration/UpgradeCommandLineTest.cs b/Sources/SqlDatabase.Test/Configuration/UpgradeCommandLineTest.cs index df5bb316..eaa6a050 100644 --- a/Sources/SqlDatabase.Test/Configuration/UpgradeCommandLineTest.cs +++ b/Sources/SqlDatabase.Test/Configuration/UpgradeCommandLineTest.cs @@ -1,10 +1,10 @@ -using System.Data.SqlClient; -using Moq; +using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Commands; using SqlDatabase.IO; using SqlDatabase.Scripts; +using SqlDatabase.TestApi; namespace SqlDatabase.Configuration { @@ -47,9 +47,7 @@ public void Parse() _sut.Scripts.ShouldBe(new[] { folder.Object }); - _sut.Connection.ShouldNotBeNull(); - _sut.Connection.DataSource.ShouldBe("."); - _sut.Connection.InitialCatalog.ShouldBe("test"); + _sut.ConnectionString.ShouldBe("Data Source=.;Initial Catalog=test"); _sut.Variables.Keys.ShouldBe(new[] { "X", "Y" }); _sut.Variables["x"].ShouldBe("1 2 3"); @@ -72,7 +70,7 @@ public void CreateCommand() { _sut.WhatIf = true; _sut.FolderAsModuleName = true; - _sut.Connection = new SqlConnectionStringBuilder(); + _sut.ConnectionString = MsSqlQuery.ConnectionString; _sut.UsePowerShell = @"c:\PowerShell"; var actual = _sut diff --git a/Sources/SqlDatabase.Test/Docker/docker-compose.yml b/Sources/SqlDatabase.Test/Docker/docker-compose.yml index 33028d2b..28c7e6d0 100644 --- a/Sources/SqlDatabase.Test/Docker/docker-compose.yml +++ b/Sources/SqlDatabase.Test/Docker/docker-compose.yml @@ -1,9 +1,8 @@ version: "3" services: - database: + mssql: image: microsoft/mssql-server-linux:latest restart: always - container_name: mssql environment: - ACCEPT_EULA=Y - SA_PASSWORD=P@ssw0rd @@ -13,4 +12,14 @@ services: ports: - 1433:1433 working_dir: /usr/src/app - command: bash -c ' chmod +x ./entrypoint.sh; ./entrypoint.sh & /opt/mssql/bin/sqlservr;' + command: bash -c ' chmod +x ./mssql.entrypoint.sh; ./mssql.entrypoint.sh & /opt/mssql/bin/sqlservr;' + + pgsql: + image: postgres + restart: always + environment: + POSTGRES_PASSWORD: qwerty + volumes: + - ./pgsql.create-database.sql:/docker-entrypoint-initdb.d/pgsql.create-database.sql + ports: + - 5432:5432 diff --git a/Sources/SqlDatabase.Test/Docker/CreateDatabase.sql b/Sources/SqlDatabase.Test/Docker/mssql.create-database.sql similarity index 62% rename from Sources/SqlDatabase.Test/Docker/CreateDatabase.sql rename to Sources/SqlDatabase.Test/Docker/mssql.create-database.sql index 89aa894d..1d54fa4b 100644 --- a/Sources/SqlDatabase.Test/Docker/CreateDatabase.sql +++ b/Sources/SqlDatabase.Test/Docker/mssql.create-database.sql @@ -1,6 +1,15 @@ USE master GO +EXEC sys.sp_configure N'show advanced options', N'1' RECONFIGURE WITH OVERRIDE +GO +EXEC sys.sp_configure N'max server memory (MB)', N'512' +GO +RECONFIGURE WITH OVERRIDE +GO +EXEC sys.sp_configure N'show advanced options', N'0' RECONFIGURE WITH OVERRIDE +GO + PRINT 'create database...' CREATE DATABASE SqlDatabaseTest GO diff --git a/Sources/SqlDatabase.Test/Docker/entrypoint.sh b/Sources/SqlDatabase.Test/Docker/mssql.entrypoint.sh similarity index 80% rename from Sources/SqlDatabase.Test/Docker/entrypoint.sh rename to Sources/SqlDatabase.Test/Docker/mssql.entrypoint.sh index caf95ad7..a1a3147a 100644 --- a/Sources/SqlDatabase.Test/Docker/entrypoint.sh +++ b/Sources/SqlDatabase.Test/Docker/mssql.entrypoint.sh @@ -2,4 +2,4 @@ sleep 5s # create database -/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P P@ssw0rd -l 60 -i ./CreateDatabase.sql \ No newline at end of file +/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P P@ssw0rd -l 60 -i ./mssql.create-database.sql \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/Docker/pgsql.create-database.sql b/Sources/SqlDatabase.Test/Docker/pgsql.create-database.sql new file mode 100644 index 00000000..ff741b56 --- /dev/null +++ b/Sources/SqlDatabase.Test/Docker/pgsql.create-database.sql @@ -0,0 +1,27 @@ +CREATE DATABASE sqldatabasetest; + +\connect sqldatabasetest; + +CREATE EXTENSION citext; + +CREATE TABLE public.version +( + module_name public.citext NOT NULL + ,version varchar(20) NOT NULL +); + +ALTER TABLE public.version + ADD CONSTRAINT pk_version PRIMARY KEY (module_name); + +INSERT INTO public.version (module_name, version) VALUES +('database', '1.0') +,('SomeModuleName', '2.0'); + + +CREATE TYPE public.mood AS ENUM ('sad', 'ok', 'happy'); + +CREATE TYPE public.inventory_item AS ( + name text, + supplier_id integer, + price numeric +); \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/Export/DataExporterTest.cs b/Sources/SqlDatabase.Test/Export/MsSqlDataExporterTest.cs similarity index 90% rename from Sources/SqlDatabase.Test/Export/DataExporterTest.cs rename to Sources/SqlDatabase.Test/Export/MsSqlDataExporterTest.cs index edc4b17b..471b5444 100644 --- a/Sources/SqlDatabase.Test/Export/DataExporterTest.cs +++ b/Sources/SqlDatabase.Test/Export/MsSqlDataExporterTest.cs @@ -6,12 +6,13 @@ using Moq; using NUnit.Framework; using Shouldly; +using SqlDatabase.Scripts.MsSql; using SqlDatabase.TestApi; namespace SqlDatabase.Export { [TestFixture] - public class DataExporterTest + public class MsSqlDataExporterTest { private StringBuilder _output; private DataExporter _sut; @@ -29,7 +30,7 @@ public void BeforeEachTest() _sut = new DataExporter { Log = log.Object, - Output = new SqlWriter(new StringWriter(_output)) + Output = new MsSqlWriter(new StringWriter(_output)) }; } @@ -38,7 +39,7 @@ public void BeforeEachTest() public void Export(string dataType, object minValue, object maxValue) { var sql = new StringBuilder(); - var script = new SqlWriter(new StringWriter(sql)) + var script = new MsSqlWriter(new StringWriter(sql)) .TextFormat("DECLARE @input TABLE(Value {0} NULL)", dataType) .Line() .Line("INSERT INTO @input VALUES"); @@ -49,7 +50,7 @@ public void Export(string dataType, object minValue, object maxValue) script.Text("SELECT * FROM @input"); - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = sql.ToString(); @@ -66,7 +67,7 @@ public void Export(string dataType, object minValue, object maxValue) exportSql.ShouldContain(" " + dataType + " "); - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = exportSql.Replace("GO", string.Empty) + "\r\n\r\nSELECT * FROM #tmp"; @@ -89,7 +90,7 @@ public void Export(string dataType, object minValue, object maxValue) [Test] public void ExportReplaceRowVersionWithVarbinary() { - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = @" @@ -100,7 +101,7 @@ insert into @x(Id) values(1) using (var reader = cmd.ExecuteReader()) { - var table = _sut.ReadSchemaTable(reader.GetSchemaTable(), "#tmp"); + var table = _sut.Output.ReadSchemaTable(reader.GetSchemaTable(), "#tmp"); table.Columns[1].SqlDataTypeName.ShouldBe("VARBINARY"); table.Columns[1].Size.ShouldBe(8); @@ -111,7 +112,7 @@ insert into @x(Id) values(1) var exportSql = _output.ToString(); Console.WriteLine(exportSql); - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = exportSql.Replace("GO", string.Empty) + "\r\n\r\nSELECT * FROM #tmp"; @@ -128,7 +129,7 @@ insert into @x(Id) values(1) [Test] public void ExportHierarchyId() { - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = @" @@ -139,7 +140,7 @@ insert into @x values('/1/') using (var reader = cmd.ExecuteReader()) { - Assert.Throws(() => _sut.ReadSchemaTable(reader.GetSchemaTable(), "#tmp")); + Assert.Throws(() => _sut.Output.ReadSchemaTable(reader.GetSchemaTable(), "#tmp")); } } } @@ -149,7 +150,7 @@ public void EmptySchemaTable() { ExportTable actual; - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = "select 1, N'2' x, NULL"; @@ -157,7 +158,7 @@ public void EmptySchemaTable() using (var reader = cmd.ExecuteReader()) { - actual = _sut.ReadSchemaTable(reader.GetSchemaTable(), "#tmp"); + actual = _sut.Output.ReadSchemaTable(reader.GetSchemaTable(), "#tmp"); } } @@ -182,7 +183,7 @@ public void InsertBatchSize() string slq500; string slq2; - using (var connection = new SqlConnection(Query.ConnectionString)) + using (var connection = new SqlConnection(MsSqlQuery.ConnectionString)) using (var cmd = connection.CreateCommand()) { cmd.CommandText = "select * from sys.databases"; diff --git a/Sources/SqlDatabase.Test/Export/PgSqlDataExporterTest.cs b/Sources/SqlDatabase.Test/Export/PgSqlDataExporterTest.cs new file mode 100644 index 00000000..ce5b89ec --- /dev/null +++ b/Sources/SqlDatabase.Test/Export/PgSqlDataExporterTest.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Dynamic; +using System.IO; +using System.Text; +using Moq; +using Npgsql; +using NpgsqlTypes; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Scripts.PgSql; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Export +{ + [TestFixture] + public class PgSqlDataExporterTest + { + private StringBuilder _output; + private DataExporter _sut; + + [SetUp] + public void BeforeEachTest() + { + _output = new StringBuilder(); + + var log = new Mock(MockBehavior.Strict); + log + .Setup(l => l.Info(It.IsAny())) + .Callback(m => Console.WriteLine("Info: {0}", m)); + + _sut = new DataExporter + { + Log = log.Object, + Output = new PgSqlWriter(new StringWriter(_output)) + }; + } + + [Test] + [TestCaseSource(nameof(GetExportCases))] + public void Export(string dataType, object minValue, object maxValue, bool allowNull, string expectedDataType) + { + var sql = new StringBuilder(); + var script = new PgSqlWriter(new StringWriter(sql)) + .TextFormat("CREATE TEMP TABLE input_data(value {0} {1});", dataType, allowNull ? "NULL" : null) + .Line() + .Line("INSERT INTO input_data VALUES"); + + script.Text("(").Value(minValue).Line(")"); + if (allowNull) + { + script.Text(",(").Value(maxValue).Line(")"); + script.Text(",(").Value(null).Line(");"); + } + else + { + script.Text(",(").Value(maxValue).Line(");"); + } + + script.Text("SELECT * FROM input_data;"); + + using (var connection = new NpgsqlConnection(PgSqlQuery.ConnectionString)) + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = sql.ToString(); + connection.Open(); + + using (var reader = cmd.ExecuteReader()) + { + _sut.Export(reader, "test_data"); + } + } + + var exportSql = _output.ToString(); + Console.WriteLine(exportSql); + + exportSql.ShouldContain(" " + (expectedDataType ?? dataType) + " "); + + using (var connection = new NpgsqlConnection(PgSqlQuery.ConnectionString)) + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = exportSql.Replace("CREATE TABLE", "CREATE TEMP TABLE") + "\r\n\r\nSELECT * FROM test_data;"; + connection.Open(); + + using (var reader = cmd.ExecuteReader()) + { + reader.Read().ShouldBeTrue(); + CompareValues(dataType, minValue, reader[0]); + + reader.Read().ShouldBeTrue(); + CompareValues(dataType, maxValue, reader[0]); + + if (allowNull) + { + reader.Read().ShouldBeTrue(); + reader[0].ShouldBe(DBNull.Value); + reader.Read().ShouldBeFalse(); + } + else + { + reader.Read().ShouldBeFalse(); + } + } + } + } + + private static void CompareValues(string dataType, object expected, object actual) + { + if (dataType.StartsWith("bit", StringComparison.OrdinalIgnoreCase) && actual is bool) + { + actual.ShouldBe(((BitArray)expected)[0]); + return; + } + + if (dataType.Equals("tsvector", StringComparison.OrdinalIgnoreCase)) + { + actual.ShouldBeOfType().ShouldBe(NpgsqlTsVector.Parse((string)expected)); + return; + } + + if (dataType.Equals("tsquery", StringComparison.OrdinalIgnoreCase)) + { + actual.ShouldBeAssignableTo().ToString().ShouldBe(NpgsqlTsQuery.Parse((string)expected).ToString()); + return; + } + + if (expected is IDictionary compositeExpected) + { + var compositeActual = actual.ShouldBeAssignableTo>(); + compositeActual.Keys.ShouldBe(compositeExpected.Keys); + foreach (var key in compositeExpected.Keys) + { + compositeActual[key].ShouldBe(compositeExpected[key]); + } + + return; + } + + actual.ShouldBe(expected); + } + + private static IEnumerable GetExportCases() + { + // Numeric Types + yield return new TestCaseData("smallint", short.MinValue, short.MaxValue, true, null) { TestName = "smallint" }; + yield return new TestCaseData("integer", int.MinValue, int.MaxValue, true, null) { TestName = "integer" }; + yield return new TestCaseData("bigint", long.MinValue, long.MaxValue, true, null) { TestName = "bigint" }; + yield return new TestCaseData("decimal", decimal.MinValue, decimal.MaxValue, true, "numeric") { TestName = "decimal" }; + yield return new TestCaseData("numeric", decimal.MinValue, decimal.MaxValue, true, null) { TestName = "numeric" }; + yield return new TestCaseData("real", -10.1F, 20.1F, true, null) { TestName = "real" }; + yield return new TestCaseData("double precision", double.MinValue, double.MaxValue, true, null) { TestName = "double precision" }; + + yield return new TestCaseData("smallserial", (short)0, short.MaxValue, false, "smallint") { TestName = "smallserial" }; + yield return new TestCaseData("serial", 0, int.MaxValue, false, "integer") { TestName = "serial" }; + yield return new TestCaseData("bigserial", 0L, long.MaxValue, false, "bigint") { TestName = "bigserial" }; + + yield return new TestCaseData("numeric(2)", -1m, 1m, true, null) { TestName = "numeric(2)" }; + yield return new TestCaseData("numeric(2,1)", -1.1m, 1.1m, true, null) { TestName = "numeric(2,1)" }; + + // Monetary Types + yield return new TestCaseData("money", -100.12m, 100.12m, true, null) { TestName = "money" }; + + // Character Types + yield return new TestCaseData("character varying", "abc", "d", true, null) { TestName = "character varying" }; + yield return new TestCaseData("varchar", "abc", "d", true, "character varying") { TestName = "varchar" }; + yield return new TestCaseData("character varying(3)", "abc", "d", true, null) { TestName = "character varying(3)" }; + yield return new TestCaseData("varchar(3)", "abc", "d", true, "character varying(3)") { TestName = "varchar(3)" }; + + yield return new TestCaseData("character", "a", "d", true, "character(1)") { TestName = "character" }; + yield return new TestCaseData("char", "a", "d", true, "character(1)") { TestName = "char" }; + yield return new TestCaseData("character(2)", "ab", "db", true, null) { TestName = "character(2)" }; + yield return new TestCaseData("char(2)", "ab", "db", true, "character(2)") { TestName = "char(2)" }; + + yield return new TestCaseData("text", "abc", "d", true, null) { TestName = "text" }; + + yield return new TestCaseData("name", "abc", "d", true, null) { TestName = "name" }; + + yield return new TestCaseData("citext", "abc", "d", true, "public.citext") { TestName = "citext" }; + yield return new TestCaseData("public.citext", "abc", "d", true, null) { TestName = "public.citext" }; + + // Binary Data Types + yield return new TestCaseData("bytea", new byte[0], new[] { byte.MinValue, byte.MaxValue, (byte)10 }, true, null) { TestName = "bytea" }; + + // Date/Time Types + var date = new DateTime(2021, 05, 13, 18, 31, 30, 10); + yield return new TestCaseData("timestamp", date, date, true, null) { TestName = "timestamp" }; + yield return new TestCaseData("timestamp(6)", date, date, true, null) { TestName = "timestamp(6)" }; + yield return new TestCaseData("date", date.Date, date.Date, true, null) { TestName = "date" }; + yield return new TestCaseData("time", date.TimeOfDay, date.TimeOfDay, true, null) { TestName = "time" }; + yield return new TestCaseData("time(6)", date.TimeOfDay, date.TimeOfDay, true, null) { TestName = "time(6)" }; + yield return new TestCaseData("interval", TimeSpan.Parse("3.04:05:06"), TimeSpan.Parse("04:05:06"), true, null) { TestName = "interval" }; + yield return new TestCaseData("interval(6)", TimeSpan.Parse("3.04:05:06"), TimeSpan.Parse("04:05:06"), true, null) { TestName = "interval(6)" }; + + // Boolean Type + yield return new TestCaseData("boolean", true, false, true, null) { TestName = "boolean" }; + + // UUID Type + yield return new TestCaseData("uuid", Guid.Empty, Guid.NewGuid(), true, null) { TestName = "uuid" }; + + // Bit String Types + yield return new TestCaseData("bit", new BitArray(new[] { true }), new BitArray(new[] { false }), true, "bit(1)") { TestName = "bit" }; + yield return new TestCaseData("bit(2)", new BitArray(new[] { false, true }), new BitArray(new[] { true, false }), true, null) { TestName = "bit(2)" }; + + // XML Type + yield return new TestCaseData("xml", "bar", "bar", true, null) { TestName = "xml" }; + + // JSON Types + yield return new TestCaseData("json", "{\"foo\": \"bar\"}", "{\"foo\": \"bar\"}", true, null) { TestName = "json" }; + yield return new TestCaseData("jsonb", "{\"foo\": \"bar\"}", "{\"foo\": \"bar\"}", true, null) { TestName = "jsonb" }; + + // Text Search Types + yield return new TestCaseData("tsvector", "a fat cat", "a fat cat", true, null) { TestName = "tsvector" }; + yield return new TestCaseData("tsquery", "fat & rat", "fat & rat", true, null) { TestName = "tsquery" }; + + // Enumerated Types + yield return new TestCaseData("public.mood", "ok", "happy", true, null) { TestName = "enum1" }; + yield return new TestCaseData("mood", "ok", "happy", true, "public.mood") { TestName = "enum2" }; + + // Arrays + yield return new TestCaseData("integer[]", new[] { 1, 2, 3 }, new[] { -1, -2, 3 }, true, null) { TestName = "integer[]" }; + yield return new TestCaseData("integer[3]", new[] { 1, 2, 3 }, new[] { -1, -2, 3 }, true, "integer[]") { TestName = "integer[3]" }; + + // Composite Types + IDictionary composite = new ExpandoObject(); + composite.Add("name", "fuzzy dice"); + composite.Add("supplier_id", 42); + composite.Add("price", 1.99); + yield return new TestCaseData("public.inventory_item", composite, composite, true, null) { TestName = "composite" }; + + // Range Types + yield return new TestCaseData("int4range", NpgsqlRange.Parse("[21,30)"), NpgsqlRange.Parse("[21,31)"), true, null) { TestName = "int4range" }; + } + } +} diff --git a/Sources/SqlDatabase.Test/Export/script.sql b/Sources/SqlDatabase.Test/Export/script.sql deleted file mode 100644 index 82e6e7c5..00000000 --- a/Sources/SqlDatabase.Test/Export/script.sql +++ /dev/null @@ -1,23 +0,0 @@ -IF (OBJECT_ID('dbo.ExportTest') IS NOT NULL) BEGIN - DROP TABLE dbo.ExportTest -END -GO - -CREATE TABLE dbo.ExportTest -( - Id INT NOT NULL IDENTITY(1, 1), - ColTinyInt TINYINT, - ColSmallInt SMALLINT, - ColBigInt BIGINT, - ColBit BIT, - ColMoneyDefault MONEY, - ColMoney MONEY, - ColNVarchar NVARCHAR(100), - CONSTRAINT [PK_ExportTest] PRIMARY KEY CLUSTERED (Id ASC) -) -GO - -INSERT INTO dbo.ExportTest(ColNVarchar) -VALUES ('NVarchar 1') - ,(NULL) -GO diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Execute/drop.database.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Execute/drop.database.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/Execute/drop.database.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Execute/drop.database.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Export/export.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Export/export.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/Export/export.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Export/export.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/01.Tables/01.Person.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.Tables/01.Person.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/01.Tables/01.Person.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.Tables/01.Person.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/01.Tables/02.PersonAddress.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.Tables/02.PersonAddress.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/01.Tables/02.PersonAddress.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.Tables/02.PersonAddress.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/01.create.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.create.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/01.create.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/01.create.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/02.Data/01.Person.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.Data/01.Person.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/02.Data/01.Person.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.Data/01.Person.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/02.Data/02.PersonAddress.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.Data/02.PersonAddress.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/02.Data/02.PersonAddress.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.Data/02.PersonAddress.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/02.schemas.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.schemas.ps1 similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/02.schemas.ps1 rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/02.schemas.ps1 diff --git a/Sources/SqlDatabase.Test/IntegrationTests/New/03.version.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/03.version.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/New/03.version.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/New/03.version.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/ProgramTest.cs b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/ProgramTest.cs similarity index 87% rename from Sources/SqlDatabase.Test/IntegrationTests/ProgramTest.cs rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/ProgramTest.cs index ba476cb9..75c0e778 100644 --- a/Sources/SqlDatabase.Test/IntegrationTests/ProgramTest.cs +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/ProgramTest.cs @@ -3,19 +3,21 @@ using System.IO; using System.Linq; using Dapper; +using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Configuration; using SqlDatabase.Scripts; +using SqlDatabase.Scripts.MsSql; using SqlDatabase.TestApi; using ConfigurationManager = System.Configuration.ConfigurationManager; -namespace SqlDatabase.IntegrationTests +namespace SqlDatabase.IntegrationTests.MsSql { [TestFixture] public class ProgramTest { - private readonly string _connectionString = new SqlConnectionStringBuilder(Query.ConnectionString) { InitialCatalog = "SqlDatabaseIT" }.ToString(); + private readonly string _connectionString = new SqlConnectionStringBuilder(MsSqlQuery.ConnectionString) { InitialCatalog = "SqlDatabaseIT" }.ToString(); private string _scriptsLocation; private AppConfiguration _configuration; @@ -26,7 +28,7 @@ public void BeforeEachTest() { TestPowerShellHost.GetOrCreateFactory(); - _scriptsLocation = ConfigurationManager.AppSettings["IntegrationTestsScriptsLocation"]; + _scriptsLocation = ConfigurationManager.AppSettings["MsSql.IntegrationTestsScriptsLocation"]; if (!Path.IsPathRooted(_scriptsLocation)) { _scriptsLocation = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _scriptsLocation); @@ -59,7 +61,7 @@ public void CreateDatabase() .SetVariable("JohnCity", "London") .SetVariable("MariaCity", "Paris") .SetLogFileName(_logFile.Location) - .BuildArray(false); + .BuildArray(); Assert.AreEqual(0, Program.Main(args)); @@ -69,12 +71,7 @@ FROM demo.Person Person INNER JOIN demo.PersonAddress PersonAddress ON (PersonAddress.PersonId = Person.Id) ORDER BY Person.Id"; - var db = new Database - { - ConnectionString = _connectionString, - Configuration = _configuration - }; - Assert.AreEqual(new Version("1.2"), db.GetCurrentVersion(null)); + Assert.AreEqual(new Version("1.2"), CreateDatabaseObject().GetCurrentVersion(null)); using (var c = new SqlConnection(_connectionString)) { @@ -100,10 +97,11 @@ public void UpgradeDatabase() .SetCommand(CommandLineFactory.CommandUpgrade) .SetConnection(_connectionString) .SetScripts(Path.Combine(_scriptsLocation, "upgrade")) + .SetConfigurationFile(Path.Combine(_scriptsLocation, "Upgrade", "SqlDatabase.exe.config")) .SetVariable("JohnSecondName", "Smitt") .SetVariable("MariaSecondName", "X") .SetLogFileName(_logFile.Location) - .BuildArray(false); + .BuildArray(); Assert.AreEqual(0, Program.Main(args)); @@ -112,12 +110,7 @@ public void UpgradeDatabase() FROM demo.Person Person ORDER BY Person.Id"; - var db = new Database - { - ConnectionString = _connectionString, - Configuration = _configuration - }; - Assert.AreEqual(new Version("2.1"), db.GetCurrentVersion(null)); + Assert.AreEqual(new Version("2.1"), CreateDatabaseObject().GetCurrentVersion(null)); using (var c = new SqlConnection(_connectionString)) { @@ -144,7 +137,7 @@ public void UpgradeDatabaseModularity() .SetConfigurationFile(Path.Combine(_scriptsLocation, "UpgradeModularity", "SqlDatabase.exe.config")) .SetLogFileName(_logFile.Location); - Program.Main(args.BuildArray(false)).ShouldBe(0); + Program.Main(args.BuildArray()).ShouldBe(0); const string Sql = @" SELECT p.Name, a.City @@ -155,11 +148,7 @@ FROM moduleA.Person p var configuration = new SqlDatabase.Configuration.ConfigurationManager(); configuration.LoadFrom(args.Line.ConfigurationFile); - var db = new Database - { - ConnectionString = _connectionString, - Configuration = configuration.SqlDatabase - }; + var db = CreateDatabaseObject(configuration.SqlDatabase); db.GetCurrentVersion("ModuleA").ShouldBe(new Version("2.0")); db.GetCurrentVersion("ModuleB").ShouldBe(new Version("1.1")); db.GetCurrentVersion("ModuleC").ShouldBe(new Version("2.0")); @@ -188,7 +177,7 @@ public void ExportDataToConsole() .SetConnection(_connectionString) .SetScripts(Path.Combine(_scriptsLocation, @"Export\export.sql")) .SetExportToTable("dbo.ExportedData1") - .BuildArray(false); + .BuildArray(); int exitCode; string output; @@ -227,7 +216,7 @@ public void ExportDataToFile() .SetScripts(Path.Combine(_scriptsLocation, @"Export\export.sql")) .SetExportToTable("dbo.ExportedData2") .SetExportToFile(output.Location) - .BuildArray(false); + .BuildArray(); Program.Main(args).ShouldBe(0); Console.WriteLine(File.ReadAllText(output.Location)); @@ -255,7 +244,7 @@ public void ExecuteScript() var sql = "SELECT DB_ID('{0}')".FormatWith(new SqlConnectionStringBuilder(_connectionString).InitialCatalog); - using (var c = new SqlConnection(Query.ConnectionString)) + using (var c = new SqlConnection(MsSqlQuery.ConnectionString)) { c.Open(); @@ -272,9 +261,17 @@ private void InvokeExecuteCommand(Action builder) .SetLogFileName(_logFile.Location); builder(cmd); - var args = cmd.BuildArray(false); + var args = cmd.BuildArray(); Program.Main(args).ShouldBe(0); } + + private IDatabase CreateDatabaseObject(AppConfiguration configuration = null) + { + return new Database + { + Adapter = new MsSqlDatabaseAdapter(_connectionString, configuration ?? _configuration, new Mock(MockBehavior.Strict).Object) + }; + } } } diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Test.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.ps1 similarity index 92% rename from Sources/SqlDatabase.Test/IntegrationTests/Test.ps1 rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.ps1 index 40e01a49..685c9bd5 100644 --- a/Sources/SqlDatabase.Test/IntegrationTests/Test.ps1 +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.ps1 @@ -17,10 +17,12 @@ exec { Write-Host "----- update database ---" $scripts = Join-Path $PSScriptRoot "Upgrade" +$configuration = (Join-Path $scripts "SqlDatabase.exe.config") exec { & $app upgrade ` "-database=$connectionString" ` "-from=$scripts" ` + "-configuration=$configuration" ` -varJohnSecondName=Smitt ` -varMariaSecondName=X } diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Test.sh b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.sh similarity index 94% rename from Sources/SqlDatabase.Test/IntegrationTests/Test.sh rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.sh index 88a9e1fb..b1afc122 100644 --- a/Sources/SqlDatabase.Test/IntegrationTests/Test.sh +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Test.sh @@ -11,6 +11,7 @@ echo "----- update database ---" dotnet SqlDatabase.dll upgrade \ "-database=$connectionString" \ -from=$test/Upgrade \ + -configuration=$test/Upgrade/SqlDatabase.exe.config \ -varJohnSecondName=Smitt \ -varMariaSecondName=X \ -log=/upgrade.log diff --git a/Sources/SqlDatabase.Test/IntegrationTests/TestGlobalTool.sh b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestGlobalTool.sh similarity index 94% rename from Sources/SqlDatabase.Test/IntegrationTests/TestGlobalTool.sh rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestGlobalTool.sh index 6fd84632..27b12269 100644 --- a/Sources/SqlDatabase.Test/IntegrationTests/TestGlobalTool.sh +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestGlobalTool.sh @@ -14,6 +14,7 @@ echo "----- update database ---" SqlDatabase upgrade \ "-database=$connectionString" \ -from=$test/Upgrade \ + -configuration=$test/Upgrade/SqlDatabase.exe.config \ -varJohnSecondName=Smitt \ -varMariaSecondName=X \ -log=/upgrade.log diff --git a/Sources/SqlDatabase.Test/IntegrationTests/TestPowerShell.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestPowerShell.ps1 similarity index 85% rename from Sources/SqlDatabase.Test/IntegrationTests/TestPowerShell.ps1 rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestPowerShell.ps1 index 3661e394..a55e158d 100644 --- a/Sources/SqlDatabase.Test/IntegrationTests/TestPowerShell.ps1 +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/TestPowerShell.ps1 @@ -4,6 +4,9 @@ $connectionString = $env:connectionString Import-Module "SqlDatabase" +Write-Host "----- info ---" +Show-SqlDatabaseInfo + Write-Host "----- create new database ---" Create-SqlDatabase ` -database $connectionString ` @@ -14,7 +17,8 @@ Write-Host "----- update database ---" Upgrade-SqlDatabase ` -database $connectionString ` -from "Upgrade" ` - -var JohnSecondName=Smitt,MariaSecondName=X + -var JohnSecondName=Smitt,MariaSecondName=X ` + -configuration "Upgrade/SqlDatabase.exe.config" Write-Host "----- update database (modularity) ---" Upgrade-SqlDatabase ` diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Upgrade/1.0_1.2.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/1.0_1.2.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/Upgrade/1.0_1.2.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/1.0_1.2.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Upgrade/1.2_2.0.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/1.2_2.0.ps1 similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/Upgrade/1.2_2.0.ps1 rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/1.2_2.0.ps1 diff --git a/Sources/SqlDatabase.Test/IntegrationTests/Upgrade/2.0_2.1.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/2.0_2.1.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/Upgrade/2.0_2.1.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/2.0_2.1.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/SqlDatabase.exe.config b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/SqlDatabase.exe.config new file mode 100644 index 00000000..e56adc44 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/Upgrade/SqlDatabase.exe.config @@ -0,0 +1,12 @@ + + + +
+ + + + + + \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/SqlDatabase.exe.config b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/SqlDatabase.exe.config new file mode 100644 index 00000000..3038245d --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/SqlDatabase.exe.config @@ -0,0 +1,12 @@ + + + +
+ + + + + + \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleA_1.0_2.0.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleA_1.0_2.0.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleA_1.0_2.0.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleA_1.0_2.0.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleB_1.0_1.1.sql b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleB_1.0_1.1.sql similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleB_1.0_1.1.sql rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleB_1.0_1.1.sql diff --git a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleC_1.0_2.0.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleC_1.0_2.0.ps1 similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleC_1.0_2.0.ps1 rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleC_1.0_2.0.ps1 diff --git a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleC_1.0_2.0.txt b/Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleC_1.0_2.0.txt similarity index 100% rename from Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/moduleC_1.0_2.0.txt rename to Sources/SqlDatabase.Test/IntegrationTests/MsSql/UpgradeModularity/moduleC_1.0_2.0.txt diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Execute/drop.database.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Execute/drop.database.ps1 new file mode 100644 index 00000000..4e1e640b --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Execute/drop.database.ps1 @@ -0,0 +1,13 @@ +[CmdletBinding()] +param ( + $Command, + $Variables +) + +$Command.Connection.ChangeDatabase("postgres"); + +Write-Information ("drop " + $Variables.DatabaseName) + +$Command.CommandText = ("DROP DATABASE {0} WITH (FORCE)" -f $Variables.DatabaseName) +$Command.ExecuteNonQuery() + diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Export/export.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Export/export.sql new file mode 100644 index 00000000..bc336a2e --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Export/export.sql @@ -0,0 +1,5 @@ +SELECT person.id + ,person.name || person.second_name AS name + ,address.city +FROM demo.person person +LEFT JOIN demo.person_address address ON person.id = address.person_id \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/01.person.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/01.person.sql new file mode 100644 index 00000000..5d09a54a --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/01.person.sql @@ -0,0 +1,7 @@ +CREATE TABLE demo.person +( + id serial + ,name varchar(250) NOT NULL +); + +ALTER TABLE demo.person ADD CONSTRAINT pk_demo_person PRIMARY KEY (id); diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/02.person_address.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/02.person_address.sql new file mode 100644 index 00000000..71204487 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.Tables/02.person_address.sql @@ -0,0 +1,10 @@ +CREATE TABLE demo.person_address +( + id serial + ,person_id integer NOT NULL + ,city varchar(250) NOT NULL +); + +ALTER TABLE demo.person_address ADD CONSTRAINT pk_demo_person_address PRIMARY KEY (id); + +ALTER TABLE demo.person_address ADD CONSTRAINT fk_demo_person_address_person FOREIGN KEY (person_id) REFERENCES demo.person (id); diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.drop.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.drop.ps1 new file mode 100644 index 00000000..efc0567e --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/01.drop.ps1 @@ -0,0 +1,10 @@ +[CmdletBinding()] +param ( + $Command, + $Variables +) + +$Command.Connection.ChangeDatabase("postgres"); + +$Command.CommandText = ("DROP DATABASE IF EXISTS {0} WITH (FORCE)" -f $Variables.DatabaseName) +$Command.ExecuteNonQuery() \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/01.person.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/01.person.sql new file mode 100644 index 00000000..1de9037f --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/01.person.sql @@ -0,0 +1,4 @@ +INSERT INTO demo.person(name) +VALUES ('John'), ('Maria'); + +SELECT * FROM demo.person; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/02.person_address.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/02.person_address.sql new file mode 100644 index 00000000..42709b41 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.Data/02.person_address.sql @@ -0,0 +1,11 @@ +INSERT INTO demo.person_address(person_id, city) +SELECT person.id, '{{JohnCity}}' +FROM demo.person person +WHERE person.Name = 'John'; + +INSERT INTO demo.person_address(person_id, city) +SELECT person.id, '{{MariaCity}}' +FROM demo.person person +WHERE person.name = 'Maria'; + +SELECT * FROM demo.person_address; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.create.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.create.sql new file mode 100644 index 00000000..a2988970 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/02.create.sql @@ -0,0 +1 @@ +CREATE DATABASE {{DatabaseName}}; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/03.database_properties.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/03.database_properties.sql new file mode 100644 index 00000000..21d31686 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/03.database_properties.sql @@ -0,0 +1 @@ +CREATE EXTENSION citext; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/04.schemas.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/04.schemas.sql new file mode 100644 index 00000000..a6adc05b --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/04.schemas.sql @@ -0,0 +1 @@ +CREATE SCHEMA demo; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/05.version.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/05.version.sql new file mode 100644 index 00000000..0fae3adb --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/New/05.version.sql @@ -0,0 +1,14 @@ +CREATE TABLE public.version +( + module_name public.citext NOT NULL + ,version varchar(20) NOT NULL +); + +ALTER TABLE public.version + ADD CONSTRAINT pk_version PRIMARY KEY (module_name); + +INSERT INTO public.version (module_name, version) VALUES +('database', '1.2') +,('ModuleA', '1.0') +,('ModuleB', '1.0') +,('ModuleC', '1.0'); diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/ProgramTest.cs b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/ProgramTest.cs new file mode 100644 index 00000000..644eb630 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/ProgramTest.cs @@ -0,0 +1,278 @@ +using System; +using System.IO; +using System.Linq; +using Dapper; +using Moq; +using Npgsql; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Configuration; +using SqlDatabase.Scripts; +using SqlDatabase.Scripts.PgSql; +using SqlDatabase.TestApi; +using ConfigurationManager = System.Configuration.ConfigurationManager; + +namespace SqlDatabase.IntegrationTests.PgSql +{ + [TestFixture] + public class ProgramTest + { + private readonly string _connectionString = new NpgsqlConnectionStringBuilder(PgSqlQuery.ConnectionString) { Database = "sqldatabasetest_it" }.ToString(); + + private string _scriptsLocation; + private AppConfiguration _configuration; + private TempFile _logFile; + + [SetUp] + public void BeforeEachTest() + { + TestPowerShellHost.GetOrCreateFactory(); + + _scriptsLocation = ConfigurationManager.AppSettings["PgSql.IntegrationTestsScriptsLocation"]; + if (!Path.IsPathRooted(_scriptsLocation)) + { + _scriptsLocation = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _scriptsLocation); + } + + _configuration = new AppConfiguration(); + + _logFile = new TempFile(".log"); + } + + [TearDown] + public void AfterEachTest() + { + FileAssert.Exists(_logFile.Location); + var fileContent = File.ReadAllLines(_logFile.Location); + _logFile.Dispose(); + + fileContent.ShouldNotBeEmpty(); + } + + [Test] + [Order(1)] + + public void CreateDatabase() + { + var args = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandCreate) + .SetConnection(_connectionString) + .SetScripts(Path.Combine(_scriptsLocation, "new")) + .SetVariable("JohnCity", "London") + .SetVariable("MariaCity", "Paris") + .SetLogFileName(_logFile.Location) + .BuildArray(); + + Program.Main(args).ShouldBe(0); + + const string Sql = @" +SELECT person.id, person.name, person_address.city +FROM demo.person person + INNER JOIN demo.person_address person_address ON (person_address.person_id = person.id) +ORDER BY person.id"; + + CreateDatabaseObject().GetCurrentVersion(null).ShouldBe(new Version("1.2")); + + using (var c = new NpgsqlConnection(_connectionString)) + { + c.Open(); + + var rows = c.Query(Sql).ToList(); + Assert.AreEqual(2, rows.Count); + + Assert.AreEqual(1, rows[0].id); + Assert.AreEqual("John", rows[0].name); + Assert.AreEqual("London", rows[0].city); + + Assert.AreEqual(2, rows[1].id); + Assert.AreEqual("Maria", rows[1].name); + Assert.AreEqual("Paris", rows[1].city); + } + } + + [Test] + [Order(2)] + public void UpgradeDatabase() + { + var args = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandUpgrade) + .SetConnection(_connectionString) + .SetScripts(Path.Combine(_scriptsLocation, "upgrade")) + .SetConfigurationFile(Path.Combine(_scriptsLocation, "Upgrade", "SqlDatabase.exe.config")) + .SetVariable("JohnSecondName", "Smitt") + .SetVariable("MariaSecondName", "X") + .SetLogFileName(_logFile.Location) + .BuildArray(); + + Program.Main(args).ShouldBe(0); + + const string Sql = @" +SELECT person.id, person.second_name +FROM demo.person person +ORDER BY person.id"; + + CreateDatabaseObject().GetCurrentVersion(null).ShouldBe(new Version("2.1")); + + using (var c = new NpgsqlConnection(_connectionString)) + { + c.Open(); + var rows = c.Query(Sql).ToList(); + Assert.AreEqual(2, rows.Count); + + Assert.AreEqual(1, rows[0].id); + Assert.AreEqual("Smitt", rows[0].second_name); + + Assert.AreEqual(2, rows[1].id); + Assert.AreEqual("X", rows[1].second_name); + } + } + + [Test] + [Order(3)] + public void UpgradeDatabaseModularity() + { + var args = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandUpgrade) + .SetConnection(_connectionString) + .SetScripts(Path.Combine(_scriptsLocation, "UpgradeModularity")) + .SetConfigurationFile(Path.Combine(_scriptsLocation, "UpgradeModularity", "SqlDatabase.exe.config")) + .SetLogFileName(_logFile.Location); + + Program.Main(args.BuildArray()).ShouldBe(0); + + const string Sql = @" +SELECT p.name, a.city +FROM module_a.person p + LEFT JOIN module_b.person_address a ON a.person_id = p.id +ORDER BY p.name"; + + var configuration = new SqlDatabase.Configuration.ConfigurationManager(); + configuration.LoadFrom(args.Line.ConfigurationFile); + + var db = CreateDatabaseObject(configuration.SqlDatabase); + db.GetCurrentVersion("ModuleA").ShouldBe(new Version("2.0")); + db.GetCurrentVersion("ModuleB").ShouldBe(new Version("1.1")); + db.GetCurrentVersion("ModuleC").ShouldBe(new Version("2.0")); + + using (var c = new NpgsqlConnection(_connectionString)) + { + c.Open(); + var rows = c.Query(Sql).ToList(); + rows.Count.ShouldBe(2); + + Assert.AreEqual("John", rows[0].name); + Assert.AreEqual("London", rows[0].city); + + Assert.AreEqual("Maria", rows[1].name); + Assert.IsNull(rows[1].city); + } + } + + [Test] + [Order(4)] + public void ExportDataToConsole() + { + // export + var args = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandExport) + .SetConnection(_connectionString) + .SetScripts(Path.Combine(_scriptsLocation, @"Export\export.sql")) + .SetExportToTable("public.exported_data1") + .BuildArray(); + + int exitCode; + string output; + using (var console = new TempConsoleOut()) + { + exitCode = Program.Main(args); + output = console.GetOutput(); + } + + Console.WriteLine(output); + exitCode.ShouldBe(0); + + // exec + InvokeExecuteCommand(b => b.SetInLineScript(output)); + + // test + using (var c = new NpgsqlConnection(_connectionString)) + { + c.Open(); + + var test = c.ExecuteScalar("SELECT COUNT(1) FROM public.exported_data1"); + test.ShouldBe(2); + } + } + + [Test] + [Order(5)] + public void ExportDataToFile() + { + using (var output = new TempFile(".sql")) + { + // export + var args = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandExport) + .SetConnection(_connectionString) + .SetScripts(Path.Combine(_scriptsLocation, @"Export\export.sql")) + .SetExportToTable("public.exported_data2") + .SetExportToFile(output.Location) + .BuildArray(); + + Program.Main(args).ShouldBe(0); + Console.WriteLine(File.ReadAllText(output.Location)); + + // exec + InvokeExecuteCommand(b => b.SetScripts(output.Location)); + } + + // test + using (var c = new NpgsqlConnection(_connectionString)) + { + c.Open(); + + var test = c.ExecuteScalar("SELECT COUNT(1) FROM public.exported_data1"); + test.ShouldBe(2); + } + } + + [Test] + [Order(6)] + public void ExecuteScript() + { + InvokeExecuteCommand(b => + b.SetScripts(Path.Combine(_scriptsLocation, "execute", "drop.database.ps1"))); + + var sql = "SELECT 1 FROM PG_DATABASE WHERE LOWER(DATNAME) = LOWER('{0}')".FormatWith(new NpgsqlConnectionStringBuilder(_connectionString).Database); + + using (var c = new NpgsqlConnection(PgSqlQuery.ConnectionString)) + { + c.Open(); + + var test = c.ExecuteScalar(sql); + Assert.IsNull(test); + } + } + + private void InvokeExecuteCommand(Action builder) + { + var cmd = new GenericCommandLineBuilder() + .SetCommand(CommandLineFactory.CommandExecute) + .SetConnection(_connectionString) + .SetLogFileName(_logFile.Location); + + builder(cmd); + var args = cmd.BuildArray(); + + Program.Main(args).ShouldBe(0); + } + + private IDatabase CreateDatabaseObject(AppConfiguration configuration = null) + { + return new Database + { + Adapter = new PgSqlDatabaseAdapter(_connectionString, configuration ?? _configuration, new Mock(MockBehavior.Strict).Object) + }; + } + } +} diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.ps1 new file mode 100644 index 00000000..a5da93f2 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.ps1 @@ -0,0 +1,55 @@ +param ( + $app, + $connectionString +) + +$ErrorActionPreference = "Stop" + +Write-Host "----- create new database ---" +$scripts = Join-Path $PSScriptRoot "New" +exec { + & $app create ` + "-database=$connectionString" ` + "-from=$scripts" ` + -varJohnCity=London ` + -varMariaCity=Paris +} + +Write-Host "----- update database ---" +$scripts = Join-Path $PSScriptRoot "Upgrade" +$configuration = (Join-Path $scripts "SqlDatabase.exe.config") +exec { + & $app upgrade ` + "-database=$connectionString" ` + "-from=$scripts" ` + "-configuration=$configuration" ` + -varJohnSecondName=Smitt ` + -varMariaSecondName=X +} + +Write-Host "----- update database (modularity) ---" +$scripts = Join-Path $PSScriptRoot "UpgradeModularity" +$configuration = (Join-Path $scripts "SqlDatabase.exe.config") +exec { + & $app upgrade ` + "-database=$connectionString" ` + "-from=$scripts" ` + "-configuration=$configuration" +} + +Write-Host "----- export data ---" +$scripts = Join-Path $PSScriptRoot "Export/export.sql" +exec { + & $app export ` + "-database=$connectionString" ` + "-from=$scripts" ` + "-toTable=public.sqldatabase_export1" +} + +Write-Host "----- execute script ---" +$scripts = Join-Path $PSScriptRoot "execute/drop.database.ps1" +exec { + & $app execute ` + "-database=$connectionString" ` + "-from=$scripts" +} \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.sh b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.sh new file mode 100644 index 00000000..c31b42e0 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Test.sh @@ -0,0 +1,37 @@ +set -e +echo "----- create new database ---" +dotnet SqlDatabase.dll create \ + "-database=$connectionString" \ + -from=$test/New \ + -varJohnCity=London \ + -varMariaCity=Paris \ + -log=/create.log + +echo "----- update database ---" +dotnet SqlDatabase.dll upgrade \ + "-database=$connectionString" \ + -from=$test/Upgrade \ + -configuration=$test/Upgrade/SqlDatabase.exe.config \ + -varJohnSecondName=Smitt \ + -varMariaSecondName=X \ + -log=/upgrade.log + +echo "----- update database (modularity) ---" +dotnet SqlDatabase.dll upgrade \ + "-database=$connectionString" \ + -from=$test/UpgradeModularity \ + -configuration=$test/UpgradeModularity/SqlDatabase.exe.config \ + -log=/upgrade.log + +echo "----- export data ---" +dotnet SqlDatabase.dll export \ + "-database=$connectionString" \ + -from=$test/Export/export.sql \ + -toTable=public.sqldatabase_export1 \ + -log=/export.log + +echo "----- execute script ---" +dotnet SqlDatabase.dll execute \ + "-database=$connectionString" \ + -from=$test/execute/drop.database.ps1 \ + -log=/execute.log diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestGlobalTool.sh b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestGlobalTool.sh new file mode 100644 index 00000000..4d600a10 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestGlobalTool.sh @@ -0,0 +1,40 @@ +set -e +export PATH="$PATH:/root/.dotnet/tools" +dotnet tool install -g --add-source $app SqlDatabase.GlobalTool --version $packageVersion + +echo "----- create new database ---" +SqlDatabase create \ + "-database=$connectionString" \ + -from=$test/New \ + -varJohnCity=London \ + -varMariaCity=Paris \ + -log=/create.log + +echo "----- update database ---" +SqlDatabase upgrade \ + "-database=$connectionString" \ + -from=$test/Upgrade \ + -configuration=$test/Upgrade/SqlDatabase.exe.config \ + -varJohnSecondName=Smitt \ + -varMariaSecondName=X \ + -log=/upgrade.log + +echo "----- update database (modularity) ---" +SqlDatabase upgrade \ + "-database=$connectionString" \ + -from=$test/UpgradeModularity \ + -configuration=$test/UpgradeModularity/SqlDatabase.exe.config \ + -log=/upgrade.log + +echo "----- export data ---" +SqlDatabase export \ + "-database=$connectionString" \ + -from=$test/Export/export.sql \ + -toTable=public.sqldatabase_export1 \ + -log=/export.log + +echo "----- execute script ---" +SqlDatabase execute \ + "-database=$connectionString" \ + -from=$test/execute/drop.database.ps1 \ + -log=/execute.log diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestPowerShell.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestPowerShell.ps1 new file mode 100644 index 00000000..00d260e7 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/TestPowerShell.ps1 @@ -0,0 +1,38 @@ +$ErrorActionPreference = "Stop" + +$connectionString = $env:connectionString + +Import-Module "SqlDatabase" + +Write-Host "----- info ---" +Show-SqlDatabaseInfo + +Write-Host "----- create new database ---" +Create-SqlDatabase ` + -database $connectionString ` + -from "New" ` + -var JohnCity=London,MariaCity=Paris + +Write-Host "----- update database ---" +Upgrade-SqlDatabase ` + -database $connectionString ` + -from "Upgrade" ` + -var JohnSecondName=Smitt,MariaSecondName=X ` + -configuration "Upgrade/SqlDatabase.exe.config" + +Write-Host "----- update database (modularity) ---" +Upgrade-SqlDatabase ` + -database $connectionString ` + -from "UpgradeModularity" ` + -configuration "UpgradeModularity/SqlDatabase.exe.config" + +Write-Host "----- export data ---" +Export-SqlDatabase ` + -database $connectionString ` + -from "Export/export.sql" ` + -toTable "public.sqldatabase_export1" + +Write-Host "----- execute script ---" +Execute-SqlDatabase ` + -database $connectionString ` + -from "execute/drop.database.ps1" diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.0_1.2.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.0_1.2.sql new file mode 100644 index 00000000..56b63fd1 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.0_1.2.sql @@ -0,0 +1,3 @@ +/* should neve be executed: current version is 1.2 */ + +DROP DATABASE {{DbName}}; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.2_2.0.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.2_2.0.ps1 new file mode 100644 index 00000000..9f3a2c38 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/1.2_2.0.ps1 @@ -0,0 +1,8 @@ +[CmdletBinding(SupportsShouldProcess=$true)] +param ( + $Command, + $Variables +) + +$Command.CommandText = "ALTER TABLE demo.person ADD second_name varchar(250) NULL" +$Command.ExecuteNonQuery() diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/2.0_2.1.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/2.0_2.1.sql new file mode 100644 index 00000000..ff3d8db2 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/2.0_2.1.sql @@ -0,0 +1,9 @@ +UPDATE demo.person +SET second_name = '{{JohnSecondName}}' +WHERE name = 'John'; + +UPDATE demo.person +SET second_name = '{{MariaSecondName}}' +WHERE name = 'Maria'; + +SELECT * FROM demo.person; \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/SqlDatabase.exe.config b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/SqlDatabase.exe.config new file mode 100644 index 00000000..59c8532f --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/Upgrade/SqlDatabase.exe.config @@ -0,0 +1,12 @@ + + + +
+ + + + + + \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/SqlDatabase.exe.config b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/SqlDatabase.exe.config new file mode 100644 index 00000000..ffb94e82 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/SqlDatabase.exe.config @@ -0,0 +1,12 @@ + + + +
+ + + + + + \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleA_1.0_2.0.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleA_1.0_2.0.sql new file mode 100644 index 00000000..2d46cd03 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleA_1.0_2.0.sql @@ -0,0 +1,10 @@ +CREATE SCHEMA module_a; + +CREATE TABLE module_a.person +( + id serial + ,name varchar(250) NOT NULL +); + +ALTER TABLE module_a.person ADD CONSTRAINT pk_module_a_person PRIMARY KEY (id); + diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleB_1.0_1.1.sql b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleB_1.0_1.1.sql new file mode 100644 index 00000000..a889939a --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleB_1.0_1.1.sql @@ -0,0 +1,15 @@ +-- module dependency: moduleA 2.0 +; + +CREATE SCHEMA module_b; + +CREATE TABLE module_b.person_address +( + id serial + ,person_id integer NOT NULL + ,city varchar(250) NOT NULL +); + +ALTER TABLE module_b.person_address ADD CONSTRAINT pk_module_b_person_address PRIMARY KEY (id); + +ALTER TABLE module_b.person_address ADD CONSTRAINT fk_module_b_person_address_person FOREIGN KEY (person_id) REFERENCES module_a.person (id); diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.ps1 b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.ps1 new file mode 100644 index 00000000..35f16d48 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.ps1 @@ -0,0 +1,11 @@ +[CmdletBinding(SupportsShouldProcess=$true)] +param ( + $Command, + $Variables +) + +$Command.CommandText = "INSERT INTO module_a.person(name) VALUES ('John'), ('Maria')" +$Command.ExecuteNonQuery() + +$Command.CommandText = "INSERT INTO module_b.person_address(person_id, city) SELECT person.id, 'London' FROM demo.person person WHERE person.name = 'John'" +$Command.ExecuteNonQuery() diff --git a/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.txt b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.txt new file mode 100644 index 00000000..b80df4a4 --- /dev/null +++ b/Sources/SqlDatabase.Test/IntegrationTests/PgSql/UpgradeModularity/moduleC_1.0_2.0.txt @@ -0,0 +1,2 @@ +-- module dependency: moduleA 2.0 +-- module dependency: moduleB 1.1 diff --git a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/SqlDatabase.exe.config b/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/SqlDatabase.exe.config deleted file mode 100644 index 0245f4d6..00000000 --- a/Sources/SqlDatabase.Test/IntegrationTests/UpgradeModularity/SqlDatabase.exe.config +++ /dev/null @@ -1,15 +0,0 @@ - - - -
- - - - - - - - \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/EntryPointResolverTest.cs b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/EntryPointResolverTest.cs index 97b89097..f068cc5d 100644 --- a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/EntryPointResolverTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/EntryPointResolverTest.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Moq; using NUnit.Framework; +using Shouldly; namespace SqlDatabase.Scripts.AssemblyInternal { @@ -35,9 +36,14 @@ public void BeforeEachTest() } [Test] - public void ResolveFromExample() + [TestCase(nameof(ExampleSqlDatabaseScript))] + [TestCase(nameof(EntryPointResolverTest) + "+" + nameof(ExampleSqlDatabaseScript))] + [TestCase("AssemblyInternal." + nameof(EntryPointResolverTest) + "+" + nameof(ExampleSqlDatabaseScript))] + [TestCase("Scripts.AssemblyInternal." + nameof(EntryPointResolverTest) + "+" + nameof(ExampleSqlDatabaseScript))] + [TestCase("SqlDatabase.Scripts.AssemblyInternal." + nameof(EntryPointResolverTest) + "+" + nameof(ExampleSqlDatabaseScript))] + public void ResolveFromExample(string className) { - _sut.ExecutorClassName = nameof(ExampleSqlDatabaseScript); + _sut.ExecutorClassName = className; _sut.ExecutorMethodName = nameof(ExampleSqlDatabaseScript.Execute); var actual = _sut.Resolve(GetType().Assembly); @@ -45,9 +51,9 @@ public void ResolveFromExample() Assert.IsInstanceOf(actual); var entryPoint = (DefaultEntryPoint)actual; - Assert.IsNotNull(entryPoint.Log); - Assert.IsInstanceOf(entryPoint.ScriptInstance); - Assert.AreEqual(nameof(ExampleSqlDatabaseScript.Execute), entryPoint.Method.Method.Name); + entryPoint.Log.ShouldNotBeNull(); + entryPoint.ScriptInstance.ShouldBeOfType(); + entryPoint.Method.Method.Name.ShouldBe(nameof(ExampleSqlDatabaseScript.Execute)); } [Test] diff --git a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.StepWithSubDomain.cs b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.StepWithSubDomain.cs index 8a22bd59..c1552f81 100644 --- a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.StepWithSubDomain.cs +++ b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.StepWithSubDomain.cs @@ -1,4 +1,4 @@ -#if NET452 +#if NET472 using System; using System.Data; using System.IO; @@ -26,7 +26,7 @@ public void ShowConfiguration(IDbCommand command) command.CommandText = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; command.ExecuteNonQuery(); - command.CommandText = Query.ConnectionString; + command.CommandText = MsSqlQuery.ConnectionString; command.ExecuteNonQuery(); } diff --git a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.cs b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.cs index e84d0552..34d6f8fa 100644 --- a/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/AssemblyInternal/Net452/Net452SubDomainTest.cs @@ -1,4 +1,4 @@ -#if NET452 +#if NET472 using System; using System.Collections.Generic; using System.Data; @@ -58,7 +58,7 @@ public void AfterEachTest() [Test] public void ValidateScriptDomainAppBase() { - _sut.ResolveScriptExecutor(typeof(StepWithSubDomain).Name, nameof(StepWithSubDomain.ShowAppBase)); + _sut.ResolveScriptExecutor(nameof(StepWithSubDomain), nameof(StepWithSubDomain.ShowAppBase)); _sut.Execute(new DbCommandStub(_command.Object), _variables); _sut.Unload(); _sut.Dispose(); @@ -77,7 +77,7 @@ public void ValidateScriptDomainAppBase() [Test] public void ValidateScriptDomainConfiguration() { - _sut.ResolveScriptExecutor(typeof(StepWithSubDomain).Name, nameof(StepWithSubDomain.ShowConfiguration)); + _sut.ResolveScriptExecutor(nameof(StepWithSubDomain), nameof(StepWithSubDomain.ShowConfiguration)); _sut.Execute(new DbCommandStub(_command.Object), _variables); _sut.Unload(); _sut.Dispose(); @@ -88,13 +88,13 @@ public void ValidateScriptDomainConfiguration() configurationFile.ShouldBe(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); var connectionString = _executedScripts[1]; - connectionString.ShouldBe(Query.ConnectionString); + connectionString.ShouldBe(MsSqlQuery.ConnectionString); } [Test] public void ValidateScriptDomainCreateSubDomain() { - _sut.ResolveScriptExecutor(typeof(StepWithSubDomain).Name, nameof(StepWithSubDomain.Execute)); + _sut.ResolveScriptExecutor(nameof(StepWithSubDomain), nameof(StepWithSubDomain.Execute)); _sut.Execute(new DbCommandStub(_command.Object), _variables); _executedScripts.Count.ShouldBe(1); diff --git a/Sources/SqlDatabase.Test/Scripts/AssemblyScriptTest.cs b/Sources/SqlDatabase.Test/Scripts/AssemblyScriptTest.cs index 130e7d03..bc1b2f11 100644 --- a/Sources/SqlDatabase.Test/Scripts/AssemblyScriptTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/AssemblyScriptTest.cs @@ -46,8 +46,10 @@ public void BeforeEachTest() } [Test] - public void ExecuteExample() + public void ExecuteExampleMsSql() { + _sut.Configuration.ClassName = "MsSql.SqlDatabaseScript"; + _variables.DatabaseName = "dbName"; _variables.CurrentVersion = "1.0"; _variables.TargetVersion = "2.0"; @@ -64,9 +66,7 @@ public void ExecuteExample() _logOutput.ShouldContain("start execution"); - _executedScripts.ShouldContain("print 'current database name is dbName'"); - _executedScripts.ShouldContain("print 'version from 1.0'"); - _executedScripts.ShouldContain("print 'version to 2.0'"); + _executedScripts.ShouldContain("print 'upgrade database dbName from version 1.0 to 2.0'"); _executedScripts.ShouldContain("create table dbo.DemoTable (Id INT)"); _executedScripts.ShouldContain("print 'drop table DemoTable'"); @@ -75,6 +75,36 @@ public void ExecuteExample() _logOutput.ShouldContain("finish execution"); } + [Test] + public void ExecuteExamplePgSql() + { + _sut.Configuration.ClassName = "PgSql.SqlDatabaseScript"; + + _variables.DatabaseName = "dbName"; + _variables.CurrentVersion = "1.0"; + _variables.TargetVersion = "2.0"; + + _sut.DisplayName = "2.1_2.2.dll"; + _sut.ReadAssemblyContent = () => File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "2.1_2.2.dll")); + +#if !NET452 + using (new ConsoleListener(_log.Object)) +#endif + { + _sut.Execute(new DbCommandStub(_command.Object), _variables, _log.Object); + } + + _logOutput.ShouldContain("start execution"); + + _executedScripts.Count.ShouldBe(4); + _executedScripts[0].ShouldContain("upgrade database dbName from version 1.0 to 2.0"); + _executedScripts[1].ShouldContain("create table public.demo_table (id integer)"); + _executedScripts[2].ShouldContain("'drop table demo_table'"); + _executedScripts[3].ShouldContain("drop table public.demo_table"); + + _logOutput.ShouldContain("finish execution"); + } + [Test] public void FailToResolveExecutor() { diff --git a/Sources/SqlDatabase.Test/Scripts/DatabaseAdapterFactoryTest.cs b/Sources/SqlDatabase.Test/Scripts/DatabaseAdapterFactoryTest.cs new file mode 100644 index 00000000..38114ed3 --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/DatabaseAdapterFactoryTest.cs @@ -0,0 +1,44 @@ +using System.Data.SqlClient; +using Moq; +using Npgsql; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Configuration; +using SqlDatabase.Scripts.MsSql; +using SqlDatabase.Scripts.PgSql; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts +{ + [TestFixture] + public class DatabaseAdapterFactoryTest + { + private ILogger _log; + private AppConfiguration _configuration; + + [SetUp] + public void BeforeEachTest() + { + _log = new Mock(MockBehavior.Strict).Object; + _configuration = new AppConfiguration(); + } + + [Test] + public void CreateMsSqlAdapter() + { + var actual = DatabaseAdapterFactory.CreateAdapter(MsSqlQuery.ConnectionString, _configuration, _log); + + var adapter = actual.ShouldBeOfType(); + adapter.DatabaseName.ShouldBe(new SqlConnectionStringBuilder(MsSqlQuery.ConnectionString).InitialCatalog); + } + + [Test] + public void CreatePgSqlAdapter() + { + var actual = DatabaseAdapterFactory.CreateAdapter(PgSqlQuery.ConnectionString, _configuration, _log); + + var adapter = actual.ShouldBeOfType(); + adapter.DatabaseName.ShouldBe(new NpgsqlConnectionStringBuilder(PgSqlQuery.ConnectionString).Database); + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/DatabaseTest.cs b/Sources/SqlDatabase.Test/Scripts/DatabaseTest.cs index b590161a..5ba2e97d 100644 --- a/Sources/SqlDatabase.Test/Scripts/DatabaseTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/DatabaseTest.cs @@ -1,24 +1,23 @@ using System; using System.Collections.Generic; using System.Data; -using System.Data.SqlClient; -using Dapper; +using System.Data.Common; +using System.Linq; using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Configuration; -using SqlDatabase.TestApi; namespace SqlDatabase.Scripts { [TestFixture] public class DatabaseTest { - private const string ModuleName = "SomeModuleName"; - private const string SelectModuleVersion = "SELECT value from sys.fn_listextendedproperty('version-{{ModuleName}}', default, default, default, default, default, default)"; - private const string UpdateModuleVersion = "EXEC sys.sp_updateextendedproperty @name=N'version-{{ModuleName}}', @value=N'{{TargetVersion}}'"; - private Database _sut; + private Mock _adapter; + private Mock _command; + private Mock _connection; + private Mock _transaction; private IList _logOutput; [SetUp] @@ -41,344 +40,440 @@ public void BeforeEachTest() _logOutput.Add(m); }); + _transaction = new Mock(MockBehavior.Strict); + _transaction + .Setup(t => t.Dispose()); + _transaction + .Setup(t => t.Commit()); + + _command = new Mock(MockBehavior.Strict); + _command + .SetupProperty(c => c.CommandText); + _command + .Setup(c => c.Dispose()); + + _connection = new Mock(MockBehavior.Strict); + _connection + .Setup(c => c.Open()); + _connection + .Setup(c => c.CreateCommand()) + .Returns(_command.Object); + _connection + .Setup(c => c.Dispose()); + + _adapter = new Mock(MockBehavior.Strict); + _sut = new Database { - ConnectionString = Query.ConnectionString, - Log = log.Object, - Configuration = new AppConfiguration() + Adapter = _adapter.Object, + Log = log.Object }; } [Test] - public void GetCurrentVersionDefault() + public void GetCurrentVersion() { - string expected; - using (var c = Query.Open()) - { - expected = c.ExecuteScalar(new AppConfiguration().GetCurrentVersionScript); - } + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => + { + _command.Object.CommandTimeout.ShouldBe(0); + _command.Object.CommandText.ShouldBe("select 1"); + }) + .Returns("1.1"); + + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select 1"); var actual = _sut.GetCurrentVersion(null); - Assert.AreEqual(new Version(expected), actual); - } - [Test] - public void GetCurrentVersionModuleName() - { - _sut.Configuration.GetCurrentVersionScript = SelectModuleVersion; - _sut.Configuration.SetCurrentVersionScript = UpdateModuleVersion; - - string expected; - using (var c = Query.Open()) - { - expected = c.ExecuteScalar(SelectModuleVersion.Replace("{{ModuleName}}", ModuleName)); - } + actual.ShouldBe(new Version("1.1")); - var actual = _sut.GetCurrentVersion(ModuleName); - Assert.AreEqual(new Version(expected), actual); + _adapter.VerifyAll(); + _connection.VerifyAll(); + _command.VerifyAll(); } [Test] - public void ExecuteUpgradeNoTransactionValidateCommand() + public void GetCurrentVersionModuleName() { - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => { - Assert.AreEqual(0, cmd.CommandTimeout); - Assert.IsNull(cmd.Transaction); - Assert.AreEqual(CommandType.Text, cmd.CommandType); - Assert.IsNotNull(cmd.Connection); - Assert.AreEqual(ConnectionState.Open, cmd.Connection.State); - - cmd.CommandText = "select DB_NAME()"; - StringAssert.AreEqualIgnoringCase(Query.DatabaseName, (string)cmd.ExecuteScalar()); - }); + _command.Object.CommandTimeout.ShouldBe(0); + _command.Object.CommandText.ShouldBe("select 'my module name'"); + }) + .Returns("1.1"); - _sut.Execute(script.Object, string.Empty, new Version("1.0"), new Version("1.0")); - script.VerifyAll(); - } + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select '{{ModuleName}}'"); - [Test] - public void ExecuteUpgradeTransactionPerStepValidateCommand() - { - _sut.Transaction = TransactionMode.PerStep; + var actual = _sut.GetCurrentVersion("my module name"); - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => - { - Assert.AreEqual(0, cmd.CommandTimeout); - Assert.IsNotNull(cmd.Transaction); - Assert.AreEqual(CommandType.Text, cmd.CommandType); - Assert.IsNotNull(cmd.Connection); - Assert.AreEqual(ConnectionState.Open, cmd.Connection.State); - - cmd.CommandText = "select DB_NAME()"; - StringAssert.AreEqualIgnoringCase(Query.DatabaseName, (string)cmd.ExecuteScalar()); - }); - - _sut.Execute(script.Object, string.Empty, new Version("1.0"), new Version("1.0")); + actual.ShouldBe(new Version("1.1")); - script.VerifyAll(); + _adapter.VerifyAll(); + _connection.VerifyAll(); + _command.VerifyAll(); } [Test] - public void ExecuteUpgradeTransactionPerStepRollbackOnError() + public void GetCurrentVersionInvalidScript() { - _sut.Transaction = TransactionMode.PerStep; + var ex = new Mock(); - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => - { - cmd.CommandText = "create table dbo.t1( Id INT )"; - cmd.ExecuteNonQuery(); + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .Setup(c => c.ExecuteScalar()) + .Throws(ex.Object); - throw new InvalidOperationException(); - }); + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select 1"); - Assert.Throws(() => _sut.Execute(script.Object, string.Empty, new Version("1.0"), new Version("1.0"))); - script.VerifyAll(); + var actual = Assert.Throws(() => _sut.GetCurrentVersion(null)); - using (var c = Query.Open()) - { - Assert.IsNull(c.ExecuteScalar("select OBJECT_ID('dbo.t1')")); - } + actual.InnerException.ShouldBe(ex.Object); + actual.Message.ShouldContain("select 1"); } [Test] - public void ExecuteUpgradeValidateVariables() + public void GetCurrentVersionInvalidVersion() { - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((_, vars, s) => - { - StringAssert.AreEqualIgnoringCase(Query.DatabaseName, vars.GetValue("DatabaseName")); - Assert.AreEqual("module name", vars.GetValue("ModuleName")); - Assert.AreEqual("1.0", vars.GetValue("CurrentVersion")); - Assert.AreEqual("2.0", vars.GetValue("TargetVersion")); - }); - - _sut.Execute(script.Object, "module name", new Version("1.0"), new Version("2.0")); - script.VerifyAll(); + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .Setup(c => c.ExecuteScalar()) + .Returns("abc"); + + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select 1"); + + var actual = Assert.Throws(() => _sut.GetCurrentVersion(null)); + + actual.Message.ShouldContain("abc"); } [Test] - public void ExecuteUpgradeWhatIf() + public void GetCurrentVersionModuleNameInvalidVersion() { - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(null, It.IsNotNull(), It.IsNotNull())); - - _sut.WhatIf = true; - _sut.Execute(script.Object, "module name", new Version("1.0"), new Version("2.0")); - script.VerifyAll(); - } - - [Test] - public void ExecuteUpgradeChangeDatabaseVersionNoModules() - { - var versionFrom = _sut.GetCurrentVersion(null); - var versionTo = new Version(versionFrom.Major + 1, 0); - - var script = new Mock(MockBehavior.Strict); - script.Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())); - - _sut.Execute(script.Object, null, versionFrom, versionTo); - script.VerifyAll(); - - Assert.AreEqual(versionTo, _sut.GetCurrentVersion(null)); + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .Setup(c => c.ExecuteScalar()) + .Returns("abc"); + + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select 1"); + + var actual = Assert.Throws(() => _sut.GetCurrentVersion("my module-name")); + + actual.Message.ShouldContain("abc"); + actual.Message.ShouldContain("my module-name"); } [Test] - public void ExecuteUpgradeChangeDatabaseVersionModuleName() + public void GetServerVersion() { - _sut.Configuration.GetCurrentVersionScript = SelectModuleVersion; - _sut.Configuration.SetCurrentVersionScript = UpdateModuleVersion; - - var versionFrom = _sut.GetCurrentVersion(ModuleName); - var versionTo = new Version(versionFrom.Major + 1, 0); + _adapter + .Setup(a => a.GetServerVersionSelectScript()) + .Returns("select server version"); + _adapter + .Setup(a => a.CreateConnection(true)) + .Returns(_connection.Object); + + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => + { + _command.Object.CommandText.ShouldBe("select server version"); + }) + .Returns("server version"); - var script = new Mock(MockBehavior.Strict); - script.Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())); + var actual = _sut.GetServerVersion(); - _sut.Execute(script.Object, ModuleName, versionFrom, versionTo); - script.VerifyAll(); - - Assert.AreEqual(versionTo, _sut.GetCurrentVersion(ModuleName)); + actual.ShouldBe("server version"); } [Test] - public void ExecuteUpgradeChangeDatabaseVersionValidateVersion() + [TestCase(TransactionMode.None)] + [TestCase(TransactionMode.PerStep)] + public void ExecuteUpgrade(TransactionMode transaction) { - _sut.Configuration.GetCurrentVersionScript = "SELECT '3.0'"; - _sut.Configuration.SetCurrentVersionScript = "SELECT 1"; + _sut.Transaction = transaction; - var script = new Mock(MockBehavior.Strict); - script.Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())); + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .SetupProperty(c => c.Transaction); - var ex = Assert.Throws(() => _sut.Execute(script.Object, null, new Version("1.0"), new Version("2.0"))); - script.VerifyAll(); + _connection + .Setup(c => c.BeginTransaction(IsolationLevel.ReadCommitted)) + .Returns(_transaction.Object); - ex.Message.ShouldContain("3.0"); - ex.Message.ShouldContain("2.0"); - } + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); - [Test] - public void SqlOutputIntoLog() - { var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, l) => + .Setup(s => s.Execute(_command.Object, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, variables, s) => { - _logOutput.Clear(); - cmd.CommandText = "print 'xx1xx'"; - cmd.ExecuteNonQuery(); - - Assert.AreEqual(1, _logOutput.Count); - StringAssert.Contains("xx1xx", _logOutput[0]); - - _logOutput.Clear(); - cmd.CommandText = "use master"; - cmd.ExecuteNonQuery(); + cmd.CommandTimeout.ShouldBe(0); - Assert.AreEqual(1, _logOutput.Count); - StringAssert.Contains("master", _logOutput[0]); + if (transaction == TransactionMode.PerStep) + { + cmd.Transaction.ShouldBe(_transaction.Object); + } + else + { + cmd.Transaction.ShouldBeNull(); + } + + variables.GetValue("DatabaseName").ShouldBe("database-name"); + variables.GetValue("CurrentVersion").ShouldBe("1.0"); + variables.GetValue("TargetVersion").ShouldBe("2.0"); + variables.GetValue("ModuleName").ShouldBe("my module"); + + _adapter + .Setup(a => a.GetVersionUpdateScript()) + .Returns("update version"); + _adapter + .Setup(a => a.GetVersionSelectScript()) + .Returns("select version"); + + _command + .Setup(c => c.ExecuteNonQuery()) + .Callback(() => _command.Object.CommandText.ShouldBe("update version")) + .Returns(0); + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => _command.Object.CommandText.ShouldBe("select version")) + .Returns("2.0"); }); - _sut.Execute(script.Object, null, new Version("1.0"), new Version("2.0")); + _sut.Execute(script.Object, "my module", new Version("1.0"), new Version("2.0")); script.VerifyAll(); + _command.VerifyAll(); } [Test] - public void ExecuteNoTransactionValidateCommand() + public void ExecuteUpgradeWhatIf() { + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); + var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => + .Setup(s => s.Execute(null, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, variables, s) => { - cmd.CommandTimeout.ShouldBe(0); - cmd.Transaction.ShouldBeNull(); - cmd.CommandType.ShouldBe(CommandType.Text); - cmd.Connection.ShouldNotBeNull(); - cmd.Connection.State.ShouldBe(ConnectionState.Open); - - cmd.CommandText = "select DB_NAME()"; - cmd.ExecuteScalar().ShouldBeOfType().ShouldBe(Query.DatabaseName, StringCompareShould.IgnoreCase); + variables.GetValue("DatabaseName").ShouldBe("database-name"); + variables.GetValue("CurrentVersion").ShouldBe("1.0"); + variables.GetValue("TargetVersion").ShouldBe("2.0"); + variables.GetValue("ModuleName").ShouldBe("my module"); }); - _sut.Execute(script.Object); + _sut.WhatIf = true; + + _sut.Execute(script.Object, "my module", new Version("1.0"), new Version("2.0")); script.VerifyAll(); + + _logOutput.Count.ShouldBe(1); + _logOutput[0].ShouldBe("what-if mode"); } [Test] - public void ExecuteTransactionPerStepValidateCommand() + [TestCase(TransactionMode.None)] + [TestCase(TransactionMode.PerStep)] + public void Execute(TransactionMode transaction) { + _sut.Transaction = transaction; + + _command + .SetupProperty(c => c.CommandTimeout, 30); + _command + .SetupProperty(c => c.Transaction); + + _connection + .Setup(c => c.BeginTransaction(IsolationLevel.ReadCommitted)) + .Returns(_transaction.Object); + + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); + _adapter + .Setup(a => a.GetDatabaseExistsScript("database-name")) + .Returns("database exits"); + _adapter + .Setup(a => a.CreateConnection(true)) + .Returns(_connection.Object); + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); + + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => _command.Object.CommandText.ShouldBe("database exits")) + .Returns("true"); + var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => + .Setup(s => s.Execute(_command.Object, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, variables, s) => { cmd.CommandTimeout.ShouldBe(0); - cmd.Transaction.ShouldNotBeNull(); - cmd.CommandType.ShouldBe(CommandType.Text); - cmd.Connection.ShouldNotBeNull(); - cmd.Connection.State.ShouldBe(ConnectionState.Open); - cmd.CommandText = "select DB_NAME()"; - cmd.ExecuteScalar().ShouldBeOfType().ShouldBe(Query.DatabaseName, StringCompareShould.IgnoreCase); + if (transaction == TransactionMode.PerStep) + { + cmd.Transaction.ShouldBe(_transaction.Object); + } + else + { + cmd.Transaction.ShouldBeNull(); + } + + variables.GetValue("DatabaseName").ShouldBe("database-name"); + variables.GetValue("CurrentVersion").ShouldBeNullOrEmpty(); + variables.GetValue("TargetVersion").ShouldBeNullOrEmpty(); + variables.GetValue("ModuleName").ShouldBeNullOrEmpty(); }); - _sut.Transaction = TransactionMode.PerStep; _sut.Execute(script.Object); script.VerifyAll(); + _command.VerifyAll(); } [Test] - public void ExecuteTransactionPerStepRollbackOnError() + public void ExecuteDatabaseNotFound() { + _command + .SetupProperty(c => c.Transaction); + _command + .SetupProperty(c => c.CommandTimeout, 30); + + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); + _adapter + .Setup(a => a.GetDatabaseExistsScript("database-name")) + .Returns("database exits"); + _adapter + .Setup(a => a.CreateConnection(true)) + .Returns(_connection.Object); + + _command + .Setup(c => c.ExecuteScalar()) + .Callback(() => _command.Object.CommandText.ShouldBe("database exits")) + .Returns(DBNull.Value); + var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, _, s) => + .Setup(s => s.Execute(_command.Object, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, v, s) => { - cmd.CommandText = "create table dbo.t1( Id INT )"; - cmd.ExecuteNonQuery(); - - throw new InvalidOperationException(); + cmd.CommandTimeout.ShouldBe(0); + cmd.Transaction.ShouldBeNull(); }); - _sut.Transaction = TransactionMode.PerStep; - Assert.Throws(() => _sut.Execute(script.Object)); + _sut.Execute(script.Object); script.VerifyAll(); - - using (var c = Query.Open()) - { - Assert.IsNull(c.ExecuteScalar("select OBJECT_ID('dbo.t1')")); - } + _command.VerifyAll(); + _adapter.VerifyAll(); } [Test] - public void ExecuteSetTargetDatabase() + public void ExecuteWhatIf() { - var currentDatabaseName = new SqlConnectionStringBuilder(_sut.ConnectionString).InitialCatalog; + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, vars, s) => + .Setup(s => s.Execute(null, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, variables, s) => { - cmd.CommandText = "select db_name()"; - StringAssert.AreEqualIgnoringCase(currentDatabaseName, (string)cmd.ExecuteScalar()); + variables.GetValue("DatabaseName").ShouldBe("database-name"); + variables.GetValue("CurrentVersion").ShouldBeNullOrEmpty(); + variables.GetValue("TargetVersion").ShouldBeNullOrEmpty(); + variables.GetValue("ModuleName").ShouldBeNullOrEmpty(); }); + _sut.WhatIf = true; + _sut.Execute(script.Object); + script.VerifyAll(); + + _logOutput.Count.ShouldBe(1); + _logOutput[0].ShouldBe("what-if mode"); } [Test] - public void ExecuteSetMasterDatabase() + public void ExecuteReader() { - var builder = new SqlConnectionStringBuilder(_sut.ConnectionString) - { - InitialCatalog = Guid.NewGuid().ToString() - }; + _command + .SetupProperty(c => c.CommandTimeout, 30); + + _adapter + .SetupGet(a => a.DatabaseName) + .Returns("database-name"); + _adapter + .Setup(a => a.CreateConnection(false)) + .Returns(_connection.Object); - _sut.ConnectionString = builder.ToString(); + var reader1 = new Mock(MockBehavior.Strict); + var reader2 = new Mock(MockBehavior.Strict); var script = new Mock(MockBehavior.Strict); script - .Setup(s => s.Execute(It.IsNotNull(), It.IsNotNull(), It.IsNotNull())) - .Callback((cmd, vars, s) => + .Setup(s => s.ExecuteReader(_command.Object, It.IsNotNull(), It.IsNotNull())) + .Callback((cmd, variables, s) => { - cmd.CommandText = "select db_name()"; - StringAssert.AreEqualIgnoringCase("master", (string)cmd.ExecuteScalar()); - }); + cmd.CommandTimeout.ShouldBe(0); + variables.GetValue("DatabaseName").ShouldBe("database-name"); + }) + .Returns(new[] { reader1.Object, reader2.Object }); - _sut.Execute(script.Object); - script.VerifyAll(); - } + var actual = _sut.ExecuteReader(script.Object).ToArray(); - [Test] - public void ExecuteWhatIf() - { - var script = new Mock(MockBehavior.Strict); - script - .Setup(s => s.Execute(null, It.IsNotNull(), It.IsNotNull())); + actual.ShouldBe(new[] { reader1.Object, reader2.Object }); - _sut.WhatIf = true; - _sut.Execute(script.Object); script.VerifyAll(); } } diff --git a/Sources/SqlDatabase.Test/Scripts/DependencyParserTest.cs b/Sources/SqlDatabase.Test/Scripts/DependencyParserTest.cs new file mode 100644 index 00000000..79b7c31e --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/DependencyParserTest.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Scripts.SqlTestCases; + +namespace SqlDatabase.Scripts +{ + [TestFixture] + public class DependencyParserTest + { + [Test] + [TestCaseSource(nameof(GetExtractDependenciesTestCases))] + public void ExtractDependencies(string sql, ScriptDependency[] expected) + { + var actual = DependencyParser.ExtractDependencies(new StringReader(sql), "file name").ToArray(); + actual.ShouldBe(expected); + } + + [Test] + [TestCase("1.a")] + [TestCase("10")] + public void ExtractDependenciesInvalidVersion(string versionText) + { + var input = "-- module dependency: moduleName " + versionText; + var ex = Assert.Throws(() => DependencyParser.ExtractDependencies(new StringReader(input), "file name").ToArray()); + + ex.Message.ShouldContain("moduleName"); + ex.Message.ShouldContain(versionText); + } + + private static IEnumerable GetExtractDependenciesTestCases() + { + foreach (var testCase in ResourceReader.Read("Dependencies")) + { + var expected = new List(); + foreach (var line in testCase.Expected) + { + if (!string.IsNullOrWhiteSpace(line)) + { + var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + parts.Length.ShouldBe(2); + expected.Add(new ScriptDependency(parts[0], new Version(parts[1]))); + } + } + + yield return new TestCaseData(testCase.Input, expected.ToArray()) + { + TestName = testCase.Name + }; + } + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlDatabaseAdapterTest.cs b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlDatabaseAdapterTest.cs new file mode 100644 index 00000000..a907ba11 --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlDatabaseAdapterTest.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using System.Data; +using Moq; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Configuration; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts.MsSql +{ + [TestFixture] + public class MsSqlDatabaseAdapterTest + { + private const string ModuleName = "SomeModuleName"; + private const string SelectModuleVersion = "SELECT value from sys.fn_listextendedproperty('version-{{ModuleName}}', default, default, default, default, default, default)"; + private const string UpdateModuleVersion = "EXEC sys.sp_updateextendedproperty @name=N'version-{{ModuleName}}', @value=N'{{TargetVersion}}'"; + + private MsSqlDatabaseAdapter _sut; + private AppConfiguration _configuration; + private IList _logOutput; + + [SetUp] + public void BeforeEachTest() + { + _logOutput = new List(); + var log = new Mock(MockBehavior.Strict); + log + .Setup(l => l.Info(It.IsAny())) + .Callback(m => + { + Console.WriteLine("Info: {0}", m); + _logOutput.Add(m); + }); + + _configuration = new AppConfiguration(); + + _sut = new MsSqlDatabaseAdapter( + MsSqlQuery.ConnectionString, + _configuration, + log.Object); + } + + [Test] + public void CreateConnectionToTargetDatabase() + { + using (var connection = _sut.CreateConnection(false)) + { + connection.State.ShouldBe(ConnectionState.Closed); + + connection.Open(); + connection.Database.ShouldBe(_sut.DatabaseName); + } + } + + [Test] + public void CreateConnectionToMaster() + { + using (var connection = _sut.CreateConnection(true)) + { + connection.State.ShouldBe(ConnectionState.Closed); + + connection.Open(); + connection.Database.ShouldBe("master"); + } + } + + [Test] + public void GetServerVersionSelectScript() + { + using (var connection = _sut.CreateConnection(false)) + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = _sut.GetServerVersionSelectScript(); + connection.Open(); + + var actual = cmd.ExecuteScalar(); + Console.WriteLine(actual); + + actual.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + } + } + + [Test] + [TestCase("master", true)] + [TestCase("unknown database", false)] + [TestCase(null, true)] + public void GetDatabaseExistsScript(string databaseName, bool expected) + { + using (var connection = _sut.CreateConnection(true)) + using (var cmd = connection.CreateCommand()) + { + connection.Open(); + + cmd.CommandText = _sut.GetDatabaseExistsScript(databaseName ?? _sut.DatabaseName); + var actual = cmd.ExecuteScalar()?.ToString(); + + if (expected) + { + actual.ShouldNotBeNullOrWhiteSpace(); + } + else + { + actual.ShouldBeNullOrEmpty(); + } + } + } + + [Test] + [TestCase("use master", "master")] + [TestCase("print 'xx1xx'", "xx1xx")] + public void SqlOutputIntoLog(string script, string expected) + { + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = script; + cmd.ExecuteNonQuery(); + + _logOutput.Count.ShouldBe(1); + _logOutput[0].ShouldContain(expected); + } + } + } + + [Test] + public void GetSetVersionScriptDefault() + { + _sut.GetVersionSelectScript().ShouldBe(MsSqlDatabaseAdapter.DefaultSelectVersion); + _sut.GetVersionUpdateScript().ShouldBe(MsSqlDatabaseAdapter.DefaultUpdateVersion); + + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) + { + using (var cmd = connection.CreateCommand()) + { + cmd.Transaction = transaction; + + cmd.CommandText = _sut.GetVersionUpdateScript().Replace("{{TargetVersion}}", "new version"); + cmd.ExecuteNonQuery(); + + cmd.CommandText = _sut.GetVersionSelectScript(); + + var actual = cmd.ExecuteScalar(); + actual.ShouldBeOfType().ShouldBe("new version"); + } + + transaction.Rollback(); + } + } + } + + [Test] + public void GetSetVersionScriptModuleName() + { + _configuration.GetCurrentVersionScript = SelectModuleVersion; + _configuration.SetCurrentVersionScript = UpdateModuleVersion; + + _sut.GetVersionSelectScript().ShouldBe(SelectModuleVersion); + _sut.GetVersionUpdateScript().ShouldBe(UpdateModuleVersion); + + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) + { + using (var cmd = connection.CreateCommand()) + { + cmd.Transaction = transaction; + + cmd.CommandText = _sut + .GetVersionUpdateScript() + .Replace("{{TargetVersion}}", "new version") + .Replace("{{ModuleName}}", ModuleName); + cmd.ExecuteNonQuery(); + + cmd.CommandText = _sut.GetVersionSelectScript().Replace("{{ModuleName}}", ModuleName); + + var actual = cmd.ExecuteScalar(); + actual.ShouldBeOfType().ShouldBe("new version"); + } + + transaction.Rollback(); + } + } + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlTextReaderTest.cs b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlTextReaderTest.cs new file mode 100644 index 00000000..fe89971c --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlTextReaderTest.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Scripts.SqlTestCases; + +namespace SqlDatabase.Scripts.MsSql +{ + [TestFixture] + public class MsSqlTextReaderTest + { + private MsSqlTextReader _sut; + + [SetUp] + public void BeforeEachTest() + { + _sut = new MsSqlTextReader(); + } + + [Test] + [TestCase("go", true)] + [TestCase("go go", true)] + [TestCase(" go ", true)] + [TestCase(" \tGO \t", true)] + [TestCase("go\tgo go", true)] + [TestCase("o", false)] + [TestCase("fo", false)] + [TestCase("go pro", false)] + public void IsGo(string line, bool expected) + { + _sut.IsGo(line).ShouldBe(expected); + } + + [Test] + [TestCaseSource(nameof(GetSplitByGoTestCases))] + public void SplitByGo(Stream input, string[] expected) + { + var batches = _sut.ReadBatches(input); + batches.ShouldBe(expected); + + input.Position = 0; + + var first = _sut.ReadFirstBatch(input); + first.ShouldBe(expected[0]); + } + + private static IEnumerable GetSplitByGoTestCases() + { + foreach (var testCase in ResourceReader.Read("Go")) + { + yield return new TestCaseData( + new MemoryStream(Encoding.Default.GetBytes(testCase.Input)), + testCase.Expected) + { + TestName = testCase.Name + }; + } + } + } +} diff --git a/Sources/SqlDatabase.Test/Export/SqlWriterTest.cs b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlWriterTest.cs similarity index 71% rename from Sources/SqlDatabase.Test/Export/SqlWriterTest.cs rename to Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlWriterTest.cs index 54f38bdc..e78ff0eb 100644 --- a/Sources/SqlDatabase.Test/Export/SqlWriterTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/MsSql/MsSqlWriterTest.cs @@ -5,19 +5,19 @@ using Shouldly; using SqlDatabase.TestApi; -namespace SqlDatabase.Export +namespace SqlDatabase.Scripts.MsSql { [TestFixture] - public class SqlWriterTest + public class MsSqlWriterTest { private StringBuilder _output; - private SqlWriter _sut; + private MsSqlWriter _sut; [SetUp] public void BeforeEachTest() { _output = new StringBuilder(); - _sut = new SqlWriter(new StringWriter(_output)); + _sut = new MsSqlWriter(new StringWriter(_output)); } [TearDown] @@ -54,7 +54,7 @@ public void EscapeVarchar(string input) { _sut.Text("SELECT ").Value(input); - Query.ExecuteScalar(_output.ToString()).ShouldBe(input); + MsSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(input); } [Test] @@ -67,7 +67,7 @@ public void ValueDateTime() .Value(value) .Text(" AS DATETIME2)"); - Query.ExecuteScalar(_output.ToString()).ShouldBe(value); + MsSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); } [Test] @@ -80,31 +80,19 @@ public void ValueGuid() .Value(value) .Text(" AS UNIQUEIDENTIFIER)"); - Query.ExecuteScalar(_output.ToString()).ShouldBe(value); + MsSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); } [Test] - public void ValueByteArray() + [TestCase(new byte[0])] + [TestCase(new byte[] { 1, 2, 3 })] + public void ValueByteArray(byte[] value) { - var value = new byte[0]; - - _sut - .Text("SELECT ") - .Value(value); - - Query.ExecuteScalar(_output.ToString()).ShouldBe(value); - } - - [Test] - public void ValueEmptyByteArray() - { - var value = new byte[0]; - _sut .Text("SELECT ") .Value(value); - Query.ExecuteScalar(_output.ToString()).ShouldBe(value); + MsSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); } [Test] @@ -117,7 +105,7 @@ public void ValueDateTimeOffset() .Value(value) .Text(" AS DATETIMEOFFSET)"); - Query.ExecuteScalar(_output.ToString()).ShouldBe(value); + MsSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); } } } diff --git a/Sources/SqlDatabase.Test/Scripts/TextScriptOutputTest.cs b/Sources/SqlDatabase.Test/Scripts/MsSql/TextScriptOutputMsSqlTest.cs similarity index 94% rename from Sources/SqlDatabase.Test/Scripts/TextScriptOutputTest.cs rename to Sources/SqlDatabase.Test/Scripts/MsSql/TextScriptOutputMsSqlTest.cs index ff9f9753..f997da61 100644 --- a/Sources/SqlDatabase.Test/Scripts/TextScriptOutputTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/MsSql/TextScriptOutputMsSqlTest.cs @@ -6,10 +6,10 @@ using Shouldly; using SqlDatabase.TestApi; -namespace SqlDatabase.Scripts +namespace SqlDatabase.Scripts.MsSql { [TestFixture] - public class TextScriptOutputTest + public class TextScriptOutputMsSqlTest { private SqlConnection _connection; private SqlCommand _command; @@ -37,8 +37,11 @@ public void BeforeEachTest() _logOutput.Add(m); }); - _sut = new TextScript(); - _connection = Query.Open(); + _sut = new TextScript + { + TextReader = new MsSqlTextReader() + }; + _connection = MsSqlQuery.Open(); _command = _connection.CreateCommand(); } diff --git a/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlDatabaseAdapterTest.cs b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlDatabaseAdapterTest.cs new file mode 100644 index 00000000..21dfdf74 --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlDatabaseAdapterTest.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.Data; +using Moq; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.Configuration; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts.PgSql +{ + [TestFixture] + public class PgSqlDatabaseAdapterTest + { + private const string ModuleName = "SomeModuleName"; + private const string SelectModuleVersion = "SELECT version FROM public.version WHERE module_name = '{{ModuleName}}'"; + private const string UpdateModuleVersion = "UPDATE public.version SET version='{{TargetVersion}}' WHERE module_name = '{{ModuleName}}'"; + + private PgSqlDatabaseAdapter _sut; + private AppConfiguration _configuration; + private IList _logOutput; + + [SetUp] + public void BeforeEachTest() + { + _logOutput = new List(); + var log = new Mock(MockBehavior.Strict); + log + .Setup(l => l.Info(It.IsAny())) + .Callback(m => + { + Console.WriteLine("Info: {0}", m); + _logOutput.Add(m); + }); + + _configuration = new AppConfiguration(); + + _sut = new PgSqlDatabaseAdapter( + PgSqlQuery.ConnectionString, + _configuration, + log.Object); + } + + [Test] + public void CreateConnectionToTargetDatabase() + { + using (var connection = _sut.CreateConnection(false)) + { + connection.State.ShouldBe(ConnectionState.Closed); + + connection.Open(); + connection.Database.ShouldBe(_sut.DatabaseName); + } + } + + [Test] + public void CreateConnectionToMaster() + { + using (var connection = _sut.CreateConnection(true)) + { + connection.State.ShouldBe(ConnectionState.Closed); + + connection.Open(); + connection.Database.ShouldBe("postgres"); + } + } + + [Test] + public void GetServerVersionSelectScript() + { + using (var connection = _sut.CreateConnection(false)) + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = _sut.GetServerVersionSelectScript(); + connection.Open(); + + var actual = cmd.ExecuteScalar(); + Console.WriteLine(actual); + + actual.ShouldBeOfType().ShouldNotBeNullOrWhiteSpace(); + } + } + + [Test] + [TestCase("postgres", true)] + [TestCase("POSTGRES", true)] + [TestCase("unknown database", false)] + [TestCase(null, true)] + public void GetDatabaseExistsScript(string databaseName, bool expected) + { + using (var connection = _sut.CreateConnection(true)) + using (var cmd = connection.CreateCommand()) + { + connection.Open(); + + cmd.CommandText = _sut.GetDatabaseExistsScript(databaseName ?? _sut.DatabaseName); + var actual = cmd.ExecuteScalar()?.ToString(); + + if (expected) + { + actual.ShouldNotBeNullOrWhiteSpace(); + } + else + { + actual.ShouldBeNullOrEmpty(); + } + } + } + + [Test] + public void SqlOutputIntoLog() + { + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = @" +DO $$ +BEGIN +RAISE NOTICE 'hello'; +END +$$;"; + cmd.ExecuteNonQuery(); + + _logOutput.Count.ShouldBe(1); + _logOutput[0].ShouldBe("NOTICE: hello"); + } + } + } + + [Test] + public void GetSetVersionScriptDefault() + { + _sut.GetVersionSelectScript().ShouldBe(PgSqlDatabaseAdapter.DefaultSelectVersion); + _sut.GetVersionUpdateScript().ShouldBe(PgSqlDatabaseAdapter.DefaultUpdateVersion); + + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) + { + using (var cmd = connection.CreateCommand()) + { + cmd.Transaction = transaction; + + cmd.CommandText = _sut.GetVersionUpdateScript().Replace("{{TargetVersion}}", "new version"); + cmd.ExecuteNonQuery(); + + cmd.CommandText = _sut.GetVersionSelectScript(); + + var actual = cmd.ExecuteScalar(); + actual.ShouldBeOfType().ShouldBe("new version"); + } + + transaction.Rollback(); + } + } + } + + [Test] + public void GetSetVersionScriptModuleName() + { + _configuration.GetCurrentVersionScript = SelectModuleVersion; + _configuration.SetCurrentVersionScript = UpdateModuleVersion; + + _sut.GetVersionSelectScript().ShouldBe(SelectModuleVersion); + _sut.GetVersionUpdateScript().ShouldBe(UpdateModuleVersion); + + using (var connection = _sut.CreateConnection(false)) + { + connection.Open(); + using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)) + { + using (var cmd = connection.CreateCommand()) + { + cmd.Transaction = transaction; + + cmd.CommandText = _sut + .GetVersionUpdateScript() + .Replace("{{TargetVersion}}", "new version") + .Replace("{{ModuleName}}", ModuleName); + cmd.ExecuteNonQuery(); + + cmd.CommandText = _sut.GetVersionSelectScript().Replace("{{ModuleName}}", ModuleName); + + var actual = cmd.ExecuteScalar(); + actual.ShouldBeOfType().ShouldBe("new version"); + } + + transaction.Rollback(); + } + } + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlTextReaderTest.cs b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlTextReaderTest.cs new file mode 100644 index 00000000..30fcbcc3 --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlTextReaderTest.cs @@ -0,0 +1,52 @@ +using NUnit.Framework; +using Shouldly; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts.PgSql +{ + [TestFixture] + public class PgSqlTextReaderTest + { + private PgSqlTextReader _sut; + + [SetUp] + public void BeforeEachTest() + { + _sut = new PgSqlTextReader(); + } + + [Test] + public void ReadFirstBatch() + { + const string Expected = @" + +/* +* module dependency: a 2.0 +* module dependency: b 1.0 +*/ +; +line 2;"; + + var actual = _sut.ReadFirstBatch(Expected.AsFuncStream()()); + + actual.ShouldBe(@"/* +* module dependency: a 2.0 +* module dependency: b 1.0 +*/"); + } + + [Test] + public void ReadBatches() + { + const string Expected = @" + +line 1; +; +line 2;"; + + var actual = _sut.ReadBatches(Expected.AsFuncStream()()); + + actual.ShouldBe(new[] { Expected }); + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlWriterTest.cs b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlWriterTest.cs new file mode 100644 index 00000000..4f564e4d --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/PgSql/PgSqlWriterTest.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Dynamic; +using System.IO; +using System.Text; +using NpgsqlTypes; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts.PgSql +{ + [TestFixture] + public class PgSqlWriterTest + { + private StringBuilder _output; + private PgSqlWriter _sut; + + [SetUp] + public void BeforeEachTest() + { + _output = new StringBuilder(); + _sut = new PgSqlWriter(new StringWriter(_output)); + } + + [TearDown] + public void AfterEachTest() + { + Console.WriteLine(_output); + } + + [Test] + public void ValueDateTime() + { + var value = new DateTime(2021, 05, 13, 18, 31, 30, 10); + + _sut + .Text("SELECT ") + .Value(value) + .Text("::timestamp"); + + PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); + } + + [Test] + [TestCase("3.04:05:06")] + [TestCase("04:05:06")] + [TestCase("04:05:06.10")] + public void ValueTimeSpan(string value) + { + var expected = TimeSpan.Parse(value); + + _sut + .Text("SELECT ") + .Value(expected) + .Text("::interval"); + + PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(expected); + } + + [Test] + [TestCase(new byte[0])] + [TestCase(new byte[] { 1, 2, 3 })] + public void ValueByteArray(byte[] value) + { + _sut + .Text("SELECT ") + .Value(value) + .Text("::bytea"); + + PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(value); + } + + [Test] + [TestCase("00000000-0000-0000-0000-000000000000")] + [TestCase("f8955206-fa52-4cb3-b269-85ddd831d4d5")] + public void ValueGuid(string value) + { + var expected = Guid.Parse(value); + + _sut + .Text("SELECT ") + .Value(expected) + .Text("::uuid"); + + PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBe(expected); + } + + [Test] + [TestCase(new byte[] { 1, 2, 3 })] + [TestCase(new byte[] { 1 })] + [TestCase(new byte[0])] + public void ValueBitArray(byte[] values) + { + var expected = new BitArray(values); + + _sut + .Text("SELECT ") + .Value(expected); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBeOfType(); + actual.Count.ShouldBe(expected.Count); + + for (var i = 0; i < actual.Count; i++) + { + actual[i].ShouldBe(expected[i]); + } + } + + [Test] + [TestCase("a fat cat")] + [TestCase("fat & rat")] + public void ValueTsVector(string value) + { + var expected = NpgsqlTsVector.Parse(value); + + _sut + .Text("SELECT ") + .Value(expected) + .Text("::tsvector"); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBeOfType(); + actual.ShouldBe(expected); + } + + [Test] + [TestCase("fat & rat")] + [TestCase("fat & (rat | cat)")] + public void ValueTsQuery(string value) + { + var expected = PgSqlQuery.ExecuteScalar("SELECT '{0}'::tsquery".FormatWith(value)).ShouldBeAssignableTo(); + + _sut + .Text("SELECT ") + .Value(NpgsqlTsQuery.Parse(value)) + .Text("::tsquery"); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBeAssignableTo(); + actual.ToString().ShouldBe(expected.ToString()); + } + + [Test] + [TestCase("integer[]", 1, 2, 3)] + [TestCase("text[]", "fat", "rat")] + public void Value1dArray(string type, params object[] values) + { + _sut + .Text("SELECT ") + .Value(values, type) + .Text("::" + type); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()); + actual.ShouldBe(values); + } + + [Test] + [TestCase("integer[][]", 1, 2, 3, 4)] + [TestCase("text[][]", "fat", "rat", "cat", "flat")] + public void Value2dArray(string type, object value11, object value12, object value21, object value22) + { + var array = Array.CreateInstance(value11.GetType(), 2, 2); + array.SetValue(value11, 0, 0); + array.SetValue(value12, 0, 1); + array.SetValue(value21, 1, 0); + array.SetValue(value22, 1, 1); + + _sut + .Text("SELECT ") + .Value(array, type) + .Text("::" + type); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()); + actual.ShouldBe(array); + } + + [Test] + public void ValueCompositeType() + { + IDictionary expected = new ExpandoObject(); + expected.Add("name", "fuzzy dice"); + expected.Add("supplier_id", 42); + expected.Add("price", 1.99); + + _sut + .Text("SELECT ") + .Value(expected) + .Text("::public.inventory_item"); + + IDictionary actual = PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBeOfType(); + actual.Keys.ShouldBe(expected.Keys); + foreach (var key in actual.Keys) + { + actual[key].ShouldBe(expected[key]); + } + } + + [Test] + [TestCase("(20,30)", "[21,30)")] + [TestCase("(20,30]", "[21,31)")] + [TestCase("[20,30)", "[20,30)")] + [TestCase("[20,30]", "[20,31)")] + [TestCase("(,30)", "(,30)")] + [TestCase("(20,)", "[21,)")] + [TestCase("empty", "empty")] + public void ValueRange(string value, string expected) + { + _sut + .Text("SELECT ") + .Value(NpgsqlRange.Parse(value)) + .Text("::int4range"); + + var actual = PgSqlQuery.ExecuteScalar(_output.ToString()).ShouldBeOfType>(); + actual.ShouldBeOneOf(NpgsqlRange.Parse(value), NpgsqlRange.Parse(expected)); + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/PgSql/TextScriptOutputPgSqlTest.cs b/Sources/SqlDatabase.Test/Scripts/PgSql/TextScriptOutputPgSqlTest.cs new file mode 100644 index 00000000..e53e276c --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/PgSql/TextScriptOutputPgSqlTest.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using Moq; +using Npgsql; +using NUnit.Framework; +using Shouldly; +using SqlDatabase.TestApi; + +namespace SqlDatabase.Scripts.PgSql +{ + [TestFixture] + public class TextScriptOutputPgSqlTest + { + private NpgsqlConnection _connection; + private NpgsqlCommand _command; + private Mock _logger; + private Variables _variables; + private TextScript _sut; + + private IList _logOutput; + + [SetUp] + public void BeforeEachTest() + { + _variables = new Variables(); + + _logOutput = new List(); + _logger = new Mock(MockBehavior.Strict); + _logger + .Setup(l => l.Indent()) + .Returns((IDisposable)null); + _logger + .Setup(l => l.Info(It.IsAny())) + .Callback(m => + { + Console.WriteLine("Info: {0}", m); + _logOutput.Add(m); + }); + + _sut = new TextScript + { + TextReader = new PgSqlTextReader() + }; + + _connection = PgSqlQuery.Open(); + _command = _connection.CreateCommand(); + } + + [TearDown] + public void AfterEachTest() + { + _command?.Dispose(); + _connection?.Dispose(); + } + + [Test] + public void ExecuteEmpty() + { + _sut.ReadSqlContent = "/* do nothing */".AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.ShouldBeEmpty(); + } + + [Test] + public void ExecuteDdlWithReader() + { + _sut.ReadSqlContent = @" +create table public.TextScriptIntegrationTest(id int, name varchar(20)); + +insert into public.TextScriptIntegrationTest values(1, 'name 1'); +insert into public.TextScriptIntegrationTest values(2, 'name 2'); + +select * from public.TextScriptIntegrationTest; + +drop table public.TextScriptIntegrationTest;" + .AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.Count.ShouldBe(8); + _logOutput[0].ShouldBe("output: id; name"); + _logOutput[1].ShouldBe("row 1"); + _logOutput[2].ShouldBe("id : 1"); + _logOutput[3].ShouldBe("name : name 1"); + _logOutput[4].ShouldBe("row 2"); + _logOutput[5].ShouldBe("id : 2"); + _logOutput[6].ShouldBe("name : name 2"); + _logOutput[7].ShouldBe("2 rows selected"); + } + + [Test] + public void NoColumnName() + { + _sut.ReadSqlContent = "select 1".AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.Count.ShouldBe(4); + _logOutput[0].ShouldBe("output: (no name)"); + _logOutput[1].ShouldBe("row 1"); + _logOutput[2].ShouldBe("(no name) : 1"); + _logOutput[3].ShouldBe("1 row selected"); + } + + [Test] + public void SelectNull() + { + _sut.ReadSqlContent = "select null".AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.Count.ShouldBe(4); + _logOutput[0].ShouldBe("output: (no name)"); + _logOutput[1].ShouldBe("row 1"); + _logOutput[2].ShouldBe("(no name) : NULL"); + _logOutput[3].ShouldBe("1 row selected"); + } + + [Test] + public void TwoSelections() + { + _sut.ReadSqlContent = @" +select 1 first_; +select 2 second_;" + .AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.Count.ShouldBe(9); + + _logOutput[0].ShouldBe("output: first_"); + _logOutput[1].ShouldBe("row 1"); + _logOutput[2].ShouldBe("first_ : 1"); + _logOutput[3].ShouldBe("1 row selected"); + + _logOutput[4].ShouldBe(string.Empty); + + _logOutput[5].ShouldBe("output: second_"); + _logOutput[6].ShouldBe("row 1"); + _logOutput[7].ShouldBe("second_ : 2"); + _logOutput[8].ShouldBe("1 row selected"); + } + + [Test] + public void SelectZeroRowsNull() + { + _sut.ReadSqlContent = "select null value_ limit 0".AsFuncStream(); + + _sut.Execute(_command, _variables, _logger.Object); + + _logOutput.Count.ShouldBe(2); + _logOutput[0].ShouldBe("output: value_"); + _logOutput[1].ShouldBe("0 rows selected"); + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/ScriptFactoryTest.cs b/Sources/SqlDatabase.Test/Scripts/ScriptFactoryTest.cs index b50ee253..709a8166 100644 --- a/Sources/SqlDatabase.Test/Scripts/ScriptFactoryTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/ScriptFactoryTest.cs @@ -1,11 +1,9 @@ using System; using System.IO; -using System.Text; using Moq; using NUnit.Framework; using Shouldly; using SqlDatabase.Configuration; -using SqlDatabase.Scripts.PowerShellInternal; using SqlDatabase.TestApi; namespace SqlDatabase.Scripts @@ -15,18 +13,21 @@ public class ScriptFactoryTest { private ScriptFactory _sut; private Mock _powerShellFactory; - private AppConfiguration _configuration; + private AssemblyScriptConfiguration _configuration; + private Mock _textReader; [SetUp] public void BeforeEachTest() { - _configuration = new AppConfiguration(); + _configuration = new AssemblyScriptConfiguration(); _powerShellFactory = new Mock(MockBehavior.Strict); + _textReader = new Mock(MockBehavior.Strict); _sut = new ScriptFactory { - Configuration = _configuration, - PowerShellFactory = _powerShellFactory.Object + AssemblyScriptConfiguration = _configuration, + PowerShellFactory = _powerShellFactory.Object, + TextReader = _textReader.Object }; } @@ -40,6 +41,7 @@ public void FromSqlFile() var script = _sut.FromFile(file).ShouldBeOfType(); script.DisplayName.ShouldBe("11.sql"); + script.TextReader.ShouldBe(_textReader.Object); new StreamReader(script.ReadSqlContent()).ReadToEnd().ShouldBe("some script"); } @@ -56,6 +58,7 @@ public void FromDllFile() var script = _sut.FromFile(file).ShouldBeOfType(); script.DisplayName.ShouldBe("11.dll"); + script.Configuration.ShouldBe(_configuration); script.ReadAssemblyContent().ShouldBe(new byte[] { 1, 2, 3 }); new StreamReader(script.ReadDescriptionContent()).ReadToEnd().ShouldBe("3, 2, 1"); } @@ -73,6 +76,7 @@ public void FromExeFile() var script = _sut.FromFile(file).ShouldBeOfType(); script.DisplayName.ShouldBe("11.exe"); + script.Configuration.ShouldBe(_configuration); script.ReadAssemblyContent().ShouldBe(new byte[] { 1, 2, 3 }); script.ReadDescriptionContent().ShouldBeNull(); } diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest.cs b/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest.cs deleted file mode 100644 index 111217b7..00000000 --- a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using NUnit.Framework; -using Shouldly; - -namespace SqlDatabase.Scripts -{ - [TestFixture] - public class SqlBatchParserTest - { - [Test] - [TestCaseSource(nameof(GetSplitByGoTestCases))] - public void SplitByGo(Stream input, string[] expected) - { - var actual = SqlBatchParser.SplitByGo(input); - CollectionAssert.AreEqual(expected, actual); - } - - [Test] - [TestCase("go", true)] - [TestCase("go go", true)] - [TestCase(" go ", true)] - [TestCase(" \tGO \t", true)] - [TestCase("go\tgo go", true)] - [TestCase("o", false)] - [TestCase("fo", false)] - [TestCase("go pro", false)] - public void IsGo(string line, bool expected) - { - Assert.AreEqual(expected, SqlBatchParser.IsGo(line)); - } - - [Test] - [TestCaseSource(nameof(GetExtractDependenciesTestCases))] - public void ExtractDependencies(string sql, ScriptDependency[] expected) - { - var actual = SqlBatchParser.ExtractDependencies(new StringReader(sql), "file name").ToArray(); - actual.ShouldBe(expected); - } - - [Test] - [TestCase("1.a")] - [TestCase("10")] - public void ExtractDependenciesInvalidVersion(string versionText) - { - var input = "-- module dependency: moduleName " + versionText; - var ex = Assert.Throws(() => SqlBatchParser.ExtractDependencies(new StringReader(input), "file name").ToArray()); - - ex.Message.ShouldContain("moduleName"); - ex.Message.ShouldContain(versionText); - } - - private static IEnumerable GetSplitByGoTestCases() - { - foreach (var testCase in ReadResources("Go")) - { - yield return new TestCaseData( - new MemoryStream(Encoding.Default.GetBytes(testCase.Input)), - testCase.Expected) - { - TestName = testCase.Name - }; - } - } - - private static IEnumerable GetExtractDependenciesTestCases() - { - foreach (var testCase in ReadResources("Dependencies")) - { - var expected = new List(); - foreach (var line in testCase.Expected) - { - if (!string.IsNullOrWhiteSpace(line)) - { - var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - parts.Length.ShouldBe(2); - expected.Add(new ScriptDependency(parts[0], new Version(parts[1]))); - } - } - - yield return new TestCaseData(testCase.Input, expected.ToArray()) - { - TestName = testCase.Name - }; - } - } - - private static IEnumerable<(string Name, string Input, string[] Expected)> ReadResources(string folder) - { - var anchor = typeof(SqlBatchParserTest); - var prefix = anchor.Namespace + "." + anchor.Name + "." + folder + "."; - - var sources = anchor - .Assembly - .GetManifestResourceNames() - .Where(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - .OrderBy(i => i); - - foreach (var sourceName in sources) - { - using (var stream = anchor.Assembly.GetManifestResourceStream(sourceName)) - using (var reader = new StreamReader(stream)) - { - var name = Path.GetFileNameWithoutExtension(sourceName.Substring(prefix.Length)); - var (input, expected) = ParseResource(reader); - - yield return (name, input, expected); - } - } - } - - private static (string Input, string[] Expected) ParseResource(TextReader reader) - { - const string Separator = "--------------"; - - var input = new StringBuilder(); - var expected = new List(); - var currentExpected = new StringBuilder(); - - var isInput = true; - - string line; - while ((line = reader.ReadLine()) != null) - { - if (line == Separator) - { - isInput = false; - if (currentExpected.Length > 0) - { - expected.Add(currentExpected.ToString()); - currentExpected.Clear(); - } - } - else if (isInput) - { - if (input.Length > 0) - { - input.AppendLine(); - } - - input.Append(line); - } - else - { - if (currentExpected.Length > 0) - { - currentExpected.AppendLine(); - } - - currentExpected.Append(line); - } - } - - if (currentExpected.Length > 0) - { - expected.Add(currentExpected.ToString()); - } - - return (input.ToString(), expected.ToArray()); - } - } -} diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case01.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case01.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case01.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case01.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case02.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case02.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case02.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case02.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case03.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case03.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case03.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case03.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case04.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case04.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case04.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case04.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case05.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case05.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Case05.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Case05.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Empty.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Empty.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Dependencies/Empty.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Dependencies/Empty.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/Case01.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/Case01.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/Case01.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/Case01.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/Case02.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/Case02.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/Case02.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/Case02.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/CaseOneLineComment.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/CaseOneLineComment.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/CaseOneLineComment.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/CaseOneLineComment.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/CaseStoredProcedure.sql b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/CaseStoredProcedure.sql similarity index 100% rename from Sources/SqlDatabase.Test/Scripts/SqlBatchParserTest/Go/CaseStoredProcedure.sql rename to Sources/SqlDatabase.Test/Scripts/SqlTestCases/Go/CaseStoredProcedure.sql diff --git a/Sources/SqlDatabase.Test/Scripts/SqlTestCases/ResourceReader.cs b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/ResourceReader.cs new file mode 100644 index 00000000..c66a979f --- /dev/null +++ b/Sources/SqlDatabase.Test/Scripts/SqlTestCases/ResourceReader.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace SqlDatabase.Scripts.SqlTestCases +{ + internal static class ResourceReader + { + public static IEnumerable<(string Name, string Input, string[] Expected)> Read(string folder) + { + var anchor = typeof(ResourceReader); + var prefix = anchor.Namespace + "." + anchor.Name + "." + folder + "."; + + var sources = anchor + .Assembly + .GetManifestResourceNames() + .Where(i => i.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) + .OrderBy(i => i); + + foreach (var sourceName in sources) + { + using (var stream = anchor.Assembly.GetManifestResourceStream(sourceName)) + using (var reader = new StreamReader(stream)) + { + var name = Path.GetFileNameWithoutExtension(sourceName.Substring(prefix.Length)); + var (input, expected) = ParseResource(reader); + + yield return (name, input, expected); + } + } + } + + private static (string Input, string[] Expected) ParseResource(TextReader reader) + { + const string Separator = "--------------"; + + var input = new StringBuilder(); + var expected = new List(); + var currentExpected = new StringBuilder(); + + var isInput = true; + + string line; + while ((line = reader.ReadLine()) != null) + { + if (line == Separator) + { + isInput = false; + if (currentExpected.Length > 0) + { + expected.Add(currentExpected.ToString()); + currentExpected.Clear(); + } + } + else if (isInput) + { + if (input.Length > 0) + { + input.AppendLine(); + } + + input.Append(line); + } + else + { + if (currentExpected.Length > 0) + { + currentExpected.AppendLine(); + } + + currentExpected.Append(line); + } + } + + if (currentExpected.Length > 0) + { + expected.Add(currentExpected.ToString()); + } + + return (input.ToString(), expected.ToArray()); + } + } +} diff --git a/Sources/SqlDatabase.Test/Scripts/TextScriptTest.cs b/Sources/SqlDatabase.Test/Scripts/TextScriptTest.cs index edb5d424..d588fbc3 100644 --- a/Sources/SqlDatabase.Test/Scripts/TextScriptTest.cs +++ b/Sources/SqlDatabase.Test/Scripts/TextScriptTest.cs @@ -7,6 +7,7 @@ using Moq; using NUnit.Framework; using Shouldly; +using SqlDatabase.Scripts.MsSql; using SqlDatabase.TestApi; namespace SqlDatabase.Scripts @@ -51,7 +52,10 @@ public void BeforeEachTest() .Callback(() => _executedScripts.Add(_command.Object.CommandText)) .Returns(_executedReader.Object); - _sut = new TextScript(); + _sut = new TextScript + { + TextReader = new MsSqlTextReader() + }; _variables.SetValue(VariableSource.CommandLine, "var1", "[some value]"); } diff --git a/Sources/SqlDatabase.Test/SqlDatabase.Test.csproj b/Sources/SqlDatabase.Test/SqlDatabase.Test.csproj index 16f5aa86..d2a55883 100644 --- a/Sources/SqlDatabase.Test/SqlDatabase.Test.csproj +++ b/Sources/SqlDatabase.Test/SqlDatabase.Test.csproj @@ -1,7 +1,7 @@  - net472;netcoreapp2.2;netcoreapp3.1;net5.0 + net472;netcoreapp2.1;netcoreapp3.1;net5.0 SqlDatabase NU1702 ..\..\bin\Tests @@ -40,16 +40,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/Sources/SqlDatabase.Test/TestApi/CreateTestDatabase.sql b/Sources/SqlDatabase.Test/TestApi/CreateTestDatabase.sql deleted file mode 100644 index 4572e49c..00000000 --- a/Sources/SqlDatabase.Test/TestApi/CreateTestDatabase.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE DATABASE SqlDatabaseTest -GO - -ALTER DATABASE SqlDatabaseTest SET RECOVERY SIMPLE WITH NO_WAIT -GO - -EXEC SqlDatabaseTest.sys.sp_addextendedproperty @name=N'version', @value=N'1.0' -GO \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/TestApi/Query.cs b/Sources/SqlDatabase.Test/TestApi/MsSqlQuery.cs similarity index 89% rename from Sources/SqlDatabase.Test/TestApi/Query.cs rename to Sources/SqlDatabase.Test/TestApi/MsSqlQuery.cs index 95c3ddec..6afffc83 100644 --- a/Sources/SqlDatabase.Test/TestApi/Query.cs +++ b/Sources/SqlDatabase.Test/TestApi/MsSqlQuery.cs @@ -3,9 +3,9 @@ namespace SqlDatabase.TestApi { - internal static class Query + internal static class MsSqlQuery { - public static string ConnectionString => ConfigurationManager.ConnectionStrings["test"].ConnectionString; + public static string ConnectionString => ConfigurationManager.ConnectionStrings["mssql"].ConnectionString; public static string DatabaseName => new SqlConnectionStringBuilder(ConnectionString).InitialCatalog; diff --git a/Sources/SqlDatabase.Test/TestApi/PgSqlQuery.cs b/Sources/SqlDatabase.Test/TestApi/PgSqlQuery.cs new file mode 100644 index 00000000..a1dccb31 --- /dev/null +++ b/Sources/SqlDatabase.Test/TestApi/PgSqlQuery.cs @@ -0,0 +1,30 @@ +using System.Configuration; +using Npgsql; + +namespace SqlDatabase.TestApi +{ + internal static class PgSqlQuery + { + public static string ConnectionString => ConfigurationManager.ConnectionStrings["pgsql"].ConnectionString; + + public static string DatabaseName => new NpgsqlConnectionStringBuilder(ConnectionString).Database; + + public static NpgsqlConnection Open() + { + var con = new NpgsqlConnection(ConnectionString); + con.Open(); + + return con; + } + + public static object ExecuteScalar(string sql) + { + using (var connection = Open()) + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = sql; + return cmd.ExecuteScalar(); + } + } + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase.Test/app.config b/Sources/SqlDatabase.Test/app.config index b02a75b7..1552ed44 100644 --- a/Sources/SqlDatabase.Test/app.config +++ b/Sources/SqlDatabase.Test/app.config @@ -7,8 +7,10 @@ - + @@ -19,7 +21,9 @@ - + + \ No newline at end of file diff --git a/Sources/SqlDatabase/App.config b/Sources/SqlDatabase/App.config index a8fe9f0f..a9a94438 100644 --- a/Sources/SqlDatabase/App.config +++ b/Sources/SqlDatabase/App.config @@ -6,31 +6,47 @@ - diff --git a/Sources/SqlDatabase/Commands/DatabaseCommandBase.cs b/Sources/SqlDatabase/Commands/DatabaseCommandBase.cs index 95e3e83b..f51c5e7e 100644 --- a/Sources/SqlDatabase/Commands/DatabaseCommandBase.cs +++ b/Sources/SqlDatabase/Commands/DatabaseCommandBase.cs @@ -1,5 +1,4 @@ -using System.Data.SqlClient; -using SqlDatabase.Scripts; +using SqlDatabase.Scripts; namespace SqlDatabase.Commands { @@ -11,10 +10,7 @@ internal abstract class DatabaseCommandBase : ICommand public void Execute() { - var cs = new SqlConnectionStringBuilder(Database.ConnectionString); - var databaseLocation = "database [{0}] on [{1}]".FormatWith(cs.InitialCatalog, cs.DataSource); - - Greet(databaseLocation); + Greet(Database.Adapter.GetUserFriendlyConnectionString()); Log.Info(Database.GetServerVersion()); ExecuteCore(); diff --git a/Sources/SqlDatabase/Commands/DatabaseExportCommand.cs b/Sources/SqlDatabase/Commands/DatabaseExportCommand.cs index ec6ea5a3..26e70208 100644 --- a/Sources/SqlDatabase/Commands/DatabaseExportCommand.cs +++ b/Sources/SqlDatabase/Commands/DatabaseExportCommand.cs @@ -31,9 +31,14 @@ protected override void ExecuteCore() var readerIndex = 0; var exporter = ExporterFactory(); - exporter.Output = new SqlWriter(output); + exporter.Output = Database.Adapter.CreateSqlWriter(output); exporter.Log = Log; + if (string.IsNullOrWhiteSpace(DestinationTableName)) + { + DestinationTableName = exporter.Output.GetDefaultTableName(); + } + foreach (var script in sequences) { var timer = Stopwatch.StartNew(); diff --git a/Sources/SqlDatabase/Configuration/AppConfiguration.cs b/Sources/SqlDatabase/Configuration/AppConfiguration.cs index 5a2a18a4..686ee8a6 100644 --- a/Sources/SqlDatabase/Configuration/AppConfiguration.cs +++ b/Sources/SqlDatabase/Configuration/AppConfiguration.cs @@ -10,15 +10,17 @@ public sealed class AppConfiguration : ConfigurationSection private const string PropertySetCurrentVersionScript = "setCurrentVersion"; private const string PropertyAssemblyScript = "assemblyScript"; private const string PropertyVariables = "variables"; + private const string PropertyMsSql = "mssql"; + private const string PropertyPgSql = "pgsql"; - [ConfigurationProperty(PropertyGetCurrentVersionScript, DefaultValue = "SELECT value from sys.fn_listextendedproperty('version', default, default, default, default, default, default)")] + [ConfigurationProperty(PropertyGetCurrentVersionScript)] public string GetCurrentVersionScript { get => (string)this[PropertyGetCurrentVersionScript]; set => this[PropertyGetCurrentVersionScript] = value; } - [ConfigurationProperty(PropertySetCurrentVersionScript, DefaultValue = "EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'{{TargetVersion}}'")] + [ConfigurationProperty(PropertySetCurrentVersionScript)] public string SetCurrentVersionScript { get => (string)this[PropertySetCurrentVersionScript]; @@ -30,5 +32,11 @@ public string SetCurrentVersionScript [ConfigurationProperty(PropertyVariables)] public NameValueConfigurationCollection Variables => (NameValueConfigurationCollection)this[PropertyVariables]; + + [ConfigurationProperty(PropertyMsSql)] + public DatabaseConfiguration MsSql => (DatabaseConfiguration)this[PropertyMsSql]; + + [ConfigurationProperty(PropertyPgSql)] + public DatabaseConfiguration PgSql => (DatabaseConfiguration)this[PropertyPgSql]; } } \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/Arg.cs b/Sources/SqlDatabase/Configuration/Arg.cs index d4fee045..8f6a7df8 100644 --- a/Sources/SqlDatabase/Configuration/Arg.cs +++ b/Sources/SqlDatabase/Configuration/Arg.cs @@ -2,7 +2,6 @@ { internal readonly struct Arg { - internal const string Base64Sign = "+"; internal const string Sign = "-"; internal const string Database = "database"; @@ -21,7 +20,6 @@ internal readonly struct Arg internal const string Help = "help"; internal const string HelpShort = "h"; - internal const string PreFormatOutputLogs = "preFormatOutputLogs"; internal const string Log = "log"; public Arg(string key, string value) diff --git a/Sources/SqlDatabase/Configuration/CommandLine.create.net452.txt b/Sources/SqlDatabase/Configuration/CommandLine.create.net452.txt index 6587255e..8d475f80 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.create.net452.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.create.net452.txt @@ -29,9 +29,11 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: -create new "NewDatabase" on "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" +example: create new "NewDatabase" on MSSQL "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" > SqlDatabase create "-database=Data Source=server;Initial Catalog=NewDatabase;Integrated Security=True" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 +example: create new "NewDatabase" on PostgreSQL "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase create "-database=Host=localhost;Username=postgres;Database=NewDatabase" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase create "-database=Data Source=server;Initial Catalog=NewDatabase;Integrated Security=True" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 -whatIf \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.create.txt b/Sources/SqlDatabase/Configuration/CommandLine.create.txt index 3a50bcef..1ffa6d3c 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.create.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.create.txt @@ -32,9 +32,11 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: -create new "NewDatabase" on "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" +example: create new "NewDatabase" on MSSQL "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" > SqlDatabase create "-database=Data Source=server;Initial Catalog=NewDatabase;Integrated Security=True" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 +example: create new "NewDatabase" on PostgreSQL "server" based on scripts from "C:\NewDatabase" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase create "-database=Host=localhost;Username=postgres;Database=NewDatabase" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase create "-database=Data Source=server;Initial Catalog=NewDatabase;Integrated Security=True" -from=C:\NewDatabase -varVariable1=value1 -varVariable2=value2 -whatIf \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.execute.net452.txt b/Sources/SqlDatabase/Configuration/CommandLine.execute.net452.txt index 1fc28e47..084cb450 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.execute.net452.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.execute.net452.txt @@ -36,8 +36,11 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on "server" with "Variable1=value1" and "Variable2=value2" +example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on MSSQL "server" with "Variable1=value1" and "Variable2=value2" > SqlDatabase execute "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 +example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on PostgreSQL "server" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase execute "-database=Host=localhost;Username=postgres;Database=MyDatabase" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase execute "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 -whatIf \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.execute.txt b/Sources/SqlDatabase/Configuration/CommandLine.execute.txt index 1eaea4bb..e1449897 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.execute.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.execute.txt @@ -39,8 +39,11 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on "server" with "Variable1=value1" and "Variable2=value2" +example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on MSSQL "server" with "Variable1=value1" and "Variable2=value2" > SqlDatabase execute "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 +example: execute scripts from "c:\Scripts\script.sql" on "MyDatabase" on PostgreSQL "server" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase execute "-database=Host=localhost;Username=postgres;Database=MyDatabase" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase execute "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=c:\Scripts\script.sql -varVariable1=value1 -varVariable2=value2 -whatIf \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.export.net452.txt b/Sources/SqlDatabase/Configuration/CommandLine.export.net452.txt index 0e8e5f0e..3e3e960b 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.export.net452.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.export.net452.txt @@ -36,5 +36,8 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: export data from sys.tables view into "c:\databases.sql" from "master" database on "server" -> SqlDatabase export "-database=Data Source=server;Initial Catalog=master;Integrated Security=True" "-fromSql=SELECT * FROM sys.tables" -toFile=c:\tables.sql \ No newline at end of file +example: export data from sys.tables view into "c:\tables.sql" from "master" database on MSSQL "server" +> SqlDatabase export "-database=Data Source=server;Initial Catalog=master;Integrated Security=True" "-fromSql=SELECT * FROM sys.tables" -toFile=c:\tables.sql + +example: export data from information_schema.tables view into "c:\tables.sql" from "postgres" database on PostgreSQL "server" +> SqlDatabase export "-database=Host=localhost;Username=postgres;Database=postgres" "-fromSql=SELECT * FROM information_schema.tables" -toFile=c:\tables.sql \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.export.txt b/Sources/SqlDatabase/Configuration/CommandLine.export.txt index 0e8e5f0e..3e3e960b 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.export.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.export.txt @@ -36,5 +36,8 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: export data from sys.tables view into "c:\databases.sql" from "master" database on "server" -> SqlDatabase export "-database=Data Source=server;Initial Catalog=master;Integrated Security=True" "-fromSql=SELECT * FROM sys.tables" -toFile=c:\tables.sql \ No newline at end of file +example: export data from sys.tables view into "c:\tables.sql" from "master" database on MSSQL "server" +> SqlDatabase export "-database=Data Source=server;Initial Catalog=master;Integrated Security=True" "-fromSql=SELECT * FROM sys.tables" -toFile=c:\tables.sql + +example: export data from information_schema.tables view into "c:\tables.sql" from "postgres" database on PostgreSQL "server" +> SqlDatabase export "-database=Host=localhost;Username=postgres;Database=postgres" "-fromSql=SELECT * FROM information_schema.tables" -toFile=c:\tables.sql \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/CommandLine.upgrade.net452.txt b/Sources/SqlDatabase/Configuration/CommandLine.upgrade.net452.txt index a1a75da2..5a0ee7fb 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.upgrade.net452.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.upgrade.net452.txt @@ -30,8 +30,11 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: upgrade "MyDatabase" on "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" +example: upgrade "MyDatabase" on MSSQL "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" > SqlDatabase upgrade "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 +example: upgrade "MyDatabase" on PostgreSQL "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase upgrade "-database=Host=localhost;Username=postgres;Database=MyDatabase" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase upgrade "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 -whatIf diff --git a/Sources/SqlDatabase/Configuration/CommandLine.upgrade.txt b/Sources/SqlDatabase/Configuration/CommandLine.upgrade.txt index 796affd6..62be9c77 100644 --- a/Sources/SqlDatabase/Configuration/CommandLine.upgrade.txt +++ b/Sources/SqlDatabase/Configuration/CommandLine.upgrade.txt @@ -33,8 +33,12 @@ exit codes: 1 - invalid command line 2 - errors during execution -example: upgrade "MyDatabase" on "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" +example: upgrade "MyDatabase" on MSSQL "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" > SqlDatabase upgrade "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 +example: upgrade "MyDatabase" on PostgreSQL "server", migration steps from "C:\MigrationSteps" with "Variable1=value1" and "Variable2=value2" +> SqlDatabase upgrade "-database=Host=localhost;Username=postgres;Database=MyDatabase" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 + example: use previous example with -whatIf options to show steps without execution > SqlDatabase upgrade "-database=Data Source=server;Initial Catalog=MyDatabase;Integrated Security=True" -from=C:\MigrationSteps -varVariable1=value1 -varVariable2=value2 -whatIf + diff --git a/Sources/SqlDatabase/Configuration/CommandLineBase.cs b/Sources/SqlDatabase/Configuration/CommandLineBase.cs index 8321013c..fe6331e8 100644 --- a/Sources/SqlDatabase/Configuration/CommandLineBase.cs +++ b/Sources/SqlDatabase/Configuration/CommandLineBase.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Data.SqlClient; using System.Linq; using SqlDatabase.Commands; using SqlDatabase.IO; @@ -10,7 +9,7 @@ namespace SqlDatabase.Configuration { internal abstract class CommandLineBase : ICommandLine { - public SqlConnectionStringBuilder Connection { get; set; } + public string ConnectionString { get; set; } public IList Scripts { get; } = new List(); @@ -27,7 +26,7 @@ public void Parse(CommandLine args) ApplyArg(arg); } - if (Connection == null) + if (string.IsNullOrWhiteSpace(ConnectionString)) { throw new InvalidCommandLineException("Options {0} is not specified.".FormatWith(Arg.Database)); } @@ -44,11 +43,20 @@ public void Parse(CommandLine args) internal Database CreateDatabase(ILogger logger, IConfigurationManager configuration, TransactionMode transaction, bool whatIf) { + IDatabaseAdapter adapter; + try + { + adapter = DatabaseAdapterFactory.CreateAdapter(ConnectionString, configuration.SqlDatabase, logger); + } + catch (Exception ex) + { + throw new InvalidCommandLineException(Arg.Database, "Invalid connection string value.", ex); + } + var database = new Database { - ConnectionString = Connection.ToString(), + Adapter = adapter, Log = logger, - Configuration = configuration.SqlDatabase, Transaction = transaction, WhatIf = whatIf }; @@ -148,7 +156,7 @@ private bool TryParseKnownPair(Arg arg) { if (Arg.Database.Equals(arg.Key, StringComparison.OrdinalIgnoreCase)) { - SetConnection(arg.Value); + ConnectionString = arg.Value; return true; } @@ -173,18 +181,6 @@ private bool TryParseKnownPair(Arg arg) return false; } - private void SetConnection(string connectionString) - { - try - { - Connection = new SqlConnectionStringBuilder(connectionString); - } - catch (ArgumentException ex) - { - throw new InvalidCommandLineException(Arg.Database, "Invalid connection string value.", ex); - } - } - private void SetScripts(string value) { Scripts.Add(FileSystemFactory.FileSystemInfoFromPath(value)); diff --git a/Sources/SqlDatabase/Configuration/CommandLineParser.cs b/Sources/SqlDatabase/Configuration/CommandLineParser.cs index 77765a83..7b524841 100644 --- a/Sources/SqlDatabase/Configuration/CommandLineParser.cs +++ b/Sources/SqlDatabase/Configuration/CommandLineParser.cs @@ -1,25 +1,10 @@ using System; using System.Collections.Generic; -using System.Text; namespace SqlDatabase.Configuration { internal sealed class CommandLineParser { - public static bool PreFormatOutputLogs(IList args) - { - for (var i = 0; i < args.Count; i++) - { - if (ParseArg(args[i], out var value) - && IsPreFormatOutputLogs(value)) - { - return string.IsNullOrEmpty(value.Value) || bool.Parse(value.Value); - } - } - - return false; - } - public static string GetLogFileName(IList args) { for (var i = 0; i < args.Count; i++) @@ -45,7 +30,7 @@ public CommandLine Parse(params string[] args) throw new InvalidCommandLineException("Invalid option [{0}].".FormatWith(arg)); } - if (!IsPreFormatOutputLogs(value) && !IsLog(value)) + if (!IsLog(value)) { result.Add(value); } @@ -63,17 +48,6 @@ internal static bool ParseArg(string input, out Arg arg) return false; } - if (input.StartsWith(Arg.Base64Sign + Arg.Sign, StringComparison.OrdinalIgnoreCase)) - { - if (SplitKeyValue(input, 2, out var key, out var value)) - { - arg = new Arg(key, value); - return true; - } - - return false; - } - if (input.StartsWith(Arg.Sign, StringComparison.OrdinalIgnoreCase)) { if (SplitKeyValue(input, 1, out var key, out var value)) @@ -85,19 +59,12 @@ internal static bool ParseArg(string input, out Arg arg) return false; } - if (input.StartsWith(Arg.Base64Sign)) - { - return false; - } - arg = new Arg(input); return true; } private static bool SplitKeyValue(string keyValue, int offset, out string key, out string value) { - var isEscaped = keyValue.StartsWith(Arg.Base64Sign, StringComparison.OrdinalIgnoreCase); - keyValue = keyValue.Substring(offset); key = keyValue; value = null; @@ -121,29 +88,7 @@ private static bool SplitKeyValue(string keyValue, int offset, out string key, o key = keyValue.Substring(0, index).Trim(); value = index == keyValue.Length - 1 ? null : keyValue.Substring(index + 1).Trim(); - if (!isEscaped) - { - return true; - } - - try - { - value = Encoding.UTF8.GetString(Convert.FromBase64String(value)); - return true; - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - - return false; - } - - private static bool IsPreFormatOutputLogs(Arg arg) - { - return arg.IsPair && Arg.PreFormatOutputLogs.Equals(arg.Key, StringComparison.OrdinalIgnoreCase); + return true; } private static bool IsLog(Arg arg) diff --git a/Sources/SqlDatabase/Configuration/ConfigurationManager.cs b/Sources/SqlDatabase/Configuration/ConfigurationManager.cs index de276b60..5ff2689b 100644 --- a/Sources/SqlDatabase/Configuration/ConfigurationManager.cs +++ b/Sources/SqlDatabase/Configuration/ConfigurationManager.cs @@ -2,6 +2,7 @@ using System.Configuration; using System.IO; using System.Linq; +using System.Reflection; using SqlDatabase.IO; using Manager = System.Configuration.ConfigurationManager; @@ -11,12 +12,11 @@ internal sealed class ConfigurationManager : IConfigurationManager { public AppConfiguration SqlDatabase { get; private set; } - public static string ResolveDefaultConfigurationFile() + public static string ResolveDefaultConfigurationFile(string probingPath) { - var currentLocation = Path.GetDirectoryName(typeof(ConfigurationManager).Assembly.Location); - var fileName = ResolveFile(new FileSystemFolder(currentLocation)).Name; + var fileName = ResolveFile(new FileSystemFolder(probingPath)).Name; - return Path.Combine(currentLocation, fileName); + return Path.Combine(probingPath, fileName); } public void LoadFrom(string configurationFile) diff --git a/Sources/SqlDatabase/Configuration/CreateCommandLine.cs b/Sources/SqlDatabase/Configuration/CreateCommandLine.cs index 1b403ce9..ca7f40e7 100644 --- a/Sources/SqlDatabase/Configuration/CreateCommandLine.cs +++ b/Sources/SqlDatabase/Configuration/CreateCommandLine.cs @@ -17,13 +17,15 @@ public override ICommand CreateCommand(ILogger logger) configuration.LoadFrom(ConfigurationFile); var powerShellFactory = PowerShellFactory.Create(UsePowerShell); + var database = CreateDatabase(logger, configuration, TransactionMode.None, WhatIf); var sequence = new CreateScriptSequence { ScriptFactory = new ScriptFactory { - Configuration = configuration.SqlDatabase, - PowerShellFactory = powerShellFactory + AssemblyScriptConfiguration = configuration.SqlDatabase.AssemblyScript, + PowerShellFactory = powerShellFactory, + TextReader = database.Adapter.CreateSqlTextReader() }, Sources = Scripts.ToArray() }; @@ -31,7 +33,7 @@ public override ICommand CreateCommand(ILogger logger) return new DatabaseCreateCommand { Log = logger, - Database = CreateDatabase(logger, configuration, TransactionMode.None, WhatIf), + Database = database, ScriptSequence = sequence, PowerShellFactory = powerShellFactory }; diff --git a/Sources/SqlDatabase/Configuration/DatabaseConfiguration.cs b/Sources/SqlDatabase/Configuration/DatabaseConfiguration.cs new file mode 100644 index 00000000..87697cd3 --- /dev/null +++ b/Sources/SqlDatabase/Configuration/DatabaseConfiguration.cs @@ -0,0 +1,28 @@ +using System.Configuration; + +namespace SqlDatabase.Configuration +{ + public sealed class DatabaseConfiguration : ConfigurationElement + { + private const string PropertyGetCurrentVersionScript = "getCurrentVersion"; + private const string PropertySetCurrentVersionScript = "setCurrentVersion"; + private const string PropertyVariables = "variables"; + + [ConfigurationProperty(PropertyGetCurrentVersionScript)] + public string GetCurrentVersionScript + { + get => (string)this[PropertyGetCurrentVersionScript]; + set => this[PropertyGetCurrentVersionScript] = value; + } + + [ConfigurationProperty(PropertySetCurrentVersionScript)] + public string SetCurrentVersionScript + { + get => (string)this[PropertySetCurrentVersionScript]; + set => this[PropertySetCurrentVersionScript] = value; + } + + [ConfigurationProperty(PropertyVariables)] + public NameValueConfigurationCollection Variables => (NameValueConfigurationCollection)this[PropertyVariables]; + } +} \ No newline at end of file diff --git a/Sources/SqlDatabase/Configuration/ExecuteCommandLine.cs b/Sources/SqlDatabase/Configuration/ExecuteCommandLine.cs index 694d17c5..2013cc82 100644 --- a/Sources/SqlDatabase/Configuration/ExecuteCommandLine.cs +++ b/Sources/SqlDatabase/Configuration/ExecuteCommandLine.cs @@ -20,13 +20,15 @@ public override ICommand CreateCommand(ILogger logger) configuration.LoadFrom(ConfigurationFile); var powerShellFactory = PowerShellFactory.Create(UsePowerShell); + var database = CreateDatabase(logger, configuration, TransactionMode.None, WhatIf); var sequence = new CreateScriptSequence { ScriptFactory = new ScriptFactory { - Configuration = configuration.SqlDatabase, - PowerShellFactory = powerShellFactory + AssemblyScriptConfiguration = configuration.SqlDatabase.AssemblyScript, + PowerShellFactory = powerShellFactory, + TextReader = database.Adapter.CreateSqlTextReader() }, Sources = Scripts.ToArray() }; @@ -34,7 +36,7 @@ public override ICommand CreateCommand(ILogger logger) return new DatabaseExecuteCommand { Log = logger, - Database = CreateDatabase(logger, configuration, Transaction, WhatIf), + Database = database, ScriptSequence = sequence, PowerShellFactory = powerShellFactory }; diff --git a/Sources/SqlDatabase/Configuration/ExportCommandLine.cs b/Sources/SqlDatabase/Configuration/ExportCommandLine.cs index 3492a242..ac83453e 100644 --- a/Sources/SqlDatabase/Configuration/ExportCommandLine.cs +++ b/Sources/SqlDatabase/Configuration/ExportCommandLine.cs @@ -18,9 +18,15 @@ public override ICommand CreateCommand(ILogger logger) var configuration = new ConfigurationManager(); configuration.LoadFrom(ConfigurationFile); + var database = CreateDatabase(logger, configuration, TransactionMode.None, false); + var sequence = new CreateScriptSequence { - ScriptFactory = new ScriptFactory { Configuration = configuration.SqlDatabase }, + ScriptFactory = new ScriptFactory + { + AssemblyScriptConfiguration = configuration.SqlDatabase.AssemblyScript, + TextReader = database.Adapter.CreateSqlTextReader() + }, Sources = Scripts.ToArray() }; @@ -28,7 +34,7 @@ public override ICommand CreateCommand(ILogger logger) { Log = WrapLogger(logger), OpenOutput = CreateOutput(), - Database = CreateDatabase(logger, configuration, TransactionMode.None, false), + Database = database, ScriptSequence = sequence, DestinationTableName = DestinationTableName }; diff --git a/Sources/SqlDatabase/Configuration/GenericCommandLine.cs b/Sources/SqlDatabase/Configuration/GenericCommandLine.cs index 5f8a87a1..23e676bc 100644 --- a/Sources/SqlDatabase/Configuration/GenericCommandLine.cs +++ b/Sources/SqlDatabase/Configuration/GenericCommandLine.cs @@ -23,8 +23,6 @@ public sealed class GenericCommandLine public string ExportToFile { get; set; } - public bool PreFormatOutputLogs { get; set; } - public bool WhatIf { get; set; } public bool FolderAsModuleName { get; set; } diff --git a/Sources/SqlDatabase/Configuration/GenericCommandLineBuilder.cs b/Sources/SqlDatabase/Configuration/GenericCommandLineBuilder.cs index 328250cc..a3280b9e 100644 --- a/Sources/SqlDatabase/Configuration/GenericCommandLineBuilder.cs +++ b/Sources/SqlDatabase/Configuration/GenericCommandLineBuilder.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Text; namespace SqlDatabase.Configuration @@ -97,12 +96,6 @@ public GenericCommandLineBuilder SetExportToFile(string fileName) return this; } - public GenericCommandLineBuilder SetPreFormatOutputLogs(bool value) - { - Line.PreFormatOutputLogs = value; - return this; - } - public GenericCommandLineBuilder SetWhatIf(bool value) { Line.WhatIf = value; @@ -126,96 +119,76 @@ public GenericCommandLine Build() return Line; } - public string[] BuildArray(bool escaped) + public string[] BuildArray() { var cmd = Build(); var result = new List { cmd.Command, - CombineArg(Arg.Database, cmd.Connection, escaped) + CombineArg(Arg.Database, cmd.Connection) }; foreach (var script in cmd.Scripts) { - result.Add(CombineArg(Arg.Scripts, script, escaped)); + result.Add(CombineArg(Arg.Scripts, script)); } foreach (var script in cmd.InLineScript) { - result.Add(CombineArg(Arg.InLineScript, script, escaped)); + result.Add(CombineArg(Arg.InLineScript, script)); } if (cmd.Transaction != default(TransactionMode)) { - result.Add(CombineArg(Arg.Transaction, cmd.Transaction.ToString(), escaped)); + result.Add(CombineArg(Arg.Transaction, cmd.Transaction.ToString())); } if (!string.IsNullOrEmpty(cmd.ConfigurationFile)) { - result.Add(CombineArg(Arg.Configuration, cmd.ConfigurationFile, escaped)); + result.Add(CombineArg(Arg.Configuration, cmd.ConfigurationFile)); } if (!string.IsNullOrEmpty(cmd.ExportToTable)) { - result.Add(CombineArg(Arg.ExportToTable, cmd.ExportToTable, escaped)); + result.Add(CombineArg(Arg.ExportToTable, cmd.ExportToTable)); } if (!string.IsNullOrEmpty(cmd.ExportToFile)) { - result.Add(CombineArg(Arg.ExportToFile, cmd.ExportToFile, escaped)); + result.Add(CombineArg(Arg.ExportToFile, cmd.ExportToFile)); } foreach (var entry in cmd.Variables) { - result.Add(CombineArg(Arg.Variable + entry.Key, entry.Value, escaped)); - } - - if (cmd.PreFormatOutputLogs) - { - result.Add(CombineArg(Arg.PreFormatOutputLogs, cmd.PreFormatOutputLogs.ToString(), false)); + result.Add(CombineArg(Arg.Variable + entry.Key, entry.Value)); } if (cmd.WhatIf) { - result.Add(CombineArg(Arg.WhatIf, cmd.WhatIf.ToString(), false)); + result.Add(CombineArg(Arg.WhatIf, cmd.WhatIf.ToString())); } if (cmd.FolderAsModuleName) { - result.Add(CombineArg(Arg.FolderAsModuleName, cmd.FolderAsModuleName.ToString(), false)); + result.Add(CombineArg(Arg.FolderAsModuleName, cmd.FolderAsModuleName.ToString())); } if (!string.IsNullOrEmpty(cmd.LogFileName)) { - result.Add(CombineArg(Arg.Log, cmd.LogFileName, escaped)); + result.Add(CombineArg(Arg.Log, cmd.LogFileName)); } return result.ToArray(); } - private static string CombineArg(string key, string value, bool escaped) + private static string CombineArg(string key, string value) { - var result = new StringBuilder(); - - if (escaped && !string.IsNullOrEmpty(value)) - { - result.Append(Arg.Base64Sign); - } - - result + var result = new StringBuilder() .Append(Arg.Sign) .Append(key) - .Append("="); - - if (escaped && !string.IsNullOrEmpty(value)) - { - result.Append(Convert.ToBase64String(Encoding.UTF8.GetBytes(value))); - } - else - { - result.Append(value); - } + .Append("=") + .Append(value); return result.ToString(); } diff --git a/Sources/SqlDatabase/Configuration/UpgradeCommandLine.cs b/Sources/SqlDatabase/Configuration/UpgradeCommandLine.cs index 8ae6f4f0..ec9e95d4 100644 --- a/Sources/SqlDatabase/Configuration/UpgradeCommandLine.cs +++ b/Sources/SqlDatabase/Configuration/UpgradeCommandLine.cs @@ -29,8 +29,9 @@ public override ICommand CreateCommand(ILogger logger) { ScriptFactory = new ScriptFactory { - Configuration = configuration.SqlDatabase, - PowerShellFactory = powerShellFactory + AssemblyScriptConfiguration = configuration.SqlDatabase.AssemblyScript, + PowerShellFactory = powerShellFactory, + TextReader = database.Adapter.CreateSqlTextReader() }, VersionResolver = new ModuleVersionResolver { Database = database, Log = logger }, Sources = Scripts.ToArray(), diff --git a/Sources/SqlDatabase/Export/DataExporter.cs b/Sources/SqlDatabase/Export/DataExporter.cs index e0fabb8d..e3769a09 100644 --- a/Sources/SqlDatabase/Export/DataExporter.cs +++ b/Sources/SqlDatabase/Export/DataExporter.cs @@ -1,12 +1,10 @@ -using System; -using System.Data; -using System.Linq; +using System.Data; namespace SqlDatabase.Export { internal sealed class DataExporter : IDataExporter { - public SqlWriter Output { get; set; } + public SqlWriterBase Output { get; set; } public int MaxInsertBatchSize { get; set; } = 500; @@ -17,7 +15,7 @@ public void Export(IDataReader source, string tableName) ExportTable table; using (var metadata = source.GetSchemaTable()) { - table = ReadSchemaTable(metadata, tableName); + table = Output.ReadSchemaTable(metadata, tableName); } CreateTable(table); @@ -32,7 +30,7 @@ public void Export(IDataReader source, string tableName) { if (batchNum > 0) { - Output.Go().Line(); + Output.BatchSeparator().Line(); } WriteInsertHeader(table); @@ -51,7 +49,7 @@ public void Export(IDataReader source, string tableName) Output.Text(", "); } - Output.Value(source[i]); + Output.Value(source[i], table.Columns[i].SqlDataTypeName); } Output.Line(")"); @@ -66,59 +64,13 @@ public void Export(IDataReader source, string tableName) } } - Output.Go(); + Output.BatchSeparator(); if (rowNum > 0) { Log.Info("{0} rows".FormatWith((batchNum * MaxInsertBatchSize) + rowNum)); } } - internal ExportTable ReadSchemaTable(DataTable metadata, string tableName) - { - var result = new ExportTable { Name = tableName }; - - const string GeneratedName = "GeneratedName"; - var generatedIndex = 0; - - var rows = metadata.Rows.Cast().OrderBy(i => (int)i["ColumnOrdinal"]); - foreach (var row in rows) - { - var name = (string)row["ColumnName"]; - if (string.IsNullOrWhiteSpace(name)) - { - generatedIndex++; - name = GeneratedName + generatedIndex; - } - - var typeName = (string)row["DataTypeName"]; - var size = (int)row["ColumnSize"]; - - if ("timestamp".Equals(typeName, StringComparison.OrdinalIgnoreCase) - || "RowVersion".Equals(typeName, StringComparison.OrdinalIgnoreCase)) - { - typeName = "VARBINARY"; - size = 8; - } - else if (typeName.EndsWith("sys.HIERARCHYID", StringComparison.OrdinalIgnoreCase)) - { - // System.IO.FileNotFoundException : Could not load file or assembly 'Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies - throw new NotSupportedException("Data type hierarchyid is not supported, to export data convert value to NVARCHAR: SELECT CAST([{0}] AND NVARCHAR(100)) [{0}]".FormatWith(name)); - } - - result.Columns.Add(new ExportTableColumn - { - Name = name, - SqlDataTypeName = typeName, - Size = size, - NumericPrecision = (short?)DataReaderTools.CleanValue(row["NumericPrecision"]), - NumericScale = (short?)DataReaderTools.CleanValue(row["NumericScale"]), - AllowNull = (bool)row["AllowDBNull"] - }); - } - - return result; - } - private void CreateTable(ExportTable table) { Output @@ -155,7 +107,7 @@ private void CreateTable(ExportTable table) Output .Line(")") - .Go(); + .BatchSeparator(); } private void WriteInsertHeader(ExportTable table) diff --git a/Sources/SqlDatabase/Export/IDataExporter.cs b/Sources/SqlDatabase/Export/IDataExporter.cs index 47b7fa03..50861431 100644 --- a/Sources/SqlDatabase/Export/IDataExporter.cs +++ b/Sources/SqlDatabase/Export/IDataExporter.cs @@ -4,7 +4,7 @@ namespace SqlDatabase.Export { internal interface IDataExporter { - SqlWriter Output { get; set; } + SqlWriterBase Output { get; set; } ILogger Log { get; set; } diff --git a/Sources/SqlDatabase/Export/SqlWriterBase.cs b/Sources/SqlDatabase/Export/SqlWriterBase.cs new file mode 100644 index 00000000..a0ce7ce3 --- /dev/null +++ b/Sources/SqlDatabase/Export/SqlWriterBase.cs @@ -0,0 +1,97 @@ +using System; +using System.Data; +using System.IO; + +namespace SqlDatabase.Export +{ + internal abstract class SqlWriterBase : IDisposable + { + public const char Q = '\''; + + protected SqlWriterBase(TextWriter output) + { + Output = output; + } + + public TextWriter Output { get; } + + public void Dispose() + { + Output.Dispose(); + } + + public SqlWriterBase Line(string value = null) + { + Output.WriteLine(value); + return this; + } + + public SqlWriterBase Text(string value) + { + Output.Write(value); + return this; + } + + public SqlWriterBase TextFormat(string format, params object[] args) + { + Output.Write(format, args); + return this; + } + + public abstract SqlWriterBase Name(string value); + + public abstract SqlWriterBase BatchSeparator(); + + public abstract SqlWriterBase DataType(string typeName, int size, int precision, int scale); + + public SqlWriterBase Null() + { + Output.Write("NULL"); + return this; + } + + public SqlWriterBase Value(object value, string typeNameHint = null) + { + value = DataReaderTools.CleanValue(value); + if (value == null) + { + Null(); + return this; + } + + if (!TryWriteValue(value, typeNameHint)) + { + throw new NotSupportedException("Type [{0}] is not supported.".FormatWith(value.GetType())); + } + + return this; + } + + public abstract ExportTable ReadSchemaTable(DataTable metadata, string tableName); + + public abstract string GetDefaultTableName(); + + protected abstract bool TryWriteValue(object value, string typeNameHint); + + protected void ValueString(string value, char q = Q) + { + Output.Write(q); + WriteEscapedString(value); + Output.Write(q); + } + + protected void WriteEscapedString(string value) + { + for (var i = 0; i < value.Length; i++) + { + var c = value[i]; + Output.Write(c); + + if (c == '\'') + { + Output.Write(Q); + } + } + } + } +} diff --git a/Sources/SqlDatabase/Log/LoggerFactory.cs b/Sources/SqlDatabase/Log/LoggerFactory.cs index 285ee8b2..8b621c1a 100644 --- a/Sources/SqlDatabase/Log/LoggerFactory.cs +++ b/Sources/SqlDatabase/Log/LoggerFactory.cs @@ -6,10 +6,5 @@ public static ILogger CreateDefault() { return new ConsoleLogger(); } - - public static ILogger CreatePreFormatted() - { - return new RedirectedConsoleLogger(); - } } } diff --git a/Sources/SqlDatabase/Log/RedirectedConsoleLogger.cs b/Sources/SqlDatabase/Log/RedirectedConsoleLogger.cs deleted file mode 100644 index 1965f4d4..00000000 --- a/Sources/SqlDatabase/Log/RedirectedConsoleLogger.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace SqlDatabase.Log -{ - internal sealed class RedirectedConsoleLogger : LoggerBase - { - // http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html - internal const string SetForegroundColorToDefault = "\x001B[39m"; - internal const string SetForegroundColorToRed = "\x001B[31m"; - - protected override void WriteError(string message) - { - Console.WriteLine(SetForegroundColorToRed + message + SetForegroundColorToDefault); - } - - protected override void WriteInfo(string message) - { - Console.WriteLine(message); - } - } -} diff --git a/Sources/SqlDatabase/Program.cs b/Sources/SqlDatabase/Program.cs index ecc8175d..47614c77 100644 --- a/Sources/SqlDatabase/Program.cs +++ b/Sources/SqlDatabase/Program.cs @@ -10,7 +10,7 @@ internal static class Program { public static int Main(string[] args) { - var logger = CreateLogger(args); + var logger = LoggerFactory.CreateDefault(); return Run(logger, args); } @@ -105,13 +105,6 @@ private static CommandLineFactory ResolveFactory(string[] args, ILogger logger) return null; } - private static ILogger CreateLogger(string[] args) - { - return CommandLineParser.PreFormatOutputLogs(args) ? - LoggerFactory.CreatePreFormatted() : - LoggerFactory.CreateDefault(); - } - private static bool TryWrapWithUsersLogger(ILogger logger, string[] args, out CombinedLogger combined) { combined = null; diff --git a/Sources/SqlDatabase/Scripts/AssemblyInternal/EntryPointResolver.cs b/Sources/SqlDatabase/Scripts/AssemblyInternal/EntryPointResolver.cs index e25e12e1..83dcb633 100644 --- a/Sources/SqlDatabase/Scripts/AssemblyInternal/EntryPointResolver.cs +++ b/Sources/SqlDatabase/Scripts/AssemblyInternal/EntryPointResolver.cs @@ -69,12 +69,20 @@ public IEntryPoint Resolve(Assembly assembly) private Type ResolveClass(Assembly assembly) { - var candidates = assembly + var filter = assembly .GetExportedTypes() - .Where(i => i.IsClass) - .Where(i => ExecutorClassName.Equals(i.Name, StringComparison.Ordinal)) - .ToList(); + .Where(i => i.IsClass && !i.IsAbstract && !i.IsGenericTypeDefinition); + + if (ExecutorClassName.IndexOf('.') >= 0 || ExecutorClassName.IndexOf('+') >= 0) + { + filter = filter.Where(i => i.FullName?.EndsWith(ExecutorClassName, StringComparison.OrdinalIgnoreCase) == true); + } + else + { + filter = filter.Where(i => ExecutorClassName.Equals(i.Name, StringComparison.Ordinal)); + } + var candidates = filter.ToList(); if (candidates.Count == 0) { Log.Error("public class {0} not found.".FormatWith(ExecutorClassName)); diff --git a/Sources/SqlDatabase/Scripts/AssemblyInternal/Net452/DomainAgent.cs b/Sources/SqlDatabase/Scripts/AssemblyInternal/Net452/DomainAgent.cs index 1e28f979..fc873b1d 100644 --- a/Sources/SqlDatabase/Scripts/AssemblyInternal/Net452/DomainAgent.cs +++ b/Sources/SqlDatabase/Scripts/AssemblyInternal/Net452/DomainAgent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Data; using System.Diagnostics; +using System.IO; using System.Reflection; namespace SqlDatabase.Scripts.AssemblyInternal.Net452 @@ -56,18 +57,25 @@ public bool Execute(IDbCommand command, IReadOnlyDictionary vari public void BeforeUnload() { _consoleRedirect?.Dispose(); + AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve; } private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) { - var sqlDataBase = GetType().Assembly; var argName = new AssemblyName(args.Name).Name; + var sqlDataBase = GetType().Assembly; if (sqlDataBase.GetName().Name.Equals(argName, StringComparison.OrdinalIgnoreCase)) { return sqlDataBase; } + var fileName = Path.Combine(Path.GetDirectoryName(sqlDataBase.Location), argName + ".dll"); + if (File.Exists(fileName)) + { + return Assembly.LoadFrom(fileName); + } + return null; } } diff --git a/Sources/SqlDatabase/Scripts/AssemblyScript.cs b/Sources/SqlDatabase/Scripts/AssemblyScript.cs index 38f16768..34cc6c73 100644 --- a/Sources/SqlDatabase/Scripts/AssemblyScript.cs +++ b/Sources/SqlDatabase/Scripts/AssemblyScript.cs @@ -57,7 +57,7 @@ public IList GetDependencies() using (var reader = new StreamReader(description)) { - return SqlBatchParser.ExtractDependencies(reader, DisplayName).ToArray(); + return DependencyParser.ExtractDependencies(reader, DisplayName).ToArray(); } } } diff --git a/Sources/SqlDatabase/Scripts/Database.cs b/Sources/SqlDatabase/Scripts/Database.cs index 101a15d0..35ac02a4 100644 --- a/Sources/SqlDatabase/Scripts/Database.cs +++ b/Sources/SqlDatabase/Scripts/Database.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Data.SqlClient; using SqlDatabase.Configuration; namespace SqlDatabase.Scripts @@ -14,9 +13,7 @@ public Database() Variables = new Variables(); } - public string ConnectionString { get; set; } - - public AppConfiguration Configuration { get; set; } + public IDatabaseAdapter Adapter { get; set; } public ILogger Log { get; set; } @@ -30,7 +27,7 @@ public Version GetCurrentVersion(string moduleName) { Variables.ModuleName = moduleName; - using (var connection = new SqlConnection(ConnectionString)) + using (var connection = Adapter.CreateConnection(false)) using (var command = connection.CreateCommand()) { command.CommandTimeout = 0; @@ -42,10 +39,10 @@ public Version GetCurrentVersion(string moduleName) public string GetServerVersion() { - using (var connection = CreateConnection(true)) + using (var connection = Adapter.CreateConnection(true)) using (var command = connection.CreateCommand()) { - command.CommandText = "select @@version"; + command.CommandText = Adapter.GetServerVersionSelectScript(); connection.Open(); return Convert.ToString(command.ExecuteScalar()); @@ -57,7 +54,7 @@ public void Execute(IScript script, string moduleName, Version currentVersion, V Variables.ModuleName = moduleName; Variables.CurrentVersion = currentVersion.ToString(); Variables.TargetVersion = targetVersion.ToString(); - Variables.DatabaseName = new SqlConnectionStringBuilder(ConnectionString).InitialCatalog; + Variables.DatabaseName = Adapter.DatabaseName; if (WhatIf) { @@ -71,7 +68,7 @@ public void Execute(IScript script, string moduleName, Version currentVersion, V public void Execute(IScript script) { - Variables.DatabaseName = new SqlConnectionStringBuilder(ConnectionString).InitialCatalog; + Variables.DatabaseName = Adapter.DatabaseName; if (WhatIf) { @@ -85,11 +82,10 @@ public void Execute(IScript script) public IEnumerable ExecuteReader(IScript script) { - Variables.DatabaseName = new SqlConnectionStringBuilder(ConnectionString).InitialCatalog; + Variables.DatabaseName = Adapter.DatabaseName; - using (var connection = CreateConnection(false)) + using (var connection = Adapter.CreateConnection(false)) { - connection.InfoMessage += OnConnectionInfoMessage; connection.Open(); using (var command = connection.CreateCommand()) @@ -104,28 +100,9 @@ public IEnumerable ExecuteReader(IScript script) } } - private void OnConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e) - { - Log.Info("output: {0}".FormatWith(e.ToString())); - } - - private SqlConnection CreateConnection(bool switchToMaster = false) - { - var connectionString = ConnectionString; - if (switchToMaster) - { - var builder = new SqlConnectionStringBuilder(ConnectionString); - builder.InitialCatalog = "master"; - connectionString = builder.ToString(); - } - - var connection = new SqlConnection(connectionString); - return connection; - } - - private void WriteCurrentVersion(SqlCommand command, Version targetVersion) + private void WriteCurrentVersion(IDbCommand command, Version targetVersion) { - var script = new SqlScriptVariableParser(Variables).ApplyVariables(Configuration.SetCurrentVersionScript); + var script = new SqlScriptVariableParser(Variables).ApplyVariables(Adapter.GetVersionUpdateScript()); command.CommandText = script; try @@ -147,9 +124,9 @@ private void WriteCurrentVersion(SqlCommand command, Version targetVersion) } } - private Version ReadCurrentVersion(SqlCommand command) + private Version ReadCurrentVersion(IDbCommand command) { - var script = new SqlScriptVariableParser(Variables).ApplyVariables(Configuration.GetCurrentVersionScript); + var script = new SqlScriptVariableParser(Variables).ApplyVariables(Adapter.GetVersionSelectScript()); command.CommandText = script; string version; @@ -177,11 +154,9 @@ private Version ReadCurrentVersion(SqlCommand command) private void InvokeExecuteUpgrade(IScript script, Version targetVersion) { - using (var connection = CreateConnection()) + using (var connection = Adapter.CreateConnection(false)) using (var command = connection.CreateCommand()) { - connection.InfoMessage += OnConnectionInfoMessage; - command.CommandTimeout = 0; connection.Open(); @@ -191,12 +166,6 @@ private void InvokeExecuteUpgrade(IScript script, Version targetVersion) script.Execute(command, Variables, Log); - if (!Variables.DatabaseName.Equals(connection.Database, StringComparison.OrdinalIgnoreCase)) - { - command.CommandText = "USE [{0}]".FormatWith(Variables.DatabaseName); - command.ExecuteNonQuery(); - } - WriteCurrentVersion(command, targetVersion); transaction?.Commit(); @@ -208,21 +177,20 @@ private void InvokeExecute(IScript script) { bool useMaster; - using (var connection = CreateConnection(true)) + using (var connection = Adapter.CreateConnection(true)) using (var command = connection.CreateCommand()) { command.CommandTimeout = 0; connection.Open(); - command.CommandText = "SELECT 1 FROM sys.databases WHERE Name=N'{0}'".FormatWith(Variables.DatabaseName); + command.CommandText = Adapter.GetDatabaseExistsScript(Variables.DatabaseName); var value = command.ExecuteScalar(); useMaster = value == null || Convert.IsDBNull(value); } - using (var connection = CreateConnection(useMaster)) + using (var connection = Adapter.CreateConnection(useMaster)) { - connection.InfoMessage += OnConnectionInfoMessage; connection.Open(); using (var transaction = Transaction == TransactionMode.PerStep ? connection.BeginTransaction(IsolationLevel.ReadCommitted) : null) diff --git a/Sources/SqlDatabase/Scripts/DatabaseAdapterFactory.cs b/Sources/SqlDatabase/Scripts/DatabaseAdapterFactory.cs new file mode 100644 index 00000000..3dab85b9 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/DatabaseAdapterFactory.cs @@ -0,0 +1,62 @@ +using System; +using System.Configuration; +using System.Data.SqlClient; +using Npgsql; +using SqlDatabase.Configuration; +using SqlDatabase.Scripts.MsSql; +using SqlDatabase.Scripts.PgSql; + +namespace SqlDatabase.Scripts +{ + internal static class DatabaseAdapterFactory + { + public static IDatabaseAdapter CreateAdapter(string connectionString, AppConfiguration configuration, ILogger log) + { + if (IsMsSql(connectionString)) + { + return new MsSqlDatabaseAdapter(connectionString, configuration, log); + } + + if (IsPgSql(connectionString)) + { + return new PgSqlDatabaseAdapter(connectionString, configuration, log); + } + + throw new ConfigurationErrorsException("Fail to define database type from provided connection string."); + } + + private static bool IsMsSql(string connectionString) + { + try + { + new SqlConnectionStringBuilder(connectionString); + return true; + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + + return false; + } + + private static bool IsPgSql(string connectionString) + { + try + { + new NpgsqlConnectionStringBuilder(connectionString); + return true; + } + catch (ArgumentException) + { + } + catch (FormatException) + { + } + + return false; + } + } +} diff --git a/Sources/SqlDatabase/Scripts/SqlBatchParser.cs b/Sources/SqlDatabase/Scripts/DependencyParser.cs similarity index 52% rename from Sources/SqlDatabase/Scripts/SqlBatchParser.cs rename to Sources/SqlDatabase/Scripts/DependencyParser.cs index 43305b4e..53c7c202 100644 --- a/Sources/SqlDatabase/Scripts/SqlBatchParser.cs +++ b/Sources/SqlDatabase/Scripts/DependencyParser.cs @@ -6,41 +6,10 @@ namespace SqlDatabase.Scripts { - internal static class SqlBatchParser + internal static class DependencyParser { private const string ModuleDependencyPattern = "^(-|\\*)+.*module dependency:\\s?(?'name'[\\w\\-]+)(\\s+|\\s*-\\s*)(?'version'[\\.\\w]+)"; - public static IEnumerable SplitByGo(Stream sql) - { - var batch = new StringBuilder(); - - foreach (var line in ReadLines(sql)) - { - if (IsGo(line)) - { - if (batch.Length > 0) - { - yield return batch.ToString(); - batch.Clear(); - } - } - else if (batch.Length > 0 || line.Trim().Length > 0) - { - if (batch.Length > 0) - { - batch.AppendLine(); - } - - batch.Append(line); - } - } - - if (batch.Length > 0) - { - yield return batch.ToString(); - } - } - public static IEnumerable ExtractDependencies(TextReader reader, string scriptName) { string line; @@ -58,23 +27,6 @@ public static IEnumerable ExtractDependencies(TextReader reade } } - internal static bool IsGo(string text) - { - return Regex.IsMatch(text, "^(\\s*(go)+\\s*)+$", RegexOptions.Compiled | RegexOptions.IgnoreCase); - } - - private static IEnumerable ReadLines(Stream sql) - { - using (var reader = new StreamReader(sql)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - yield return line; - } - } - } - private static bool TryParseDependencyLine(string line, out string moduleName, out string version) { moduleName = null; diff --git a/Sources/SqlDatabase/Scripts/IDatabase.cs b/Sources/SqlDatabase/Scripts/IDatabase.cs index ffa51cb4..883ffaa3 100644 --- a/Sources/SqlDatabase/Scripts/IDatabase.cs +++ b/Sources/SqlDatabase/Scripts/IDatabase.cs @@ -4,9 +4,9 @@ namespace SqlDatabase.Scripts { - public interface IDatabase + internal interface IDatabase { - string ConnectionString { get; } + IDatabaseAdapter Adapter { get; } string GetServerVersion(); diff --git a/Sources/SqlDatabase/Scripts/IDatabaseAdapter.cs b/Sources/SqlDatabase/Scripts/IDatabaseAdapter.cs new file mode 100644 index 00000000..83c0e9d6 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/IDatabaseAdapter.cs @@ -0,0 +1,27 @@ +using System.Data; +using System.IO; +using SqlDatabase.Export; + +namespace SqlDatabase.Scripts +{ + internal interface IDatabaseAdapter + { + string DatabaseName { get; } + + string GetUserFriendlyConnectionString(); + + ISqlTextReader CreateSqlTextReader(); + + SqlWriterBase CreateSqlWriter(TextWriter output); + + IDbConnection CreateConnection(bool switchToMaster); + + string GetServerVersionSelectScript(); + + string GetDatabaseExistsScript(string databaseName); + + string GetVersionSelectScript(); + + string GetVersionUpdateScript(); + } +} diff --git a/Sources/SqlDatabase/Scripts/ISqlTextReader.cs b/Sources/SqlDatabase/Scripts/ISqlTextReader.cs new file mode 100644 index 00000000..ca0e5df9 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/ISqlTextReader.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.IO; + +namespace SqlDatabase.Scripts +{ + internal interface ISqlTextReader + { + string ReadFirstBatch(Stream sql); + + IEnumerable ReadBatches(Stream sql); + } +} diff --git a/Sources/SqlDatabase/Scripts/MsSql/MsSqlDatabaseAdapter.cs b/Sources/SqlDatabase/Scripts/MsSql/MsSqlDatabaseAdapter.cs new file mode 100644 index 00000000..6bf130a2 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/MsSql/MsSqlDatabaseAdapter.cs @@ -0,0 +1,100 @@ +using System.Data; +using System.Data.SqlClient; +using System.IO; +using SqlDatabase.Configuration; +using SqlDatabase.Export; + +namespace SqlDatabase.Scripts.MsSql +{ + internal sealed class MsSqlDatabaseAdapter : IDatabaseAdapter + { + public const string DefaultSelectVersion = "SELECT value from sys.fn_listextendedproperty('version', default, default, default, default, default, default)"; + public const string DefaultUpdateVersion = "EXEC sys.sp_updateextendedproperty @name=N'version', @value=N'{{TargetVersion}}'"; + + private readonly string _connectionString; + private readonly string _connectionStringMaster; + private readonly AppConfiguration _configuration; + private readonly ILogger _log; + private readonly SqlInfoMessageEventHandler _onConnectionInfoMessage; + + public MsSqlDatabaseAdapter( + string connectionString, + AppConfiguration configuration, + ILogger log) + { + _connectionString = connectionString; + _configuration = configuration; + _log = log; + + var builder = new SqlConnectionStringBuilder(connectionString); + DatabaseName = builder.InitialCatalog; + builder.InitialCatalog = "master"; + _connectionStringMaster = builder.ToString(); + + _onConnectionInfoMessage = OnConnectionInfoMessage; + } + + public string DatabaseName { get; } + + public string GetUserFriendlyConnectionString() + { + var cs = new SqlConnectionStringBuilder(_connectionString); + return "database [{0}] on [{1}]".FormatWith(cs.InitialCatalog, cs.DataSource); + } + + public ISqlTextReader CreateSqlTextReader() => new MsSqlTextReader(); + + public SqlWriterBase CreateSqlWriter(TextWriter output) => new MsSqlWriter(output); + + public IDbConnection CreateConnection(bool switchToMaster) + { + var connectionString = switchToMaster ? _connectionStringMaster : _connectionString; + + var connection = new SqlConnection(connectionString); + connection.InfoMessage += _onConnectionInfoMessage; + + return connection; + } + + public string GetServerVersionSelectScript() => "select @@version"; + + public string GetDatabaseExistsScript(string databaseName) => "SELECT 1 FROM sys.databases WHERE Name=N'{0}'".FormatWith(databaseName); + + public string GetVersionSelectScript() + { + var script = _configuration.MsSql.GetCurrentVersionScript; + if (string.IsNullOrWhiteSpace(script)) + { + script = _configuration.GetCurrentVersionScript; + } + + if (string.IsNullOrWhiteSpace(script)) + { + script = DefaultSelectVersion; + } + + return script; + } + + public string GetVersionUpdateScript() + { + var script = _configuration.MsSql.SetCurrentVersionScript; + if (string.IsNullOrWhiteSpace(script)) + { + script = _configuration.SetCurrentVersionScript; + } + + if (string.IsNullOrWhiteSpace(script)) + { + script = DefaultUpdateVersion; + } + + return script; + } + + private void OnConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e) + { + _log.Info("output: {0}".FormatWith(e.ToString())); + } + } +} diff --git a/Sources/SqlDatabase/Scripts/MsSql/MsSqlTextReader.cs b/Sources/SqlDatabase/Scripts/MsSql/MsSqlTextReader.cs new file mode 100644 index 00000000..390569ab --- /dev/null +++ b/Sources/SqlDatabase/Scripts/MsSql/MsSqlTextReader.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlDatabase.Scripts.MsSql +{ + internal sealed class MsSqlTextReader : ISqlTextReader + { + private readonly Regex _goRegex = new Regex("^(\\s*(go)+\\s*)+$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public string ReadFirstBatch(Stream sql) + { + return ReadBatches(sql).FirstOrDefault(); + } + + public IEnumerable ReadBatches(Stream sql) + { + var batch = new StringBuilder(); + + foreach (var line in ReadLines(sql)) + { + if (IsGo(line)) + { + if (batch.Length > 0) + { + yield return batch.ToString(); + batch.Clear(); + } + } + else if (batch.Length > 0 || line.Trim().Length > 0) + { + if (batch.Length > 0) + { + batch.AppendLine(); + } + + batch.Append(line); + } + } + + if (batch.Length > 0) + { + yield return batch.ToString(); + } + } + + internal bool IsGo(string text) => _goRegex.IsMatch(text); + + private static IEnumerable ReadLines(Stream sql) + { + using (var reader = new StreamReader(sql)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + yield return line; + } + } + } + } +} diff --git a/Sources/SqlDatabase/Export/SqlWriter.cs b/Sources/SqlDatabase/Scripts/MsSql/MsSqlWriter.cs similarity index 66% rename from Sources/SqlDatabase/Export/SqlWriter.cs rename to Sources/SqlDatabase/Scripts/MsSql/MsSqlWriter.cs index 5fc593b2..357f05c4 100644 --- a/Sources/SqlDatabase/Export/SqlWriter.cs +++ b/Sources/SqlDatabase/Scripts/MsSql/MsSqlWriter.cs @@ -1,51 +1,21 @@ using System; +using System.Data; using System.Globalization; using System.IO; +using System.Linq; using System.Text; +using SqlDatabase.Export; -namespace SqlDatabase.Export +namespace SqlDatabase.Scripts.MsSql { - internal sealed class SqlWriter : IDisposable + internal sealed class MsSqlWriter : SqlWriterBase { - private const char Q = '\''; - - public SqlWriter(TextWriter output) - { - Output = output; - } - - public TextWriter Output { get; } - - public void Dispose() + public MsSqlWriter(TextWriter output) + : base(output) { - Output.Dispose(); } - public SqlWriter Line(string value = null) - { - Output.WriteLine(value); - return this; - } - - public SqlWriter Go() - { - Output.WriteLine("GO"); - return this; - } - - public SqlWriter Text(string value) - { - Output.Write(value); - return this; - } - - public SqlWriter TextFormat(string format, params object[] args) - { - Output.Write(format, args); - return this; - } - - public SqlWriter Name(string value) + public override SqlWriterBase Name(string value) { const char OpenBracket = '['; const char CloseBracket = ']'; @@ -65,7 +35,13 @@ public SqlWriter Name(string value) return this; } - public SqlWriter DataType(string typeName, int size, int precision, int scale) + public override SqlWriterBase BatchSeparator() + { + Output.WriteLine("GO"); + return this; + } + + public override SqlWriterBase DataType(string typeName, int size, int precision, int scale) { var name = typeName.ToUpperInvariant(); string sizeText = null; @@ -122,30 +98,55 @@ public SqlWriter DataType(string typeName, int size, int precision, int scale) return this; } - public SqlWriter Null() + public override ExportTable ReadSchemaTable(DataTable metadata, string tableName) { - Output.Write("NULL"); - return this; - } + var result = new ExportTable { Name = tableName }; - public SqlWriter Value(object value) - { - value = DataReaderTools.CleanValue(value); - if (value == null) - { - Null(); - return this; - } + const string GeneratedName = "GeneratedName"; + var generatedIndex = 0; - if (!TryWriteValue(value)) + var rows = metadata.Rows.Cast().OrderBy(i => (int)i["ColumnOrdinal"]); + foreach (var row in rows) { - throw new NotSupportedException("Type [{0}] is not supported.".FormatWith(value.GetType())); + var name = (string)row["ColumnName"]; + if (string.IsNullOrWhiteSpace(name)) + { + generatedIndex++; + name = GeneratedName + generatedIndex; + } + + var typeName = (string)row["DataTypeName"]; + var size = (int)row["ColumnSize"]; + + if ("timestamp".Equals(typeName, StringComparison.OrdinalIgnoreCase) + || "RowVersion".Equals(typeName, StringComparison.OrdinalIgnoreCase)) + { + typeName = "VARBINARY"; + size = 8; + } + else if (typeName.EndsWith("sys.HIERARCHYID", StringComparison.OrdinalIgnoreCase)) + { + // System.IO.FileNotFoundException : Could not load file or assembly 'Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies + throw new NotSupportedException("Data type hierarchyid is not supported, to export data convert value to NVARCHAR: SELECT CAST([{0}] AND NVARCHAR(100)) [{0}]".FormatWith(name)); + } + + result.Columns.Add(new ExportTableColumn + { + Name = name, + SqlDataTypeName = typeName, + Size = size, + NumericPrecision = (short?)DataReaderTools.CleanValue(row["NumericPrecision"]), + NumericScale = (short?)DataReaderTools.CleanValue(row["NumericScale"]), + AllowNull = (bool)row["AllowDBNull"] + }); } - return this; + return result; } - private bool TryWriteValue(object value) + public override string GetDefaultTableName() => "dbo.SqlDatabaseExport"; + + protected override bool TryWriteValue(object value, string typeNameHint) { var type = value.GetType(); @@ -179,6 +180,7 @@ private bool TryWriteValue(object value) return true; case TypeCode.String: + Output.Write('N'); ValueString((string)value); return true; } @@ -210,24 +212,6 @@ private bool TryWriteValue(object value) return false; } - private void ValueString(string value) - { - Output.Write('N'); - Output.Write(Q); - for (var i = 0; i < value.Length; i++) - { - var c = value[i]; - Output.Write(c); - - if (c == '\'') - { - Output.Write(Q); - } - } - - Output.Write(Q); - } - private void ValueDate(DateTime value) { Output.Write(Q); @@ -244,7 +228,7 @@ private void ValueGuid(Guid value) private void ValueByteArray(byte[] value) { - var buff = new StringBuilder(value.Length * 2); + var buff = new StringBuilder((value.Length * 2) + 2); buff.Append("0x"); for (var i = 0; i < value.Length; i++) { diff --git a/Sources/SqlDatabase/Scripts/PgSql/PgSqlDatabaseAdapter.cs b/Sources/SqlDatabase/Scripts/PgSql/PgSqlDatabaseAdapter.cs new file mode 100644 index 00000000..7fdd78df --- /dev/null +++ b/Sources/SqlDatabase/Scripts/PgSql/PgSqlDatabaseAdapter.cs @@ -0,0 +1,106 @@ +using System.Data; +using System.IO; +using Npgsql; +using SqlDatabase.Configuration; +using SqlDatabase.Export; + +namespace SqlDatabase.Scripts.PgSql +{ + internal sealed class PgSqlDatabaseAdapter : IDatabaseAdapter + { + public const string DefaultSelectVersion = "SELECT version FROM public.version WHERE module_name = 'database'"; + public const string DefaultUpdateVersion = "UPDATE public.version SET version='{{TargetVersion}}' WHERE module_name = 'database'"; + + private readonly string _connectionString; + private readonly string _connectionStringMaster; + private readonly AppConfiguration _configuration; + private readonly ILogger _log; + private readonly NoticeEventHandler _onConnectionNotice; + + public PgSqlDatabaseAdapter( + string connectionString, + AppConfiguration configuration, + ILogger log) + { + _configuration = configuration; + _log = log; + + var builder = new NpgsqlConnectionStringBuilder(connectionString) + { + // force disable pooling, see IT 01.drop.ps1; 02.create.sql + Pooling = false + }; + + DatabaseName = builder.Database; + _connectionString = builder.ToString(); + + builder.Database = null; + _connectionStringMaster = builder.ToString(); + + _onConnectionNotice = OnConnectionNotice; + } + + public string DatabaseName { get; } + + public string GetUserFriendlyConnectionString() + { + var cs = new NpgsqlConnectionStringBuilder(_connectionString); + return "database [{0}] on [{1}]".FormatWith(cs.Database, cs.Host); + } + + public ISqlTextReader CreateSqlTextReader() => new PgSqlTextReader(); + + public SqlWriterBase CreateSqlWriter(TextWriter output) => new PgSqlWriter(output); + + public IDbConnection CreateConnection(bool switchToMaster) + { + var connectionString = switchToMaster ? _connectionStringMaster : _connectionString; + + var connection = new NpgsqlConnection(connectionString); + connection.Notice += _onConnectionNotice; + + return connection; + } + + public string GetServerVersionSelectScript() => "SELECT version();"; + + public string GetDatabaseExistsScript(string databaseName) => "SELECT 1 FROM PG_DATABASE WHERE LOWER(DATNAME) = LOWER('{0}')".FormatWith(databaseName); + + public string GetVersionSelectScript() + { + var script = _configuration.PgSql.GetCurrentVersionScript; + if (string.IsNullOrWhiteSpace(script)) + { + script = _configuration.GetCurrentVersionScript; + } + + if (string.IsNullOrWhiteSpace(script)) + { + script = DefaultSelectVersion; + } + + return script; + } + + public string GetVersionUpdateScript() + { + var script = _configuration.PgSql.SetCurrentVersionScript; + if (string.IsNullOrWhiteSpace(script)) + { + script = _configuration.SetCurrentVersionScript; + } + + if (string.IsNullOrWhiteSpace(script)) + { + script = DefaultUpdateVersion; + } + + return script; + } + + private void OnConnectionNotice(object sender, NpgsqlNoticeEventArgs e) + { + _log.Info("{0}: {1}".FormatWith(e.Notice.Severity, e.Notice.MessageText)); + } + } +} diff --git a/Sources/SqlDatabase/Scripts/PgSql/PgSqlTextReader.cs b/Sources/SqlDatabase/Scripts/PgSql/PgSqlTextReader.cs new file mode 100644 index 00000000..2d092434 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/PgSql/PgSqlTextReader.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace SqlDatabase.Scripts.PgSql +{ + internal sealed class PgSqlTextReader : ISqlTextReader + { + private const int MaxFirstBatchSize = 20; + private readonly Regex _semicolonRegex = new Regex("^(\\s*;+\\s*)+$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public string ReadFirstBatch(Stream sql) + { + var script = new StringBuilder(); + + using (var reader = new StreamReader(sql)) + { + string line; + var lineNumber = 0; + while ((line = reader.ReadLine()) != null) + { + if (script.Length == 0 && string.IsNullOrWhiteSpace(line)) + { + continue; + } + + lineNumber++; + if (_semicolonRegex.IsMatch(line) || lineNumber > MaxFirstBatchSize) + { + break; + } + + if (script.Length > 0) + { + script.AppendLine(); + } + + script.Append(line); + } + } + + return script.ToString(); + } + + public IEnumerable ReadBatches(Stream sql) + { + string script; + using (var reader = new StreamReader(sql)) + { + script = reader.ReadToEnd(); + } + + if (string.IsNullOrWhiteSpace(script)) + { + return new string[0]; + } + + return new[] { script }; + } + } +} diff --git a/Sources/SqlDatabase/Scripts/PgSql/PgSqlWriter.cs b/Sources/SqlDatabase/Scripts/PgSql/PgSqlWriter.cs new file mode 100644 index 00000000..52b36133 --- /dev/null +++ b/Sources/SqlDatabase/Scripts/PgSql/PgSqlWriter.cs @@ -0,0 +1,493 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Dynamic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using NpgsqlTypes; +using SqlDatabase.Export; + +namespace SqlDatabase.Scripts.PgSql +{ + internal sealed class PgSqlWriter : SqlWriterBase + { + public PgSqlWriter(TextWriter output) + : base(output) + { + } + + public override SqlWriterBase Name(string value) + { + Output.Write(value); + return this; + } + + public override SqlWriterBase BatchSeparator() + { + Output.WriteLine(";"); + return this; + } + + public override SqlWriterBase DataType(string typeName, int size, int precision, int scale) + { + var name = typeName.ToUpperInvariant(); + string sizeText = null; + + switch (name) + { + case "INTEGER": + case "SMALLINT": + case "BIGINT": + break; + case "NUMERIC": + case "TIMESTAMP": + case "INTERVAL": + case "TIME": + if (scale != 0) + { + sizeText = "{0},{1}".FormatWith(precision, scale); + } + else if (precision != 0) + { + sizeText = precision.ToString(CultureInfo.InvariantCulture); + } + + break; + case "CHARACTER VARYING": + case "CHARACTER": + case "BIT": + if (size > 0) + { + sizeText = size.ToString(CultureInfo.InvariantCulture); + } + + break; + } + + Output.Write(name.ToUpperInvariant()); + if (sizeText != null) + { + Output.Write("("); + Output.Write(sizeText); + Output.Write(")"); + } + + return this; + } + + public override ExportTable ReadSchemaTable(DataTable metadata, string tableName) + { + var result = new ExportTable { Name = tableName }; + + const string GeneratedName = "GeneratedName"; + var generatedIndex = 0; + + var rows = metadata.Rows.Cast().OrderBy(i => (int)i["ColumnOrdinal"]); + foreach (var row in rows) + { + var name = (string)row["ColumnName"]; + if (string.IsNullOrWhiteSpace(name)) + { + generatedIndex++; + name = GeneratedName + generatedIndex; + } + + var typeName = (string)row["DataTypeName"]; + var size = (int)row["ColumnSize"]; + + result.Columns.Add(new ExportTableColumn + { + Name = name, + SqlDataTypeName = typeName, + Size = size, + NumericPrecision = (int?)DataReaderTools.CleanValue(row["NumericPrecision"]), + NumericScale = (int?)DataReaderTools.CleanValue(row["NumericScale"]), + AllowNull = (bool?)DataReaderTools.CleanValue(row["AllowDBNull"]) ?? true + }); + } + + return result; + } + + public override string GetDefaultTableName() => "public.sqldatabase_export"; + + protected override bool TryWriteValue(object value, string typeNameHint) + { + var type = value.GetType(); + + switch (Type.GetTypeCode(type)) + { + case TypeCode.Boolean: + if (string.Equals(typeNameHint, "bit", StringComparison.OrdinalIgnoreCase)) + { + Output.Write('B'); + Output.Write(Q); + Output.Write((bool)value ? "1" : "0"); + Output.Write(Q); + } + else + { + Output.Write((bool)value ? "true" : "false"); + } + + return true; + + case TypeCode.Char: + break; + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.Byte: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.Int16: + case TypeCode.Single: + case TypeCode.UInt32: + case TypeCode.UInt64: + case TypeCode.Decimal: + Output.Write(Convert.ToString(value, CultureInfo.InvariantCulture)); + return true; + + case TypeCode.Double: + ValueDouble((double)value); + return true; + + case TypeCode.DateTime: + ValueDate((DateTime)value); + return true; + + case TypeCode.String: + if (typeNameHint?.IndexOf('[') > 0) + { + // '{{"meeting", "lunch"}, {"meeting"}}' + ValueString((string)value, '"'); + } + else + { + ValueString((string)value); + } + + return true; + } + + if (value is Guid id) + { + ValueGuid(id); + return true; + } + + if (value is byte[] byteArray) + { + ValueByteArray(byteArray); + return true; + } + + if (value is TimeSpan timeSpan) + { + ValueTimeSpan(timeSpan); + return true; + } + + if (value is BitArray bitArray) + { + ValueBitArray(bitArray); + return true; + } + + if (value is NpgsqlTsVector vector) + { + ValueTsVector(vector); + return true; + } + + if (value is NpgsqlTsQuery query) + { + ValueTsQuery(query); + return true; + } + + if (value is Array array) + { + if (array.Rank == 1) + { + Value1dArray(array, typeNameHint); + return true; + } + + if (array.Rank == 2) + { + Value2dArray(array, typeNameHint); + return true; + } + + throw new NotSupportedException("{0}d array is not supported.".FormatWith(array.Rank)); + } + + if (value is ExpandoObject composite) + { + ValueComposite(composite); + return true; + } + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(NpgsqlRange<>)) + { + GetType() + .GetMethod(nameof(ValueRange), BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .MakeGenericMethod(type.GenericTypeArguments) + .Invoke(this, new[] { value }); + return true; + } + + return false; + } + + private void ValueDate(DateTime value) + { + Output.Write(Q); + Output.Write(value.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)); + Output.Write(Q); + } + + private void ValueGuid(Guid value) + { + Output.Write(Q); + Output.Write(value); + Output.Write(Q); + } + + private void ValueByteArray(byte[] value) + { + var buff = new StringBuilder((value.Length * 2) + 4); + buff.Append(Q).Append("\\x"); + for (var i = 0; i < value.Length; i++) + { + buff.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", value[i]); + } + + buff.Append(Q); + Output.Write(buff.ToString()); + } + + private void ValueBitArray(BitArray value) + { + var buff = new StringBuilder((value.Length * 2) + 4); + buff.Append('B').Append(Q); + for (var i = 0; i < value.Length; i++) + { + buff.Append(value[i] ? '1' : '0'); + } + + buff.Append(Q); + Output.Write(buff.ToString()); + } + + private void ValueDouble(double value) + { + Output.Write(value.ToString("G17", CultureInfo.InvariantCulture)); + } + + private void ValueTimeSpan(TimeSpan value) + { + Output.Write(Q); + + if (value.Days > 0) + { + Output.Write(value.Days.ToString(CultureInfo.InvariantCulture)); + Output.Write(" "); + value = value.Add(-TimeSpan.FromDays(value.Days)); + } + + Output.Write(value.ToString("g", CultureInfo.InvariantCulture)); + Output.Write(Q); + } + + private void ValueTsVector(NpgsqlTsVector value) + { + Output.Write(Q); + for (var i = 0; i < value.Count; i++) + { + if (i > 0) + { + Output.Write(' '); + } + + var lexeme = value[i]; + WriteEscapedString(lexeme.Text); + + if (lexeme.Count > 0) + { + Output.Write(':'); + for (var j = 0; j < lexeme.Count; j++) + { + if (j > 0) + { + Output.Write(','); + } + + Output.Write(lexeme[j].ToString()); + } + } + } + + Output.Write(Q); + } + + private void ValueTsQuery(NpgsqlTsQuery value) + { + var valueByLexeme = new Dictionary(); + CollectLexeme(value, valueByLexeme); + + var text = new StringBuilder(value.ToString()); + foreach (var entry in valueByLexeme.Values) + { + text.Replace(entry.Name, entry.Original); + } + + Output.Write(Q); + WriteEscapedString(text.ToString()); + Output.Write(Q); + } + + private void CollectLexeme(NpgsqlTsQuery value, IDictionary valueByLexeme) + { + if (value is NpgsqlTsQueryLexeme lexeme) + { + if (!valueByLexeme.ContainsKey(lexeme)) + { + var name = "___sqldb___" + valueByLexeme.Count.ToString(CultureInfo.InvariantCulture); + valueByLexeme.Add(lexeme, (lexeme.Text, Q + name + Q)); + lexeme.Text = name; + } + + return; + } + + if (value is NpgsqlTsQueryNot not) + { + if (not.Child != null) + { + CollectLexeme(not.Child, valueByLexeme); + } + + return; + } + + if (value is NpgsqlTsQueryBinOp bin) + { + if (bin.Left != null) + { + CollectLexeme(bin.Left, valueByLexeme); + } + + if (bin.Right != null) + { + CollectLexeme(bin.Right, valueByLexeme); + } + } + } + + private void Value1dArray(Array value, string typeNameHint) + { + Output.Write(Q); + Output.Write('{'); + for (var i = 0; i < value.Length; i++) + { + if (i > 0) + { + Output.Write(", "); + } + + Value(value.GetValue(i), typeNameHint); + } + + Output.Write('}'); + Output.Write(Q); + } + + private void Value2dArray(Array value, string typeNameHint) + { + Output.Write(Q); + Output.Write('{'); + + if (value.Length > 0) + { + var length1 = value.GetLength(0); + var length2 = value.GetLength(1); + + for (var i1 = 0; i1 < length1; i1++) + { + if (i1 > 0) + { + Output.Write(", "); + } + + Output.Write('{'); + for (var i2 = 0; i2 < length2; i2++) + { + if (i2 > 0) + { + Output.Write(", "); + } + + Value(value.GetValue(i1, i2), typeNameHint); + } + + Output.Write('}'); + } + } + + Output.Write('}'); + Output.Write(Q); + } + + private void ValueComposite(IDictionary value) + { + Output.Write("ROW("); + + var index = 0; + foreach (var entry in value.Values) + { + if (index > 0) + { + Output.Write(", "); + } + + Value(entry); + index++; + } + + Output.Write(')'); + } + + private void ValueRange(NpgsqlRange value) + { + Output.Write(Q); + + if (value.IsEmpty) + { + Output.Write("empty"); + } + else + { + Output.Write(value.LowerBoundIsInclusive ? '[' : '('); + if (!value.LowerBoundInfinite) + { + Value(value.LowerBound); + } + + Output.Write(','); + if (!value.UpperBoundInfinite) + { + Value(value.UpperBound); + } + + Output.Write(value.UpperBoundIsInclusive ? ']' : ')'); + } + + Output.Write(Q); + } + } +} diff --git a/Sources/SqlDatabase/Scripts/PowerShellInternal/InstallationSeeker.cs b/Sources/SqlDatabase/Scripts/PowerShellInternal/InstallationSeeker.cs index 67544a26..df482115 100644 --- a/Sources/SqlDatabase/Scripts/PowerShellInternal/InstallationSeeker.cs +++ b/Sources/SqlDatabase/Scripts/PowerShellInternal/InstallationSeeker.cs @@ -134,7 +134,7 @@ private static bool IsCompatibleVersion(Version version) return version < new Version("7.2"); #elif NETCOREAPP3_1_OR_GREATER return version < new Version("7.1"); -#elif NETCOREAPP2_2_OR_GREATER +#elif NETCOREAPP2_1_OR_GREATER return version < new Version("7.0"); #else return false; diff --git a/Sources/SqlDatabase/Scripts/PowerShellScript.cs b/Sources/SqlDatabase/Scripts/PowerShellScript.cs index 530fa197..d15ee01a 100644 --- a/Sources/SqlDatabase/Scripts/PowerShellScript.cs +++ b/Sources/SqlDatabase/Scripts/PowerShellScript.cs @@ -57,7 +57,7 @@ public IList GetDependencies() using (var reader = new StreamReader(description)) { - return SqlBatchParser.ExtractDependencies(reader, DisplayName).ToArray(); + return DependencyParser.ExtractDependencies(reader, DisplayName).ToArray(); } } } diff --git a/Sources/SqlDatabase/Scripts/ScriptFactory.cs b/Sources/SqlDatabase/Scripts/ScriptFactory.cs index 9ec6411a..10deffd7 100644 --- a/Sources/SqlDatabase/Scripts/ScriptFactory.cs +++ b/Sources/SqlDatabase/Scripts/ScriptFactory.cs @@ -8,10 +8,12 @@ namespace SqlDatabase.Scripts { internal sealed class ScriptFactory : IScriptFactory { - public AppConfiguration Configuration { get; set; } + public AssemblyScriptConfiguration AssemblyScriptConfiguration { get; set; } public IPowerShellFactory PowerShellFactory { get; set; } + public ISqlTextReader TextReader { get; set; } + public bool IsSupported(string fileName) { var ext = Path.GetExtension(fileName); @@ -31,7 +33,8 @@ public IScript FromFile(IFile file) return new TextScript { DisplayName = file.Name, - ReadSqlContent = file.OpenRead + ReadSqlContent = file.OpenRead, + TextReader = TextReader }; } @@ -41,7 +44,7 @@ public IScript FromFile(IFile file) return new AssemblyScript { DisplayName = file.Name, - Configuration = Configuration.AssemblyScript, + Configuration = AssemblyScriptConfiguration, ReadAssemblyContent = CreateBinaryReader(file), ReadDescriptionContent = CreateScriptDescriptionReader(file) }; diff --git a/Sources/SqlDatabase/Scripts/SqlScriptVariableParser.cs b/Sources/SqlDatabase/Scripts/SqlScriptVariableParser.cs index fec68982..ee4d9562 100644 --- a/Sources/SqlDatabase/Scripts/SqlScriptVariableParser.cs +++ b/Sources/SqlDatabase/Scripts/SqlScriptVariableParser.cs @@ -38,7 +38,7 @@ public static bool IsValidVariableName(string name) public string ApplyVariables(string script) { - if (string.IsNullOrEmpty(script)) + if (string.IsNullOrWhiteSpace(script)) { return script; } diff --git a/Sources/SqlDatabase/Scripts/TextScript.cs b/Sources/SqlDatabase/Scripts/TextScript.cs index c2fbc9d8..14c69bbc 100644 --- a/Sources/SqlDatabase/Scripts/TextScript.cs +++ b/Sources/SqlDatabase/Scripts/TextScript.cs @@ -13,6 +13,8 @@ internal sealed class TextScript : IScript public Func ReadSqlContent { get; set; } + public ISqlTextReader TextReader { get; set; } + public void Execute(IDbCommand command, IVariables variables, ILogger logger) { var batches = ResolveBatches(variables, logger); @@ -70,7 +72,7 @@ public IList GetDependencies() string batch; using (var sql = ReadSqlContent()) { - batch = SqlBatchParser.SplitByGo(sql).FirstOrDefault(); + batch = TextReader.ReadFirstBatch(sql); } if (string.IsNullOrWhiteSpace(batch)) @@ -78,18 +80,20 @@ public IList GetDependencies() return new ScriptDependency[0]; } - return SqlBatchParser.ExtractDependencies(new StringReader(batch), DisplayName).ToArray(); + return DependencyParser.ExtractDependencies(new StringReader(batch), DisplayName).ToArray(); } private static string[] GetReaderColumns(IDataReader reader) { using (var metadata = reader.GetSchemaTable()) { + // mssql: ColumnName is string.Empty if not defined + // pgsql: ColumnName is DbNull if not defined return metadata ?.Rows .Cast() .OrderBy(i => (int)i["ColumnOrdinal"]) - .Select(i => (string)i["ColumnName"]) + .Select(i => i["ColumnName"]?.ToString()) .ToArray(); } } @@ -158,10 +162,10 @@ private IEnumerable ResolveBatches(IVariables variables, ILogger logger) var batches = new List(); using (var sql = ReadSqlContent()) { - foreach (var batch in SqlBatchParser.SplitByGo(sql)) + foreach (var batch in TextReader.ReadBatches(sql)) { var script = scriptParser.ApplyVariables(batch); - if (!string.IsNullOrEmpty(script)) + if (!string.IsNullOrWhiteSpace(script)) { batches.Add(script); } diff --git a/Sources/SqlDatabase/SqlDatabase.csproj b/Sources/SqlDatabase/SqlDatabase.csproj index 142aa536..7bc66772 100644 --- a/Sources/SqlDatabase/SqlDatabase.csproj +++ b/Sources/SqlDatabase/SqlDatabase.csproj @@ -1,11 +1,11 @@  - net452;netcoreapp2.2;netcoreapp3.1;net5.0;netstandard2.0 + net452;netcoreapp2.1;netcoreapp3.1;net5.0;netstandard2.0 - netcoreapp2.2;netcoreapp3.1;net5.0 + netcoreapp2.1;netcoreapp3.1;net5.0 @@ -20,7 +20,7 @@ SqlDatabase.GlobalTool Max Ieremenko - SqlDatabase is a tool for SQL Server, allows executing scripts, database migrations and data export. + SqlDatabase is a tool for MSSQL Server and PostgreSQL, allows executing scripts, database migrations and data export. https://github.com/max-ieremenko/SqlDatabase/releases https://github.com/max-ieremenko/SqlDatabase https://github.com/max-ieremenko/SqlDatabase @@ -29,7 +29,7 @@ MIT (C) 2018-2021 Max Ieremenko. git - sqlserver sqlcmd migration-tool c-sharp command-line-tool miration-step sql-script sql-database database-migrations export-data + sqlserver postgresql sqlcmd migration-tool c-sharp command-line-tool miration-step sql-script sql-database database-migrations export-data @@ -66,7 +66,7 @@ - + @@ -84,4 +84,8 @@ + + + + diff --git a/Sources/StyleCope.ruleset b/Sources/StyleCope.ruleset index e59a23d4..aca17fd7 100644 --- a/Sources/StyleCope.ruleset +++ b/Sources/StyleCope.ruleset @@ -17,6 +17,9 @@ + + +