diff --git a/.github/workflows/build_release.yaml b/.github/workflows/build_release.yaml new file mode 100644 index 0000000..39f4b7b --- /dev/null +++ b/.github/workflows/build_release.yaml @@ -0,0 +1,58 @@ +name: WorkloadTools Build & MSI + +on: + push: + paths: + - 'SharedAssemblyInfo.cs' + +jobs: + build-msi: + runs-on: self-hosted + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Extract Version + id: extract_version + shell: pwsh + run: | + $assemblyInfoPath = "${{ github.workspace }}\SharedAssemblyInfo.cs" + $assemblyVersion = Get-Content $assemblyInfoPath | + Select-String -Pattern 'AssemblyFileVersion\("([0-9.]+)"\)' | + ForEach-Object { $_.Matches.Groups[1].Value } + + Write-Host "Version: $assemblyVersion" + echo "version=$assemblyVersion" | Out-File -FilePath $env:GITHUB_ENV -Append + echo "::set-output name=version::$assemblyVersion" + + - name: Build Solution + run: dotnet build WorkloadTools.sln --configuration Release + + - name: Generate MSI + shell: pwsh + run: | + powershell Setup\buildmsi_giuthubaction.ps1 ` + -BuildVersion "${{ steps.extract_version.outputs.version }}" ` + -WixBinPath "C:\wix" + + - name: Create GitHub Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.extract_version.outputs.version }} + release_name: "Release ${{ steps.extract_version.outputs.version }}" + draft: false + prerelease: false + + - name: Upload MSI to GitHub Release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: "C:/temp/WorkloadTools-${{ steps.extract_version.outputs.version }}.msi" + asset_name: "WorkloadTools-${{ steps.extract_version.outputs.version }}.msi" + asset_content_type: application/octet-stream diff --git a/ConvertWorkload/App.config b/ConvertWorkload/App.config deleted file mode 100644 index e8eb563..0000000 --- a/ConvertWorkload/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/ConvertWorkload/ConvertWorkload.csproj b/ConvertWorkload/ConvertWorkload.csproj index 6c2b2ea..233bc48 100644 --- a/ConvertWorkload/ConvertWorkload.csproj +++ b/ConvertWorkload/ConvertWorkload.csproj @@ -1,118 +1,18 @@ - - - + + - Debug - AnyCPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B} Exe - ConvertWorkload - ConvertWorkload - v4.8 - 512 - false - true - - - + net9.0 + enable + enable - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - TRACE;DEBUG - AnyCPU - bin\Debug\ - false - - - bin\Release\ - false - TRACE - true - - - bin\Release\ - false - TRACE - true - - - bin\Debug\ - - - - ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - ..\packages\NLog.4.4.12\lib\net45\NLog.dll - - - - - ..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll - - - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - + - - Designer - - - Always - - + + - - {ae6e4548-8c33-4728-8504-88aa9666020b} - WorkloadTools - + - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/ConvertWorkload/EventReader.cs b/ConvertWorkload/EventReader.cs index 0b74e3b..423fd06 100644 --- a/ConvertWorkload/EventReader.cs +++ b/ConvertWorkload/EventReader.cs @@ -1,5 +1,4 @@ -using System; -using WorkloadTools; +using WorkloadTools; namespace ConvertWorkload { diff --git a/ConvertWorkload/EventWriter.cs b/ConvertWorkload/EventWriter.cs index 9ebefb5..69e6abb 100644 --- a/ConvertWorkload/EventWriter.cs +++ b/ConvertWorkload/EventWriter.cs @@ -1,5 +1,4 @@ -using System; -using WorkloadTools; +using WorkloadTools; namespace ConvertWorkload { diff --git a/ConvertWorkload/ExtendedEventsEventReader.cs b/ConvertWorkload/ExtendedEventsEventReader.cs index ccd6887..761356d 100644 --- a/ConvertWorkload/ExtendedEventsEventReader.cs +++ b/ConvertWorkload/ExtendedEventsEventReader.cs @@ -1,16 +1,7 @@ -using NLog; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using NLog; using WorkloadTools; -using WorkloadTools.Listener; using WorkloadTools.Listener.ExtendedEvents; -using WorkloadTools.Util; namespace ConvertWorkload { diff --git a/ConvertWorkload/LocalDBManager.cs b/ConvertWorkload/LocalDBManager.cs index 30cfa58..98c7e88 100644 --- a/ConvertWorkload/LocalDBManager.cs +++ b/ConvertWorkload/LocalDBManager.cs @@ -1,13 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Diagnostics; -using System.IO; -using System.Linq; +using System.Diagnostics; using System.Net; using System.Security.Principal; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Data.SqlClient; + using WorkloadTools; namespace ConvertWorkload diff --git a/ConvertWorkload/NLog.config b/ConvertWorkload/NLog.config deleted file mode 100644 index 4364328..0000000 --- a/ConvertWorkload/NLog.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/ConvertWorkload/Program.cs b/ConvertWorkload/Program.cs index b269ab1..90fd1df 100644 --- a/ConvertWorkload/Program.cs +++ b/ConvertWorkload/Program.cs @@ -2,16 +2,8 @@ using CommandLine.Text; using NLog; using NLog.Targets; -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Runtime; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using WorkloadTools.Listener.Trace; namespace ConvertWorkload { @@ -36,11 +28,23 @@ static void Main(string[] args) try { var options = new Options(); - if (!CommandLine.Parser.Default.ParseArguments(args, options)) - { - - return; - } + var result = Parser.Default.ParseArguments(args); + result + .WithParsed(parsedOptions => options = parsedOptions) + .WithNotParsed(errors => + { + foreach (var error in errors) + { + logger.Error(error.ToString()); + } + var helpText = HelpText.AutoBuild(result, h => + { + h.AdditionalNewLineAfterOption = false; + return h; + }, e => e); + Console.WriteLine(helpText); + Environment.Exit(1); + }); Run(options); } catch (Exception e) @@ -184,16 +188,5 @@ class Options [Option('U', "LoginFilter", HelpText = "Login Filter")] public string LoginFilter { get; set; } - - [ParserState] - public IParserState LastParserState { get; set; } - - [HelpOption] - public string GetUsage() - { - return HelpText.AutoBuild(this, - (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current)); - } - } } diff --git a/ConvertWorkload/Properties/AssemblyInfo.cs b/ConvertWorkload/Properties/AssemblyInfo.cs index 8f20c80..d859bb1 100644 --- a/ConvertWorkload/Properties/AssemblyInfo.cs +++ b/ConvertWorkload/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; // Setting ComVisible to false makes the types in this assembly not visible diff --git a/ConvertWorkload/SqlTraceEventReader.cs b/ConvertWorkload/SqlTraceEventReader.cs index 0100208..ef0df4d 100644 --- a/ConvertWorkload/SqlTraceEventReader.cs +++ b/ConvertWorkload/SqlTraceEventReader.cs @@ -1,14 +1,6 @@ -using NLog; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using NLog; using WorkloadTools; -using WorkloadTools.Listener; using WorkloadTools.Listener.Trace; namespace ConvertWorkload diff --git a/ConvertWorkload/WorkloadConverter.cs b/ConvertWorkload/WorkloadConverter.cs index 282ff00..39bd421 100644 --- a/ConvertWorkload/WorkloadConverter.cs +++ b/ConvertWorkload/WorkloadConverter.cs @@ -1,10 +1,4 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WorkloadTools; namespace ConvertWorkload { diff --git a/ConvertWorkload/WorkloadFileEventWriter.cs b/ConvertWorkload/WorkloadFileEventWriter.cs index 33a38bc..ecbd327 100644 --- a/ConvertWorkload/WorkloadFileEventWriter.cs +++ b/ConvertWorkload/WorkloadFileEventWriter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WorkloadTools; +using WorkloadTools; using WorkloadTools.Consumer.WorkloadFile; namespace ConvertWorkload diff --git a/ConvertWorkload/packages.config b/ConvertWorkload/packages.config deleted file mode 100644 index a0e26ea..0000000 --- a/ConvertWorkload/packages.config +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Setup/Product.wxs b/Setup/Product.wxs index 82093d7..abe17ed 100644 --- a/Setup/Product.wxs +++ b/Setup/Product.wxs @@ -1,63 +1,28 @@ - - - - - - - - - - - - - + + - + - - - + - - + @@ -68,6 +33,7 @@ + @@ -77,14 +43,15 @@ + - + - + @@ -92,5 +59,4 @@ - diff --git a/Setup/Setup.wixproj b/Setup/Setup.wixproj index 5d23bad..8377b95 100644 --- a/Setup/Setup.wixproj +++ b/Setup/Setup.wixproj @@ -33,33 +33,6 @@ - - - ConvertWorkload - {62e37c03-ba08-46ce-a583-d71fb7a8825b} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - SqlWorkload - {fb46ad2c-df81-4d35-b419-d93e5ef9d98a} - True - - - Binaries;Content;Satellites - INSTALLFOLDER - - - WorkloadViewer - {6e10e31f-d04d-4cb7-8bb9-71abd4b6b973} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - diff --git a/Setup/buildmsi_giuthubaction.ps1 b/Setup/buildmsi_giuthubaction.ps1 new file mode 100644 index 0000000..3bad889 --- /dev/null +++ b/Setup/buildmsi_giuthubaction.ps1 @@ -0,0 +1,91 @@ +param ( + [Parameter(Mandatory=$false)] + [string]$BuildVersion = "1.0.0.0", + + [Parameter(Mandatory=$false)] + [string]$WixBinPath = "C:\Program Files (x86)\WiX Toolset v3.11\bin" +) + +Set-Location $PSScriptRoot + +# ---------------------------------------------------------------- +$heatArgs1 = @( + "dir", + "$PSScriptRoot\..\SqlWorkload\bin\release\net9.0", + "-gg", + "-sfrag", + "-sreg", + "-srd", + "-nologo", + "-cg", "ProductComponents", + "-dr", "INSTALLFOLDER", + "-out", "$PSScriptRoot\harvest.wxs", + "-var", "var.SqlWorkload.TargetDir", + "-t", "$PSScriptRoot\transform.xsl" +) +& "$WixBinPath\heat.exe" @heatArgs1 + +# ---------------------------------------------------------------- +#$heatArgs2 = @( +# "dir", +# "$PSScriptRoot\..\WorkloadViewer\bin\release", +# "-gg", +# "-sfrag", +# "-sreg", +# "-srd", +# "-nologo", +# "-cg", "WorkloadViewerComponents", +# "-dr", "INSTALLFOLDER", +# "-out", "$PSScriptRoot\harvest2.wxs", +# "-var", "var.WorkloadViewer.TargetDir", +# "-t", "$PSScriptRoot\transform.xsl", +# "-t", "$PSScriptRoot\transform2.xsl" +#) +#& "$WixBinPath\heat.exe" @heatArgs2 + +# ---------------------------------------------------------------- +$heatArgs3 = @( + "dir", + "$PSScriptRoot\..\ConvertWorkload\bin\release\net9.0", + "-gg", + "-sfrag", + "-sreg", + "-srd", + "-nologo", + "-cg", "ConvertWorkloadComponents", + "-dr", "INSTALLFOLDER", + "-out", "$PSScriptRoot\harvest3.wxs", + "-var", "var.ConvertWorkload.TargetDir", + "-t", "$PSScriptRoot\transform.xsl", + "-t", "$PSScriptRoot\transform2.xsl", + "-t", "$PSScriptRoot\transform3.xsl" +) +& "$WixBinPath\heat.exe" @heatArgs3 + +# ---------------------------------------------------------------- +$candleArgs = @( + "-nologo", + "-out", "$PSScriptRoot\candleout\", + "-dSqlWorkload.TargetDir=`"$PSScriptRoot\..\SqlWorkload\bin\release\net9.0`"", + #"-dWorkloadViewer.TargetDir=`"$PSScriptRoot\..\WorkloadViewer\bin\release`"", + "-dConvertWorkload.TargetDir=`"$PSScriptRoot\..\ConvertWorkload\bin\release\net9.0`"", + "-dBuildVersion=$BuildVersion", + #"-dPlatform=x64", + "$PSScriptRoot\Product.wxs", + "$PSScriptRoot\harvest.wxs", + #"$PSScriptRoot\harvest2.wxs", + "$PSScriptRoot\harvest3.wxs" + #"-arch", "x64" +) +& "$WixBinPath\candle.exe" @candleArgs + +# ---------------------------------------------------------------- +# Light: link the wixobj files to create the MSI +$lightArgs = @( + "-out", "C:\temp\WorkloadTools-$BuildVersion.msi", + "$PSScriptRoot\candleout\*.wixobj", + "-ext", "WixUIExtension" +) +& "$WixBinPath\light.exe" @lightArgs + +Write-Host "MSI Generated: C:\temp\WorkloadTools-$BuildVersion.msi" diff --git a/SetupBootstrapper/Bundle.wxs b/SetupBootstrapper/Bundle.wxs deleted file mode 100644 index aa5bdba..0000000 --- a/SetupBootstrapper/Bundle.wxs +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SetupBootstrapper/License/Icon.png b/SetupBootstrapper/License/Icon.png deleted file mode 100644 index 16f178c..0000000 Binary files a/SetupBootstrapper/License/Icon.png and /dev/null differ diff --git a/SetupBootstrapper/License/License.rtf b/SetupBootstrapper/License/License.rtf deleted file mode 100644 index 55fb231..0000000 --- a/SetupBootstrapper/License/License.rtf +++ /dev/null @@ -1,228 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch0\stshfloch31506\stshfhich31506\stshfbi31506\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} -{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f63\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f64\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;} -{\f66\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f67\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f68\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f69\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} -{\f70\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f71\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;} -{\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} -{\f413\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f414\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f416\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f417\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\f418\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f419\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f420\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} -{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;} -{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);} -{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);} -{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} -{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; -\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \f31506\fs22 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 -\f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive -\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf2 \sbasedon10 \ssemihidden \sunhideused \styrsid6231089 Hyperlink;}{\s16\ql \li0\ri0\widctlpar -\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 -\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 \slink17 \ssemihidden \sunhideused \styrsid6231089 HTML Preformatted;}{\*\cs17 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 -\sbasedon10 \slink16 \slocked \ssemihidden \styrsid6231089 HTML Preformatted Char;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid1144825\rsid6231089\rsid7602890\rsid8207159\rsid10379327\rsid11422003\rsid12734223\rsid13719530\rsid14571638 -\rsid15563878}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Gianluca Sartori}{\operator Gianluca Sartori}{\creatim\yr2020\mo3\dy30\hr16\min21} -{\revtim\yr2020\mo3\dy30\hr17\min5}{\version5}{\edmins3}{\nofpages1}{\nofwords160}{\nofchars914}{\nofcharsws1072}{\vern123}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen -\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 -\jexpand\viewkind1\viewscale120\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct -\asianbrkrule\rsidroot6231089\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 -{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang -{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} -\pard\plain \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6231089 \rtlch\fcs1 -\af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid12734223 MIT License}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 - -\par -\par Copyright (c) 20}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089 20}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 Gianluca Sartori -\par -\par Permission is hereby granted, free of charge, to any person obtaining a copy}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 -of this software and associated documentation files (the "Software"), to deal}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 -in the Software without restriction, including without limitation the rights}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 to use, copy, modify, merge, pu -blish, distribute, sublicense, and/or sell}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 -copies of the Software, and to permit persons to whom the Software is}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 -furnished to do so, subject to the following conditions:}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089 -\par }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825\charrsid6231089 -\par }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 The above copyright notice and this permission notice shall be included in }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 a}{\rtlch\fcs1 \af2\afs20 -\ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 ll}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 copies or substantial portions of the Software. - -\par -\par }\pard \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1144825 {\rtlch\fcs1 -\af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid6231089\charrsid6231089 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 -\f2\fs20\cf1\insrsid6231089\charrsid6231089 SOFTWARE.}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\cf1\insrsid1144825 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13719530\charrsid6231089 -\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a -9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad -5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 -b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 -0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 -a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f -c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 -0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 -a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 -6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b -4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b -4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f -7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd -ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d -7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b -d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52 -fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71 -b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b -fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567 -9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd -79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf -5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2 -d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1 -738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68 -2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac -5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a -b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9 -493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2 -be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f -f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64 -7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e -b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4 -6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd -f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d -7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39 -4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf -1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a -faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2 -67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9 -416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27 -1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b -8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4 -8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65 -2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36 -3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e -3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985 -0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000 -0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000 -000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000 -7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000 -000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000 -000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; -\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; -\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid; -\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid; -\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1; -\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2; -\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; -\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; -\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; -\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; -\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; -\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; -\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; -\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; -\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; -\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; -\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; -\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; -\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; -\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; -\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; -\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; -\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; -\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; -\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; -\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; -\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; -\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; -\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; -\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; -\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; -\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; -\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; -\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; -\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; -\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; -\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000 -02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000d0bc -a2b6a406d601feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/SetupBootstrapper/License/SideLogo.png b/SetupBootstrapper/License/SideLogo.png deleted file mode 100644 index 739ac63..0000000 Binary files a/SetupBootstrapper/License/SideLogo.png and /dev/null differ diff --git a/SetupBootstrapper/Redist/vcredist_x64.exe b/SetupBootstrapper/Redist/vcredist_x64.exe deleted file mode 100644 index f77258e..0000000 Binary files a/SetupBootstrapper/Redist/vcredist_x64.exe and /dev/null differ diff --git a/SetupBootstrapper/Redist/vcredist_x86.exe b/SetupBootstrapper/Redist/vcredist_x86.exe deleted file mode 100644 index b2016a5..0000000 Binary files a/SetupBootstrapper/Redist/vcredist_x86.exe and /dev/null differ diff --git a/SetupBootstrapper/SetupBootstrapper.wixproj b/SetupBootstrapper/SetupBootstrapper.wixproj deleted file mode 100644 index 69fcad5..0000000 --- a/SetupBootstrapper/SetupBootstrapper.wixproj +++ /dev/null @@ -1,81 +0,0 @@ - - - - Debug - x86 - 3.10 - cad976c4-d0c6-4313-b605-ec3749a23b5f - 2.0 - WorkloadTools - Bundle - - - bin\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - Debug - - - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - - - Debug - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - - - bin\$(Platform)\$(Configuration)\ - obj\$(Platform)\$(Configuration)\ - - - - - - - $(WixExtDir)\WixBalExtension.dll - WixBalExtension - - - - - - - - - - - - - - - - - Setup - {bbf5fda0-c08f-48c9-9b98-e017dd8abb5d} - True - True - Binaries;Content;Satellites - INSTALLFOLDER - - - - - - - - - call $(ProjectDir)postbuild.bat "!(TargetPath)" "$(TargetDir)$(SolutionName)_$(Platform)$(TargetExt)" - - - - - - - - BuildVersion=%(AssemblyVersion.Version) - - - - - - \ No newline at end of file diff --git a/SetupBootstrapper/SignMsi.ps1 b/SetupBootstrapper/SignMsi.ps1 deleted file mode 100644 index bd685d7..0000000 --- a/SetupBootstrapper/SignMsi.ps1 +++ /dev/null @@ -1,53 +0,0 @@ -[CmdletBinding()] -Param( - [Parameter(Mandatory=$True,Position=1)] - [string]$InputFile, - [Parameter(Mandatory=$True,Position=2)] - [string]$OutputFile -) - - -if(-not (Test-Path $PSScriptRoot\SignParams.ps1)) -{ - Write-Warning "No code signing is applied to the .msi file." - Write-Warning "You need to create a file called SignParams.ps1 and provide signing info." - - Write-Output "Moving $InputFile --> $OutputFile" - Move-Item $InputFile $OutputFile -Force - - exit -} - -# read paramters -$signParams = get-content $PSScriptRoot\SignParams.ps1 -Raw -Invoke-Expression $signParams - -$params = $( - 'sign' - ,'/fd' - ,'SHA1' - ,'/f' - ,('"' + $certPath + '"') - ,'/p' - ,('"' + $certPass + '"') - ,'/sha1' - ,$certSha - ,'/t' - ,('"' + $certTime + '"') - ,'/d' - ,'"WorkloadTools"' -) - -$ParentPath = Split-Path -Path $InputFile - -& $insigniaPath $("-ib","$InputFile","-o","$ParentPath\engine.exe") -& $signTool ($params + "$ParentPath\engine.exe") - -& $insigniaPath $("-ab","$ParentPath\engine.exe",$InputFile,"-o",$InputFile) -& $signTool ($params + $InputFile) - - -Write-Output "Moving $InputFile --> $OutputFile" -Move-Item $InputFile $OutputFile -Force - -Remove-Item "$ParentPath\engine.exe" \ No newline at end of file diff --git a/SetupBootstrapper/buildexe.ps1 b/SetupBootstrapper/buildexe.ps1 deleted file mode 100644 index 013be70..0000000 --- a/SetupBootstrapper/buildexe.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -param ( - [Parameter(Mandatory=$false)] - [string]$BuildVersion = "1.0.0.0", - [Parameter(Mandatory=$false)] - [string]$Platform = "x64", - [Parameter(Mandatory=$false)] - [string]$WixBinPath = "c:\Program Files (x86)\WiX Toolset v3.11\bin" -) - - -. $PSScriptRoot\..\Setup\buildmsi.ps1 -BuildVersion $BuildVersion -Platform $Platform -WixBinPath $WixBinPath - -Set-Location $PSScriptRoot - -# Remove previous builds -If(Test-Path $PSScriptRoot\bin\$Platform\Release\* -PathType Any) { - Remove-Item $PSScriptRoot\bin\$Platform\Release\* -} - - -if($BuildVersion -eq "1.0.0.0") { - # Try to read from SharedAssemblyInfo - $BuildVersion = (Get-Content ..\SharedAssemblyInfo.cs | Where-Object { $_.StartsWith("[assembly: AssemblyVersion(") }).Replace('[assembly: AssemblyVersion("','').Replace('")]','') -} - -#---------------------------------------------------------------- - - -$candleArgs = @( - "-nologo", - "-out", - "$PSScriptRoot\candleout\", - "-dBuildVersion=$BuildVersion", - "-dPlatform=$Platform", - "$PSScriptRoot\Bundle.wxs", - "-arch", - "$Platform", - "-ext", - "WixBalExtension" -) - -# Write-Host $candleArgs - -& "$WixBinPath\candle.exe" @candleArgs - -#---------------------------------------------------------------- - -$lightArgs = @( - "-out", - ".\bin\Release\WorkloadTools.exe" - "$PSScriptRoot\candleout\*.wixobj", - "-ext", - "WixUIExtension", - "-ext", - "WixBalExtension" -) - -# Write-Host $lightArgs - - -& "$WixBinPath\light.exe" @lightArgs - -. $PSScriptRoot\SignMsi.ps1 -InputFile ".\bin\Release\WorkloadTools.exe" -OutputFile ".\bin\Release\WorkloadTools_$Platform.exe" \ No newline at end of file diff --git a/SetupBootstrapper/postbuild.bat b/SetupBootstrapper/postbuild.bat deleted file mode 100644 index a62c62d..0000000 --- a/SetupBootstrapper/postbuild.bat +++ /dev/null @@ -1,2 +0,0 @@ -powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File %~dp0\SignMsi.ps1 -InputFile %1 -OutputFile %2 - diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs index 8908e46..73965e4 100644 --- a/SharedAssemblyInfo.cs +++ b/SharedAssemblyInfo.cs @@ -29,5 +29,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.2")] -[assembly: AssemblyFileVersion("1.7.2")] +[assembly: AssemblyVersion("1.7.3")] +[assembly: AssemblyFileVersion("1.7.3")] diff --git a/SqlWorkload/NLog.config b/SqlWorkload/NLog.config index d68856f..84cfed0 100644 --- a/SqlWorkload/NLog.config +++ b/SqlWorkload/NLog.config @@ -4,18 +4,18 @@ xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="false" - internalLogLevel="Off" - internalLogFile="c:\temp\nlog-internal.log"> + internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> + - - - + + + - + diff --git a/SqlWorkload/Program.cs b/SqlWorkload/Program.cs index 9ae634f..aa3fa73 100644 --- a/SqlWorkload/Program.cs +++ b/SqlWorkload/Program.cs @@ -2,21 +2,10 @@ using CommandLine.Text; using NLog; using NLog.Targets; -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Runtime; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using WorkloadTools; using WorkloadTools.Config; -using WorkloadTools.Consumer; -using WorkloadTools.Listener; -using WorkloadTools.Listener.ExtendedEvents; -using WorkloadTools.Listener.Trace; namespace SqlWorkload { @@ -40,11 +29,24 @@ static void Main(string[] args) try { var options = new Options(); - if (!CommandLine.Parser.Default.ParseArguments(args, options)) - { - return; - } - Run(options); + var result = Parser.Default.ParseArguments(args); + result + .WithParsed(parsedOptions => options = parsedOptions) + .WithNotParsed(errors => + { + foreach (var error in errors) + { + logger.Error(error.ToString()); + } + var helpText = HelpText.AutoBuild(result, h => + { + h.AdditionalNewLineAfterOption = false; + return h; + }, e => e); + Console.WriteLine(helpText); + Environment.Exit(1); + }); + Run(options, result); } catch(Exception e) { @@ -53,7 +55,7 @@ static void Main(string[] args) } - static void Run(Options options) + static void Run(Options options, ParserResult parseResult) { // reconfigure loggers to use a file in the current directory // or the file specified by the "Log" commandline parameter @@ -89,18 +91,18 @@ static void Run(Options options) } } - options.ConfigurationFile = System.IO.Path.GetFullPath(options.ConfigurationFile); + options.ConfigurationFile = Path.GetFullPath(options.ConfigurationFile); logger.Info(String.Format("Reading configuration from '{0}'", options.ConfigurationFile)); if (!File.Exists(options.ConfigurationFile)) { logger.Error("File not found!"); - Console.WriteLine(options.GetUsage()); + Console.WriteLine(options.GetUsage(parseResult)); return; } var config = SqlWorkloadConfig.LoadFromFile(options.ConfigurationFile); - config.Controller.Listener.Source = System.IO.Path.GetFullPath(config.Controller.Listener.Source); + config.Controller.Listener.Source = Path.GetFullPath(config.Controller.Listener.Source); Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) { e.Cancel = true; @@ -155,7 +157,7 @@ public static void CancelNotification() class Options { - [Option('F', "File", DefaultValue = "SqlWorkload.json", HelpText = "Configuration file")] + [Option('F', "File", Default = "SqlWorkload.json", HelpText = "Configuration file")] public string ConfigurationFile { get; set; } [Option('L', "Log", HelpText = "Log file")] @@ -164,16 +166,15 @@ class Options [Option('E', "LogLevel", HelpText = "Log level")] public string LogLevel { get; set; } - [ParserState] - public IParserState LastParserState { get; set; } - - [HelpOption] - public string GetUsage() + public string GetUsage(ParserResult parseResult) { - return HelpText.AutoBuild(this, - (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current)); + var help = HelpText.AutoBuild(parseResult, h => + { + h.AdditionalNewLineAfterOption = false; + return h; + }, e => e); + return help; } - - } + } } diff --git a/SqlWorkload/Properties/AssemblyInfo.cs b/SqlWorkload/Properties/AssemblyInfo.cs index 9e48597..f5e1d06 100644 --- a/SqlWorkload/Properties/AssemblyInfo.cs +++ b/SqlWorkload/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information diff --git a/SqlWorkload/SqlWorkload.csproj b/SqlWorkload/SqlWorkload.csproj index ae3d87f..75edcba 100644 --- a/SqlWorkload/SqlWorkload.csproj +++ b/SqlWorkload/SqlWorkload.csproj @@ -1,112 +1,27 @@ - - - + + - Debug - AnyCPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A} + net9.0 + enable + enable Exe - SqlWorkload - SqlWorkload - v4.8 - 512 - - - - - - AnyCPU - true - full - false - bin\x64\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\x64\Release\ - TRACE - prompt - 4 - false - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset + - - ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - ..\packages\DouglasCrockford.JsMin.1.1.3\lib\net40-client\DouglasCrockford.JsMin.dll - - - ..\packages\NLog.4.7.15\lib\net45\NLog.dll - - - - - - ..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll - - - - - - - - - - - + + + + + - - Properties\SharedAssemblyInfo.cs - - - + + - - + Always - - - - - {ae6e4548-8c33-4728-8504-88aa9666020b} - WorkloadTools - True - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/SqlWorkload/app.config b/SqlWorkload/app.config deleted file mode 100644 index 277db2f..0000000 --- a/SqlWorkload/app.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/SqlWorkload/packages.config b/SqlWorkload/packages.config deleted file mode 100644 index 1880aa1..0000000 --- a/SqlWorkload/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/WorkloadTools.sln b/WorkloadTools.sln index 59bc87a..9022fb9 100644 --- a/WorkloadTools.sln +++ b/WorkloadTools.sln @@ -3,20 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33829.357 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlWorkload", "SqlWorkload\SqlWorkload.csproj", "{FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}" - ProjectSection(ProjectDependencies) = postProject - {AE6E4548-8C33-4728-8504-88AA9666020B} = {AE6E4548-8C33-4728-8504-88AA9666020B} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkloadTools", "WorkloadTools\WorkloadTools.csproj", "{AE6E4548-8C33-4728-8504-88AA9666020B}" -EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "Setup\Setup.wixproj", "{BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}" - ProjectSection(ProjectDependencies) = postProject - {62E37C03-BA08-46CE-A583-D71FB7A8825B} = {62E37C03-BA08-46CE-A583-D71FB7A8825B} - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973} = {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973} - {AE6E4548-8C33-4728-8504-88AA9666020B} = {AE6E4548-8C33-4728-8504-88AA9666020B} - {898DF47E-429A-441C-B879-AC0D9EC7FA0E} = {898DF47E-429A-441C-B879-AC0D9EC7FA0E} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CB5A2D19-E789-4555-B04D-FEA2908A5C92}" ProjectSection(SolutionItems) = preProject @@ -26,99 +13,32 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SharedAssemblyInfo.cs = SharedAssemblyInfo.cs EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConvertWorkload", "ConvertWorkload\ConvertWorkload.csproj", "{62E37C03-BA08-46CE-A583-D71FB7A8825B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkloadToolsTests", "WorkloadToolsTests\WorkloadToolsTests.csproj", "{898DF47E-429A-441C-B879-AC0D9EC7FA0E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkloadTools", "WorkloadTools\WorkloadTools.csproj", "{0373E657-8D1C-83A9-88E4-D45A6E6D65BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkloadViewer", "WorkloadViewer\WorkloadViewer.csproj", "{6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}" - ProjectSection(ProjectDependencies) = postProject - {AE6E4548-8C33-4728-8504-88AA9666020B} = {AE6E4548-8C33-4728-8504-88AA9666020B} - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlWorkload", "SqlWorkload\SqlWorkload.csproj", "{7B1AA7E5-3833-43D3-AC96-B3F8BA6CF47D}" EndProject -Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "SetupBootstrapper", "SetupBootstrapper\SetupBootstrapper.wixproj", "{CAD976C4-D0C6-4313-B605-EC3749A23B5F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConvertWorkload", "ConvertWorkload\ConvertWorkload.csproj", "{1226451B-99B4-4BD1-94E8-7F41BB2E40BD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|x64.ActiveCfg = Debug|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|x64.Build.0 = Debug|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|x86.ActiveCfg = Debug|x86 - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Debug|x86.Build.0 = Debug|x86 - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|Any CPU.Build.0 = Release|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|x64.ActiveCfg = Release|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|x64.Build.0 = Release|Any CPU - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|x86.ActiveCfg = Release|x86 - {FB46AD2C-DF81-4D35-B419-D93E5EF9D98A}.Release|x86.Build.0 = Release|x86 - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|x64.ActiveCfg = Debug|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|x64.Build.0 = Debug|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|x86.ActiveCfg = Debug|x86 - {AE6E4548-8C33-4728-8504-88AA9666020B}.Debug|x86.Build.0 = Debug|x86 - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|Any CPU.Build.0 = Release|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|x64.ActiveCfg = Release|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|x64.Build.0 = Release|Any CPU - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|x86.ActiveCfg = Release|x86 - {AE6E4548-8C33-4728-8504-88AA9666020B}.Release|x86.Build.0 = Release|x86 {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Debug|Any CPU.ActiveCfg = Debug|x64 - {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Debug|x64.ActiveCfg = Debug|x64 - {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Debug|x86.ActiveCfg = Debug|x86 {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Release|Any CPU.ActiveCfg = Release|x86 - {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Release|x64.ActiveCfg = Release|x64 - {BBF5FDA0-C08F-48C9-9B98-E017DD8ABB5D}.Release|x86.ActiveCfg = Release|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|Any CPU.ActiveCfg = Debug|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|Any CPU.Build.0 = Debug|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|x64.ActiveCfg = Debug|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|x64.Build.0 = Debug|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|x86.ActiveCfg = Debug|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Debug|x86.Build.0 = Debug|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|Any CPU.Build.0 = Release|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|x64.ActiveCfg = Release|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|x64.Build.0 = Release|Any CPU - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|x86.ActiveCfg = Release|x86 - {62E37C03-BA08-46CE-A583-D71FB7A8825B}.Release|x86.Build.0 = Release|x86 - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|x64.ActiveCfg = Debug|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|x64.Build.0 = Debug|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|x86.ActiveCfg = Debug|x86 - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Debug|x86.Build.0 = Debug|x86 - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|Any CPU.Build.0 = Release|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|x64.ActiveCfg = Release|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|x64.Build.0 = Release|Any CPU - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|x86.ActiveCfg = Release|x86 - {898DF47E-429A-441C-B879-AC0D9EC7FA0E}.Release|x86.Build.0 = Release|x86 - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|x64.ActiveCfg = Debug|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|x64.Build.0 = Debug|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|x86.ActiveCfg = Debug|x86 - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Debug|x86.Build.0 = Debug|x86 - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|Any CPU.Build.0 = Release|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|x64.ActiveCfg = Release|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|x64.Build.0 = Release|Any CPU - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|x86.ActiveCfg = Release|x86 - {6E10E31F-D04D-4CB7-8BB9-71ABD4B6B973}.Release|x86.Build.0 = Release|x86 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Debug|Any CPU.ActiveCfg = Debug|x86 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Debug|x64.ActiveCfg = Debug|x64 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Debug|x86.ActiveCfg = Debug|x86 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Release|Any CPU.ActiveCfg = Release|x86 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Release|x64.ActiveCfg = Release|x64 - {CAD976C4-D0C6-4313-B605-EC3749A23B5F}.Release|x86.ActiveCfg = Release|x86 + {0373E657-8D1C-83A9-88E4-D45A6E6D65BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0373E657-8D1C-83A9-88E4-D45A6E6D65BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0373E657-8D1C-83A9-88E4-D45A6E6D65BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0373E657-8D1C-83A9-88E4-D45A6E6D65BA}.Release|Any CPU.Build.0 = Release|Any CPU + {7B1AA7E5-3833-43D3-AC96-B3F8BA6CF47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B1AA7E5-3833-43D3-AC96-B3F8BA6CF47D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B1AA7E5-3833-43D3-AC96-B3F8BA6CF47D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B1AA7E5-3833-43D3-AC96-B3F8BA6CF47D}.Release|Any CPU.Build.0 = Release|Any CPU + {1226451B-99B4-4BD1-94E8-7F41BB2E40BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1226451B-99B4-4BD1-94E8-7F41BB2E40BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1226451B-99B4-4BD1-94E8-7F41BB2E40BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1226451B-99B4-4BD1-94E8-7F41BB2E40BD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/WorkloadTools/BinarySerializedBufferedEventQueue.cs b/WorkloadTools/BinarySerializedBufferedEventQueue.cs index 8f21fc2..395d1a7 100644 --- a/WorkloadTools/BinarySerializedBufferedEventQueue.cs +++ b/WorkloadTools/BinarySerializedBufferedEventQueue.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Runtime.Serialization.Formatters.Binary; +using Newtonsoft.Json; using WorkloadTools.Util; using System.Diagnostics; @@ -18,8 +18,6 @@ public class BinarySerializedBufferedEventQueue : BufferedEventQueue private readonly string file_name_uniquifier = ""; - private readonly BinaryFormatter _formatter = new BinaryFormatter(); - public BinarySerializedBufferedEventQueue() : base() { file_name_uniquifier = DateTime.Now.ToString("yyyyMMddHHmm") + "_" + ("000000000" + (Environment.TickCount & int.MaxValue)).Right(9) + "_"; @@ -27,19 +25,19 @@ public BinarySerializedBufferedEventQueue() : base() _ = System.IO.Directory.CreateDirectory(baseFolder); _minFile = 0; _maxFile = 0; - } protected override WorkloadEvent[] ReadEvents(int count) { WorkloadEvent[] result = null; var destFile = Path.Combine(baseFolder, file_name_uniquifier + ("000000000" + _minFile).Right(9) + ".cache"); - - using (var fileStream = new System.IO.FileStream(destFile, System.IO.FileMode.Open)) - using (var bufferedStream = new BufferedStream(fileStream)) + + using (var fileStream = new FileStream(destFile, FileMode.Open)) + using (var streamReader = new StreamReader(fileStream)) { - result = (WorkloadEvent[])_formatter.Deserialize(bufferedStream); - if(result.Length != count) + var json = streamReader.ReadToEnd(); + result = JsonConvert.DeserializeObject(json); + if (result.Length != count) { throw new ArgumentOutOfRangeException($"The deserialized array is of the wrong size (expected: {count}, found: {result.Length})"); } @@ -54,8 +52,6 @@ protected override WorkloadEvent[] ReadEvents(int count) protected override void WriteEvents(WorkloadEvent[] events) { var destFile = Path.Combine(baseFolder, file_name_uniquifier); - // c# does not have a String.Right method, so I created - // an extension for it. Crazy, right? destFile += ("000000000" + _maxFile).Right(9) + ".cache"; if (File.Exists(destFile)) @@ -64,10 +60,10 @@ protected override void WriteEvents(WorkloadEvent[] events) } using (var fileStream = new FileStream(destFile, FileMode.CreateNew)) - using (var bufferedStream = new BufferedStream(fileStream)) + using (var streamWriter = new StreamWriter(fileStream)) { - _formatter.Serialize(bufferedStream, events); - fileStream.Close(); + var json = JsonConvert.SerializeObject(events); + streamWriter.Write(json); } _maxFile++; } @@ -75,7 +71,7 @@ protected override void WriteEvents(WorkloadEvent[] events) protected override void Dispose(bool disposing) { // delete all pending files - for (var i=_minFile; i<=_maxFile; i++) + for (var i = _minFile; i <= _maxFile; i++) { var destFile = Path.Combine(baseFolder, file_name_uniquifier); destFile += ("000000000" + i).Right(9) + ".cache"; @@ -83,9 +79,7 @@ protected override void Dispose(bool disposing) { File.Delete(destFile); } - } } - } } diff --git a/WorkloadTools/BufferedEventQueue.cs b/WorkloadTools/BufferedEventQueue.cs index d90da97..2276b4b 100644 --- a/WorkloadTools/BufferedEventQueue.cs +++ b/WorkloadTools/BufferedEventQueue.cs @@ -1,9 +1,4 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace WorkloadTools { diff --git a/WorkloadTools/Config/SqlWorkloadConfig.cs b/WorkloadTools/Config/SqlWorkloadConfig.cs index 23ec37c..6d1efe9 100644 --- a/WorkloadTools/Config/SqlWorkloadConfig.cs +++ b/WorkloadTools/Config/SqlWorkloadConfig.cs @@ -1,22 +1,15 @@ -using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using WorkloadTools; -using System.Web.Script.Serialization; -using System.IO; -using DouglasCrockford.JsMin; +using DouglasCrockford.JsMin; +using Newtonsoft.Json; +using NLog; using WorkloadTools.Listener.ExtendedEvents; using WorkloadTools.Consumer.Replay; -using WorkloadTools.Consumer.Analysis; -using WorkloadTools.Util; +using WorkloadTools.Utils; namespace WorkloadTools.Config { public class SqlWorkloadConfig { + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); public SqlWorkloadConfig() { } @@ -25,33 +18,40 @@ public SqlWorkloadConfig() public static SqlWorkloadConfig LoadFromFile(string path) { - var ser = new JavaScriptSerializer(new SqlWorkloadConfigTypeResolver()); - ser.RegisterConverters(new JavaScriptConverter[] { new ModelConverter() }); using (var r = new StreamReader(path)) { - var json = r.ReadToEnd(); + string json = r.ReadToEnd(); var minifier = new JsMinifier(); - // minify JSON to strip away comments - // Comments in config files are very useful but JSON parsers - // do not allow comments. Minification solves the issue. - SqlWorkloadConfig result = null; - string jsonMin = null; + string jsonMin; try { jsonMin = minifier.Minify(json); } catch (Exception e) { - throw new FormatException($"Unable to load configuration from '{path}'. The file contains syntax errors.", e); + throw new FormatException($"Unable to load configuration from '{path}'. " + + "The file contains syntax errors.", e); } + Dictionary dictionary; try { - result = ser.Deserialize(jsonMin); + dictionary = JsonConvert.DeserializeObject>(jsonMin); } catch (Exception e) { - throw new FormatException($"Unable to load configuration from '{path}'. The file contains semantic errors.", e); + throw new FormatException($"Unable to load configuration from '{path}'. The file contains semantic errors (invalid JSON).", e); + } + + ModelConverter converter = new ModelConverter(); + SqlWorkloadConfig result; + try + { + result = (SqlWorkloadConfig)converter.Deserialize(dictionary, typeof(SqlWorkloadConfig)); + } + catch (Exception e) + { + throw new FormatException($"Unable to convert dictionary to SqlWorkloadConfig.", e); } return result; } @@ -59,7 +59,6 @@ public static SqlWorkloadConfig LoadFromFile(string path) public static void Test() { - var ser = new JavaScriptSerializer(new SqlWorkloadConfigTypeResolver()); var x = new SqlWorkloadConfig() { Controller = new WorkloadController() @@ -103,13 +102,8 @@ public static void Test() } }); - var s = ser.Serialize(x); - + string s = JsonConvert.SerializeObject(x, Formatting.Indented); Console.WriteLine(s); - - //SqlWorkloadConfig tc = ser.Deserialize(Samples.Sample.ToString()); - } - } } diff --git a/WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs b/WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs deleted file mode 100644 index bb6da0e..0000000 --- a/WorkloadTools/Config/SqlWorkloadConfigTypeResolver.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Web.Script.Serialization; - -namespace WorkloadTools.Config -{ - internal class SqlWorkloadConfigTypeResolver : SimpleTypeResolver - { - - private static readonly Dictionary mappedTypes = new Dictionary(); - - static SqlWorkloadConfigTypeResolver() - { - var currentAssembly = Assembly.GetExecutingAssembly(); - var nameSpace = "WorkloadTools"; - var types = currentAssembly.GetTypes().Where(t => t != null && t.FullName.StartsWith(nameSpace) & !t.FullName.Contains("+")).ToArray(); - foreach (var t in types) - { - try - { - mappedTypes.Add(t.AssemblyQualifiedName, t); - mappedTypes.Add(t.Name, t); - } - catch(Exception) - { - throw; - } - } - } - - public override Type ResolveType(string id) - { - if (mappedTypes.ContainsKey(id)) - { - return mappedTypes[id]; - } - else - { - return base.ResolveType(id); - } - } - - public override string ResolveTypeId(Type type) - { - return base.ResolveTypeId(type); - } - } -} \ No newline at end of file diff --git a/WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs b/WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs index 2c3cdde..3c1ab5f 100644 --- a/WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs +++ b/WorkloadTools/Consumer/Analysis/WorkloadAnalyzer.cs @@ -1,19 +1,10 @@ using NLog; -using System; -using System.Collections.Generic; using System.Data; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Reflection; +using Microsoft.Data.SqlClient; using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using WorkloadTools.Util; using System.Collections.Concurrent; using FastMember; -using Microsoft.SqlServer.Management.SqlParser.SqlCodeDom; namespace WorkloadTools.Consumer.Analysis { @@ -471,7 +462,7 @@ private void WriteWaitsData(SqlConnection conn, SqlTransaction tran, int current lock (waitsData) { - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -522,7 +513,7 @@ private void WritePerformanceCounters(SqlConnection conn, SqlTransaction tran, i lock (counterData) { - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -579,7 +570,7 @@ IF OBJECT_ID('tempdb..#WorkloadSummary') IS NOT NULL } // bulk copy data to temp table - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -706,7 +697,7 @@ private void WriteExecutionDetails(SqlConnection conn, SqlTransaction tran, int { int numRows; - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -791,7 +782,7 @@ private void WriteExecutionErrors(SqlConnection conn, SqlTransaction tran, int c lock (errorData) { - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -844,7 +835,7 @@ SELECT TOP(0) * } // bulk insert into temporary - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | @@ -900,7 +891,7 @@ SELECT TOP(0) * } // bulk insert into temporary - using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(conn, + using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.CheckConstraints | diff --git a/WorkloadTools/Consumer/Replay/ReplayWorker.cs b/WorkloadTools/Consumer/Replay/ReplayWorker.cs index 55ff99b..69b0ced 100644 --- a/WorkloadTools/Consumer/Replay/ReplayWorker.cs +++ b/WorkloadTools/Consumer/Replay/ReplayWorker.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; diff --git a/WorkloadTools/Consumer/Replay/ReplayWorker.cs.bak b/WorkloadTools/Consumer/Replay/ReplayWorker.cs.bak index 4a80ea6..8032bc3 100644 --- a/WorkloadTools/Consumer/Replay/ReplayWorker.cs.bak +++ b/WorkloadTools/Consumer/Replay/ReplayWorker.cs.bak @@ -1,7 +1,7 @@ using NLog; using System; using System.Collections.Generic; -using System.Data.SqlClient; +using Micosoft.Data.SqlClient; using System.Linq; using System.Runtime.CompilerServices; using System.Text; diff --git a/WorkloadTools/Consumer/Replay/ResultSetConsumer.cs b/WorkloadTools/Consumer/Replay/ResultSetConsumer.cs index d2e5c6c..bf40c3c 100644 --- a/WorkloadTools/Consumer/Replay/ResultSetConsumer.cs +++ b/WorkloadTools/Consumer/Replay/ResultSetConsumer.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Linq; using System.Text; diff --git a/WorkloadTools/CounterWorkloadEvent.cs b/WorkloadTools/CounterWorkloadEvent.cs index 0852daf..674a52d 100644 --- a/WorkloadTools/CounterWorkloadEvent.cs +++ b/WorkloadTools/CounterWorkloadEvent.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools +namespace WorkloadTools { [Serializable] public class CounterWorkloadEvent : WorkloadEvent diff --git a/WorkloadTools/ErrorWorkloadEvent.cs b/WorkloadTools/ErrorWorkloadEvent.cs index 69e2ea0..80c66f2 100644 --- a/WorkloadTools/ErrorWorkloadEvent.cs +++ b/WorkloadTools/ErrorWorkloadEvent.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WorkloadTools +namespace WorkloadTools { [Serializable] public class ErrorWorkloadEvent : ExecutionWorkloadEvent diff --git a/WorkloadTools/ExecutionWorkloadEvent.cs b/WorkloadTools/ExecutionWorkloadEvent.cs index 2003d9a..3bb86ff 100644 --- a/WorkloadTools/ExecutionWorkloadEvent.cs +++ b/WorkloadTools/ExecutionWorkloadEvent.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools +namespace WorkloadTools { [Serializable] public class ExecutionWorkloadEvent : WorkloadEvent diff --git a/WorkloadTools/FilterPredicate.cs b/WorkloadTools/FilterPredicate.cs index d36f6e5..f497e6c 100644 --- a/WorkloadTools/FilterPredicate.cs +++ b/WorkloadTools/FilterPredicate.cs @@ -1,6 +1,4 @@ -using System; - -namespace WorkloadTools +namespace WorkloadTools { public abstract class FilterPredicate { diff --git a/WorkloadTools/IEventQueue.cs b/WorkloadTools/IEventQueue.cs index fe2e5f7..ea38ee1 100644 --- a/WorkloadTools/IEventQueue.cs +++ b/WorkloadTools/IEventQueue.cs @@ -1,6 +1,4 @@ -using System; - -namespace WorkloadTools +namespace WorkloadTools { public enum EventQueueType diff --git a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs index c2f04e1..c0b8319 100644 --- a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs +++ b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsEventFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.ExtendedEvents +namespace WorkloadTools.Listener.ExtendedEvents { public class ExtendedEventsEventFilter : WorkloadEventFilter { diff --git a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs index b588809..c6489fa 100644 --- a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs +++ b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsFilterPredicate.cs @@ -1,6 +1,4 @@ -using System; - -namespace WorkloadTools.Listener.ExtendedEvents +namespace WorkloadTools.Listener.ExtendedEvents { public class ExtendedEventsFilterPredicate : FilterPredicate { diff --git a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs index 899784d..5ee88f0 100644 --- a/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs +++ b/WorkloadTools/Listener/ExtendedEvents/ExtendedEventsWorkloadListener.cs @@ -1,13 +1,5 @@ -using Microsoft.SqlServer.XEvent.Linq; -using NLog; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; +using NLog; +using Microsoft.Data.SqlClient; namespace WorkloadTools.Listener.ExtendedEvents { diff --git a/WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs b/WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs index 135d341..d61d7ec 100644 --- a/WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs +++ b/WorkloadTools/Listener/ExtendedEvents/FileTargetXEventDataReader.cs @@ -1,13 +1,6 @@ using NLog; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading; +using Microsoft.Data.SqlClient; using System.Xml; -using System.Xml.Linq; using WorkloadTools.Util; namespace WorkloadTools.Listener.ExtendedEvents diff --git a/WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs b/WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs index 57ba6ac..cc09c99 100644 --- a/WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs +++ b/WorkloadTools/Listener/ExtendedEvents/StreamXEventDataReader.cs @@ -1,11 +1,6 @@ -using Microsoft.SqlServer.XEvent.Linq; +using Microsoft.SqlServer.XEvent.XELite; using NLog; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; using System.Text; -using static WorkloadTools.Listener.Trace.TraceEventParser; namespace WorkloadTools.Listener.ExtendedEvents { @@ -32,235 +27,239 @@ public override void ReadEvents() EventCount = 0; var transformer = new SqlTransformer(); + /* using (var eventstream = new QueryableXEventData( ConnectionString, SessionName, EventStreamSourceOptions.EventStream, EventStreamCacheOptions.CacheToDisk)) - { - - var eventsEnumerator = eventstream.GetEnumerator(); + */ + var eventstream = new XELiveEventStreamer(ConnectionString, SessionName); + Task eventTask = eventstream.ReadEventStream(xevent => + { while (!stopped) - { - if (eventsEnumerator.MoveNext()) + { + var evt = xevent; + var workloadEvent = new ExecutionWorkloadEvent(); + try { - var evt = eventsEnumerator.Current; - var workloadEvent = new ExecutionWorkloadEvent(); - try + workloadEvent.EventSequence = Convert.ToInt64(TryGetValue(evt, FieldType.Action, "event_sequence")); + var commandText = string.Empty; + if (evt.Name == "rpc_starting") + { + commandText = (string)TryGetValue(evt, FieldType.Field, "statement"); + workloadEvent.Type = WorkloadEvent.EventType.RPCStarting; + } + else if (evt.Name == "sql_batch_starting") { - workloadEvent.EventSequence = Convert.ToInt64(TryGetValue(evt, FieldType.Action, "event_sequence")); - var commandText = string.Empty; - if (evt.Name == "rpc_starting") + commandText = (string)TryGetValue(evt, FieldType.Field, "batch_text"); + workloadEvent.Type = WorkloadEvent.EventType.BatchStarting; + } + else if (evt.Name == "rpc_completed") + { + commandText = (string)TryGetValue(evt, FieldType.Field, "statement"); + workloadEvent.Type = WorkloadEvent.EventType.RPCCompleted; + } + else if (evt.Name == "sql_batch_completed") + { + commandText = (string)TryGetValue(evt, FieldType.Field, "batch_text"); + workloadEvent.Type = WorkloadEvent.EventType.BatchCompleted; + } + else if (evt.Name == "login") + { + var vIsCached = Convert.ToBoolean(TryGetValue(evt, FieldType.Field, "is_cached")); + if (!vIsCached) /* If is not cached then consider it a new login */ { - commandText = (string)TryGetValue(evt, FieldType.Field, "statement"); workloadEvent.Type = WorkloadEvent.EventType.RPCStarting; + // A nonpooled login will trigger Login event with EventSubClass = 1 + // Setting text to sp_reset_connection and including comment on to + // be able to understand this is a nonpooled login on replay + commandText = "exec sp_reset_connection /*Nonpooled*/"; } - else if (evt.Name == "sql_batch_starting") - { - commandText = (string)TryGetValue(evt, FieldType.Field, "batch_text"); - workloadEvent.Type = WorkloadEvent.EventType.BatchStarting; - } - else if (evt.Name == "rpc_completed") + else { - commandText = (string)TryGetValue(evt, FieldType.Field, "statement"); - workloadEvent.Type = WorkloadEvent.EventType.RPCCompleted; + workloadEvent.Type = WorkloadEvent.EventType.Unknown; + continue; } - else if (evt.Name == "sql_batch_completed") + } + else if (evt.Name == "attention") + { + workloadEvent = new ErrorWorkloadEvent(); + var value = TryGetValue(evt, FieldType.Action, "sql_text"); + + if (value == null) { - commandText = (string)TryGetValue(evt, FieldType.Field, "batch_text"); - workloadEvent.Type = WorkloadEvent.EventType.BatchCompleted; + continue; } - else if (evt.Name == "login") + + try { - var vIsCached = Convert.ToBoolean(TryGetValue(evt, FieldType.Field, "is_cached")); - if (!vIsCached) /* If is not cached then consider it a new login */ + if (value is string stringValue) { - workloadEvent.Type = WorkloadEvent.EventType.RPCStarting; - // A nonpooled login will trigger Login event with EventSubClass = 1 - // Setting text to sp_reset_connection and including comment on to - // be able to understand this is a nonpooled login on replay - commandText = "exec sp_reset_connection /*Nonpooled*/"; + commandText = stringValue; + } + else if (value is byte[] byteValue) + { + commandText = Encoding.Unicode.GetString(byteValue); } else { - workloadEvent.Type = WorkloadEvent.EventType.Unknown; - continue; + throw new ArgumentException("Argument is of the wrong type"); } } - else if (evt.Name == "attention") + catch (Exception e) { - workloadEvent = new ErrorWorkloadEvent(); - var value = TryGetValue(evt, FieldType.Action, "sql_text"); + logger.Error(e, $"Unable to extract sql_text from attention event. Value is of type ${value.GetType().FullName}"); - if (value == null) + } + workloadEvent.Text = commandText; + workloadEvent.Type = WorkloadEvent.EventType.Timeout; + } + else if (evt.Name == "user_event") + { + workloadEvent = new ErrorWorkloadEvent(); + var num = (int)TryGetValue(evt, FieldType.Field, "event_id"); + if (num == 83 || num == 82) + { + if (TryGetString(evt, FieldType.Field, "user_info").StartsWith("WorkloadTools.")) { - continue; - } + commandText = TryGetString(evt, FieldType.Field, "user_data"); + workloadEvent.Text = commandText; - try - { - if (value is string stringValue) - { - commandText = stringValue; - } - else if (value is byte[] byteValue) + if (num == 83) { - commandText = Encoding.Unicode.GetString(byteValue); + workloadEvent.Type = WorkloadEvent.EventType.Error; } else { - throw new ArgumentException("Argument is of the wrong type"); + workloadEvent.Type = WorkloadEvent.EventType.Timeout; } } - catch (Exception e) + else { - logger.Error(e, $"Unable to extract sql_text from attention event. Value is of type ${value.GetType().FullName}"); - + workloadEvent.Type = WorkloadEvent.EventType.Unknown; + continue; } - workloadEvent.Text = commandText; - workloadEvent.Type = WorkloadEvent.EventType.Timeout; } - else if (evt.Name == "user_event") - { - workloadEvent = new ErrorWorkloadEvent(); - var num = (int)TryGetValue(evt, FieldType.Field, "event_id"); - if (num == 83 || num == 82) - { - if (TryGetString(evt, FieldType.Field, "user_info").StartsWith("WorkloadTools.")) - { - commandText = TryGetString(evt, FieldType.Field, "user_data"); - workloadEvent.Text = commandText; + } + else + { + workloadEvent.Type = WorkloadEvent.EventType.Unknown; + continue; + } - if (num == 83) - { - workloadEvent.Type = WorkloadEvent.EventType.Error; - } - else - { - workloadEvent.Type = WorkloadEvent.EventType.Timeout; - } - } - else - { - workloadEvent.Type = WorkloadEvent.EventType.Unknown; - continue; - } - } - } - else + try + { + workloadEvent.ApplicationName = TryGetString(evt, FieldType.Action, "client_app_name"); + workloadEvent.DatabaseName = TryGetString(evt, FieldType.Action, "database_name"); + workloadEvent.HostName = TryGetString(evt, FieldType.Action, "client_hostname"); + workloadEvent.LoginName = TryGetString(evt, FieldType.Action, "server_principal_name"); + workloadEvent.SPID = TryGetInt32(evt, FieldType.Action, "session_id"); + if (commandText != null) { - workloadEvent.Type = WorkloadEvent.EventType.Unknown; - continue; + workloadEvent.Text = commandText; } - try - { - workloadEvent.ApplicationName = TryGetString(evt, FieldType.Action, "client_app_name"); - workloadEvent.DatabaseName = TryGetString(evt, FieldType.Action, "database_name"); - workloadEvent.HostName = TryGetString(evt, FieldType.Action, "client_hostname"); - workloadEvent.LoginName = TryGetString(evt, FieldType.Action, "server_principal_name"); - workloadEvent.SPID = TryGetInt32(evt, FieldType.Action, "session_id"); - if (commandText != null) - { - workloadEvent.Text = commandText; - } - - workloadEvent.StartTime = evt.Timestamp.LocalDateTime; + workloadEvent.StartTime = evt.Timestamp.LocalDateTime; - if (workloadEvent.Type == WorkloadEvent.EventType.Error) - { - workloadEvent.Duration = 0; - workloadEvent.CPU = 0; - } - else if (workloadEvent.Type == WorkloadEvent.EventType.Timeout) - { - workloadEvent.Duration = TryGetInt64(evt, FieldType.Field, "duration"); - workloadEvent.CPU = Convert.ToInt64(workloadEvent.Duration); - } - else - { - if (evt.Name == "rpc_completed" || evt.Name == "sql_batch_completed") - { - workloadEvent.Reads = TryGetInt64(evt, FieldType.Field, "logical_reads"); - workloadEvent.Writes = TryGetInt64(evt, FieldType.Field, "writes"); - workloadEvent.CPU = TryGetInt64(evt, FieldType.Field, "cpu_time"); - workloadEvent.Duration = TryGetInt64(evt, FieldType.Field, "duration"); - } - } + if (workloadEvent.Type == WorkloadEvent.EventType.Error) + { + workloadEvent.Duration = 0; + workloadEvent.CPU = 0; } - catch (Exception e) + else if (workloadEvent.Type == WorkloadEvent.EventType.Timeout) { - logger.Error(e, "Error converting XE data from the stream."); - throw; + workloadEvent.Duration = TryGetInt64(evt, FieldType.Field, "duration"); + workloadEvent.CPU = Convert.ToInt64(workloadEvent.Duration); } - - // preprocess and filter events - if (workloadEvent.Type == WorkloadEvent.EventType.BatchStarting - || - workloadEvent.Type == WorkloadEvent.EventType.BatchCompleted - || - workloadEvent.Type == WorkloadEvent.EventType.RPCStarting - || - workloadEvent.Type == WorkloadEvent.EventType.RPCCompleted - || - workloadEvent.Type == WorkloadEvent.EventType.Message) + else { - if (transformer.Skip(workloadEvent.Text)) + if (evt.Name == "rpc_completed" || evt.Name == "sql_batch_completed") { - continue; + workloadEvent.Reads = TryGetInt64(evt, FieldType.Field, "logical_reads"); + workloadEvent.Writes = TryGetInt64(evt, FieldType.Field, "writes"); + workloadEvent.CPU = TryGetInt64(evt, FieldType.Field, "cpu_time"); + workloadEvent.Duration = TryGetInt64(evt, FieldType.Field, "duration"); } - - workloadEvent.Text = transformer.Transform(workloadEvent.Text); } + } + catch (Exception e) + { + logger.Error(e, "Error converting XE data from the stream."); + throw; + } - Events.Enqueue(workloadEvent); + // preprocess and filter events + if (workloadEvent.Type == WorkloadEvent.EventType.BatchStarting + || + workloadEvent.Type == WorkloadEvent.EventType.BatchCompleted + || + workloadEvent.Type == WorkloadEvent.EventType.RPCStarting + || + workloadEvent.Type == WorkloadEvent.EventType.RPCCompleted + || + workloadEvent.Type == WorkloadEvent.EventType.Message) + { + if (transformer.Skip(workloadEvent.Text)) + { + continue; + } - EventCount++; + workloadEvent.Text = transformer.Transform(workloadEvent.Text); } - catch (Exception ex) + + Events.Enqueue(workloadEvent); + + EventCount++; + } + catch (Exception ex) + { + logger.Error($"Error converting XE data from the stream: {ex.Message}"); + try { - logger.Error($"Error converting XE data from the stream: {ex.Message}"); - try - { - logger.Error($" event type : {workloadEvent.Type}"); - logger.Error($" client_app_name : {TryGetString(evt, FieldType.Action, "client_app_name")}"); - logger.Error($" database_name : {TryGetString(evt, FieldType.Action, "database_name")}"); - logger.Error($" client_hostname : {TryGetString(evt, FieldType.Action, "client_hostname")}"); - logger.Error($" server_principal_name : {TryGetString(evt, FieldType.Action, "server_principal_name")}"); - logger.Error($" session_id : {TryGetString(evt, FieldType.Action, "session_id")}"); - logger.Error($" duration : {TryGetString(evt, FieldType.Field, "duration")}"); - logger.Error($" logical_reads : {TryGetString(evt, FieldType.Field, "logical_reads")}"); - logger.Error($" writes : {TryGetString(evt, FieldType.Field, "writes")}"); - logger.Error($" cpu_time : {TryGetString(evt, FieldType.Field, "cpu_time")}"); - } - catch (Exception) - { - //ignore, it is only logging - } - throw; + logger.Error($" event type : {workloadEvent.Type}"); + logger.Error($" client_app_name : {TryGetString(evt, FieldType.Action, "client_app_name")}"); + logger.Error($" database_name : {TryGetString(evt, FieldType.Action, "database_name")}"); + logger.Error($" client_hostname : {TryGetString(evt, FieldType.Action, "client_hostname")}"); + logger.Error($" server_principal_name : {TryGetString(evt, FieldType.Action, "server_principal_name")}"); + logger.Error($" session_id : {TryGetString(evt, FieldType.Action, "session_id")}"); + logger.Error($" duration : {TryGetString(evt, FieldType.Field, "duration")}"); + logger.Error($" logical_reads : {TryGetString(evt, FieldType.Field, "logical_reads")}"); + logger.Error($" writes : {TryGetString(evt, FieldType.Field, "writes")}"); + logger.Error($" cpu_time : {TryGetString(evt, FieldType.Field, "cpu_time")}"); } + catch (Exception) + { + //ignore, it is only logging + } + throw; } + } - } + return Task.CompletedTask; + }, + CancellationToken.None); + + Task.WaitAll(eventTask); } - private object TryGetValue(PublishedEvent evt, FieldType t, string name) + private object TryGetValue(IXEvent evt, FieldType t, string name) { object result = null; if (t == FieldType.Action) { if (evt.Actions.TryGetValue(name, out var act)) { - result = act.Value; + result = act; } } else { if (evt.Fields.TryGetValue(name, out var fld)) { - result = fld.Value; + result = fld; } } @@ -269,16 +268,17 @@ private object TryGetValue(PublishedEvent evt, FieldType t, string name) // which considers it as a BLOB if (result is string stringValue) { - while (stringValue.EndsWith("\0")) - { - stringValue = stringValue.Remove(stringValue.Length - 1); - } + int pos = stringValue.IndexOf('\0'); + if (pos >= 0) + stringValue = stringValue.Substring(0, pos); + //stringValue = stringValue.Remove(stringValue.Length - 1); + result = stringValue; } return result; } - private string TryGetString(PublishedEvent evt, FieldType t, string name) + private string TryGetString(IXEvent evt, FieldType t, string name) { var tmp = TryGetValue(evt, t, name); if(tmp != null && tmp.GetType() != typeof(DBNull)) @@ -302,7 +302,7 @@ private string TryGetString(PublishedEvent evt, FieldType t, string name) } } - private int? TryGetInt32(PublishedEvent evt, FieldType t, string name) + private int? TryGetInt32(IXEvent evt, FieldType t, string name) { var tmp = TryGetValue(evt, t, name); if (tmp != null && tmp.GetType() != typeof(DBNull)) @@ -315,7 +315,7 @@ private string TryGetString(PublishedEvent evt, FieldType t, string name) } } - private long? TryGetInt64(PublishedEvent evt, FieldType t, string name) + private long? TryGetInt64(IXEvent evt, FieldType t, string name) { var tmp = TryGetValue(evt, t, name); if (tmp != null && tmp.GetType() != typeof(DBNull)) diff --git a/WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs b/WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs index cf8767b..edc275f 100644 --- a/WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs +++ b/WorkloadTools/Listener/ExtendedEvents/XEventDataReader.cs @@ -1,11 +1,4 @@ -using Microsoft.SqlServer.XEvent.Linq; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.ExtendedEvents +namespace WorkloadTools.Listener.ExtendedEvents { public abstract class XEventDataReader { diff --git a/WorkloadTools/Listener/File/FileEventFilter.cs b/WorkloadTools/Listener/File/FileEventFilter.cs index b940ee6..379e024 100644 --- a/WorkloadTools/Listener/File/FileEventFilter.cs +++ b/WorkloadTools/Listener/File/FileEventFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.File +namespace WorkloadTools.Listener.File { public class FileEventFilter : WorkloadEventFilter { diff --git a/WorkloadTools/Listener/File/FileFilterPredicate.cs b/WorkloadTools/Listener/File/FileFilterPredicate.cs index 1522aa5..27e3a97 100644 --- a/WorkloadTools/Listener/File/FileFilterPredicate.cs +++ b/WorkloadTools/Listener/File/FileFilterPredicate.cs @@ -1,6 +1,4 @@ -using System; - -namespace WorkloadTools.Listener.File +namespace WorkloadTools.Listener.File { public class FileFilterPredicate : FilterPredicate { diff --git a/WorkloadTools/Listener/File/FileWorkloadListener.cs b/WorkloadTools/Listener/File/FileWorkloadListener.cs index 04d43c5..0d4d5e8 100644 --- a/WorkloadTools/Listener/File/FileWorkloadListener.cs +++ b/WorkloadTools/Listener/File/FileWorkloadListener.cs @@ -1,14 +1,8 @@ -using System; -using System.Data; -using System.Data.Common; -using System.Data.SQLite; -using System.Linq; +using System.Data.SQLite; using System.Text; using NLog; -using WorkloadTools.Util; - namespace WorkloadTools.Listener.File { public class FileWorkloadListener : WorkloadListener diff --git a/WorkloadTools/Listener/ReadIteration.cs b/WorkloadTools/Listener/ReadIteration.cs index 17acfe7..2465964 100644 --- a/WorkloadTools/Listener/ReadIteration.cs +++ b/WorkloadTools/Listener/ReadIteration.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WorkloadTools.Listener +namespace WorkloadTools.Listener { // This class is used internally to keep track // of the files, offsets and event_sequences diff --git a/WorkloadTools/Listener/SqlTransformer.cs b/WorkloadTools/Listener/SqlTransformer.cs index 136f62d..e20d959 100644 --- a/WorkloadTools/Listener/SqlTransformer.cs +++ b/WorkloadTools/Listener/SqlTransformer.cs @@ -1,8 +1,4 @@ -using Microsoft.SqlServer.Management.SqlParser.Metadata; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Text; using System.Text.RegularExpressions; using WorkloadTools.Consumer.Analysis; diff --git a/WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs b/WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs index a2a6741..8804471 100644 --- a/WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs +++ b/WorkloadTools/Listener/Trace/FileTraceEventDataReader.cs @@ -1,12 +1,5 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; +using Microsoft.Data.SqlClient; using WorkloadTools.Util; namespace WorkloadTools.Listener.Trace diff --git a/WorkloadTools/Listener/Trace/ProfilerEventFilter.cs b/WorkloadTools/Listener/Trace/ProfilerEventFilter.cs index 7621d39..5822c52 100644 --- a/WorkloadTools/Listener/Trace/ProfilerEventFilter.cs +++ b/WorkloadTools/Listener/Trace/ProfilerEventFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.Trace +namespace WorkloadTools.Listener.Trace { public class ProfilerEventFilter : WorkloadEventFilter { diff --git a/WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs b/WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs index 359c39c..e38aa2e 100644 --- a/WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs +++ b/WorkloadTools/Listener/Trace/ProfilerFilterPredicate.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.Trace +namespace WorkloadTools.Listener.Trace { public class ProfilerFilterPredicate : FilterPredicate { diff --git a/WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs b/WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs index b20236c..c4f436b 100644 --- a/WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs +++ b/WorkloadTools/Listener/Trace/ProfilerWorkloadListener.cs @@ -1,12 +1,5 @@ using NLog; -using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using WorkloadTools.Listener.Trace; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs b/WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs index ed4a47c..e3ad6f3 100644 --- a/WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs +++ b/WorkloadTools/Listener/Trace/SqlConnectionInfoWrapper.cs @@ -1,9 +1,5 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs b/WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs index 5b27e3a..1b30a5c 100644 --- a/WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs +++ b/WorkloadTools/Listener/Trace/SqlTraceWorkloadListener.cs @@ -1,16 +1,5 @@ using NLog; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Data; -using System.Data.SqlClient; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using WorkloadTools.Listener.Trace; -using WorkloadTools.Util; +using Microsoft.Data.SqlClient; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/TraceEventDataReader.cs b/WorkloadTools/Listener/Trace/TraceEventDataReader.cs index f7be846..1ed4273 100644 --- a/WorkloadTools/Listener/Trace/TraceEventDataReader.cs +++ b/WorkloadTools/Listener/Trace/TraceEventDataReader.cs @@ -1,11 +1,4 @@ -using Microsoft.SqlServer.XEvent.Linq; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.Trace +namespace WorkloadTools.Listener.Trace { public abstract class TraceEventDataReader : IDisposable { diff --git a/WorkloadTools/Listener/Trace/TraceEventFilter.cs b/WorkloadTools/Listener/Trace/TraceEventFilter.cs index 4604862..f302223 100644 --- a/WorkloadTools/Listener/Trace/TraceEventFilter.cs +++ b/WorkloadTools/Listener/Trace/TraceEventFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.Trace +namespace WorkloadTools.Listener.Trace { public class TraceEventFilter : WorkloadEventFilter { diff --git a/WorkloadTools/Listener/Trace/TraceEventParser.cs b/WorkloadTools/Listener/Trace/TraceEventParser.cs index 0ee198a..e667fcc 100644 --- a/WorkloadTools/Listener/Trace/TraceEventParser.cs +++ b/WorkloadTools/Listener/Trace/TraceEventParser.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Linq; +using Microsoft.Data.SqlClient; + using System.Text; -using System.Threading.Tasks; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/TraceFileWrapper.cs b/WorkloadTools/Listener/Trace/TraceFileWrapper.cs index 22c646b..3fb3426 100644 --- a/WorkloadTools/Listener/Trace/TraceFileWrapper.cs +++ b/WorkloadTools/Listener/Trace/TraceFileWrapper.cs @@ -1,9 +1,5 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/TraceFilterPredicate.cs b/WorkloadTools/Listener/Trace/TraceFilterPredicate.cs index 612b056..3145790 100644 --- a/WorkloadTools/Listener/Trace/TraceFilterPredicate.cs +++ b/WorkloadTools/Listener/Trace/TraceFilterPredicate.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools.Listener.Trace +namespace WorkloadTools.Listener.Trace { class TraceFilterPredicate : FilterPredicate { diff --git a/WorkloadTools/Listener/Trace/TraceServerWrapper.cs b/WorkloadTools/Listener/Trace/TraceServerWrapper.cs index 00e0453..004f17a 100644 --- a/WorkloadTools/Listener/Trace/TraceServerWrapper.cs +++ b/WorkloadTools/Listener/Trace/TraceServerWrapper.cs @@ -1,12 +1,5 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Linq; using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/Listener/Trace/TraceUtils.cs b/WorkloadTools/Listener/Trace/TraceUtils.cs index e86370d..1bbcebb 100644 --- a/WorkloadTools/Listener/Trace/TraceUtils.cs +++ b/WorkloadTools/Listener/Trace/TraceUtils.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace WorkloadTools.Listener.Trace { diff --git a/WorkloadTools/MMFEventQueue.cs b/WorkloadTools/MMFEventQueue.cs index 3af5623..d065fbc 100644 --- a/WorkloadTools/MMFEventQueue.cs +++ b/WorkloadTools/MMFEventQueue.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using NFX.ApplicationModel.Pile; +using System.Collections.Concurrent; + +using Azos; +using Azos.Pile; namespace WorkloadTools { @@ -17,7 +15,8 @@ public class MMFEventQueue : IDisposable , IEventQueue public MMFEventQueue() { - pile = new MMFPile("workloadevents"); + var app = new Azos.Apps.AzosApplication(null); + pile = new MMFPile(app, "workloadevents"); pile.DataDirectoryRoot = System.IO.Path.GetTempPath(); pointers = new ConcurrentQueue(); pile.Start(); diff --git a/WorkloadTools/MessagWorkloadEvent.cs b/WorkloadTools/MessagWorkloadEvent.cs index 78358b2..9c5166e 100644 --- a/WorkloadTools/MessagWorkloadEvent.cs +++ b/WorkloadTools/MessagWorkloadEvent.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WorkloadTools +namespace WorkloadTools { [Serializable] public class MessageWorkloadEvent : WorkloadEvent diff --git a/WorkloadTools/Properties/AssemblyInfo.cs b/WorkloadTools/Properties/AssemblyInfo.cs index 097edca..f961804 100644 --- a/WorkloadTools/Properties/AssemblyInfo.cs +++ b/WorkloadTools/Properties/AssemblyInfo.cs @@ -1,6 +1,4 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("ae6e4548-8c33-4728-8504-88aa9666020b")] diff --git a/WorkloadTools/Properties/SharedAssemblyInfo.cs b/WorkloadTools/Properties/SharedAssemblyInfo.cs deleted file mode 100644 index 39e1a92..0000000 --- a/WorkloadTools/Properties/SharedAssemblyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SqlWorkload")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("spaghettidba")] -[assembly: AssemblyProduct("SqlWorkload")] -[assembly: AssemblyCopyright("Copyright © 2018 spaghettidba")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.4")] -[assembly: AssemblyFileVersion("1.0.4")] diff --git a/WorkloadTools/SqlConnectionInfo.cs b/WorkloadTools/SqlConnectionInfo.cs index 5e13cbf..57c7666 100644 --- a/WorkloadTools/SqlConnectionInfo.cs +++ b/WorkloadTools/SqlConnectionInfo.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools +namespace WorkloadTools { public class SqlConnectionInfo { @@ -14,7 +9,7 @@ public class SqlConnectionInfo public string UserName { get; set; } public string Password { get; set; } public bool Encrypt { get; set; } = false; - public bool TrustServerCertificate { get; set; } = false; + public bool TrustServerCertificate { get; set; } = true; public string ApplicationName { get; set; } = "WorkloadTools"; public int MaxPoolSize { get; set; } = 500; public Dictionary DatabaseMap { get; set; } = new Dictionary(); diff --git a/WorkloadTools/SqliteEventQueue.cs b/WorkloadTools/SqliteEventQueue.cs index 9ebb523..b45077d 100644 --- a/WorkloadTools/SqliteEventQueue.cs +++ b/WorkloadTools/SqliteEventQueue.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WorkloadTools +namespace WorkloadTools { public class SqliteEventQueue : BufferedEventQueue { diff --git a/WorkloadTools/Util/DataUtils.cs b/WorkloadTools/Util/DataUtils.cs index 80c2f44..3ffa848 100644 --- a/WorkloadTools/Util/DataUtils.cs +++ b/WorkloadTools/Util/DataUtils.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; +using System.Data; using System.Reflection; -using System.Text; namespace WorkloadTools.Util { diff --git a/WorkloadTools/Util/ModelConverter.cs b/WorkloadTools/Util/ModelConverter.cs index c20db88..a6f2719 100644 --- a/WorkloadTools/Util/ModelConverter.cs +++ b/WorkloadTools/Util/ModelConverter.cs @@ -1,28 +1,25 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using NLog.Targets; + using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using System.Web.Script.Serialization; -using WorkloadTools; +using System.Runtime.Serialization; -namespace WorkloadTools.Util +namespace WorkloadTools.Utils { - public class ModelConverter : JavaScriptConverter + public class ModelConverter { - public override IEnumerable SupportedTypes + public IEnumerable SupportedTypes { get { - var result = new List(); - var currentAssembly = Assembly.GetExecutingAssembly(); - var nameSpace = "WorkloadTools"; - var types = currentAssembly.GetTypes().Where(t => t != null && t.FullName.StartsWith(nameSpace) & !t.FullName.Contains("+")).ToArray(); - foreach (var t in types) + List result = new List(); + Assembly currentAssembly = Assembly.GetExecutingAssembly(); + string nameSpace = "WorkloadTools"; + Type[] types = currentAssembly.GetTypes().Where(t => t != null && t.FullName.StartsWith(nameSpace) & !t.FullName.Contains("+")).ToArray(); + foreach (Type t in types) { try { @@ -37,114 +34,182 @@ public override IEnumerable SupportedTypes } } - public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer) + public T Deserialize(string json) { - object p; - try - { - // try to create the object using its parameterless constructor - p = Activator.CreateInstance(type); - } - catch { - // try to create the object using this scary initializer that - // doesn't need the parameterless constructor - p = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); - } + return (T)Deserialize(json, typeof(T)); + } - var props = type.GetProperties(); + public object Deserialize(string json, Type type) + { + if (string.IsNullOrWhiteSpace(json)) + return null; - foreach (var key in dictionary.Keys) + JToken token = JsonConvert.DeserializeObject(json); + var dictionary = token.ToObject>(); + return Deserialize(dictionary, type); + } + + public object Deserialize(IDictionary dictionary, Type type) + { + object instance = CreateInstance(dictionary, type); + var props = instance.GetType().GetProperties(); + + foreach (var kvp in dictionary) { - var prop = props.Where(t => t.Name == key).FirstOrDefault(); - if (prop != null) + string key = kvp.Key; + var prop = props.FirstOrDefault(p => string.Equals(p.Name, key, StringComparison.OrdinalIgnoreCase)); + if (prop == null) + continue; + + object rawValue = ConvertJTokenIfNeeded(kvp.Value); + if (rawValue == null) + continue; + + + if (prop.Name == "ServerName") { - if (prop.Name.EndsWith("Filter")) + if (prop.PropertyType == typeof(string)) { - if (dictionary[key] is string stringValue) - { - prop.SetValue(p, new string[] { stringValue }, null); - } - else - { - prop.SetValue(p, (string[])((ArrayList)dictionary[key]).ToArray(typeof(string)), null); - } + prop.SetValue(instance, rawValue.ToString()); } else { - if (dictionary[key] is Dictionary dictionaryValue) - { - if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) - { - var rawDic = dictionaryValue; - - var obj = Activator.CreateInstance(prop.PropertyType); - foreach (var itm in rawDic.Keys) - { - ((Dictionary)obj).Add(itm, rawDic[itm].ToString()); - } - prop.SetValue(p, obj, null); - } - else - { - prop.SetValue(p, Deserialize(dictionaryValue, prop.PropertyType, serializer), null); - } - } - else + prop.SetValue(instance, ConvertToStringArray(rawValue)); + } + continue; + } + + + if (rawValue is IDictionary subDict) + { + prop.SetValue(instance, Deserialize(subDict, prop.PropertyType)); + } + else if (rawValue is IList list && prop.PropertyType.IsGenericType) + { + var listInstance = (IList)Activator.CreateInstance(prop.PropertyType); + Type elementType = prop.PropertyType.GetGenericArguments()[0]; + foreach (var item in list) + { + object convertedItem = ConvertJTokenIfNeeded(item); + if (convertedItem is IDictionary dictItem) { - if (dictionary[key] is IList && prop.PropertyType.IsGenericType) - { - var obj = Activator.CreateInstance(prop.PropertyType); - foreach (var itm in (IEnumerable)dictionary[key]) - { - _ = ((IList)obj).Add(itm); - } - prop.SetValue(p, obj, null); - } - else - { - prop.SetValue(p, GetValueOfType(dictionary[key], prop.PropertyType), null); - } + convertedItem = Deserialize(dictItem, elementType); } - + listInstance.Add(convertedItem); } + prop.SetValue(instance, listInstance); + } + else if (prop.PropertyType.IsEnum) + { + prop.SetValue(instance, Enum.Parse(prop.PropertyType, rawValue.ToString())); + } + else + { + prop.SetValue(instance, GetValueOfType(rawValue, prop.PropertyType)); } } - - return p; + return instance; } - - private object GetValueOfType(object v, Type propertyType) + private object CreateInstance(IDictionary dictionary, Type type) { - if (propertyType == typeof(string)) + try + { + if (type.IsAbstract && dictionary.TryGetValue("__type", out var subTypeObj) && subTypeObj != null) + { + var subTypeName = subTypeObj.ToString(); + + var realType = Assembly.GetExecutingAssembly().GetType(subTypeName) + ?? Type.GetType(subTypeName); + + if (realType == null) + { + realType = SupportedTypes + .FirstOrDefault(t => + t.FullName.EndsWith("." + subTypeName, StringComparison.OrdinalIgnoreCase) + || t.Name.Equals(subTypeName, StringComparison.OrdinalIgnoreCase)); + } + + if (realType != null && !realType.IsAbstract) + { + return Activator.CreateInstance(realType); + } + } + + return Activator.CreateInstance(type); + } + catch (Exception ex) { - return (string)v; + Console.WriteLine("Exception during instance creation: " + ex.Message); + return FormatterServices.GetUninitializedObject(type); } - else if (propertyType == typeof(bool)) + } + + + + private object ConvertJTokenIfNeeded(object value) + { + if (value is JObject jObj) { - return Convert.ToBoolean(v); + var dict = new Dictionary(); + foreach (var prop in jObj.Properties()) + { + dict[prop.Name] = ConvertJTokenIfNeeded(prop.Value); + } + return dict; } - else if (propertyType == typeof(int)) + else if (value is JArray jArr) { - return Convert.ToInt32(v); + var list = new List(); + foreach (var item in jArr) + { + list.Add(ConvertJTokenIfNeeded(item)); + } + return list; } - else if (propertyType == typeof(long)) + else if (value is JValue jVal) { - return Convert.ToInt64(v); + return jVal.Value; } - else if (propertyType == typeof(DateTime)) + return value; + } + + private string[] ConvertToStringArray(object val) + { + if (val == null) + return null; + if (val is IEnumerable enumerable && !(val is string)) { - return Convert.ToDateTime(v); + var strList = new List(); + foreach (var item in enumerable) + { + strList.Add(item?.ToString()); + } + return strList.ToArray(); } + return new string[] { val.ToString() }; + } + + private object GetValueOfType(object v, Type propertyType) + { + if (propertyType == typeof(string)) + return v?.ToString(); + else if (propertyType == typeof(bool)) + return Convert.ToBoolean(v); + else if (propertyType == typeof(int)) + return Convert.ToInt32(v); + else if (propertyType == typeof(long)) + return Convert.ToInt64(v); + else if (propertyType == typeof(int?)) + return v == null ? (int?)null : Convert.ToInt32(v); + else if (propertyType == typeof(long?)) + return v == null ? (long?)null : Convert.ToInt64(v); else - { return v; - } } - public override IDictionary Serialize(object obj, JavaScriptSerializer serializer) + public IDictionary Serialize(object obj) { throw new NotImplementedException(); } - } } diff --git a/WorkloadTools/Util/RingBuffer.cs b/WorkloadTools/Util/RingBuffer.cs index 9faf92a..c190a97 100644 --- a/WorkloadTools/Util/RingBuffer.cs +++ b/WorkloadTools/Util/RingBuffer.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections; -using System.Collections.Generic; +using System.Collections; using System.Diagnostics; namespace WorkloadTools.Util diff --git a/WorkloadTools/Util/StringExtensions.cs b/WorkloadTools/Util/StringExtensions.cs index 909e39f..a2bd25d 100644 --- a/WorkloadTools/Util/StringExtensions.cs +++ b/WorkloadTools/Util/StringExtensions.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WorkloadTools.Util +namespace WorkloadTools.Util { public static class StringExtensions { diff --git a/WorkloadTools/WaitStatsWorkloadEvent.cs b/WorkloadTools/WaitStatsWorkloadEvent.cs index 6d68858..2b621e5 100644 --- a/WorkloadTools/WaitStatsWorkloadEvent.cs +++ b/WorkloadTools/WaitStatsWorkloadEvent.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; +using System.Data; namespace WorkloadTools { diff --git a/WorkloadTools/WorkloadController.cs b/WorkloadTools/WorkloadController.cs index 768d503..da7d4f6 100644 --- a/WorkloadTools/WorkloadController.cs +++ b/WorkloadTools/WorkloadController.cs @@ -1,10 +1,4 @@ using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using WorkloadTools.Consumer; namespace WorkloadTools diff --git a/WorkloadTools/WorkloadEvent.cs b/WorkloadTools/WorkloadEvent.cs index 6ae1f13..bba6a16 100644 --- a/WorkloadTools/WorkloadEvent.cs +++ b/WorkloadTools/WorkloadEvent.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools +namespace WorkloadTools { [Serializable] public abstract class WorkloadEvent diff --git a/WorkloadTools/WorkloadEventFilter.cs b/WorkloadTools/WorkloadEventFilter.cs index 8131960..4107901 100644 --- a/WorkloadTools/WorkloadEventFilter.cs +++ b/WorkloadTools/WorkloadEventFilter.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace WorkloadTools +namespace WorkloadTools { public abstract class WorkloadEventFilter { diff --git a/WorkloadTools/WorkloadListener.cs b/WorkloadTools/WorkloadListener.cs index 4eb5985..77caaa5 100644 --- a/WorkloadTools/WorkloadListener.cs +++ b/WorkloadTools/WorkloadListener.cs @@ -1,12 +1,6 @@ using NLog; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Text; -using System.Threading; +using Microsoft.Data.SqlClient; using WorkloadTools.Util; namespace WorkloadTools diff --git a/WorkloadTools/WorkloadTools.csproj b/WorkloadTools/WorkloadTools.csproj index 36ee954..f5236cc 100644 --- a/WorkloadTools/WorkloadTools.csproj +++ b/WorkloadTools/WorkloadTools.csproj @@ -1,332 +1,36 @@ - - - + + - Debug - AnyCPU - {AE6E4548-8C33-4728-8504-88AA9666020B} - Library - Properties - WorkloadTools - WorkloadTools - v4.8 - 512 - - - + net9.0 + enable + enable - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - x86 - x64 - - - true - bin\x86\Debug\ - DEBUG;TRACE - full - x86 - prompt - MinimumRecommendedRules.ruleset - false - - - bin\x86\Release\ - TRACE - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - false - - - - ..\packages\DouglasCrockford.JsMin.1.1.3\lib\net40-client\DouglasCrockford.JsMin.dll - - - ..\packages\FastMember.1.5.0\lib\net461\FastMember.dll - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.AzureStorageEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.BatchParserClient.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.ConnectionInfo.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.ConnectionInfoExtended.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Diagnostics.Strace.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Dmf.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Dmf.Common.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.Collector.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.CollectorEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.RegisteredServers.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.Sdk.Sfc.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.SqlParser.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.Utility.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.UtilityEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.XEvent.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.XEventDbScoped.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.XEventDbScopedEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Management.XEventEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.PolicyEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.RegSvrEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.ServiceBrokerEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Smo.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SmoExtended.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SqlClrProvider.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SqlEnum.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SqlTDiagm.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SqlWmiManagement.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.SString.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.Types.dll - True - - - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\lib\net40\Microsoft.SqlServer.WmiEnum.dll - True - - - False - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\runtimes\win-$(CurrentPlatform)\native\Microsoft.SqlServer.Xe.Core.dll - - - False - ..\packages\Microsoft.SqlServer.SqlManagementObjects.140.17279.0\runtimes\win-$(CurrentPlatform)\native\Microsoft.SqlServer.XEvent.Linq.dll - - - ..\packages\NFX.3.5.0.5\lib\NFX.dll - - - ..\packages\NLog.4.7.15\lib\net45\NLog.dll - - - - - - ..\packages\System.Data.SQLite.Core.1.0.112.0\lib\net46\System.Data.SQLite.dll - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - - - - - - - - - - - - - - - + + + + + + + + + + - - + Always - + Always - + Always - + Always - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - Always - - - Always - - - - - Always - - - Always - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file + + diff --git a/WorkloadTools/app.config b/WorkloadTools/app.config deleted file mode 100644 index 8468eb3..0000000 --- a/WorkloadTools/app.config +++ /dev/null @@ -1,26 +0,0 @@ - - - - -
- - - - - - 64 - - - 15 - - - - - - - - - - - -