├── appveyor.yml
├── .travis.yml
├── sql_profiler
├── Code
│ ├── OutputWriter
│ │ ├── OutputWriter.cs
│ │ ├── HtmlOutputWriter.cs
│ │ ├── ConsoleOutputWriter.cs
│ │ └── RtfBuilder.cs
│ ├── Helpers
│ │ ├── PerfColumn.cs
│ │ ├── WindowsFix.cs
│ │ ├── CommandLineArguments.cs
│ │ └── SecretManager.cs
│ ├── Lexer
│ │ ├── SqlTokens.cs
│ │ └── YukonLexer.cs
│ ├── SqlServerProfiler.cs
│ └── NotImplemented
│ │ └── TraceProperties.cs
├── sql_profiler.csproj
├── SQL
│ └── Clear_Traces.sql
├── EventList.cs
├── LICENSE.md
└── Program.cs
├── sql_profiler.sln
├── .gitattributes
├── README.md
└── .gitignore
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2017
2 | environment:
3 | DOTNET_CLI_TELEMETRY_OPTOUT: true
4 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
5 | before_build:
6 | - cmd: dotnet restore
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | language: csharp
3 | dist: xenial
4 | # http://www.erikschierboom.com/2017/03/21/continuous-integration-of-dotnet-core-applications/
5 | # SDK-version:
6 | dotnet: 2.1.4
7 | mono: none
8 | env:
9 | global:
10 | - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
11 | - DOTNET_CLI_TELEMETRY_OPTOUT: 1
12 | script:
13 | - dotnet restore
14 | - dotnet build
15 |
--------------------------------------------------------------------------------
/sql_profiler/Code/OutputWriter/OutputWriter.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace ExpressProfiler
3 | {
4 |
5 |
6 | public abstract class OutputWriter
7 | {
8 | public abstract System.Drawing.Color ForeColor { set; }
9 | public abstract System.Drawing.Color BackColor { set; }
10 | public abstract void AppendLine();
11 | public abstract void Append(string text);
12 | public new abstract string ToString();
13 | }
14 |
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/sql_profiler/Code/Helpers/PerfColumn.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace ExpressProfiler
3 | {
4 |
5 |
6 | public enum HorizontalAlignment
7 | {
8 | Left = 0,
9 | Right = 1,
10 | Center = 2
11 | }
12 |
13 |
14 | public class PerfColumn
15 | {
16 | public string Caption;
17 | public int Column;
18 | public int Width;
19 | public string Format;
20 | public HorizontalAlignment Alignment = HorizontalAlignment.Left;
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/sql_profiler/sql_profiler.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/sql_profiler/SQL/Clear_Traces.sql:
--------------------------------------------------------------------------------
1 |
2 | DECLARE @trace_id AS integer;
3 | DECLARE @trace_iterator AS CURSOR;
4 |
5 | SET @trace_iterator = CURSOR FOR
6 | (
7 | SELECT id FROM sys.traces WHERE is_default <> 1
8 | );
9 |
10 |
11 | OPEN @trace_iterator;
12 | FETCH NEXT FROM @trace_iterator INTO @trace_id;
13 |
14 | WHILE @@FETCH_STATUS = 0
15 | BEGIN
16 | PRINT 'sp_trace_setstatus ' + CAST(@trace_id AS varchar(20)) + ', 0';
17 | PRINT 'sp_trace_setstatus ' + CAST(@trace_id AS varchar(20)) + ', 2';
18 |
19 | -- 0: Stops the specified trace.
20 | -- 1: Starts the specified trace.
21 | -- 2: Closes the specified trace and deletes its definition from the server.
22 |
23 | EXEC sp_trace_setstatus @trace_id, 0;
24 | EXEC sp_trace_setstatus @trace_id, 2;
25 |
26 | FETCH NEXT FROM @trace_iterator INTO @trace_id;
27 | END
28 |
29 | CLOSE @trace_iterator;
30 | DEALLOCATE @trace_iterator;
31 |
--------------------------------------------------------------------------------
/sql_profiler.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.12
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "sql_profiler", "sql_profiler\sql_profiler.csproj", "{337F0509-40BF-4F38-BA9B-F7972E40BED4}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{48DE8B2B-ED7D-42DB-BD6A-01C35D978401}"
9 | ProjectSection(SolutionItems) = preProject
10 | .travis.yml = .travis.yml
11 | appveyor.yml = appveyor.yml
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {337F0509-40BF-4F38-BA9B-F7972E40BED4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {337F0509-40BF-4F38-BA9B-F7972E40BED4}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {337F0509-40BF-4F38-BA9B-F7972E40BED4}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {337F0509-40BF-4F38-BA9B-F7972E40BED4}.Release|Any CPU.Build.0 = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | GlobalSection(ExtensibilityGlobals) = postSolution
30 | SolutionGuid = {BF379AE7-8ADA-4F77-8CF2-2DFF82062284}
31 | EndGlobalSection
32 | EndGlobal
33 |
--------------------------------------------------------------------------------
/sql_profiler/Code/Helpers/WindowsFix.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace sql_profiler
3 | {
4 |
5 | // https://social.msdn.microsoft.com/Forums/vstudio/en-US/707e9ae1-a53f-4918-8ac4-62a1eddb3c4a/detecting-console-application-exit-in-c?forum=csharpgeneral
6 | internal static class WindowsFix
7 | {
8 |
9 | // An enumerated type for the control messages
10 | // sent to the handler routine.
11 | public enum CtrlTypes
12 | {
13 | CTRL_C_EVENT = 0,
14 | CTRL_BREAK_EVENT,
15 | CTRL_CLOSE_EVENT,
16 | CTRL_LOGOFF_EVENT = 5,
17 | CTRL_SHUTDOWN_EVENT
18 | }
19 |
20 | // A delegate type to be used as the handler routine
21 | // for SetConsoleCtrlHandler.
22 | public delegate bool HandlerRoutine_t(CtrlTypes CtrlType);
23 |
24 | public static void AddConsoleHandler(HandlerRoutine_t on)
25 | {
26 | bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
27 | System.Runtime.InteropServices.OSPlatform.Windows
28 | );
29 |
30 | if(isWindows)
31 | SetConsoleCtrlHandler(on, true);
32 | }
33 |
34 |
35 | private static bool isclosing = false;
36 |
37 |
38 |
39 |
40 | [System.Runtime.InteropServices.DllImport("Kernel32")]
41 | private static extern bool SetConsoleCtrlHandler(HandlerRoutine_t Handler, bool Add);
42 |
43 | private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
44 | {
45 | System.Console.WriteLine(isclosing);
46 |
47 | // Put your own handler here
48 | switch (ctrlType)
49 | {
50 | case CtrlTypes.CTRL_C_EVENT:
51 | isclosing = true;
52 | System.Console.WriteLine("CTRL+C received!");
53 | break;
54 | case CtrlTypes.CTRL_BREAK_EVENT:
55 | isclosing = true;
56 | System.Console.WriteLine("CTRL+BREAK received!");
57 | break;
58 | case CtrlTypes.CTRL_CLOSE_EVENT:
59 | isclosing = true;
60 | System.Console.WriteLine("Program being closed!");
61 | break;
62 | case CtrlTypes.CTRL_LOGOFF_EVENT:
63 | case CtrlTypes.CTRL_SHUTDOWN_EVENT:
64 | isclosing = true;
65 | System.Console.WriteLine("User is logging off!");
66 | break;
67 | }
68 |
69 | return true;
70 | }
71 |
72 |
73 | }
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/sql_profiler/Code/OutputWriter/HtmlOutputWriter.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace ExpressProfiler
3 | {
4 |
5 |
6 | public class HtmlOutputWriter
7 | : OutputWriter
8 | {
9 | private static System.Collections.Generic.Dictionary<
10 | System.Drawing.Color, System.ConsoleColor> s_colorDict;
11 |
12 |
13 | private System.ConsoleColor m_backupForeground;
14 | private System.ConsoleColor m_backupBackground;
15 |
16 |
17 | static HtmlOutputWriter()
18 | {
19 | s_colorDict = SetupColorDictionary();
20 | }
21 |
22 |
23 |
24 | public HtmlOutputWriter()
25 | {
26 | this.m_backupForeground = System.Console.ForegroundColor;
27 | this.m_backupBackground = System.Console.BackgroundColor;
28 | }
29 |
30 |
31 | private static System.Collections.Generic.Dictionary<
32 | System.Drawing.Color, System.ConsoleColor>
33 | SetupColorDictionary()
34 | {
35 | System.Collections.Generic.Dictionary
36 | dict = new System.Collections.Generic.Dictionary<
37 | System.Drawing.Color, System.ConsoleColor
38 | >();
39 |
40 | dict.Add(System.Drawing.Color.Black, System.ConsoleColor.Black);
41 | dict.Add(System.Drawing.Color.DarkBlue, System.ConsoleColor.DarkBlue);
42 | dict.Add(System.Drawing.Color.DarkGreen, System.ConsoleColor.DarkGreen);
43 | dict.Add(System.Drawing.Color.DarkCyan, System.ConsoleColor.DarkCyan);
44 | dict.Add(System.Drawing.Color.DarkRed, System.ConsoleColor.DarkRed);
45 | dict.Add(System.Drawing.Color.DarkMagenta, System.ConsoleColor.DarkMagenta);
46 | dict.Add(System.Drawing.Color.FromArgb(215, 195, 42), System.ConsoleColor.DarkYellow);
47 | dict.Add(System.Drawing.Color.Gray, System.ConsoleColor.Gray);
48 | dict.Add(System.Drawing.Color.DarkGray, System.ConsoleColor.DarkGray);
49 | dict.Add(System.Drawing.Color.Blue, System.ConsoleColor.Blue);
50 | dict.Add(System.Drawing.Color.Green, System.ConsoleColor.Green);
51 | dict.Add(System.Drawing.Color.Cyan, System.ConsoleColor.Cyan);
52 | dict.Add(System.Drawing.Color.Red, System.ConsoleColor.Red);
53 | dict.Add(System.Drawing.Color.Magenta, System.ConsoleColor.Magenta);
54 | dict.Add(System.Drawing.Color.Yellow, System.ConsoleColor.Yellow);
55 | dict.Add(System.Drawing.Color.White, System.ConsoleColor.White);
56 |
57 | return dict;
58 | }
59 |
60 |
61 | public override System.Drawing.Color ForeColor
62 | {
63 | set { System.Console.ForegroundColor = s_colorDict[value]; }
64 | }
65 |
66 |
67 | public override System.Drawing.Color BackColor
68 | {
69 | set
70 | {
71 | System.Console.BackgroundColor = s_colorDict[value];
72 | System.Console.WriteLine(new string(' ', System.Console.BufferWidth));
73 | }
74 | }
75 |
76 |
77 | public override void AppendLine()
78 | {
79 | System.Console.WriteLine();
80 | }
81 |
82 |
83 | public override void Append(string text)
84 | {
85 | System.Console.Write(text);
86 | }
87 |
88 |
89 | public override string ToString()
90 | {
91 | System.Console.ForegroundColor = this.m_backupForeground;
92 | System.Console.BackgroundColor = this.m_backupBackground;
93 |
94 | return "";
95 | }
96 |
97 |
98 | }
99 |
100 |
101 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # MS-SQL-Server command line profiler  
3 |
4 |
5 | sql_profiler is a simple and fast replacement for SQL Server Profiler.
6 | It's a .NET-Core command-line port of ExpressProfiler, and runs everywhere .NET Core runs.
7 | So it runs on
8 | - Windows (x86-32, x86-64)
9 | - Linux (x86-64, ARM-32)
10 | - Mac/OS-X.
11 |
12 | It's a fork of [ExpressProfiler](https://github.com/OleksiiKovalov/expressprofiler) for MS-SQL-Server ([actually a fork of a slightly modified version](https://github.com/ststeiger/ExpressProfiler) - working datetime-format for any language).
13 | I used it to port ExpressProfiler to .NET Core (command-line).
14 |
15 |
16 | sql_profiler can be used with both Express and non-Express editions of SQL Server 2005/2008/2008r2/2012/2014.
17 | Installation or administrative rights are not required.
18 | Trace permission are required for the SQL-user.
19 |
20 |
21 | **Invocation**
22 | ```bash
23 | ./sql_profiler --server {computername\instance} --username WebAppWebServices --password TOP_SECRET --db "The DB you want to profile";
24 | ```
25 |
26 | or from the project:
27 |
28 | ```bash
29 | dotnet run sql_profiler --server {computername\instance} --username WebAppWebServices --password TOP_SECRET --db "The DB you want to profile";
30 | ```
31 | If you omit the username, it will attempt to connect with integrated security.
32 |
33 | [![Windows-Console-Profiler: This is Sparta !][1]][1]
34 |
35 | [![Linux-Console-Profiler: This is Sparta !][2]][2]
36 |
37 |
38 |
39 | **Grant rights:**
40 |
41 |
42 | ```sql
43 |
44 | -- To Grant access to a Windows Login
45 | USE Master;
46 | GO
47 | GRANT ALTER TRACE TO [DomainNAME\WindowsLogin]
48 | GO
49 |
50 | -- To Grant access to a SQL Login
51 | USE master;
52 | GO
53 | GRANT ALTER TRACE TO manvendra
54 | GO
55 |
56 | ```
57 |
58 | [(source)](https://www.mssqltips.com/sqlservertip/3559/how-to-grant-permissions-to-run-sql-server-profiler-for-a-non-system-admin-user/)
59 |
60 |
61 | ### Standalone Building
62 |
63 | **Build for Windows x86-64:**
64 | > dotnet restore -r win-x64
65 | > dotnet build -r win-x64
66 | > dotnet publish -f netcoreapp2.0 -c Release -r win-x64
67 |
68 | **Build for Windows x86-32:**
69 | > dotnet restore -r win-x86
70 | > dotnet build -r win-x86
71 | > dotnet publish -f netcoreapp2.0 -c Release -r win-x86
72 |
73 |
74 | **Build for Linux x86-32:**
75 | > **not supported by framework**
76 |
77 | **Build for Linux x86-64:**
78 | > dotnet restore -r linux-x64
79 | > dotnet build -r linux-x64
80 | > dotnet publish -f netcoreapp2.0 -c Release -r linux-x64
81 |
82 |
83 | **Build for Linux ARM-32 (Raspberry PI/Chromebook/Android):**
84 | > dotnet restore -r linux-arm
85 | > dotnet build -r linux-arm
86 | > dotnet publish -f netcoreapp2.0 -c Release -r linux-arm
87 |
88 | **Build for Linux ARM-64:**
89 | > **not supported by framework**
90 |
91 |
92 | **Build for Mac OSX x86-32:**
93 | > **not supported by framework**
94 |
95 | **Build for Mac OSX x86-64:**
96 | > dotnet restore -r osx-x64
97 | > dotnet build -r osx-x64
98 | > dotnet publish -f netcoreapp2.0 -c Release -r osx-x64
99 |
100 | Mac build requires MacOS >= Sierra (10.12+)
101 |
102 |
103 |
104 | # Future:
105 | **Build for Android (arch?):**
106 | > dotnet restore -r android
107 | > dotnet build -r android
108 | > dotnet publish -f netcoreapp2.0 -c Release -r android
109 |
110 |
111 | [List of RIDs][3]
112 |
113 |
114 |
115 | [1]: https://i.stack.imgur.com/IgYvq.png
116 | [2]: https://i.stack.imgur.com/hEaFY.png
117 | [3]: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
118 |
--------------------------------------------------------------------------------
/sql_profiler/Code/OutputWriter/ConsoleOutputWriter.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace ExpressProfiler
3 | {
4 |
5 |
6 | public class ConsoleOutputWriter
7 | : OutputWriter
8 | {
9 | private static bool s_isWindows;
10 | private static System.Collections.Generic.Dictionary<
11 | System.Drawing.Color, System.ConsoleColor> s_colorDict;
12 |
13 |
14 | private System.ConsoleColor m_backupForeground;
15 | private System.ConsoleColor m_backupBackground;
16 |
17 |
18 | static ConsoleOutputWriter()
19 | {
20 | s_isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
21 | System.Runtime.InteropServices.OSPlatform.Windows
22 | );
23 |
24 | s_colorDict = SetupColorDictionary();
25 | }
26 |
27 |
28 |
29 | public ConsoleOutputWriter()
30 | {
31 | this.m_backupForeground = System.Console.ForegroundColor;
32 | this.m_backupBackground = System.Console.BackgroundColor;
33 | }
34 |
35 |
36 | private static System.Collections.Generic.Dictionary<
37 | System.Drawing.Color, System.ConsoleColor>
38 | SetupColorDictionary()
39 | {
40 | System.Collections.Generic.Dictionary
41 | dict = new System.Collections.Generic.Dictionary<
42 | System.Drawing.Color, System.ConsoleColor
43 | >();
44 |
45 | dict.Add(System.Drawing.Color.Black, System.ConsoleColor.Black);
46 | dict.Add(System.Drawing.Color.DarkBlue, System.ConsoleColor.DarkBlue);
47 | dict.Add(System.Drawing.Color.DarkGreen, System.ConsoleColor.DarkGreen);
48 | dict.Add(System.Drawing.Color.DarkCyan, System.ConsoleColor.DarkCyan);
49 | dict.Add(System.Drawing.Color.DarkRed, System.ConsoleColor.DarkRed);
50 | dict.Add(System.Drawing.Color.DarkMagenta, System.ConsoleColor.DarkMagenta);
51 | dict.Add(System.Drawing.Color.FromArgb(215, 195, 42), System.ConsoleColor.DarkYellow);
52 | dict.Add(System.Drawing.Color.Gray, System.ConsoleColor.Gray);
53 | dict.Add(System.Drawing.Color.DarkGray, System.ConsoleColor.DarkGray);
54 | dict.Add(System.Drawing.Color.Blue, System.ConsoleColor.Blue);
55 | dict.Add(System.Drawing.Color.Green, System.ConsoleColor.Green);
56 | dict.Add(System.Drawing.Color.Cyan, System.ConsoleColor.Cyan);
57 | dict.Add(System.Drawing.Color.Red, System.ConsoleColor.Red);
58 | dict.Add(System.Drawing.Color.Magenta, System.ConsoleColor.Magenta);
59 | dict.Add(System.Drawing.Color.Yellow, System.ConsoleColor.Yellow);
60 | dict.Add(System.Drawing.Color.White, System.ConsoleColor.White);
61 | dict.Add(System.Drawing.Color.Fuchsia, System.ConsoleColor.Magenta); // Correct ?
62 |
63 | return dict;
64 | }
65 |
66 |
67 | public override System.Drawing.Color ForeColor
68 | {
69 |
70 |
71 | set
72 | {
73 | // if (!s_colorDict.ContainsKey(value)) System.Console.WriteLine(value);
74 | System.Console.ForegroundColor = s_colorDict[value];
75 | }
76 | }
77 |
78 |
79 | public override System.Drawing.Color BackColor
80 | {
81 | set
82 | {
83 | // if (!s_colorDict.ContainsKey(value)) System.Console.WriteLine(value);
84 | System.Console.BackgroundColor = s_colorDict[value];
85 | //this.AppendLine();
86 | }
87 | }
88 |
89 |
90 | public override void AppendLine()
91 | {
92 | // Finish the line with empty color
93 | System.Console.Write(new string(' ', System.Console.BufferWidth - System.Console.CursorLeft));
94 |
95 | if(!s_isWindows)
96 | System.Console.Write(System.Environment.NewLine);
97 | //else System.Console.WriteLine();
98 | }
99 |
100 |
101 | public override void Append(string text)
102 | {
103 | System.Console.Write(text);
104 | }
105 |
106 |
107 | public override string ToString()
108 | {
109 | System.Console.ForegroundColor = this.m_backupForeground;
110 | System.Console.BackgroundColor = this.m_backupBackground;
111 |
112 | return "";
113 | }
114 |
115 |
116 | }
117 |
118 |
119 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/sql_profiler/Code/OutputWriter/RtfBuilder.cs:
--------------------------------------------------------------------------------
1 |
2 | // Traceutils assembly
3 | // writen by Locky, 2009.
4 |
5 | namespace ExpressProfiler
6 | {
7 |
8 |
9 | class RTFBuilder
10 | : OutputWriter
11 | {
12 | private readonly System.Text.StringBuilder m_Sb = new System.Text.StringBuilder();
13 | private readonly System.Collections.Generic.List
14 | m_Colortable = new System.Collections.Generic.List();
15 | private readonly System.Collections.Specialized.StringCollection m_Fonttable =
16 | new System.Collections.Specialized.StringCollection();
17 | private System.Drawing.Color m_Forecolor;
18 |
19 | public override System.Drawing.Color ForeColor
20 | {
21 | set
22 | {
23 | if (!m_Colortable.Contains(value))
24 | {
25 | m_Colortable.Add(value);
26 | }
27 |
28 | if (value != m_Forecolor)
29 | {
30 | m_Sb.Append(string.Format("\\cf{0} ", m_Colortable.IndexOf(value) + 1));
31 | }
32 |
33 | m_Forecolor = value;
34 | }
35 | }
36 |
37 |
38 | private System.Drawing.Color m_Backcolor;
39 |
40 | public override System.Drawing.Color BackColor
41 | {
42 | set
43 | {
44 | if (!m_Colortable.Contains(value))
45 | {
46 | m_Colortable.Add(value);
47 | }
48 |
49 | if (value != m_Backcolor)
50 | {
51 | m_Sb.Append(string.Format("\\highlight{0} ", m_Colortable.IndexOf(value) + 1));
52 | }
53 |
54 | m_Backcolor = value;
55 | }
56 | }
57 |
58 |
59 | public RTFBuilder()
60 | {
61 | ForeColor = System.Drawing.Color.Black; // Color.FromKnownColor(KnownColor.WindowText);
62 | BackColor = System.Drawing.Color.White; // Color.FromKnownColor(KnownColor.Window);
63 | m_DefaultFontSize = 20F;
64 | }
65 |
66 | public override void AppendLine()
67 | {
68 | m_Sb.AppendLine("\\line ");
69 | }
70 |
71 | public override void Append(string value)
72 | {
73 | if (!string.IsNullOrEmpty(value))
74 | {
75 | value = value.Replace("\r\n", "\n");
76 |
77 | // A sole carriage return should not be treated as Environment.NewLine
78 | value = value.Replace("\r", "");
79 | value = CheckChar(value);
80 |
81 | int newlineIndex = -1;
82 | while ((newlineIndex = value.IndexOf('\n')) != -1)
83 | {
84 | string valueToAdd = value.Substring(0, newlineIndex);
85 | if (!string.IsNullOrEmpty(valueToAdd))
86 | m_Sb.Append(valueToAdd);
87 |
88 | m_Sb.Append("\\line ");
89 |
90 | value = value.Substring(newlineIndex + 1);
91 | } // Whend
92 |
93 | if (!string.IsNullOrEmpty(value))
94 | m_Sb.Append(value);
95 | }
96 | }
97 |
98 | private static readonly char[] Slashable = new[] {'{', '}', '\\'};
99 | private readonly float m_DefaultFontSize;
100 |
101 | private static string CheckChar(string value)
102 | {
103 | if (!string.IsNullOrEmpty(value))
104 | {
105 | if (value.IndexOfAny(Slashable) >= 0)
106 | {
107 | // value = value.Replace("{", "\\{").Replace("}", "\\}").Replace("\\", "\\\\");
108 | value = value.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}");
109 | }
110 |
111 | bool replaceuni = false;
112 | for (int i = 0; i < value.Length; i++)
113 | {
114 | if (value[i] > 255)
115 | {
116 | replaceuni = true;
117 | break;
118 | }
119 | }
120 |
121 | if (replaceuni)
122 | {
123 | System.Text.StringBuilder sb = new System.Text.StringBuilder();
124 | for (int i = 0; i < value.Length; i++)
125 | {
126 | if (value[i] <= 255)
127 | {
128 | sb.Append(value[i]);
129 | }
130 | else
131 | {
132 | sb.Append("\\u");
133 | sb.Append((int) value[i]);
134 | sb.Append("?");
135 | }
136 | }
137 |
138 | value = sb.ToString();
139 | }
140 | }
141 |
142 |
143 | return value;
144 | }
145 |
146 | public override string ToString()
147 | {
148 | System.Text.StringBuilder result = new System.Text.StringBuilder();
149 | result.Append("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang3081");
150 | result.Append("{\\fonttbl");
151 | for (int i = 0; i < m_Fonttable.Count; i++)
152 | {
153 | try
154 | {
155 | result.Append(string.Format(m_Fonttable[i], i));
156 | }
157 | catch (System.Exception ex)
158 | {
159 | System.Console.WriteLine(ex.Message);
160 | }
161 | }
162 |
163 | result.AppendLine("}");
164 | result.Append("{\\colortbl ;");
165 | foreach (System.Drawing.Color item in m_Colortable)
166 | {
167 | result.AppendFormat("\\red{0}\\green{1}\\blue{2};", item.R, item.G, item.B);
168 | }
169 |
170 | result.AppendLine("}");
171 | result.Append("\\viewkind4\\uc1\\pard\\plain\\f0");
172 | result.AppendFormat("\\fs{0} ", m_DefaultFontSize);
173 | result.AppendLine();
174 | result.Append(m_Sb.ToString());
175 | result.Append("}");
176 | return result.ToString();
177 | }
178 |
179 |
180 | }
181 |
182 |
183 | }
184 |
--------------------------------------------------------------------------------
/sql_profiler/EventList.cs:
--------------------------------------------------------------------------------
1 |
2 | // Traceutils assembly
3 | // writen by Locky, 2009.
4 |
5 |
6 | using System;
7 | using System.Collections.Generic;
8 | using System.IO;
9 | using System.Xml.Serialization;
10 |
11 |
12 | namespace ExpressProfiler
13 | {
14 |
15 |
16 | [Serializable]
17 | public class CEvent
18 | {
19 | // ReSharper disable UnaccessedField.Global
20 | // ReSharper disable FieldCanBeMadeReadOnly.Global
21 | // ReSharper disable InconsistentNaming
22 | // ReSharper disable MemberCanBePrivate.Global
23 | [XmlAttribute] public long EventClass;
24 | [XmlAttribute] public long DatabaseID;
25 | [XmlAttribute] public long ObjectID;
26 | [XmlAttribute] public long RowCounts;
27 | public string TextData;
28 | [XmlAttribute] public string DatabaseName;
29 | [XmlAttribute] public string ObjectName;
30 |
31 | [XmlAttribute] public long Count, CPU, Reads, Writes, Duration, SPID, NestLevel;
32 | // ReSharper restore MemberCanBePrivate.Global
33 | // ReSharper restore InconsistentNaming
34 | // ReSharper restore FieldCanBeMadeReadOnly.Global
35 | // ReSharper restore UnaccessedField.Global
36 |
37 | public long AvgCPU
38 | {
39 | get { return Count == 0 ? 0 : CPU / Count; }
40 | }
41 |
42 | public long AvgReads
43 | {
44 | get { return Count == 0 ? 0 : Reads / Count; }
45 | }
46 |
47 | public long AvgWrites
48 | {
49 | get { return Count == 0 ? 0 : Writes / Count; }
50 | }
51 |
52 | public long AvgDuration
53 | {
54 | get { return Count == 0 ? 0 : Duration / Count; }
55 | }
56 |
57 |
58 | //needed for serialization
59 | // ReSharper disable UnusedMember.Global
60 | public CEvent()
61 | {
62 | }
63 | // ReSharper restore UnusedMember.Global
64 |
65 | public CEvent(long aDatabaseID, string aDatabaseName, long aObjectID, string aObjectName, string aTextData)
66 | {
67 | DatabaseID = aDatabaseID;
68 | DatabaseName = aDatabaseName;
69 | ObjectID = aObjectID;
70 | ObjectName = aObjectName;
71 | TextData = aTextData;
72 | }
73 |
74 | public CEvent(long eventClass, long spid, long nestLevel, long aDatabaseID, string aDatabaseName,
75 | long aObjectID, string aObjectName, string aTextData, long duration, long reads, long writes, long cpu)
76 | {
77 | EventClass = eventClass;
78 | DatabaseID = aDatabaseID;
79 | DatabaseName = aDatabaseName;
80 | ObjectID = aObjectID;
81 | ObjectName = aObjectName;
82 | TextData = aTextData;
83 | Duration = duration;
84 | Reads = reads;
85 | Writes = writes;
86 | CPU = cpu;
87 | SPID = spid;
88 | NestLevel = nestLevel;
89 | }
90 |
91 | public string GetKey()
92 | {
93 | return String.Format("({0}).({1}).({2}).({3})", DatabaseID, ObjectID, ObjectName, TextData);
94 | }
95 | }
96 |
97 | public class SimpleEventList
98 | {
99 | public readonly SortedDictionary List;
100 |
101 | public SimpleEventList()
102 | {
103 | List = new SortedDictionary();
104 | }
105 |
106 | public void SaveToFile(string filename)
107 | {
108 | CEvent[] a = new CEvent[List.Count];
109 | List.Values.CopyTo(a, 0);
110 | XmlSerializer x = new XmlSerializer(typeof(CEvent[]));
111 |
112 | FileStream fs = new FileStream(filename, FileMode.Create);
113 | x.Serialize(fs, a);
114 | fs.Dispose();
115 | }
116 |
117 | public void AddEvent(long eventClass, long nestLevel, long databaseID, string databaseName, long objectID,
118 | string objectName, string textData, long cpu, long reads, long writes, long duration, long count,
119 | long rowcounts)
120 | {
121 | CEvent evt;
122 | string key = String.Format("({0}).({1}).({2})", databaseID, objectID, textData);
123 | if (!List.TryGetValue(key, out evt))
124 | {
125 | evt = new CEvent(databaseID, databaseName, objectID, objectName, textData);
126 | List.Add(key, evt);
127 | }
128 |
129 | evt.NestLevel = nestLevel;
130 | evt.EventClass = eventClass;
131 | evt.Count += count;
132 | evt.CPU += cpu;
133 | evt.Reads += reads;
134 | evt.Writes += writes;
135 | evt.Duration += duration;
136 | evt.RowCounts += rowcounts;
137 | }
138 | }
139 |
140 | public class CEventList
141 | {
142 | public readonly SortedDictionary EventList;
143 |
144 | public CEventList()
145 | {
146 | EventList = new SortedDictionary();
147 | }
148 |
149 | public void AppendFromFile(int cnt, string filename, bool ignorenonamesp, bool transform)
150 | {
151 | XmlSerializer x = new XmlSerializer(typeof(CEvent[]));
152 | FileStream fs = new FileStream(filename, FileMode.Open);
153 | CEvent[] a = (CEvent[]) x.Deserialize(fs);
154 | YukonLexer lex = new YukonLexer();
155 | foreach (CEvent e in a)
156 | {
157 | if (e.TextData.Contains("statman") || e.TextData.Contains("UPDATE STATISTICS")) continue;
158 | if (!ignorenonamesp || e.ObjectName.Length != 0)
159 | {
160 | if (transform)
161 | {
162 | AddEvent(cnt, e.DatabaseID, e.DatabaseName
163 | , e.ObjectName.Length == 0 ? 0 : e.ObjectID
164 | , e.ObjectName.Length == 0 ? "" : e.ObjectName
165 | , e.ObjectName.Length == 0 ? lex.StandardSql(e.TextData) : e.TextData, e.CPU, e.Reads,
166 | e.Writes, e.Duration, e.Count, e.RowCounts);
167 | }
168 | else
169 | {
170 | AddEvent(cnt, e.DatabaseID, e.DatabaseName, e.ObjectID, e.ObjectName, e.TextData, e.CPU,
171 | e.Reads, e.Writes, e.Duration, e.Count, e.RowCounts);
172 | }
173 | }
174 | }
175 |
176 | fs.Dispose();
177 | }
178 |
179 | public void AddEvent(int cnt, long databaseID, string databaseName, long objectID, string objectName,
180 | string textData, long cpu, long reads, long writes, long duration, long count, long rowcounts)
181 | {
182 | CEvent[] evt;
183 | CEvent e;
184 | string key = String.Format("({0}).({1}).({2}).({3})", databaseID, objectID, objectName, textData);
185 | if (!EventList.TryGetValue(key, out evt))
186 | {
187 | evt = new CEvent[2];
188 | for (int k = 0; k < evt.Length; k++)
189 | {
190 | evt[k] = new CEvent(databaseID, databaseName, objectID, objectName, textData);
191 | }
192 |
193 | EventList.Add(key, evt);
194 | e = evt[cnt];
195 | }
196 | else
197 | {
198 | e = evt[cnt];
199 | }
200 |
201 | e.Count += count;
202 | e.CPU += cpu;
203 | e.Reads += reads;
204 | e.Writes += writes;
205 | e.Duration += duration;
206 | e.RowCounts += rowcounts;
207 | }
208 | }
209 | }
--------------------------------------------------------------------------------
/sql_profiler/Code/Helpers/CommandLineArguments.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace sql_profiler
3 | {
4 |
5 |
6 | ///
7 | /// Arguments class
8 | ///
9 | public class CommandLineArguments
10 | {
11 |
12 |
13 | private System.Collections.Specialized.StringDictionary Parameters;
14 |
15 |
16 | public CommandLineArguments(string[] Args)
17 | : this(Args, null)
18 | { } // End Constructor
19 |
20 |
21 | public CommandLineArguments(string[] Args
22 | , System.Collections.Generic.Dictionary defaultValues)
23 | {
24 | Parameters = new System.Collections.Specialized.StringDictionary();
25 | System.Text.RegularExpressions.Regex Spliter =
26 | new System.Text.RegularExpressions.Regex(@"^-{1,2}|^/|=|:",
27 | System.Text.RegularExpressions.RegexOptions.IgnoreCase
28 | | System.Text.RegularExpressions.RegexOptions.Compiled
29 | );
30 |
31 | System.Text.RegularExpressions.Regex Remover =
32 | new System.Text.RegularExpressions.Regex(@"^['""]?(.*?)['""]?$",
33 | System.Text.RegularExpressions.RegexOptions.IgnoreCase
34 | | System.Text.RegularExpressions.RegexOptions.Compiled
35 | );
36 |
37 | string Parameter = null;
38 | string[] Parts;
39 |
40 | // Valid parameters forms:
41 | // {-,/,--}param{ ,=,:}((",')value(",'))
42 | // Examples:
43 | // -param1 value1 --param2 /param3:"Test-:-work"
44 | // /param4=happy -param5 '--=nice=--'
45 | foreach (string Txt in Args)
46 | {
47 | // Look for new parameters (-,/ or --) and a
48 | // possible enclosed value (=,:)
49 | Parts = Spliter.Split(Txt, 3);
50 |
51 | switch (Parts.Length)
52 | {
53 | // Found a value (for the last parameter
54 | // found (space separator))
55 | case 1:
56 | if (Parameter != null)
57 | {
58 | if (!Parameters.ContainsKey(Parameter))
59 | {
60 | Parts[0] =
61 | Remover.Replace(Parts[0], "$1");
62 |
63 | Parameters.Add(Parameter, Parts[0]);
64 | }
65 | Parameter = null;
66 | }
67 | // else Error: no parameter waiting for a value (skipped)
68 | break;
69 |
70 | // Found just a parameter
71 | case 2:
72 | // The last parameter is still waiting.
73 | // With no value, set it to true.
74 | if (Parameter != null)
75 | {
76 | if (!Parameters.ContainsKey(Parameter))
77 | Parameters.Add(Parameter, "true");
78 | }
79 | Parameter = Parts[1];
80 | break;
81 |
82 | // Parameter with enclosed value
83 | case 3:
84 | // The last parameter is still waiting.
85 | // With no value, set it to true.
86 | if (Parameter != null)
87 | {
88 | if (!Parameters.ContainsKey(Parameter))
89 | Parameters.Add(Parameter, "true");
90 | } // End if(Parameter != null)
91 |
92 | Parameter = Parts[1];
93 |
94 | // Remove possible enclosing characters (",')
95 | if (!Parameters.ContainsKey(Parameter))
96 | {
97 | Parts[2] = Remover.Replace(Parts[2], "$1");
98 | Parameters.Add(Parameter, Parts[2]);
99 | } // End if(!Parameters.ContainsKey(Parameter))
100 |
101 | Parameter = null;
102 | break;
103 | } // End switch(Parts.Length)
104 |
105 | } // Next Txt
106 |
107 | // In case a parameter is still waiting
108 | if (Parameter != null)
109 | {
110 | if (!Parameters.ContainsKey(Parameter))
111 | Parameters.Add(Parameter, "true");
112 | } // End if(Parameter != null)
113 |
114 | // Add default values
115 | if (defaultValues != null)
116 | {
117 | foreach (System.Collections.Generic.KeyValuePair kvp in defaultValues)
118 | {
119 | if (!this.Parameters.ContainsKey(kvp.Key))
120 | this.Parameters[kvp.Key] = kvp.Value;
121 | } // Next kvp
122 | } // End if (defaultValues != null)
123 |
124 | } // End Constructor
125 |
126 |
127 | public int? GetInt(string param)
128 | {
129 | string str = this[param];
130 | int iValue;
131 | if (int.TryParse(str, out iValue))
132 | return iValue;
133 |
134 | return null;
135 | } // End Function GetInt
136 |
137 |
138 | public long? GetLong(string param)
139 | {
140 | string str = this[param];
141 | long lngValue;
142 | if (long.TryParse(str, out lngValue))
143 | return lngValue;
144 |
145 | return null;
146 | } // End Function GetLong
147 |
148 |
149 | public bool? GetBool(string param)
150 | {
151 | string str = this[param];
152 | bool bValue;
153 | if (bool.TryParse(str, out bValue))
154 | return bValue;
155 |
156 | return null;
157 | } // End Function GetBool
158 |
159 |
160 | public T GetValue(string name)
161 | {
162 | System.Type t = typeof(T);
163 | bool nullable = false;
164 | if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(System.Nullable<>))
165 | {
166 | nullable = true;
167 | t = System.Nullable.GetUnderlyingType(t);
168 | }
169 |
170 |
171 | if (!this.ContainsKey(name))
172 | return (T)(object)null;
173 |
174 | if (object.ReferenceEquals(t, typeof(string)))
175 | {
176 | return (T)(object)this[name];
177 | }
178 |
179 | if (object.ReferenceEquals(t, typeof(bool)))
180 | {
181 | bool? val = GetBool(name);
182 | return (T)(object)val;
183 | }
184 |
185 | if (object.ReferenceEquals(t, typeof(int)))
186 | {
187 | int? val = GetInt(name);
188 | return (T)(object)val;
189 | }
190 |
191 | if (object.ReferenceEquals(t, typeof(long)))
192 | {
193 | long? val = GetLong(name);
194 | return (T)(object)val;
195 | }
196 |
197 | throw new System.NotSupportedException($"Type {t.FullName} not supported.");
198 | return (T)(object)null;
199 | } // End Function GetValue
200 |
201 |
202 | // Retrieve a parameter value if it exists
203 | // (overriding C# indexer property)
204 | public string this[string Param]
205 | {
206 | get
207 | {
208 | return (Parameters[Param]);
209 | }
210 | set
211 | {
212 | this.Parameters[Param] = value;
213 | }
214 | } // End Default-Property
215 |
216 |
217 | public bool ContainsKey(string key)
218 | {
219 | return Parameters.ContainsKey(key);
220 | } // End Function ContainsKey
221 |
222 |
223 | } // End Class CommandLineArguments
224 |
225 |
226 | } // End Namespace sql_profiler
227 |
--------------------------------------------------------------------------------
/sql_profiler/Code/Lexer/SqlTokens.cs:
--------------------------------------------------------------------------------
1 |
2 | // Traceutils assembly
3 | // writen by Locky, 2009.
4 |
5 |
6 | namespace ExpressProfiler
7 | {
8 |
9 |
10 | class Sqltokens
11 | {
12 |
13 | #region Keywords
14 | private const string Keywords = "ADD,ALTER,AS,ASC,AUTHORIZATION,BACKUP," +
15 | "BEGIN,BREAK,BROWSE,BULK,BY,CASCADE," +
16 | "CHECK,CHECKPOINT,CLOSE,CLUSTERED,COLLATE," +
17 | "COLUMN,COMMIT,COMPUTE,CONSTRAINT,CONTAINS,CONTAINSTABLE," +
18 | "CONTINUE,CREATE,CURRENT,CURSOR,DATABASE," +
19 | "DBCC,DEALLOCATE,DECLARE,DEFAULT,DELETE,DENY,DESC,DISK," +
20 | "DISTINCT,DISTRIBUTED,DOUBLE,DROP,DUMMY,DUMP,ELSE,END," +
21 | "ERRLVL,ESCAPE,EXCEPT,EXEC,EXECUTE,EXIT,FETCH,FILE," +
22 | "FILLFACTOR,FOR,FOREIGN,FORMSOF,FREETEXT,FREETEXTTABLE,FROM,FULL," +
23 | "FUNCTION,GOTO,GRANT,GROUP,HAVING,HOLDLOCK,IDENTITY," +
24 | "IDENTITYCOL,IDENTITY_INSERT,IF,INFLECTIONAL,INDEX,INNER,INSERT," +
25 | "INTERSECT,INTO,IS,ISABOUT,KEY,KILL,LINENO,LOAD," +
26 | "NATIONAL,NOCHECK,NONCLUSTERED,OF,OFF," +
27 | "OFFSETS,ON,OPEN,OPENDATASOURCE,OPENQUERY,OPENROWSET,OPENXML," +
28 | "OPTION,ORDER,OVER,PERCENT,PLAN,PRECISION," +
29 | "PRIMARY,PRINT,PROC,PROCEDURE,PUBLIC,RAISERROR,READ," +
30 | "READTEXT,RECONFIGURE,REFERENCES,REPLICATION,RESTORE," +
31 | "RESTRICT,RETURN,REVOKE,ROLLBACK,ROWCOUNT,ROWGUIDCOL," +
32 | "RULE,SAVE,SCHEMA,SELECT,SET,SETUSER,SHUTDOWN," +
33 | "STATISTICS,TABLE,TEXTSIZE,THEN,TO,TOP,TRAN,TRANSACTION," +
34 | "TRIGGER,TRUNCATE,TSEQUAL,UNION,UNIQUE,UPDATE,UPDATETEXT," +
35 | "USE,VALUES,VARYING,VIEW,WAITFOR,WEIGHT,WHEN,WHERE,WHILE," +
36 | "WITH,WRITETEXT,CURRENT_DATE,CURRENT_TIME" +
37 | ",OUT,NEXT,PRIOR,RETURNS,ABSOLUTE,ACTION,PARTIAL,FALSE" +
38 | ",PREPARE,FIRST,PRIVILEGES,AT,GLOBAL,RELATIVE,ROWS,HOUR,MIN,MAX" +
39 | ",SCROLL,SECOND,SECTION,SIZE,INSENSITIVE,CONNECT,CONNECTION" +
40 | ",ISOLATION,LEVEL,LOCAL,DATE,MINUTE,TRANSLATION" +
41 | ",TRUE,NO,ONLY,WORK,OUTPUT" +
42 | ",ABSOLUTE,ACTION,FREE,PRIOR,PRIVILEGES,AFTER,GLOBAL" +
43 | ",HOUR,RELATIVE,IGNORE,AT,RETURNS,ROLLUP,ROWS,SCROLL" +
44 | ",ISOLATION,SECOND,SECTION,SEQUENCE,LAST,SIZE,LEVEL" +
45 | ",CONNECT,CONNECTION,LOCAL,CUBE,MINUTE,MODIFY,STATIC" +
46 | ",DATE,TEMPORARY,TIME,NEXT,NO,TRANSLATION,TRUE,ONLY" +
47 | ",OUT,DYNAMIC,OUTPUT,PARTIAL,WORK,FALSE,FIRST,PREPARE,GROUPING,FORMAT,INIT,STATS" +
48 | "FORMAT,INIT,STATS,NOCOUNT,FORWARD_ONLY,KEEPFIXED,FORCE,KEEP,MERGE,HASH,LOOP,maxdop,nolock" +
49 | ",updlock,tablock,tablockx,paglock,readcommitted,readpast,readuncommitted,repeatableread,rowlock,serializable,xlock"
50 | + ",delay";
51 |
52 | #endregion
53 |
54 |
55 | #region Functions
56 | private const string Functions = "@@CONNECTIONS,@@CPU_BUSY,@@CURSOR_ROWS,@@DATEFIRST,@@DBTS,@@ERROR," +
57 | "@@FETCH_STATUS,@@IDENTITY,@@IDLE,@@IO_BUSY,@@LANGID,@@LANGUAGE," +
58 | "@@LOCK_TIMEOUT,@@MAX_CONNECTIONS,@@MAX_PRECISION,@@NESTLEVEL,@@OPTIONS," +
59 | "@@PACKET_ERRORS,@@PACK_RECEIVED,@@PACK_SENT,@@PROCID,@@REMSERVER," +
60 | "@@ROWCOUNT,@@SERVERNAME,@@SERVICENAME,@@SPID,@@TEXTSIZE,@@TIMETICKS," +
61 | "@@TOTAL_ERRORS,@@TOTAL_READ,@@TOTAL_WRITE,@@TRANCOUNT,@@VERSION," +
62 | "ABS,ACOS,APP_NAME,ASCII,ASIN,ATAN,ATN2,AVG,BINARY_CHECKSUM,CAST," +
63 | "CEILING,CHARINDEX,CHECKSUM,CHECKSUM_AGG,COLLATIONPROPERTY," +
64 | "COLUMNPROPERTY,COL_LENGTH,COL_NAME,COS,COT,COUNT," +
65 | "COUNT_BIG," +
66 | "CURSOR_STATUS,DATABASEPROPERTY,DATABASEPROPERTYEX," +
67 | "DATALENGTH,DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,DB_ID,DB_NAME,DEGREES," +
68 | "DIFFERENCE,EXP,FILEGROUPPROPERTY,FILEGROUP_ID,FILEGROUP_NAME,FILEPROPERTY," +
69 | "FILE_ID,FILE_NAME,FLOOR" +
70 | "" +
71 | "FORMATMESSAGE,FULLTEXTCATALOGPROPERTY,FULLTEXTSERVICEPROPERTY," +
72 | "GETANSINULL,GETDATE,GETUTCDATE,HAS_DBACCESS,HOST_ID,HOST_NAME," +
73 | "IDENT_CURRENT,IDENT_INCR,IDENT_SEED,INDEXKEY_PROPERTY,INDEXPROPERTY," +
74 | "INDEX_COL,ISDATE,ISNULL,ISNUMERIC,IS_MEMBER,IS_SRVROLEMEMBER,LEN,LOG," +
75 | "LOG10,LOWER,LTRIM,MONTH,NEWID,OBJECTPROPERTY,OBJECT_ID," +
76 | "OBJECT_NAME,PARSENAME,PATINDEX," +
77 | "PERMISSIONS,PI,POWER,QUOTENAME,RADIANS,RAND,REPLACE,REPLICATE,REVERSE," +
78 | "ROUND,ROWCOUNT_BIG,RTRIM,SCOPE_IDENTITY,SERVERPROPERTY,SESSIONPROPERTY," +
79 | "SIGN,SIN,SOUNDEX,SPACE,SQL_VARIANT_PROPERTY,SQRT,SQUARE," +
80 | "STATS_DATE,STDEV,STDEVP,STR,STUFF,SUBSTRING,SUM,SUSER_SID,SUSER_SNAME," +
81 | "TAN,TEXTPTR,TEXTVALID,TYPEPROPERTY,UNICODE,UPPER," +
82 | "USER_ID,USER_NAME,VAR,VARP,YEAR";
83 |
84 | #endregion
85 | #region Types
86 | private const string Types = "bigint,binary,bit,char,character,datetime," +
87 | "dec,decimal,float,image,int," +
88 | "integer,money,nchar,ntext,nvarchar,real," +
89 | "rowversion,smalldatetime,smallint,smallmoney," +
90 | "sql_variant,sysname,text,timestamp,tinyint,uniqueidentifier," +
91 | "varbinary,varchar,NUMERIC";
92 | #endregion
93 |
94 | private const string Greykeywords = "AND,EXISTS,ALL,ANY,BETWEEN,IN,SOME,JOIN,CROSS,OR,NULL,OUTER,NOT,LIKE";
95 | private const string Fukeywords = "CASE,RIGHT,COALESCE,SESSION_USER,CONVERT,SYSTEM_USER,LEFT,CURRENT_TIMESTAMP,CURRENT_USER,NULLIF,USER";
96 |
97 | private readonly System.Collections.Generic.Dictionary
98 | m_Words = new System.Collections.Generic
99 | .Dictionary();
100 |
101 | public YukonLexer.TokenKind this[string token] { get { token = token.ToLower(); return m_Words.ContainsKey(token) ? m_Words[token] : YukonLexer.TokenKind.tkUnknown; } }
102 |
103 |
104 | private void AddTokens(string tokens, YukonLexer.TokenKind tokenkind)
105 | {
106 | System.Text.StringBuilder curtoken = new System.Text.StringBuilder();
107 | for (int i = 0; i < tokens.Length; i++)
108 | {
109 | if (tokens[i] == ',')
110 | {
111 | string s = curtoken.ToString().ToLower();
112 | if (!m_Words.ContainsKey(s))
113 | m_Words.Add(s, tokenkind);
114 | curtoken = new System.Text.StringBuilder();
115 | }
116 | else
117 | {
118 | curtoken.Append(tokens[i]);
119 | }
120 | }
121 | if (curtoken.Length != 0) m_Words.Add(curtoken.ToString(), tokenkind);
122 | }
123 |
124 |
125 | public Sqltokens()
126 | {
127 | AddTokens(Keywords, YukonLexer.TokenKind.tkKey);
128 | AddTokens(Functions, YukonLexer.TokenKind.tkFunction);
129 | AddTokens(Types, YukonLexer.TokenKind.tkDatatype);
130 | AddTokens(Greykeywords, YukonLexer.TokenKind.tkGreyKeyword);
131 | AddTokens(Fukeywords, YukonLexer.TokenKind.tkFuKeyword);
132 | }
133 |
134 |
135 | }
136 |
137 |
138 | }
--------------------------------------------------------------------------------
/sql_profiler/Code/Helpers/SecretManager.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace TestPlotly
3 | {
4 |
5 |
6 | public class SecretManager
7 | {
8 |
9 | // TestPlotly.SecretManager.GetSecret("DefaultDbPassword")
10 | // TestPlotly.SecretManager.GetSecret("GoogleGeoCodingApiKey")
11 | public static T GetSecret(string secretName)
12 | {
13 | string asmName = typeof(SecretManager).Assembly.FullName;
14 |
15 | int ipos = asmName.IndexOf(',');
16 | if (ipos != -1)
17 | {
18 | asmName = asmName.Substring(0, ipos);
19 | }
20 |
21 | return GetSecret(secretName, asmName);
22 | } // End Function GetSecret
23 |
24 |
25 | public static T GetSecret(string secretName, string asmName)
26 | {
27 | T obj = default(T);
28 |
29 | if (System.Environment.OSVersion.Platform == System.PlatformID.Unix)
30 | {
31 | obj = SecretManagerHelper.GetEtcKey("/etc/COR/" + asmName, secretName);
32 | if(obj == null)
33 | obj = SecretManagerHelper.GetEtcKey(@"/etc/COR/All", secretName);
34 | }
35 | else
36 | {
37 | obj = SecretManagerHelper.GetRegistryKey(@"Software\COR\" + asmName, secretName);
38 | if(obj == null)
39 | obj = SecretManagerHelper.GetRegistryKey(@"Software\COR\All", secretName);
40 | }
41 |
42 | return obj;
43 | } // End Function GetSecret
44 |
45 |
46 | } // End Class SecretManager
47 |
48 |
49 | public class SecretManagerHelper
50 | {
51 |
52 |
53 | public static T GetRegistryKey(string key, string value)
54 | {
55 | object obj = GetRegistryKey(key, value);
56 | return ObjectToGeneric(obj);
57 | } // End Function GetRegistryKey
58 |
59 |
60 | public static T GetEtcKey(string path, string value)
61 | {
62 | string obj = null;
63 |
64 | string p = System.IO.Path.Combine(path, value);
65 | if(System.IO.File.Exists(p))
66 | obj = System.IO.File.ReadAllText(p, System.Text.Encoding.Default);
67 |
68 | if(obj == null)
69 | return ObjectToGeneric((object)obj);
70 |
71 | // || obj.EndsWith(" ") || obj.EndsWith("\t")
72 | while ( obj.EndsWith("\r") || obj.EndsWith("\n") )
73 | obj = obj.Substring(0, obj.Length - 1);
74 |
75 | return ObjectToGeneric((object)obj);
76 | } // End Function GetRegistryKey
77 |
78 |
79 | private static object GetRegistryKey(string key, string value)
80 | {
81 | object objReturnValue = null;
82 | // HKEY_CURRENT_USER
83 |
84 | //using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine
85 | using (Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.CurrentUser
86 | .OpenSubKey(key))
87 | {
88 | if (regKey != null)
89 | {
90 | objReturnValue = regKey.GetValue(value);
91 | } // End if (regKey != null)
92 |
93 | } // End Using regKey
94 |
95 | return objReturnValue;
96 | } // End Function GetRegistryKey
97 |
98 |
99 | private static T InlineTypeAssignHelper(object UTO)
100 | {
101 | if (UTO == null)
102 | {
103 | T NullSubstitute = default(T);
104 | return NullSubstitute;
105 | } // End if (UTO == null)
106 |
107 | return (T)UTO;
108 | } // End Template InlineTypeAssignHelper
109 |
110 |
111 | private static T ObjectToGeneric(object objReturnValue)
112 | {
113 | string strReturnValue = null;
114 | System.Type tReturnType = typeof(T);
115 |
116 | if (!object.ReferenceEquals(tReturnType, typeof(System.Byte[])))
117 | {
118 | if(objReturnValue != null)
119 | strReturnValue = System.Convert.ToString(objReturnValue);
120 | } // End if (!object.ReferenceEquals(tReturnType, typeof(System.Byte[])))
121 |
122 | try
123 | {
124 |
125 | if (object.ReferenceEquals(tReturnType, typeof(object)))
126 | {
127 | return InlineTypeAssignHelper(objReturnValue);
128 | }
129 | else if (object.ReferenceEquals(tReturnType, typeof(string)))
130 | {
131 | return InlineTypeAssignHelper(strReturnValue);
132 | } // End if string
133 | else if (object.ReferenceEquals(tReturnType, typeof(bool)))
134 | {
135 | bool bReturnValue = false;
136 | bool bSuccess = bool.TryParse(strReturnValue, out bReturnValue);
137 |
138 | if (bSuccess)
139 | return InlineTypeAssignHelper(bReturnValue);
140 |
141 | if (strReturnValue == "0")
142 | return InlineTypeAssignHelper(false);
143 |
144 | return InlineTypeAssignHelper(true);
145 | } // End if bool
146 | else if (object.ReferenceEquals(tReturnType, typeof(int)))
147 | {
148 | int iReturnValue = int.Parse(strReturnValue);
149 | return InlineTypeAssignHelper(iReturnValue);
150 | } // End if int
151 | else if (object.ReferenceEquals(tReturnType, typeof(uint)))
152 | {
153 | uint uiReturnValue = uint.Parse(strReturnValue);
154 | return InlineTypeAssignHelper(uiReturnValue);
155 | } // End if uint
156 | else if (object.ReferenceEquals(tReturnType, typeof(long)))
157 | {
158 | long lngReturnValue = long.Parse(strReturnValue);
159 | return InlineTypeAssignHelper(lngReturnValue);
160 | } // End if long
161 | else if (object.ReferenceEquals(tReturnType, typeof(ulong)))
162 | {
163 | ulong ulngReturnValue = ulong.Parse(strReturnValue);
164 | return InlineTypeAssignHelper(ulngReturnValue);
165 | } // End if ulong
166 | else if (object.ReferenceEquals(tReturnType, typeof(float)))
167 | {
168 | float fltReturnValue = float.Parse(strReturnValue);
169 | return InlineTypeAssignHelper(fltReturnValue);
170 | }
171 | else if (object.ReferenceEquals(tReturnType, typeof(double)))
172 | {
173 | double dblReturnValue = double.Parse(strReturnValue);
174 | return InlineTypeAssignHelper(dblReturnValue);
175 | }
176 | else if (object.ReferenceEquals(tReturnType, typeof(System.Net.IPAddress)))
177 | {
178 | System.Net.IPAddress ipaAddress = null;
179 |
180 | if (string.IsNullOrEmpty(strReturnValue))
181 | return InlineTypeAssignHelper(ipaAddress);
182 |
183 | ipaAddress = System.Net.IPAddress.Parse(strReturnValue);
184 | return InlineTypeAssignHelper(ipaAddress);
185 | } // End if IPAddress
186 | else if (object.ReferenceEquals(tReturnType, typeof(System.Byte[])))
187 | {
188 | if (objReturnValue == System.DBNull.Value)
189 | return InlineTypeAssignHelper(null);
190 |
191 | return InlineTypeAssignHelper(objReturnValue);
192 | }
193 | else if (object.ReferenceEquals(tReturnType, typeof(System.Guid)))
194 | {
195 | if (string.IsNullOrEmpty(strReturnValue)) return InlineTypeAssignHelper(null);
196 |
197 | return InlineTypeAssignHelper(new System.Guid(strReturnValue));
198 | } // End if GUID
199 | else if (object.ReferenceEquals(tReturnType, typeof(System.DateTime)))
200 | {
201 | System.DateTime bReturnValue = System.DateTime.Now;
202 | bool bSuccess = System.DateTime.TryParse(strReturnValue, out bReturnValue);
203 |
204 | if (bSuccess)
205 | return InlineTypeAssignHelper(bReturnValue);
206 |
207 | if (strReturnValue == "0")
208 | return InlineTypeAssignHelper(false);
209 |
210 | return InlineTypeAssignHelper(true);
211 | } // End if datetime
212 | else // No datatype matches
213 | {
214 | throw new System.NotImplementedException("ExecuteScalar: This type is not yet defined.");
215 | } // End else of if tReturnType = datatype
216 |
217 | } // End Try
218 | catch (System.Exception ex)
219 | {
220 | throw;
221 | } // End Catch
222 |
223 | return InlineTypeAssignHelper(null);
224 | } // End Function ObjectToGeneric
225 |
226 |
227 | } // End Class SecretManager
228 |
229 |
230 | } // End Namespace
231 |
--------------------------------------------------------------------------------
/sql_profiler/LICENSE.md:
--------------------------------------------------------------------------------
1 |
2 | Original code by
3 | https://github.com/OleksiiKovalov/expressprofiler
4 | (no license)
5 |
6 |
7 | All other code
8 | Apache License V2
9 |
10 |
11 |
12 |
13 | Apache License
14 | Version 2.0, January 2004
15 | http://www.apache.org/licenses/
16 |
17 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
18 |
19 | 1. Definitions.
20 |
21 | "License" shall mean the terms and conditions for use, reproduction,
22 | and distribution as defined by Sections 1 through 9 of this document.
23 |
24 | "Licensor" shall mean the copyright owner or entity authorized by
25 | the copyright owner that is granting the License.
26 |
27 | "Legal Entity" shall mean the union of the acting entity and all
28 | other entities that control, are controlled by, or are under common
29 | control with that entity. For the purposes of this definition,
30 | "control" means (i) the power, direct or indirect, to cause the
31 | direction or management of such entity, whether by contract or
32 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
33 | outstanding shares, or (iii) beneficial ownership of such entity.
34 |
35 | "You" (or "Your") shall mean an individual or Legal Entity
36 | exercising permissions granted by this License.
37 |
38 | "Source" form shall mean the preferred form for making modifications,
39 | including but not limited to software source code, documentation
40 | source, and configuration files.
41 |
42 | "Object" form shall mean any form resulting from mechanical
43 | transformation or translation of a Source form, including but
44 | not limited to compiled object code, generated documentation,
45 | and conversions to other media types.
46 |
47 | "Work" shall mean the work of authorship, whether in Source or
48 | Object form, made available under the License, as indicated by a
49 | copyright notice that is included in or attached to the work
50 | (an example is provided in the Appendix below).
51 |
52 | "Derivative Works" shall mean any work, whether in Source or Object
53 | form, that is based on (or derived from) the Work and for which the
54 | editorial revisions, annotations, elaborations, or other modifications
55 | represent, as a whole, an original work of authorship. For the purposes
56 | of this License, Derivative Works shall not include works that remain
57 | separable from, or merely link (or bind by name) to the interfaces of,
58 | the Work and Derivative Works thereof.
59 |
60 | "Contribution" shall mean any work of authorship, including
61 | the original version of the Work and any modifications or additions
62 | to that Work or Derivative Works thereof, that is intentionally
63 | submitted to Licensor for inclusion in the Work by the copyright owner
64 | or by an individual or Legal Entity authorized to submit on behalf of
65 | the copyright owner. For the purposes of this definition, "submitted"
66 | means any form of electronic, verbal, or written communication sent
67 | to the Licensor or its representatives, including but not limited to
68 | communication on electronic mailing lists, source code control systems,
69 | and issue tracking systems that are managed by, or on behalf of, the
70 | Licensor for the purpose of discussing and improving the Work, but
71 | excluding communication that is conspicuously marked or otherwise
72 | designated in writing by the copyright owner as "Not a Contribution."
73 |
74 | "Contributor" shall mean Licensor and any individual or Legal Entity
75 | on behalf of whom a Contribution has been received by Licensor and
76 | subsequently incorporated within the Work.
77 |
78 | 2. Grant of Copyright License. Subject to the terms and conditions of
79 | this License, each Contributor hereby grants to You a perpetual,
80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
81 | copyright license to reproduce, prepare Derivative Works of,
82 | publicly display, publicly perform, sublicense, and distribute the
83 | Work and such Derivative Works in Source or Object form.
84 |
85 | 3. Grant of Patent License. Subject to the terms and conditions of
86 | this License, each Contributor hereby grants to You a perpetual,
87 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
88 | (except as stated in this section) patent license to make, have made,
89 | use, offer to sell, sell, import, and otherwise transfer the Work,
90 | where such license applies only to those patent claims licensable
91 | by such Contributor that are necessarily infringed by their
92 | Contribution(s) alone or by combination of their Contribution(s)
93 | with the Work to which such Contribution(s) was submitted. If You
94 | institute patent litigation against any entity (including a
95 | cross-claim or counterclaim in a lawsuit) alleging that the Work
96 | or a Contribution incorporated within the Work constitutes direct
97 | or contributory patent infringement, then any patent licenses
98 | granted to You under this License for that Work shall terminate
99 | as of the date such litigation is filed.
100 |
101 | 4. Redistribution. You may reproduce and distribute copies of the
102 | Work or Derivative Works thereof in any medium, with or without
103 | modifications, and in Source or Object form, provided that You
104 | meet the following conditions:
105 |
106 | (a) You must give any other recipients of the Work or
107 | Derivative Works a copy of this License; and
108 |
109 | (b) You must cause any modified files to carry prominent notices
110 | stating that You changed the files; and
111 |
112 | (c) You must retain, in the Source form of any Derivative Works
113 | that You distribute, all copyright, patent, trademark, and
114 | attribution notices from the Source form of the Work,
115 | excluding those notices that do not pertain to any part of
116 | the Derivative Works; and
117 |
118 | (d) If the Work includes a "NOTICE" text file as part of its
119 | distribution, then any Derivative Works that You distribute must
120 | include a readable copy of the attribution notices contained
121 | within such NOTICE file, excluding those notices that do not
122 | pertain to any part of the Derivative Works, in at least one
123 | of the following places: within a NOTICE text file distributed
124 | as part of the Derivative Works; within the Source form or
125 | documentation, if provided along with the Derivative Works; or,
126 | within a display generated by the Derivative Works, if and
127 | wherever such third-party notices normally appear. The contents
128 | of the NOTICE file are for informational purposes only and
129 | do not modify the License. You may add Your own attribution
130 | notices within Derivative Works that You distribute, alongside
131 | or as an addendum to the NOTICE text from the Work, provided
132 | that such additional attribution notices cannot be construed
133 | as modifying the License.
134 |
135 | You may add Your own copyright statement to Your modifications and
136 | may provide additional or different license terms and conditions
137 | for use, reproduction, or distribution of Your modifications, or
138 | for any such Derivative Works as a whole, provided Your use,
139 | reproduction, and distribution of the Work otherwise complies with
140 | the conditions stated in this License.
141 |
142 | 5. Submission of Contributions. Unless You explicitly state otherwise,
143 | any Contribution intentionally submitted for inclusion in the Work
144 | by You to the Licensor shall be under the terms and conditions of
145 | this License, without any additional terms or conditions.
146 | Notwithstanding the above, nothing herein shall supersede or modify
147 | the terms of any separate license agreement you may have executed
148 | with Licensor regarding such Contributions.
149 |
150 | 6. Trademarks. This License does not grant permission to use the trade
151 | names, trademarks, service marks, or product names of the Licensor,
152 | except as required for reasonable and customary use in describing the
153 | origin of the Work and reproducing the content of the NOTICE file.
154 |
155 | 7. Disclaimer of Warranty. Unless required by applicable law or
156 | agreed to in writing, Licensor provides the Work (and each
157 | Contributor provides its Contributions) on an "AS IS" BASIS,
158 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
159 | implied, including, without limitation, any warranties or conditions
160 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
161 | PARTICULAR PURPOSE. You are solely responsible for determining the
162 | appropriateness of using or redistributing the Work and assume any
163 | risks associated with Your exercise of permissions under this License.
164 |
165 | 8. Limitation of Liability. In no event and under no legal theory,
166 | whether in tort (including negligence), contract, or otherwise,
167 | unless required by applicable law (such as deliberate and grossly
168 | negligent acts) or agreed to in writing, shall any Contributor be
169 | liable to You for damages, including any direct, indirect, special,
170 | incidental, or consequential damages of any character arising as a
171 | result of this License or out of the use or inability to use the
172 | Work (including but not limited to damages for loss of goodwill,
173 | work stoppage, computer failure or malfunction, or any and all
174 | other commercial damages or losses), even if such Contributor
175 | has been advised of the possibility of such damages.
176 |
177 | 9. Accepting Warranty or Additional Liability. While redistributing
178 | the Work or Derivative Works thereof, You may choose to offer,
179 | and charge a fee for, acceptance of support, warranty, indemnity,
180 | or other liability obligations and/or rights consistent with this
181 | License. However, in accepting such obligations, You may act only
182 | on Your own behalf and on Your sole responsibility, not on behalf
183 | of any other Contributor, and only if You agree to indemnify,
184 | defend, and hold each Contributor harmless for any liability
185 | incurred by, or claims asserted against, such Contributor by reason
186 | of your accepting any such warranty or additional liability.
187 |
188 | END OF TERMS AND CONDITIONS
189 |
190 | APPENDIX: How to apply the Apache License to your work.
191 |
192 | To apply the Apache License to your work, attach the following
193 | boilerplate notice, with the fields enclosed by brackets "[]"
194 | replaced with your own identifying information. (Don't include
195 | the brackets!) The text should be enclosed in the appropriate
196 | comment syntax for the file format. We also recommend that a
197 | file or class name and description of purpose be included on the
198 | same "printed page" as the copyright notice for easier
199 | identification within third-party archives.
200 |
201 | Copyright [yyyy] [name of copyright owner]
202 |
203 | Licensed under the Apache License, Version 2.0 (the "License");
204 | you may not use this file except in compliance with the License.
205 | You may obtain a copy of the License at
206 |
207 | http://www.apache.org/licenses/LICENSE-2.0
208 |
209 | Unless required by applicable law or agreed to in writing, software
210 | distributed under the License is distributed on an "AS IS" BASIS,
211 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
212 | See the License for the specific language governing permissions and
213 | limitations under the License.
214 |
--------------------------------------------------------------------------------
/sql_profiler/Code/Lexer/YukonLexer.cs:
--------------------------------------------------------------------------------
1 |
2 | // Traceutils assembly
3 | // writen by Locky, 2009.
4 |
5 |
6 | namespace ExpressProfiler
7 | {
8 |
9 |
10 | public class YukonLexer
11 | {
12 |
13 | public enum TokenKind
14 | {
15 | tkComment, tkDatatype,
16 | tkFunction, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace, tkString, tkSymbol, tkUnknown, tkVariable, tkGreyKeyword, tkFuKeyword
17 | }
18 |
19 | private enum SqlRange { rsUnknown, rsComment, rsString }
20 | private readonly Sqltokens m_Tokens = new Sqltokens();
21 |
22 |
23 | const string IdentifierStr = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_#$";
24 | private readonly char[] m_IdentifiersArray = IdentifierStr.ToCharArray();
25 | const string HexDigits = "1234567890abcdefABCDEF";
26 | const string NumberStr = "1234567890.-";
27 | private int m_StringLen;
28 | private int m_TokenPos;
29 | private string m_Token = "";
30 | private TokenKind m_TokenId;
31 | private string m_Line;
32 | private int m_Run;
33 |
34 |
35 | private TokenKind TokenId
36 | {
37 | get { return m_TokenId; }
38 | }
39 |
40 |
41 | private string Token { get { /*int len = m_Run - m_TokenPos; return m_Line.Substring(m_TokenPos, len);*/return m_Token; } }
42 | private SqlRange Range { get; set; }
43 |
44 |
45 |
46 | public YukonLexer()
47 | {
48 | System.Array.Sort(m_IdentifiersArray);
49 | } // End Constructor
50 |
51 |
52 | private char GetChar(int idx)
53 | {
54 | return idx >= m_Line.Length ? '\x00' : m_Line[idx];
55 | }
56 |
57 |
58 | public string StandardSql(string sql)
59 | {
60 | System.Text.StringBuilder result = new System.Text.StringBuilder();
61 | Line = sql;
62 | while (TokenId != TokenKind.tkNull)
63 | {
64 | switch (TokenId)
65 | {
66 | case TokenKind.tkNumber:
67 | case TokenKind.tkString: result.Append("?>"); break;
68 | default: result.Append(Token); break;
69 | }
70 | Next();
71 | }
72 | return result.ToString();
73 | }
74 |
75 |
76 | public string SyntaxHighlight(OutputWriter sb, string value)
77 | {
78 | Line = value;
79 |
80 | sb.AppendLine();
81 |
82 | System.Collections.Generic.List lsTokenTypeHistory =
83 | new System.Collections.Generic.List();
84 |
85 | while (TokenId != TokenKind.tkNull)
86 | {
87 | if (TokenId != TokenKind.tkSpace)
88 | lsTokenTypeHistory.Add(TokenId);
89 |
90 | System.Drawing.Color forecolor;
91 | switch (TokenId)
92 | {
93 | case TokenKind.tkKey:
94 | forecolor = System.Drawing.Color.Blue;
95 | break;
96 | case TokenKind.tkFunction: forecolor = System.Drawing.Color.Fuchsia; break;
97 | case TokenKind.tkGreyKeyword: forecolor = System.Drawing.Color.Gray; break;
98 | case TokenKind.tkFuKeyword: forecolor = System.Drawing.Color.Fuchsia; break;
99 | case TokenKind.tkDatatype:
100 | forecolor = System.Drawing.Color.Blue; break;
101 | case TokenKind.tkNumber: forecolor = System.Drawing.Color.Red; break;
102 | case TokenKind.tkString: forecolor = System.Drawing.Color.Red; break;
103 | case TokenKind.tkComment:
104 | forecolor = System.Drawing.Color.DarkGreen;
105 | break;
106 | default: forecolor = System.Drawing.Color.Black; break;
107 | }
108 | sb.ForeColor = forecolor;
109 |
110 | if (Token == System.Environment.NewLine || Token == "\n")
111 | {
112 | sb.AppendLine();
113 | }
114 | else if(Token != "\r")
115 | {
116 | int cntHistory = lsTokenTypeHistory.Count;
117 |
118 | // If the token has a datetime parameter-value that is passed as string,
119 | // ensure yyyy-MM-dd' 'HH:mm:ss[.fff] is replaced with yyyy-MM-dd'T'HH:mm:ss[.fff]
120 | if (TokenKind.tkString == TokenId
121 | && cntHistory > 3
122 | && lsTokenTypeHistory[cntHistory - 2] == TokenKind.tkSymbol
123 | && lsTokenTypeHistory[cntHistory - 3] == TokenKind.tkVariable
124 | && System.Text.RegularExpressions.Regex
125 | .IsMatch(
126 | Token
127 | , @"^'\d\d\d\d-\d\d-\d\d\s\d\d\:\d\d\:\d\d(\.\d\d\d)?'$"
128 | , System.Text.RegularExpressions.RegexOptions.Compiled
129 | )
130 | )
131 | {
132 | // System.DateTime dt;
133 | // if (System.DateTime.TryParseExact(Token, "yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out dt))
134 | // sb.Append(dt.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff"));
135 | sb.Append(Token.Replace(" ", "T"));
136 | }
137 | else
138 | sb.Append(Token);
139 | }
140 | Next();
141 | }
142 |
143 | sb.AppendLine();
144 | sb.AppendLine();
145 |
146 | lsTokenTypeHistory.Clear();
147 | lsTokenTypeHistory = null;
148 |
149 | return sb.ToString();
150 | }
151 |
152 | private string Line
153 | {
154 | set { Range = SqlRange.rsUnknown; m_Line = value; m_Run = 0; Next(); }
155 | }
156 | private void NullProc() { m_TokenId = TokenKind.tkNull; }
157 | // ReSharper disable InconsistentNaming
158 | private void LFProc() { m_TokenId = TokenKind.tkSpace; m_Run++; }
159 | private void CRProc() { m_TokenId = TokenKind.tkSpace; m_Run++; if (GetChar(m_Run) == '\x0A') m_Run++; }
160 | // ReSharper restore InconsistentNaming
161 |
162 | private void AnsiCProc()
163 | {
164 | switch (GetChar(m_Run))
165 | {
166 | case '\x00': NullProc(); break;
167 | case '\x0A': LFProc(); break;
168 | case '\x0D': CRProc(); break;
169 |
170 | default:
171 | {
172 | m_TokenId = TokenKind.tkComment;
173 | char c;
174 | do
175 | {
176 | if (GetChar(m_Run) == '*' && GetChar(m_Run + 1) == '/')
177 | {
178 | Range = SqlRange.rsUnknown; m_Run += 2; break;
179 | }
180 | m_Run++;
181 | c = GetChar(m_Run);
182 | }
183 | while (!(c == '\x00' || c == '\x0A' || c == '\x0D'));
184 | break;
185 | }
186 |
187 |
188 |
189 | }
190 | }
191 |
192 | private void AsciiCharProc()
193 | {
194 | if (GetChar(m_Run) == '\x00') { NullProc(); }
195 | else
196 | {
197 | m_TokenId = TokenKind.tkString;
198 | if (m_Run > 0 || Range != SqlRange.rsString || GetChar(m_Run) != '\x27')
199 | {
200 | Range = SqlRange.rsString;
201 | char c;
202 | do { m_Run++; c = GetChar(m_Run); } while (!(c == '\x00' || c == '\x0A' || c == '\x0D' || c == '\x27'));
203 | if (GetChar(m_Run) == '\x27')
204 | {
205 | m_Run++;
206 | Range = SqlRange.rsUnknown;
207 | }
208 | }
209 | }
210 | }
211 |
212 | private void DoProcTable(char chr)
213 | {
214 | switch (chr)
215 | {
216 | case '\x00': NullProc(); break;
217 | case '\x0A': LFProc(); break;
218 | case '\x0D': CRProc(); break;
219 | case '\x27': AsciiCharProc(); break;
220 |
221 | case '=': EqualProc(); break;
222 | case '>': GreaterProc(); break;
223 | case '<': LowerProc(); break;
224 | case '-': MinusProc(); break;
225 | case '|': OrSymbolProc(); break;
226 | case '+': PlusProc(); break;
227 | case '/': SlashProc(); break;
228 | case '&': AndSymbolProc(); break;
229 | case '\x22': QuoteProc(); break;
230 | case ':':
231 | case '@': VariableProc(); break;
232 | case '^':
233 | case '%':
234 | case '*':
235 | case '!': SymbolAssignProc(); break;
236 | case '{':
237 | case '}':
238 | case '.':
239 | case ',':
240 | case ';':
241 | case '?':
242 | case '(':
243 | case ')':
244 | case ']':
245 | case '~': SymbolProc(); break;
246 | case '[': BracketProc(); break;
247 | default:
248 | DoInsideProc(chr); break;
249 |
250 | }
251 | }
252 |
253 | private void DoInsideProc(char chr)
254 | {
255 |
256 | if ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z') || (chr == '_') || (chr == '#')) { IdentProc(); return; }
257 | if (chr >= '0' && chr <= '9') { NumberProc(); return; }
258 | if ((chr >= '\x00' && chr <= '\x09') || (chr >= '\x0B' && chr <= '\x0C') || (chr >= '\x0E' && chr <= '\x20')) { SpaceProc(); return; }
259 | UnknownProc();
260 | }
261 |
262 | private void SpaceProc()
263 | {
264 | m_TokenId = TokenKind.tkSpace;
265 | char c;
266 | do { m_Run++; c = GetChar(m_Run); }
267 | while (!(c > '\x20' || c == '\x00' || c == '\x0A' || c == '\x0D'));
268 | }
269 |
270 | private void UnknownProc()
271 | {
272 | m_Run++;
273 | m_TokenId = TokenKind.tkUnknown;
274 | }
275 |
276 | private void NumberProc()
277 | {
278 | m_TokenId = TokenKind.tkNumber;
279 | if (GetChar(m_Run) == '0' && (GetChar(m_Run + 1) == 'X' || GetChar(m_Run + 1) == 'x'))
280 | {
281 | m_Run += 2;
282 | while (HexDigits.IndexOf(GetChar(m_Run)) != -1) m_Run++;
283 | return;
284 | }
285 | m_Run++;
286 | m_TokenId = TokenKind.tkNumber;
287 | while (NumberStr.IndexOf(GetChar(m_Run)) != -1)
288 | {
289 | if (GetChar(m_Run) == '.' && GetChar(m_Run + 1) == '.') break;
290 | m_Run++;
291 | }
292 |
293 | }
294 |
295 | private void QuoteProc()
296 | {
297 | m_TokenId = TokenKind.tkIdentifier;
298 | m_Run++;
299 | while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D'))
300 | {
301 | if (GetChar(m_Run) == '\x22') { m_Run++; break; }
302 | m_Run++;
303 | }
304 | }
305 |
306 | private void BracketProc()
307 | {
308 |
309 | m_TokenId = TokenKind.tkIdentifier;
310 | m_Run++;
311 | while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D'))
312 | {
313 | if (GetChar(m_Run) == ']') { m_Run++; break; }
314 | m_Run++;
315 | }
316 |
317 | }
318 |
319 | private void SymbolProc()
320 | {
321 | m_Run++;
322 | m_TokenId = TokenKind.tkSymbol;
323 | }
324 |
325 | private void SymbolAssignProc()
326 | {
327 | m_TokenId = TokenKind.tkSymbol;
328 | m_Run++;
329 | if (GetChar(m_Run) == '=') m_Run++;
330 | }
331 |
332 | private void KeyHash(int pos)
333 | {
334 | m_StringLen = 0;
335 | while (System.Array.BinarySearch(m_IdentifiersArray, GetChar(pos)) >= 0) { m_StringLen++; pos++; }
336 | return;
337 | }
338 | private TokenKind IdentKind()
339 | {
340 | KeyHash(m_Run);
341 | return m_Tokens[m_Line.Substring(m_TokenPos, m_Run + m_StringLen - m_TokenPos)];
342 | }
343 | private void IdentProc()
344 | {
345 | m_TokenId = IdentKind();
346 | m_Run += m_StringLen;
347 | if (m_TokenId == TokenKind.tkComment)
348 | {
349 | while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D')) { m_Run++; }
350 | }
351 | else
352 | {
353 | while (IdentifierStr.IndexOf(GetChar(m_Run)) != -1) m_Run++;
354 | }
355 | }
356 | private void VariableProc()
357 | {
358 | if (GetChar(m_Run) == '@' && GetChar(m_Run + 1) == '@') { m_Run += 2; IdentProc(); }
359 | else
360 | {
361 | m_TokenId = TokenKind.tkVariable;
362 | int i = m_Run;
363 | do { i++; } while (!(IdentifierStr.IndexOf(GetChar(i)) == -1));
364 | m_Run = i;
365 | }
366 | }
367 |
368 | private void AndSymbolProc()
369 | {
370 | m_TokenId = TokenKind.tkSymbol;
371 | m_Run++;
372 | if (GetChar(m_Run) == '=' || GetChar(m_Run) == '&') m_Run++;
373 | }
374 |
375 | private void SlashProc()
376 | {
377 | m_Run++;
378 | switch (GetChar(m_Run))
379 | {
380 | case '*':
381 | {
382 | Range = SqlRange.rsComment;
383 | m_TokenId = TokenKind.tkComment;
384 | do
385 | {
386 | m_Run++;
387 | if (GetChar(m_Run) == '*' && GetChar(m_Run + 1) == '/') { Range = SqlRange.rsUnknown; m_Run += 2; break; }
388 | } while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0D' || GetChar(m_Run) == '\x0A'));
389 | }
390 | break;
391 | case '=': m_Run++; m_TokenId = TokenKind.tkSymbol; break;
392 | default: m_TokenId = TokenKind.tkSymbol; break;
393 |
394 | }
395 | }
396 |
397 | private void PlusProc()
398 | {
399 | m_TokenId = TokenKind.tkSymbol;
400 | m_Run++;
401 | if (GetChar(m_Run) == '=' || GetChar(m_Run) == '=') m_Run++;
402 |
403 | }
404 |
405 | private void OrSymbolProc()
406 | {
407 | m_TokenId = TokenKind.tkSymbol;
408 | m_Run++;
409 | if (GetChar(m_Run) == '=' || GetChar(m_Run) == '|') m_Run++;
410 | }
411 |
412 | private void MinusProc()
413 | {
414 | m_Run++;
415 | if (GetChar(m_Run) == '-')
416 | {
417 | m_TokenId = TokenKind.tkComment;
418 | char c;
419 | do
420 | {
421 | m_Run++;
422 | c = GetChar(m_Run);
423 | } while (!(c == '\x00' || c == '\x0A' || c == '\x0D'));
424 | }
425 | else { m_TokenId = TokenKind.tkSymbol; }
426 | }
427 |
428 | private void LowerProc()
429 | {
430 | m_TokenId = TokenKind.tkSymbol;
431 | m_Run++;
432 | switch (GetChar(m_Run))
433 | {
434 | case '=': m_Run++; break;
435 | case '<': m_Run++; if (GetChar(m_Run) == '=') m_Run++; break;
436 | }
437 |
438 | }
439 |
440 | private void GreaterProc()
441 | {
442 | m_TokenId = TokenKind.tkSymbol;
443 | m_Run++;
444 | if (GetChar(m_Run) == '=' || GetChar(m_Run) == '>') m_Run++;
445 | }
446 |
447 | private void EqualProc()
448 | {
449 | m_TokenId = TokenKind.tkSymbol;
450 | m_Run++;
451 | if (GetChar(m_Run) == '=' || GetChar(m_Run) == '>') m_Run++;
452 | }
453 |
454 | private void Next()
455 | {
456 | m_TokenPos = m_Run;
457 | switch (Range)
458 | {
459 | case SqlRange.rsComment: AnsiCProc(); break;
460 | case SqlRange.rsString: AsciiCharProc(); break;
461 | default: DoProcTable(GetChar(m_Run)); break;
462 | }
463 | m_Token = m_Line.Substring(m_TokenPos, m_Run - m_TokenPos);
464 | }
465 |
466 |
467 | }
468 |
469 |
470 | }
471 |
--------------------------------------------------------------------------------
/sql_profiler/Program.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace sql_profiler
3 | {
4 |
5 |
6 | public class Program
7 | {
8 |
9 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/create-and-run-traces-using-transact-sql-stored-procedures
10 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/create-a-trace-transact-sql
11 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/set-a-trace-filter-transact-sql
12 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/modify-an-existing-trace-transact-sql
13 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/view-a-saved-trace-transact-sql
14 | // https://docs.microsoft.com/en-us/sql/relational-databases/sql-trace/delete-a-trace-transact-sql
15 |
16 | // Create a trace by using sp_trace_create.
17 | // Add events with sp_trace_setevent.
18 | // (Optional) Set a filter with sp_trace_setfilter.
19 | // Start the trace with sp_trace_setstatus.
20 | // Stop the trace with sp_trace_setstatus.
21 | // Close the trace with sp_trace_setstatus.
22 |
23 | // https://stackoverflow.com/questions/637013/how-do-i-find-running-traces-in-sql-server
24 | // SELECT * FROM sys.traces
25 | // SELECT * FROM::fn_trace_getinfo(trace_id)
26 | // SELECT * FROM::fn_trace_getfilterinfo(trace_id)
27 |
28 | // A trace must be stopped first before it can be closed.
29 | // EXEC sp_trace_setstatus [ @traceid = ] trace_id , [ @status = ] status
30 |
31 | // EXEC sp_trace_setstatus 2, 0
32 | // EXEC sp_trace_setstatus 2, 2
33 |
34 | // Execute sp_trace_setstatus by specifying @status = 0 to stop the trace.
35 | // Execute sp_trace_setstatus by specifying @status = 2 to close the trace and delete its information from the server.
36 |
37 | private static ExpressProfiler.SqlServerProfiler s_profiler;
38 |
39 |
40 | public class Argument
41 | {
42 | public string Key;
43 |
44 | private object m_value;
45 | private object InternalValue
46 | {
47 | get
48 | {
49 | if (this.m_value != null)
50 | return this.m_value;
51 |
52 | if (!CommandLine.ContainsKey(this.Key))
53 | return null;
54 |
55 | if (object.ReferenceEquals(@Type, typeof(string)))
56 | {
57 | this.m_value = CommandLine.GetValue(this.Key);
58 | return this.m_value;
59 | } // End if (object.ReferenceEquals(@Type, typeof(string)))
60 |
61 | if (object.ReferenceEquals(@Type, typeof(bool)))
62 | {
63 | bool? arg = CommandLine.GetValue(this.Key);
64 | if (!arg.HasValue)
65 | arg = false;
66 |
67 | this.m_value = arg.Value;
68 | return this.m_value;
69 | } // End if (object.ReferenceEquals(@Type, typeof(bool)))
70 |
71 | if (object.ReferenceEquals(@Type, typeof(int)))
72 | {
73 | int? arg = CommandLine.GetValue(this.Key);
74 | if (!arg.HasValue)
75 | arg = 0;
76 |
77 | this.m_value = arg.Value;
78 | return this.m_value;
79 | } // End if (object.ReferenceEquals(@Type, typeof(int)))
80 |
81 | if (object.ReferenceEquals(@Type, typeof(long)))
82 | {
83 | long? arg = CommandLine.GetValue(this.Key);
84 | if (!arg.HasValue)
85 | arg = 0;
86 |
87 | this.m_value = arg.Value;
88 | return this.m_value;
89 | } // End if (object.ReferenceEquals(@Type, typeof(long)))
90 |
91 | return this.m_value;
92 | } // End Get
93 |
94 | } // End Property InternalValue
95 |
96 |
97 | public T Value()
98 | {
99 | return (T) this.InternalValue;
100 | } // End Function Value
101 |
102 |
103 | public string StringValue
104 | {
105 | get { return this.CommandLine[this.Key]; }
106 | } // End Property StringValue
107 |
108 |
109 | public bool IsPresent
110 | {
111 | get { return this.CommandLine.ContainsKey(this.Key); }
112 | } // End Property IsPresent
113 |
114 |
115 | public System.Type @Type;
116 | public string HelpText;
117 | public bool Required;
118 | public bool IsCommand;
119 |
120 | public sql_profiler.CommandLineArguments CommandLine;
121 | } // End Class Argument
122 |
123 |
124 | public static System.Collections.Generic.Dictionary
125 | GetCommandLineArguments(string[] args
126 | , System.Collections.Generic.Dictionary defaultValues)
127 | {
128 | sql_profiler.CommandLineArguments arguments =
129 | new sql_profiler.CommandLineArguments(args, defaultValues);
130 |
131 |
132 | System.Collections.Generic.Dictionary ls = new
133 | System.Collections.Generic.Dictionary(
134 | System.StringComparer.InvariantCultureIgnoreCase
135 | );
136 |
137 | ls.Add("server",
138 | new Argument()
139 | {
140 | Key = "server"
141 | , @Type=typeof(string)
142 | , HelpText = @"The server\instance on which the DB to profile is"
143 | , Required = true
144 | }
145 | );
146 |
147 | ls.Add("db",
148 | new Argument()
149 | {
150 | Key = "db"
151 | , @Type=typeof(string)
152 | , HelpText = "The db to profile"
153 | , Required = true
154 | }
155 | );
156 |
157 | ls.Add("username",
158 | new Argument()
159 | {
160 | Key = "username"
161 | , @Type=typeof(string)
162 | , HelpText = "The SQL user-name; On Windows, uses integrated security if username is NULL or EMPTY."
163 | , Required = false
164 | }
165 | );
166 |
167 | ls.Add("password",
168 | new Argument()
169 | {
170 | Key = "password"
171 | , @Type=typeof(string)
172 | , HelpText = "The password for the sql-user"
173 | , Required = false
174 | }
175 | );
176 |
177 |
178 | ls.Add("help",
179 | new Argument()
180 | {
181 | Key = "help"
182 | , @Type=typeof(string)
183 | , HelpText = "Display help"
184 | , Required = false
185 | , IsCommand = true
186 | }
187 | );
188 |
189 |
190 | ls.Add("list",
191 | new Argument()
192 | {
193 | Key = "list"
194 | , @Type=typeof(string)
195 | , HelpText = "Show the command line values used."
196 | , Required = false
197 | , IsCommand = true
198 | }
199 | );
200 |
201 |
202 | ls.Add("showinput",
203 | new Argument()
204 | {
205 | Key = "showinput"
206 | , @Type=typeof(string)
207 | , HelpText = "Show the command line values as passed from console."
208 | , Required = false
209 | , IsCommand = true
210 | }
211 | );
212 |
213 | if (arguments != null)
214 | {
215 | foreach (System.Collections.Generic.KeyValuePair kvp in ls)
216 | {
217 | kvp.Value.CommandLine = arguments;
218 | } // Next kvp
219 |
220 | } // End if (arguments != null)
221 |
222 | return ls;
223 | } // End Function GetCommandLineArguments
224 |
225 | public static void Help(System.Collections.Generic.Dictionary arg_list)
226 | {
227 | System.Console.WriteLine("Valid command-line arguments:");
228 |
229 | foreach(System.Collections.Generic.KeyValuePair kvp in arg_list)
230 | {
231 | System.Console.WriteLine($" --{kvp.Key}: {kvp.Value.HelpText}");
232 | } // Next kvp
233 |
234 | } // End Sub Help
235 |
236 |
237 | public static void ListValues(System.Collections.Generic.Dictionary arg_list)
238 | {
239 | System.Console.WriteLine("Used command-line argument's values:");
240 |
241 | foreach (System.Collections.Generic.KeyValuePair kvp in arg_list)
242 | {
243 | if (!kvp.Value.IsCommand)
244 | System.Console.WriteLine($"{kvp.Key}: {kvp.Value.StringValue}");
245 | } // Next kvp
246 |
247 | } // End Sub ListValues
248 |
249 |
250 | public static void ShowInput(string[] args)
251 | {
252 |
253 | for (int i = 0; i < args.Length; ++i)
254 | {
255 | System.Console.WriteLine($"{i}: {args[i]}");
256 | } // Next i
257 |
258 | } // End Sub ShowInput
259 |
260 |
261 | public static string GetPlatformDefaultInstance()
262 | {
263 | bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
264 | System.Runtime.InteropServices.OSPlatform.Windows
265 | );
266 |
267 | // TODO: Check if there is an instance SQLExpress
268 | // https://stackoverflow.com/questions/141154/how-can-i-determine-installed-sql-server-instances-and-their-versions
269 | // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSRS13.SQLEXPRESS
270 | // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.SQLEXPRESS
271 | // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13E.LOCALDB
272 | // Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer
273 |
274 | if (isWindows)
275 | return System.Environment.MachineName + @"\" + "SQLEXPRESS";
276 |
277 | return System.Environment.MachineName;
278 | } // End Function GetPlatformDefaultInstance
279 |
280 |
281 | static void Main(string[] args)
282 | {
283 | System.Console.Clear();
284 | System.Console.Title = "https://github.com/ststeiger/sql_profiler";
285 |
286 | ᅠ300 = new System.Timers.Timer(4000);
287 | ᅠ300.AutoReset = true;
288 | ᅠ300.Elapsed += new System.Timers.ElapsedEventHandler(Sparta_Elapsed);
289 | ᅠ300.Start();
290 |
291 | MainTest(args);
292 | // DoProfiling(args);
293 | }
294 |
295 | // https://stackoverflow.com/a/48274520
296 | private static System.Timers.Timer ᅠ300;
297 | private static bool s_showSparta = true;
298 |
299 | private static void Sparta_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
300 | {
301 | if(s_showSparta)
302 | System.Console.Title = "THIS IS MADNESS!!! Madness huh? THIS IS SPARTA!!!!!!! ";
303 | else
304 | System.Console.Title = "https://github.com/ststeiger/sql_profiler";
305 |
306 | s_showSparta ^= true;
307 | }
308 |
309 |
310 | static void MainTest(string[] args)
311 | {
312 | string instance = GetPlatformDefaultInstance();
313 | // dotnet run --server localhost --username MY_USER --password MY_PASSWORD --db MY_DB
314 | // string ar = $"--server {instance} --username WebAppWebServices --password TOP_SECRET --Db COR_Basic_Demo_V4";
315 |
316 | string ar = $"--server {instance} /db \"COR_Basic_Demo_V4\"";
317 |
318 | bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
319 | System.Runtime.InteropServices.OSPlatform.Windows
320 | );
321 |
322 | if(!isWindows)
323 | {
324 | try
325 | {
326 | string un = TestPlotly.SecretManager.GetSecret("DefaultDbUser");
327 | string pw = TestPlotly.SecretManager.GetSecret("DefaultDbPassword");
328 | ar = $"--server {instance} --username {un} --password {pw} --db \"Redmine\"";
329 | }
330 | catch (System.Exception e)
331 | {
332 | System.Console.WriteLine(e);
333 | throw;
334 | }
335 | }
336 |
337 | DoProfiling(ar.Split(' '));
338 | } // End Sub Main
339 |
340 |
341 | static void DoProfiling(string[] args)
342 | {
343 | // https://github.com/dotnet/coreclr/issues/8565
344 | // https://shazwazza.com/post/aspnet-core-application-shutdown-events/
345 | // Will not be executed when !windows
346 | WindowsFix.AddConsoleHandler(ConsoleCtrlCheck);
347 |
348 | System.AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
349 | System.AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
350 | System.Console.CancelKeyPress += Console_CancelKeyPress;
351 |
352 | System.Collections.Generic.Dictionary defaultValues =
353 | new System.Collections.Generic.Dictionary();
354 |
355 | defaultValues["server"] = GetPlatformDefaultInstance();
356 | defaultValues["db"] = "COR_Basic_Demo_V4";
357 |
358 | System.Collections.Generic.Dictionary arg_list =
359 | GetCommandLineArguments(args, defaultValues);
360 |
361 |
362 | if (arg_list["showinput"].IsPresent)
363 | {
364 | ShowInput(args);
365 | System.Console.WriteLine(System.Environment.NewLine);
366 | System.Console.WriteLine("--- Press any key to stop continue --- ");
367 | System.Console.ReadKey();
368 | return;
369 | }
370 |
371 | if (arg_list["list"].IsPresent)
372 | {
373 | ListValues(arg_list);
374 | System.Console.WriteLine(System.Environment.NewLine);
375 | System.Console.WriteLine("--- Press any key to stop continue --- ");
376 | System.Console.ReadKey();
377 | return;
378 | }
379 |
380 | if (arg_list["help"].IsPresent)
381 | {
382 | Help(arg_list);
383 | System.Console.WriteLine(System.Environment.NewLine);
384 | System.Console.WriteLine("--- Press any key to stop continue --- ");
385 | System.Console.ReadKey();
386 | return;
387 | }
388 |
389 |
390 | string server = arg_list["server"].Value();
391 | string db = arg_list["db"].Value();
392 | string username = arg_list["username"].Value();
393 | string password = arg_list["password"].Value();
394 |
395 |
396 | s_profiler = new ExpressProfiler.SqlServerProfiler(server, db, username, password);
397 |
398 | s_profiler.StartProfiling();
399 |
400 |
401 | System.Console.ResetColor();
402 |
403 | // System.Console.WriteLine("--- Press ENTER to stop profiling --- ");
404 | // System.Console.ReadLine();
405 |
406 | // System.Console.WriteLine("--- Press any key to stop profiling --- ");
407 | // System.Console.ReadKey();
408 |
409 | System.Console.WriteLine("--- Press ENTER to stop profiling --- ");
410 |
411 | System.ConsoleKey cc = default(System.ConsoleKey);
412 |
413 | do
414 | {
415 | // THIS IS MADNESS!!! Madness huh? THIS IS SPARTA!!!!!!!
416 | while (!System.Console.KeyAvailable)
417 | {
418 | System.Threading.Thread.Sleep(100);
419 | }
420 |
421 | cc = System.Console.ReadKey().Key;
422 |
423 | if(cc == System.ConsoleKey.C)
424 | System.Console.Clear();
425 |
426 | } while (cc != System.ConsoleKey.Enter);
427 |
428 | OnExit();
429 | } // End Sub Test
430 |
431 |
432 | [System.Runtime.CompilerServices.MethodImpl(
433 | System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)
434 | ]
435 | private static void OnExit()
436 | {
437 | System.Console.ResetColor();
438 |
439 | if (s_profiler != null) // Is there any chance this could happen ?
440 | s_profiler.StopProfiling();
441 |
442 | System.Console.ResetColor();
443 | } // End Sub OnExit
444 |
445 |
446 | private static bool ConsoleCtrlCheck(WindowsFix.CtrlTypes ctrlType)
447 | {
448 | // Put your own handler here
449 | switch (ctrlType)
450 | {
451 | case WindowsFix.CtrlTypes.CTRL_C_EVENT: // CTRL+C received!
452 | case WindowsFix.CtrlTypes.CTRL_BREAK_EVENT: // CTRL+BREAK received!
453 | case WindowsFix.CtrlTypes.CTRL_CLOSE_EVENT: // Program being closed!
454 | case WindowsFix.CtrlTypes.CTRL_LOGOFF_EVENT: // User is logging off!
455 | case WindowsFix.CtrlTypes.CTRL_SHUTDOWN_EVENT:
456 | OnExit();
457 | break;
458 | } // End switch (ctrlType)
459 |
460 | return true;
461 | } // End Function ConsoleCtrlCheck
462 |
463 |
464 | // Catch CTRL+C
465 | private static void Console_CancelKeyPress(object sender, System.ConsoleCancelEventArgs e)
466 | {
467 | OnExit();
468 | } // End Sub Console_CancelKeyPress
469 |
470 |
471 | // Does not catch anything...
472 | private static void CurrentDomain_ProcessExit(object sender, System.EventArgs e)
473 | {
474 | OnExit();
475 | } // End Sub CurrentDomain_ProcessExit
476 |
477 |
478 | // Catch unhandled exceptions
479 | private static void CurrentDomain_UnhandledException(object sender, System.UnhandledExceptionEventArgs e)
480 | {
481 | System.Console.WriteLine(((System.Exception)e.ExceptionObject).Message, "Error");
482 | OnExit();
483 | } // End Sub CurrentDomain_UnhandledException
484 |
485 |
486 | } // End Class Program
487 |
488 |
489 | } // End Namespace sql_profiler
490 |
--------------------------------------------------------------------------------
/sql_profiler/Code/SqlServerProfiler.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 |
4 | namespace ExpressProfiler
5 | {
6 |
7 |
8 | public class SqlServerProfiler
9 | {
10 | protected enum ProfilingStateEnum { psStopped, psProfiling, psPaused }
11 | protected ProfilingStateEnum m_ProfilingState;
12 |
13 | protected System.Data.SqlClient.SqlConnection m_Conn;
14 | protected RawTraceReader m_Rdr;
15 | protected bool m_NeedStop;
16 | protected System.Timers.Timer m_timer;
17 | protected System.Threading.Thread m_Thr;
18 | protected System.Collections.Concurrent.ConcurrentQueue m_events;
19 | protected readonly System.Collections.Generic.List m_columns;
20 | protected readonly YukonLexer m_Lex;
21 | protected readonly bool m_isWindows;
22 |
23 |
24 | protected readonly ProfilerEvent m_EventStarted = new ProfilerEvent();
25 | protected readonly ProfilerEvent m_EventStopped = new ProfilerEvent();
26 | protected readonly ProfilerEvent m_EventPaused = new ProfilerEvent();
27 |
28 |
29 | protected string m_server;
30 | protected string m_username;
31 | protected string m_password;
32 | protected bool m_integrated_security;
33 | protected string m_database;
34 |
35 |
36 | public SqlServerProfiler()
37 | :this(System.Environment.MachineName + @"\" + "SQLEXPRESS")
38 | { }
39 |
40 | public SqlServerProfiler(string server)
41 | : this(server, null)
42 | { }
43 |
44 | public SqlServerProfiler(string server, string database)
45 | : this(server, database, null, null)
46 | { }
47 |
48 |
49 | public SqlServerProfiler(string server, string database
50 | , string username, string password)
51 | {
52 | this.m_server = server;
53 | this.m_database = database;
54 | this.m_username = username;
55 | this.m_password = password;
56 | this.m_integrated_security = string.IsNullOrWhiteSpace(username);
57 |
58 | this.m_isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
59 | System.Runtime.InteropServices.OSPlatform.Windows
60 | );
61 |
62 | if (this.m_integrated_security && !this.m_isWindows)
63 | {
64 | throw new System.ArgumentException($"Username is NULL or empty. Cannot use integrated-security on non-windows platform.");
65 | }
66 |
67 | if (!this.m_integrated_security)
68 | {
69 | if (password == null)
70 | throw new System.ArgumentException($"{nameof(password)} cannot be NULL when integrated security is false.");
71 | } // End if (!integratedSecurity)
72 |
73 |
74 | this.m_Lex = new YukonLexer();
75 | //this.m_events = new Queue(10);
76 | this.m_events = new System.Collections.Concurrent.ConcurrentQueue();
77 | this.m_timer = new System.Timers.Timer(1000);
78 | this.m_timer.AutoReset = false;
79 | this.m_timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
80 | this.m_timer.Start();
81 |
82 | this.m_columns = new System.Collections.Generic.List();
83 | this.m_columns.Add(new PerfColumn { Caption = "Event Class", Column = ProfilerEventColumns.EventClass, Width = 122 });
84 | this.m_columns.Add(new PerfColumn { Caption = "Text Data", Column = ProfilerEventColumns.TextData, Width = 255 });
85 | this.m_columns.Add(new PerfColumn { Caption = "Login Name", Column = ProfilerEventColumns.LoginName, Width = 79 });
86 | this.m_columns.Add(new PerfColumn { Caption = "CPU", Column = ProfilerEventColumns.CPU, Width = 82, Alignment = HorizontalAlignment.Right, Format = "#,0" });
87 | this.m_columns.Add(new PerfColumn { Caption = "Reads", Column = ProfilerEventColumns.Reads, Width = 78, Alignment = HorizontalAlignment.Right, Format = "#,0" });
88 | this.m_columns.Add(new PerfColumn { Caption = "Writes", Column = ProfilerEventColumns.Writes, Width = 78, Alignment = HorizontalAlignment.Right, Format = "#,0" });
89 | this.m_columns.Add(new PerfColumn { Caption = "Duration, ms", Column = ProfilerEventColumns.Duration, Width = 82, Alignment = HorizontalAlignment.Right, Format = "#,0" });
90 | this.m_columns.Add(new PerfColumn { Caption = "SPID", Column = ProfilerEventColumns.SPID, Width = 50, Alignment = HorizontalAlignment.Right });
91 |
92 | // if (m_currentsettings.EventsColumns.StartTime)
93 | m_columns.Add(new PerfColumn { Caption = "Start time", Column = ProfilerEventColumns.StartTime, Width = 140, Format = "yyyy-MM-ddThh:mm:ss.ffff" });
94 | // if (m_currentsettings.EventsColumns.EndTime)
95 | m_columns.Add(new PerfColumn { Caption = "End time", Column = ProfilerEventColumns.EndTime, Width = 140, Format = "yyyy-MM-ddThh:mm:ss.ffff" });
96 | // if (m_currentsettings.EventsColumns.DatabaseName)
97 | m_columns.Add(new PerfColumn { Caption = "DatabaseName", Column = ProfilerEventColumns.DatabaseName, Width = 70 });
98 | // if (m_currentsettings.EventsColumns.ObjectName)
99 | m_columns.Add(new PerfColumn { Caption = "Object name", Column = ProfilerEventColumns.ObjectName, Width = 70 });
100 | // if (m_currentsettings.EventsColumns.ApplicationName)
101 | m_columns.Add(new PerfColumn { Caption = "Application name", Column = ProfilerEventColumns.ApplicationName, Width = 70 });
102 | // if (m_currentsettings.EventsColumns.HostName)
103 | m_columns.Add(new PerfColumn { Caption = "Host name", Column = ProfilerEventColumns.HostName, Width = 70 });
104 |
105 | // m_columns.Add(new PerfColumn { Caption = "#", Column = -1, Width = 53, Alignment = HorizontalAlignment.Right });
106 | } // End Constructor
107 |
108 |
109 |
110 | protected void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
111 | {
112 | this.m_timer.Stop();
113 |
114 | try
115 | {
116 | int i = -1;
117 | while ((i = this.m_events.Count) > 0)
118 | {
119 | ProfilerEvent evt;
120 | if (this.m_events.TryDequeue(out evt))
121 | NewEventArrived(evt, i == 1);
122 | else
123 | System.Threading.Thread.Sleep(50);
124 | } // Whend
125 |
126 | } // End try
127 | catch (System.Exception ex)
128 | {
129 | System.Console.WriteLine($"Timer_Elapsed Error: {ex.Message}\n{ex.StackTrace}");
130 | }
131 |
132 | this.m_timer.Start();
133 | } // End Sub Timer_Elapsed
134 |
135 |
136 | protected System.Data.SqlClient.SqlConnection GetConnection()
137 | {
138 | string cs = string.Format(@"Data Source = {0}; Initial Catalog = master;
139 | Integrated Security=SSPI;Application Name=Express Profiler", this.m_server);
140 |
141 | if (!this.m_integrated_security)
142 | {
143 | cs = string.Format(@"Data Source={0};Initial Catalog=master;
144 | User Id={1};Password='{2}';;Application Name=Express Profiler"
145 | , this.m_server, this.m_username, this.m_password);
146 | } // End if (!this.m_integrated_security)
147 |
148 | return new System.Data.SqlClient.SqlConnection(cs);
149 | } // End Function GetConnection
150 |
151 |
152 | protected void OpenConnection(System.Data.SqlClient.SqlConnection con)
153 | {
154 | if (con.State != System.Data.ConnectionState.Open)
155 | con.Open();
156 | } // End Sub OpenConnection
157 |
158 | protected void CloseConnection(System.Data.SqlClient.SqlConnection con)
159 | {
160 | if (con.State != System.Data.ConnectionState.Closed)
161 | con.Close();
162 | } // End Sub CloseConnection
163 |
164 |
165 | protected void ProfilerThread(object state)
166 | {
167 | try
168 | {
169 | while (!this.m_NeedStop && this.m_Rdr.TraceIsActive)
170 | {
171 | ProfilerEvent evt = this.m_Rdr.Next();
172 | if (evt != null)
173 | {
174 | // lock (this)
175 | m_events.Enqueue(evt);
176 | } // End if (evt != null)
177 | } // Whend
178 | }
179 | catch (System.Exception e)
180 | {
181 | // lock (this)
182 | // {
183 | if (!this.m_NeedStop && this.m_Rdr.TraceIsActive)
184 | {
185 | System.Console.WriteLine($"Error: {e.Message}\n{e.StackTrace}");
186 | }
187 | // } // End lock
188 | } // End Catch
189 | } // End Sub ProfilerThread
190 |
191 |
192 | /*
193 | protected void RunProfiling(bool showfilters)
194 | {
195 | if (showfilters)
196 | {
197 | // ts m_currentsettings.GetCopy();
198 | TraceProperties.TraceSettings ts = new TraceProperties.TraceSettings();
199 | using (TraceProperties frm = new TraceProperties())
200 | {
201 | frm.SetSettings(ts);
202 | // if (DialogResult.OK != frm.ShowDialog()) return;
203 | // m_currentsettings = frm.m_currentsettings.GetCopy();
204 | }
205 | }
206 |
207 | StartProfiling();
208 | } // End Sub RunProfiling
209 | */
210 |
211 | public enum StringFilterCondition
212 | {
213 | Like,
214 | NotLike
215 | } // End Enum StringFilterCondition
216 |
217 | public enum IntFilterCondition
218 | {
219 | Equal,
220 | NotEqual,
221 | GreaterThan,
222 | LessThan
223 | } // End Enum IntFilterCondition
224 |
225 |
226 | protected void SetIntFilter(int? value, IntFilterCondition condition, int column)
227 | {
228 | int[] com = new[] {
229 | ComparisonOperators.Equal
230 | , ComparisonOperators.NotEqual
231 | , ComparisonOperators.GreaterThan
232 | , ComparisonOperators.LessThan
233 | };
234 |
235 | if ((null != value))
236 | {
237 | long? v = value;
238 | this.m_Rdr.SetFilter(column, LogicalOperators.AND, com[(int)condition], v);
239 | } // End if ((null != value))
240 |
241 | } // End Sub SetIntFilter
242 |
243 |
244 | protected void SetStringFilter(string value, StringFilterCondition condition, int column)
245 | {
246 | if (!string.IsNullOrEmpty(value))
247 | {
248 | this.m_Rdr.SetFilter(column, LogicalOperators.AND
249 | , condition == StringFilterCondition.Like ?
250 | ComparisonOperators.Like : ComparisonOperators.NotLike
251 | , value
252 | );
253 | } // End if (!string.IsNullOrEmpty(value))
254 |
255 | } // End Sub SetStringFilter
256 |
257 |
258 | public void StartProfiling()
259 | {
260 | this.m_events.Clear();
261 |
262 | this.m_Conn = GetConnection();
263 | OpenConnection(this.m_Conn);
264 |
265 | this.m_Rdr = new RawTraceReader(m_Conn);
266 | this.m_Rdr.CreateTrace();
267 |
268 | //if (m_currentsettings.EventsColumns.BatchCompleted)
269 | {
270 | m_Rdr.SetEvent(ProfilerEvents.TSQL.SQLBatchCompleted,
271 | ProfilerEventColumns.TextData,
272 | ProfilerEventColumns.LoginName,
273 | ProfilerEventColumns.CPU,
274 | ProfilerEventColumns.Reads,
275 | ProfilerEventColumns.Writes,
276 | ProfilerEventColumns.Duration,
277 | ProfilerEventColumns.SPID,
278 | ProfilerEventColumns.StartTime,
279 | ProfilerEventColumns.EndTime,
280 | ProfilerEventColumns.DatabaseName,
281 | ProfilerEventColumns.ApplicationName,
282 | ProfilerEventColumns.HostName
283 | );
284 | } // End if (m_currentsettings.EventsColumns.BatchCompleted)
285 |
286 | //if (m_currentsettings.EventsColumns.RPCCompleted)
287 | {
288 | m_Rdr.SetEvent(ProfilerEvents.StoredProcedures.RPCCompleted,
289 | ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
290 | ProfilerEventColumns.CPU, ProfilerEventColumns.Reads,
291 | ProfilerEventColumns.Writes, ProfilerEventColumns.Duration,
292 | ProfilerEventColumns.SPID
293 | , ProfilerEventColumns.StartTime, ProfilerEventColumns.EndTime
294 | , ProfilerEventColumns.DatabaseName
295 | , ProfilerEventColumns.ObjectName
296 | , ProfilerEventColumns.ApplicationName
297 | , ProfilerEventColumns.HostName
298 |
299 | );
300 | } // End if (m_currentsettings.EventsColumns.RPCCompleted)
301 |
302 |
303 | if (!string.IsNullOrWhiteSpace(this.m_database))
304 | SetStringFilter(this.m_database, StringFilterCondition.Like, ProfilerEventColumns.DatabaseName);
305 |
306 | this.m_Rdr.SetFilter(ProfilerEventColumns.ApplicationName, LogicalOperators.AND
307 | , ComparisonOperators.NotLike, "Express Profiler");
308 |
309 |
310 | this.m_Rdr.StartTrace();
311 | this.m_NeedStop = false;
312 | this.m_Thr = new System.Threading.Thread(ProfilerThread) {
313 | IsBackground = true,
314 | Priority = System.Threading.ThreadPriority.Lowest
315 | };
316 |
317 | this.m_ProfilingState = ProfilingStateEnum.psProfiling;
318 | NewEventArrived(m_EventStarted, true);
319 | m_Thr.Start();
320 | } // End Sub StartProfiling
321 |
322 |
323 |
324 | public void PauseProfiling()
325 | {
326 | if (this.m_ProfilingState != ProfilingStateEnum.psProfiling)
327 | return;
328 |
329 | using (System.Data.SqlClient.SqlConnection cn = GetConnection())
330 | {
331 | OpenConnection(cn);
332 | this.m_Rdr.StopTrace(cn);
333 | CloseConnection(cn);
334 | } // End Using cn
335 |
336 | this.m_ProfilingState = ProfilingStateEnum.psPaused;
337 | NewEventArrived(m_EventPaused, true);
338 | } // End Sub PauseProfiling
339 |
340 |
341 | public void StopProfiling()
342 | {
343 | if (this.m_ProfilingState == ProfilingStateEnum.psStopped)
344 | return;
345 |
346 | using (System.Data.SqlClient.SqlConnection cn = GetConnection())
347 | {
348 | OpenConnection(cn);
349 | this.m_Rdr.StopTrace(cn);
350 | this.m_Rdr.CloseTrace(cn);
351 | CloseConnection(cn);
352 | } // End Using cn
353 |
354 | this.m_NeedStop = true;
355 | this.m_ProfilingState = ProfilingStateEnum.psStopped;
356 | NewEventArrived(m_EventStopped, true);
357 | } // End Sub StopProfiling
358 |
359 |
360 | protected string GetEventCaption(ProfilerEvent evt)
361 | {
362 | if (evt == m_EventStarted)
363 | return "Trace started";
364 |
365 | if (evt == m_EventPaused)
366 | return "Trace paused";
367 |
368 | if (evt == m_EventStopped)
369 | {
370 |
371 | return "Trace stopped";
372 | }
373 |
374 | return ProfilerEvents.Names[evt.EventClass];
375 | } // End Function GetEventCaption
376 |
377 |
378 | protected void NewEventArrived(ProfilerEvent evt, bool last)
379 | {
380 | // if (evt == m_EventStarted || evt == m_EventPaused || evt == m_EventStopped) return;
381 |
382 | //m_columns.Add(new PerfColumn { Caption = "Event Class", Column = ProfilerEventColumns.EventClass, Width = 122 });
383 | //m_columns.Add(new PerfColumn { Caption = "Text Data", Column = ProfilerEventColumns.TextData, Width = 255 });
384 | //m_columns.Add(new PerfColumn { Caption = "Login Name", Column = ProfilerEventColumns.LoginName, Width = 79 });
385 | //m_columns.Add(new PerfColumn { Caption = "CPU", Column = ProfilerEventColumns.CPU, Width = 82, Alignment = HorizontalAlignment.Right, Format = "#,0" });
386 | //m_columns.Add(new PerfColumn { Caption = "Reads", Column = ProfilerEventColumns.Reads, Width = 78, Alignment = HorizontalAlignment.Right, Format = "#,0" });
387 | //m_columns.Add(new PerfColumn { Caption = "Writes", Column = ProfilerEventColumns.Writes, Width = 78, Alignment = HorizontalAlignment.Right, Format = "#,0" });
388 | //m_columns.Add(new PerfColumn { Caption = "Duration, ms", Column = ProfilerEventColumns.Duration, Width = 82, Alignment = HorizontalAlignment.Right, Format = "#,0" });
389 | //m_columns.Add(new PerfColumn { Caption = "SPID", Column = ProfilerEventColumns.SPID, Width = 50, Alignment = HorizontalAlignment.Right });
390 | //m_columns.Add(new PerfColumn { Caption = "Start time", Column = ProfilerEventColumns.StartTime, Width = 140, Format = "yyyy-MM-ddThh:mm:ss.ffff" });
391 | //m_columns.Add(new PerfColumn { Caption = "End time", Column = ProfilerEventColumns.EndTime, Width = 140, Format = "yyyy-MM-ddThh:mm:ss.ffff" });
392 | //m_columns.Add(new PerfColumn { Caption = "DatabaseName", Column = ProfilerEventColumns.DatabaseName, Width = 70 });
393 | //m_columns.Add(new PerfColumn { Caption = "Object name", Column = ProfilerEventColumns.ObjectName, Width = 70 });
394 | //m_columns.Add(new PerfColumn { Caption = "Application name", Column = ProfilerEventColumns.ApplicationName, Width = 70 });
395 | //m_columns.Add(new PerfColumn { Caption = "Host name", Column = ProfilerEventColumns.HostName, Width = 70 });
396 |
397 |
398 | // System.Console.WriteLine(evt);
399 | System.Console.ResetColor();
400 | string caption = GetEventCaption(evt);
401 | System.Console.Write(caption);
402 | System.Console.Write(new string(' ', System.Console.BufferWidth - System.Console.CursorLeft));
403 |
404 | if(!this.m_isWindows)
405 | System.Console.Write(System.Environment.NewLine);
406 |
407 |
408 |
409 | string td = evt.GetFormattedData(ProfilerEventColumns.TextData, null);
410 | // System.Console.WriteLine(td);
411 |
412 |
413 | // System.Windows.Forms.RichTextBox rich,
414 | // RTFBuilder rb = new RTFBuilder {
415 | // BackColor = System.Drawing.Color.White
416 | // };
417 | // rich.Text = "";
418 |
419 |
420 | ConsoleOutputWriter cw = new ConsoleOutputWriter(){
421 | BackColor = System.Drawing.Color.White
422 | };
423 |
424 |
425 | if (!string.IsNullOrEmpty(td))
426 | {
427 | // var lex = new YukonLexer(); lex.SyntaxHighlight(cw, td);
428 | this.m_Lex.SyntaxHighlight(cw, td);
429 | // rich.Rtf = this.m_Lex.SyntaxHighlight(rb, td);
430 | }
431 |
432 | // for(int i = 0; i < 65; ++i) // 65 is size of array
433 | // System.Console.WriteLine(evt.GetFormattedData(i, null));
434 |
435 | //for (int i = 1; i < this.m_columns.Count; ++i)
436 | //{
437 | // System.Console.WriteLine(i);
438 | // System.Console.WriteLine(this.m_columns[i].Caption);
439 | // System.Console.WriteLine(evt.GetFormattedData(this.m_columns[i].Column, this.m_columns[i].Format));
440 | //} // Next i
441 |
442 | } // End Sub NewEventArrived
443 |
444 |
445 | } // End Class MyProfiler
446 |
447 |
448 | } // End Namespace ExpressProfiler
449 |
--------------------------------------------------------------------------------
/sql_profiler/Code/NotImplemented/TraceProperties.cs:
--------------------------------------------------------------------------------
1 |
2 | // using System.Windows.Forms;
3 |
4 |
5 | namespace ExpressProfiler
6 | {
7 |
8 |
9 |
10 | public partial class TraceProperties // : Form
11 | : System.IDisposable
12 | {
13 |
14 |
15 | public enum StringFilterCondition
16 | {
17 | Like,
18 | NotLike
19 | }
20 |
21 | public enum IntFilterCondition
22 | {
23 | Equal,
24 | NotEqual,
25 | GreaterThan,
26 | LessThan
27 | }
28 |
29 |
30 | public static StringFilterCondition ParseStringCondition(string value)
31 | {
32 | switch (value.ToLower())
33 | {
34 | case "like":
35 | case "eq":
36 | case "=": return StringFilterCondition.Like;
37 | case "notlike": return StringFilterCondition.NotLike;
38 | }
39 | throw new System.Exception("Unknown filter condition:" + value);
40 | }
41 |
42 |
43 | public static IntFilterCondition ParseIntCondition(string value)
44 | {
45 | switch (value.ToLower())
46 | {
47 | case "equal":
48 | case "eq":
49 | case "=":
50 | return IntFilterCondition.Equal;
51 | case "notequal":
52 | case "ne":
53 | case "!=":
54 | case "<>": return IntFilterCondition.NotEqual;
55 | case "greaterthan":
56 | case "ge":
57 | case ">": return IntFilterCondition.GreaterThan;
58 | case "lessthan":
59 | case "le":
60 | case "<": return IntFilterCondition.LessThan;
61 | }
62 | throw new System.Exception("Unknown filter condition:" + value);
63 | }
64 | /*
65 | declare @xml xml
66 | set @xml = '
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | '
75 |
76 | select '
77 | [System.ComponentModel.Category(@"'+b.value('@text','varchar(512)')+'")]
78 | [System.ComponentModel.DisplayName(@"Condition")]
79 | public '+b.value('@type','varchar(512)')+'FilterComparison '+replace(b.value('@text','varchar(512)'),' ','')+'FilterComparison { get; set; }
80 | [System.ComponentModel.Category(@"'+b.value('@text','varchar(512)')+'")]
81 | [System.ComponentModel.DisplayName(@"Value")]
82 | public '+lower(b.value('@type','varchar(512)'))+' '+replace(b.value('@text','varchar(512)'),' ','')+ '{ get; set; }'
83 |
84 | from @xml.nodes('/root/r') a(b)
85 | order by b.value('@text','varchar(512)')
86 | */
87 |
88 | [System.Serializable]
89 | public class TraceSettings
90 | {
91 | public TraceEventsColumns EventsColumns;
92 | public TraceFilters Filters;
93 |
94 | public TraceSettings()
95 | {
96 |
97 | EventsColumns = new TraceEventsColumns
98 | {
99 | BatchCompleted = true,
100 | RPCCompleted = true,
101 | StartTime = true,
102 | EndTime = true
103 | };
104 | Filters = new TraceFilters
105 | {
106 | MaximumEventCount = 5000,
107 | CpuFilterCondition = IntFilterCondition.GreaterThan,
108 | ReadsFilterCondition = IntFilterCondition.GreaterThan,
109 | WritesFilterCondition = IntFilterCondition.GreaterThan,
110 | DurationFilterCondition = IntFilterCondition.GreaterThan
111 | };
112 | }
113 |
114 | public string GetAsXmlString()
115 | {
116 | System.Xml.Serialization.XmlSerializer x =
117 | new System.Xml.Serialization.XmlSerializer(typeof(TraceSettings));
118 |
119 | using (System.IO.StringWriter sw = new System.IO.StringWriter())
120 | {
121 | x.Serialize(sw, this);
122 | return sw.ToString();
123 | }
124 | }
125 |
126 | public static TraceSettings GetDefaultSettings()
127 | {
128 | return new TraceSettings { };
129 | }
130 |
131 | public TraceSettings GetCopy()
132 | {
133 | return new TraceSettings
134 | {
135 |
136 | EventsColumns = new TraceEventsColumns
137 | {
138 | BatchCompleted = EventsColumns.BatchCompleted,
139 | BatchStarting = EventsColumns.BatchStarting,
140 | ExistingConnection = EventsColumns.ExistingConnection,
141 | LoginLogout = EventsColumns.LoginLogout,
142 | RPCCompleted = EventsColumns.RPCCompleted,
143 | RPCStarting = EventsColumns.RPCStarting,
144 | SPStmtCompleted = EventsColumns.SPStmtCompleted,
145 | SPStmtStarting = EventsColumns.SPStmtStarting,
146 | UserErrorMessage = EventsColumns.UserErrorMessage,
147 | ApplicationName = EventsColumns.ApplicationName,
148 | HostName = EventsColumns.HostName,
149 | DatabaseName = EventsColumns.DatabaseName,
150 | EndTime = EventsColumns.EndTime,
151 | ObjectName = EventsColumns.ObjectName,
152 | StartTime = EventsColumns.StartTime,
153 | BlockedProcessPeport = EventsColumns.BlockedProcessPeport,
154 | SQLStmtStarting = EventsColumns.SQLStmtStarting,
155 | SQLStmtCompleted = EventsColumns.SQLStmtCompleted
156 | }
157 | ,
158 | Filters = new TraceFilters
159 | {
160 | CPU = Filters.CPU,
161 | CpuFilterCondition = Filters.CpuFilterCondition,
162 | DatabaseName = Filters.DatabaseName,
163 | DatabaseNameFilterCondition = Filters.DatabaseNameFilterCondition,
164 | Duration = Filters.Duration,
165 | DurationFilterCondition = Filters.DurationFilterCondition,
166 | LoginName = Filters.LoginName,
167 | HostName = Filters.HostName,
168 | HostNameFilterCondition = Filters.HostNameFilterCondition,
169 | LoginNameFilterCondition = Filters.LoginNameFilterCondition,
170 | Reads = Filters.Reads,
171 | ReadsFilterCondition = Filters.ReadsFilterCondition,
172 | TextData = Filters.TextData,
173 | TextDataFilterCondition = Filters.TextDataFilterCondition,
174 | Writes = Filters.Writes,
175 | WritesFilterCondition = Filters.WritesFilterCondition,
176 | MaximumEventCount = Filters.MaximumEventCount,
177 | SPID = Filters.SPID,
178 | SPIDFilterCondition = Filters.SPIDFilterCondition,
179 | ApplicationName = Filters.ApplicationName,
180 | ApplicationNameFilterCondition = Filters.ApplicationNameFilterCondition,
181 |
182 | }
183 | }
184 | ;
185 | }
186 |
187 | }
188 |
189 | internal TraceSettings m_currentsettings;
190 | [System.Serializable]
191 | public class TraceEventsColumns
192 | {
193 | [System.ComponentModel.Category(@"Events")]
194 | [System.ComponentModel.DisplayName(@"ExistingConnection")]
195 | [System.ComponentModel.Description(@"The ExistingConnection event class indicates the properties of existing user connections when the trace was started. The server raises one ExistingConnection event per existing user connection.")]
196 | [System.ComponentModel.DefaultValue(false)]
197 | public bool ExistingConnection { get; set; }
198 | [System.ComponentModel.Category(@"Events")]
199 | [System.ComponentModel.DisplayName(@"LoginLogout")]
200 | [System.ComponentModel.Description(@"The Audit Login event class indicates that a user has successfully logged in to SQL Server. Events in this class are fired by new connections or by connections that are reused from a connection pool. The Audit Logout event class indicates that a user has logged out of (logged off) Microsoft SQL Server. Events in this class are fired by new connections or by connections that are reused from a connection pool.")]
201 | [System.ComponentModel.DefaultValue(false)]
202 | public bool LoginLogout { get; set; }
203 | [System.ComponentModel.Category(@"Events")]
204 | [System.ComponentModel.DisplayName(@"RPC:Starting")]
205 | [System.ComponentModel.Description(@"The RPC:Starting event class indicates that a remote procedure call has started.")]
206 | [System.ComponentModel.DefaultValue(false)]
207 | public bool RPCStarting { get; set; }
208 | [System.ComponentModel.Category(@"Events")]
209 | [System.ComponentModel.DisplayName(@"RPC:Completed")]
210 | [System.ComponentModel.Description(@"The RPC:Completed event class indicates that a remote procedure call has been completed. ")]
211 | [System.ComponentModel.DefaultValue(false)]
212 | public bool RPCCompleted { get; set; }
213 | [System.ComponentModel.Category(@"Events")]
214 | [System.ComponentModel.DisplayName(@"SQL:BatchStarting")]
215 | [System.ComponentModel.Description(@"The SQL:BatchStarting event class indicates that a Transact-SQL batch is starting.")]
216 | [System.ComponentModel.DefaultValue(false)]
217 | public bool BatchStarting { get; set; }
218 | [System.ComponentModel.Category(@"Events")]
219 | [System.ComponentModel.DisplayName(@"SQL:BatchCompleted")]
220 | [System.ComponentModel.Description(@"The SQL:BatchCompleted event class indicates that the Transact-SQL batch has completed. ")]
221 | [System.ComponentModel.DefaultValue(false)]
222 | public bool BatchCompleted { get; set; }
223 | [System.ComponentModel.Category(@"Events")]
224 | [System.ComponentModel.DisplayName(@"SP:StmtCompleted")]
225 | [System.ComponentModel.Description(@"The SP:StmtCompleted event class indicates that a Transact-SQL statement within a stored procedure has completed. ")]
226 | [System.ComponentModel.DefaultValue(false)]
227 | public bool SPStmtCompleted { get; set; }
228 | [System.ComponentModel.Category(@"Events")]
229 | [System.ComponentModel.DisplayName(@"SP:StmtStarting")]
230 | [System.ComponentModel.Description(@"The SP:StmtStarting event class indicates that a Transact-SQL statement within a stored procedure has started. ")]
231 | [System.ComponentModel.DefaultValue(false)]
232 | public bool SPStmtStarting { get; set; }
233 | [System.ComponentModel.Category(@"Events")]
234 | [System.ComponentModel.DisplayName(@"User Error Message")]
235 | [System.ComponentModel.Description(@"The User Error Message event class displays the error message as seen by the user in the case of an error or exception. The error message text appears in the TextData field.")]
236 | [System.ComponentModel.DefaultValue(false)]
237 | public bool UserErrorMessage { get; set; }
238 | [System.ComponentModel.Category(@"Events")]
239 | [System.ComponentModel.DisplayName(@"Blocked process report")]
240 | [System.ComponentModel.Description(@"The Blocked Process Report event class indicates that a task has been blocked for more than a specified amount of time. This event class does not include system tasks or tasks that are waiting on non deadlock-detectable resources.")]
241 | [System.ComponentModel.DefaultValue(false)]
242 | public bool BlockedProcessPeport { get; set; }
243 | [System.ComponentModel.Category(@"Events")]
244 | [System.ComponentModel.DisplayName(@"SQL:StmtStarting")]
245 | [System.ComponentModel.Description(@"The SQL:StmtStarting event class indicates that a Transact-SQL statement has started.")]
246 | [System.ComponentModel.DefaultValue(false)]
247 | public bool SQLStmtStarting { get; set; }
248 | [System.ComponentModel.Category(@"Events")]
249 | [System.ComponentModel.DisplayName(@"SQL:StmtCompleted")]
250 | [System.ComponentModel.Description(@"The SQL:StmtCompleted event class indicates that a Transact-SQL statement has completed. ")]
251 | [System.ComponentModel.DefaultValue(false)]
252 | public bool SQLStmtCompleted { get; set; }
253 |
254 |
255 |
256 |
257 | [System.ComponentModel.Category(@"Columns")]
258 | [System.ComponentModel.DisplayName(@"Start time")]
259 | [System.ComponentModel.Description(@"The time at which the event started, when available.")]
260 | [System.ComponentModel.DefaultValue(false)]
261 | public bool StartTime { get; set; }
262 | [System.ComponentModel.Category(@"Columns")]
263 | [System.ComponentModel.DisplayName(@"End time")]
264 | [System.ComponentModel.Description(@"The time at which the event ended. This column is not populated for event classes that refer to an event that is starting, such as SQL:BatchStarting or SP:Starting.")]
265 | [System.ComponentModel.DefaultValue(false)]
266 | public bool EndTime { get; set; }
267 | [System.ComponentModel.Category(@"Columns")]
268 | [System.ComponentModel.DisplayName(@"DatabaseName")]
269 | [System.ComponentModel.Description(@"The name of the database in which the user statement is running.")]
270 | [System.ComponentModel.DefaultValue(false)]
271 | public bool DatabaseName { get; set; }
272 | [System.ComponentModel.Category(@"Columns")]
273 | [System.ComponentModel.DisplayName(@"Application name")]
274 | [System.ComponentModel.Description(@"The name of the client application that created the connection to an instance of SQL Server. This column is populated with the values passed by the application and not the name of the program.")]
275 | [System.ComponentModel.DefaultValue(false)]
276 | public bool ApplicationName { get; set; }
277 | [System.ComponentModel.Category(@"Columns")]
278 | [System.ComponentModel.DisplayName(@"Object name")]
279 | [System.ComponentModel.Description(@"The name of the object that is referenced.")]
280 | [System.ComponentModel.DefaultValue(false)]
281 | public bool ObjectName { get; set; }
282 | [System.ComponentModel.Category(@"Columns")]
283 | [System.ComponentModel.DisplayName(@"Host name")]
284 | [System.ComponentModel.Description(@"Name of the client computer that originated the request.")]
285 | [System.ComponentModel.DefaultValue(false)]
286 | public bool HostName { get; set; }
287 |
288 | }
289 |
290 |
291 |
292 | [System.Serializable]
293 | public class TraceFilters
294 | {
295 |
296 | [System.ComponentModel.Category(@"CPU")]
297 | [System.ComponentModel.DisplayName(@"Condition")]
298 | public IntFilterCondition CpuFilterCondition { get; set; }
299 | [System.ComponentModel.Category(@"CPU")]
300 | [System.ComponentModel.DisplayName(@"Value")]
301 | public int? CPU { get; set; }
302 |
303 | [System.ComponentModel.Category(@"DatabaseName")]
304 | [System.ComponentModel.DisplayName(@"Condition")]
305 | public StringFilterCondition DatabaseNameFilterCondition { get; set; }
306 | [System.ComponentModel.Category(@"DatabaseName")]
307 | [System.ComponentModel.DisplayName(@"Value")]
308 | public string DatabaseName { get; set; }
309 |
310 | [System.ComponentModel.Category(@"Duration")]
311 | [System.ComponentModel.DisplayName(@"Condition")]
312 | public IntFilterCondition DurationFilterCondition { get; set; }
313 | [System.ComponentModel.Category(@"Duration")]
314 | [System.ComponentModel.DisplayName(@"Value")]
315 | public int? Duration { get; set; }
316 |
317 | [System.ComponentModel.Category(@"LoginName")]
318 | [System.ComponentModel.DisplayName(@"Condition")]
319 | public StringFilterCondition LoginNameFilterCondition { get; set; }
320 | [System.ComponentModel.Category(@"LoginName")]
321 | [System.ComponentModel.DisplayName(@"Value")]
322 | public string LoginName { get; set; }
323 |
324 | [System.ComponentModel.Category(@"HostName")]
325 | [System.ComponentModel.DisplayName(@"Condition")]
326 | public StringFilterCondition HostNameFilterCondition { get; set; }
327 | [System.ComponentModel.Category(@"HostName")]
328 | [System.ComponentModel.DisplayName(@"Value")]
329 | public string HostName { get; set; }
330 |
331 |
332 | [System.ComponentModel.Category(@"Reads")]
333 | [System.ComponentModel.DisplayName(@"Condition")]
334 | public IntFilterCondition ReadsFilterCondition { get; set; }
335 | [System.ComponentModel.Category(@"Reads")]
336 | [System.ComponentModel.DisplayName(@"Value")]
337 | public int? Reads { get; set; }
338 |
339 | [System.ComponentModel.Category(@"TextData")]
340 | [System.ComponentModel.DisplayName(@"Condition")]
341 | public StringFilterCondition TextDataFilterCondition { get; set; }
342 | [System.ComponentModel.Category(@"TextData")]
343 | [System.ComponentModel.DisplayName(@"Value")]
344 | public string TextData { get; set; }
345 |
346 | [System.ComponentModel.Category(@"Writes")]
347 | [System.ComponentModel.DisplayName(@"Condition")]
348 | public IntFilterCondition WritesFilterCondition { get; set; }
349 |
350 | [System.ComponentModel.Category(@"Writes")]
351 | [System.ComponentModel.DisplayName(@"Value")]
352 | public int? Writes { get; set; }
353 |
354 | [System.ComponentModel.Category(@"Maximum events count")]
355 | [System.ComponentModel.DisplayName(@"Maximum events count")]
356 | // [System.ComponentModel.DefaultValue(5000)]
357 | public int MaximumEventCount { get; set; }
358 |
359 | [System.ComponentModel.Category(@"SPID")]
360 | [System.ComponentModel.DisplayName(@"Condition")]
361 | public IntFilterCondition SPIDFilterCondition { get; set; }
362 | [System.ComponentModel.Category(@"SPID")]
363 | [System.ComponentModel.DisplayName(@"Value")]
364 | public int? SPID { get; set; }
365 |
366 | [System.ComponentModel.Category(@"ApplicationName")]
367 | [System.ComponentModel.DisplayName(@"Condition")]
368 | public StringFilterCondition ApplicationNameFilterCondition { get; set; }
369 | [System.ComponentModel.Category(@"ApplicationName")]
370 | [System.ComponentModel.DisplayName(@"Value")]
371 | public string ApplicationName { get; set; }
372 |
373 | }
374 |
375 | public TraceProperties()
376 | {
377 | // InitializeComponent();
378 | }
379 |
380 | public void SetSettings(TraceSettings st)
381 | {
382 | m_currentsettings = st;
383 | // edEvents.SelectedObject = m_currentsettings.EventsColumns;
384 | // edFilters.SelectedObject = m_currentsettings.Filters;
385 | }
386 |
387 | private void btnReset_Click(object sender, System.EventArgs e)
388 | {
389 | SetSettings(TraceSettings.GetDefaultSettings());
390 | }
391 |
392 | private void btnSaveAsDefault_Click(object sender, System.EventArgs e)
393 | {
394 | // Properties.Settings.Default.TraceSettings = m_currentsettings.GetAsXmlString();
395 | // Properties.Settings.Default.Save();
396 | }
397 |
398 |
399 | internal static bool AtLeastOneEventSelected(TraceSettings ts)
400 | {
401 | return ts.EventsColumns.BatchCompleted
402 | || ts.EventsColumns.BatchStarting
403 | || ts.EventsColumns.LoginLogout
404 | || ts.EventsColumns.ExistingConnection
405 | || ts.EventsColumns.RPCCompleted
406 | || ts.EventsColumns.RPCStarting
407 | || ts.EventsColumns.SPStmtCompleted
408 | || ts.EventsColumns.SPStmtStarting
409 | || ts.EventsColumns.UserErrorMessage
410 | || ts.EventsColumns.BlockedProcessPeport
411 | || ts.EventsColumns.SQLStmtStarting
412 | || ts.EventsColumns.SQLStmtCompleted;
413 |
414 | }
415 |
416 | private void btnRun_Click(object sender, System.EventArgs e)
417 | {
418 | if (!AtLeastOneEventSelected(m_currentsettings))
419 | {
420 | System.Console.WriteLine("Error Starting trace: You should select at least 1 event");
421 |
422 | // tabControl1.SelectedTab = tabPage2;
423 | return;
424 | }
425 | // DialogResult = DialogResult.OK;
426 | }
427 |
428 | /*
429 | public bool IsIncluded(ListViewItem lvi)
430 | {
431 | bool included = true;
432 |
433 | //Fragile here to hard coding the columns, but they are currently this way.
434 | included &= IsIncluded(m_currentsettings.Filters.ApplicationNameFilterCondition, m_currentsettings.Filters.ApplicationName, lvi.SubItems[0].Text);
435 | included &= IsIncluded(m_currentsettings.Filters.TextDataFilterCondition, m_currentsettings.Filters.TextData, lvi.SubItems[1].Text);
436 | included &= IsIncluded(m_currentsettings.Filters.LoginNameFilterCondition, m_currentsettings.Filters.LoginName, lvi.SubItems[2].Text);
437 | included &= IsIncluded(m_currentsettings.Filters.CpuFilterCondition, m_currentsettings.Filters.CPU, lvi.SubItems[3].Text);
438 | included &= IsIncluded(m_currentsettings.Filters.ReadsFilterCondition, m_currentsettings.Filters.Reads, lvi.SubItems[4].Text);
439 | included &= IsIncluded(m_currentsettings.Filters.WritesFilterCondition, m_currentsettings.Filters.Writes, lvi.SubItems[5].Text);
440 | included &= IsIncluded(m_currentsettings.Filters.DurationFilterCondition, m_currentsettings.Filters.Duration, lvi.SubItems[6].Text);
441 | included &= IsIncluded(m_currentsettings.Filters.SPIDFilterCondition, m_currentsettings.Filters.SPID, lvi.SubItems[7].Text);
442 |
443 | return included;
444 | }
445 | */
446 |
447 |
448 | private bool IsIncluded(StringFilterCondition filterCondition, string filter, string entryToCheck)
449 | {
450 | bool included = true; //Until removed. Negative logic is applied here.
451 | if (string.IsNullOrEmpty(filter) == false)
452 | {
453 | if (filterCondition == StringFilterCondition.Like)
454 | {
455 | if (entryToCheck.Contains(filter) == false)
456 | {
457 | included = false;
458 | }
459 | }
460 | else if (filterCondition == StringFilterCondition.NotLike)
461 | {
462 | if (entryToCheck.Contains(filter) == true)
463 | {
464 | included = false;
465 | }
466 | }
467 | }
468 | return included;
469 | }
470 |
471 |
472 | private bool IsIncluded(IntFilterCondition filterCondition, int? filter, string entryToCheck)
473 | {
474 | bool included = true; //Until removed. Negative logic is applied here.
475 |
476 | int intEntry;
477 | if ((int.TryParse(entryToCheck, out intEntry)) && (filter.HasValue))
478 | {
479 | if (filterCondition == IntFilterCondition.Equal)
480 | {
481 | if (filter != intEntry)
482 | {
483 | included = false;
484 | }
485 | }
486 | else if (filterCondition == IntFilterCondition.GreaterThan)
487 | {
488 | if (filter >= intEntry) // <= because we are using negative logic here.
489 | {
490 | included = false;
491 | }
492 | }
493 | else if (filterCondition == IntFilterCondition.LessThan)
494 | {
495 | if (filter <= intEntry) // >= because we are using negative logic here.
496 | {
497 | included = false;
498 | }
499 | }
500 | else if (filterCondition == IntFilterCondition.NotEqual)
501 | {
502 | if (filter == intEntry)
503 | {
504 | included = false;
505 | }
506 | }
507 | }
508 | return included;
509 | }
510 |
511 | #region IDisposable Support
512 | private bool disposedValue = false; // Dient zur Erkennung redundanter Aufrufe.
513 |
514 | protected virtual void Dispose(bool disposing)
515 | {
516 | if (!disposedValue)
517 | {
518 | if (disposing)
519 | {
520 | // TODO: verwalteten Zustand (verwaltete Objekte) entsorgen.
521 | }
522 |
523 | // TODO: nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalizer weiter unten überschreiben.
524 | // TODO: große Felder auf Null setzen.
525 |
526 | disposedValue = true;
527 | }
528 | }
529 |
530 | // TODO: Finalizer nur überschreiben, wenn Dispose(bool disposing) weiter oben Code für die Freigabe nicht verwalteter Ressourcen enthält.
531 | // ~TraceProperties() {
532 | // // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in Dispose(bool disposing) weiter oben ein.
533 | // Dispose(false);
534 | // }
535 |
536 | // Dieser Code wird hinzugefügt, um das Dispose-Muster richtig zu implementieren.
537 | void System.IDisposable.Dispose()
538 | {
539 | // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in Dispose(bool disposing) weiter oben ein.
540 | Dispose(true);
541 | // TODO: Auskommentierung der folgenden Zeile aufheben, wenn der Finalizer weiter oben überschrieben wird.
542 | // GC.SuppressFinalize(this);
543 | }
544 | #endregion
545 | }
546 | }
547 |
--------------------------------------------------------------------------------