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