diff options
author | Oleksii Kovalov <OleksiiKovalov@users.noreply.github.com> | 2012-08-28 22:02:40 +0000 |
---|---|---|
committer | Oleksii Kovalov <OleksiiKovalov@users.noreply.github.com> | 2012-08-28 22:02:40 +0000 |
commit | 696beec2540fff0cc613edc87f59f9d77bef9a82 (patch) | |
tree | fd504ab355bfe7bd17fb89556269c96489b3f092 | |
parent | e99031dc3eac1957b5e61d091ba582037efe252d (diff) | |
download | expressprofiler-696beec2540fff0cc613edc87f59f9d77bef9a82.zip expressprofiler-696beec2540fff0cc613edc87f59f9d77bef9a82.tar.gz expressprofiler-696beec2540fff0cc613edc87f59f9d77bef9a82.tar.bz2 |
[+] Initial checkin
19 files changed, 3659 insertions, 0 deletions
diff --git a/ExpressProfiler/ExpressProfiler.sln b/ExpressProfiler/ExpressProfiler.sln new file mode 100644 index 0000000..0f4c942 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler.sln @@ -0,0 +1,29 @@ +
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressProfiler", "ExpressProfiler\ExpressProfiler.csproj", "{74D3E3A1-9DBC-4880-841C-FA5583611A73}"
+EndProject
+Global
+ GlobalSection(TeamFoundationVersionControl) = preSolution
+ SccNumberOfProjects = 2
+ SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
+ SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs11
+ SccLocalPath0 = .
+ SccProjectUniqueName1 = ExpressProfiler\\ExpressProfiler.csproj
+ SccProjectName1 = ExpressProfiler
+ SccLocalPath1 = ExpressProfiler
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {74D3E3A1-9DBC-4880-841C-FA5583611A73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74D3E3A1-9DBC-4880-841C-FA5583611A73}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74D3E3A1-9DBC-4880-841C-FA5583611A73}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74D3E3A1-9DBC-4880-841C-FA5583611A73}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ExpressProfiler/ExpressProfiler.vssscc b/ExpressProfiler/ExpressProfiler.vssscc new file mode 100644 index 0000000..794f014 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler.vssscc @@ -0,0 +1,10 @@ +""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT"
+}
diff --git a/ExpressProfiler/ExpressProfiler/EventList.cs b/ExpressProfiler/ExpressProfiler/EventList.cs new file mode 100644 index 0000000..d7d4dc8 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/EventList.cs @@ -0,0 +1,195 @@ +//Traceutils assembly
+//writen by Locky, 2009.
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Serialization;
+
+namespace ExpressProfiler
+{
+ [Serializable]
+ public class CEvent
+ {
+ // ReSharper disable UnaccessedField.Global
+ // ReSharper disable FieldCanBeMadeReadOnly.Global
+ // ReSharper disable InconsistentNaming
+ // ReSharper disable MemberCanBePrivate.Global
+ [XmlAttribute]
+ public long EventClass;
+ [XmlAttribute]
+ public long DatabaseID;
+ [XmlAttribute]
+ public long ObjectID;
+ [XmlAttribute]
+ public long RowCounts;
+ public string TextData;
+ [XmlAttribute]
+ public string DatabaseName;
+ [XmlAttribute]
+ public string ObjectName;
+ [XmlAttribute]
+ public long Count, CPU, Reads, Writes, Duration, SPID, NestLevel;
+ // ReSharper restore MemberCanBePrivate.Global
+ // ReSharper restore InconsistentNaming
+ // ReSharper restore FieldCanBeMadeReadOnly.Global
+ // ReSharper restore UnaccessedField.Global
+
+ public long AvgCPU
+ {
+ get { return Count == 0 ? 0 : CPU/Count; }
+ }
+ public long AvgReads
+ {
+ get{ return Count == 0 ? 0 : Reads / Count;}
+ }
+ public long AvgWrites
+ {
+ get { return Count == 0 ? 0 : Writes / Count;}
+ }
+ public long AvgDuration
+ {
+ get { return Count == 0 ? 0 : Duration / Count; }
+ }
+
+
+ //needed for serialization
+// ReSharper disable UnusedMember.Global
+ public CEvent() { }
+// ReSharper restore UnusedMember.Global
+
+ public CEvent(long aDatabaseID, string aDatabaseName, long aObjectID, string aObjectName, string aTextData)
+ {
+ DatabaseID = aDatabaseID;
+ DatabaseName = aDatabaseName;
+ ObjectID = aObjectID;
+ ObjectName = aObjectName;
+ TextData = aTextData;
+ }
+
+ public CEvent(long eventClass,long spid, long nestLevel, long aDatabaseID, string aDatabaseName, long aObjectID, string aObjectName, string aTextData, long duration, long reads, long writes,long cpu)
+ {
+ EventClass = eventClass;
+ DatabaseID = aDatabaseID;
+ DatabaseName = aDatabaseName;
+ ObjectID = aObjectID;
+ ObjectName = aObjectName;
+ TextData = aTextData;
+ Duration = duration;
+ Reads = reads;
+ Writes = writes;
+ CPU = cpu;
+ SPID = spid;
+ NestLevel = nestLevel;
+ }
+
+ public string GetKey()
+ {
+ return String.Format("({0}).({1}).({2}).({3})", DatabaseID, ObjectID, ObjectName, TextData);
+ }
+ }
+
+ public class SimpleEventList
+ {
+ public readonly SortedDictionary<string,CEvent> List;
+
+ public SimpleEventList()
+ {
+ List = new SortedDictionary<string, CEvent>();
+ }
+
+ public void SaveToFile(string filename)
+ {
+ CEvent[] a = new CEvent[List.Count];
+ List.Values.CopyTo(a, 0);
+ XmlSerializer x = new XmlSerializer(typeof(CEvent[]));
+
+ FileStream fs = new FileStream(filename, FileMode.Create);
+ x.Serialize(fs, a);
+ fs.Dispose();
+
+ }
+ public void AddEvent(long eventClass, long nestLevel, long databaseID,string databaseName,long objectID,string objectName, string textData, long cpu, long reads, long writes, long duration,long count,long rowcounts)
+ {
+ CEvent evt;
+ string key = String.Format("({0}).({1}).({2})",databaseID,objectID,textData);
+ if(!List.TryGetValue(key,out evt))
+ {
+ evt = new CEvent(databaseID,databaseName,objectID,objectName,textData);
+ List.Add(key, evt);
+ }
+ evt.NestLevel = nestLevel;
+ evt.EventClass = eventClass;
+ evt.Count += count;
+ evt.CPU += cpu;
+ evt.Reads += reads;
+ evt.Writes += writes;
+ evt.Duration += duration;
+ evt.RowCounts += rowcounts;
+
+ }
+ }
+
+ public class CEventList
+ {
+ public readonly SortedDictionary<string, CEvent[]> EventList;
+ public CEventList() { EventList = new SortedDictionary<string, CEvent[]>(); }
+
+ public void AppendFromFile(int cnt, string filename, bool ignorenonamesp, bool transform)
+ {
+ XmlSerializer x = new XmlSerializer(typeof(CEvent[]));
+ FileStream fs = new FileStream(filename, FileMode.Open);
+ CEvent[] a = (CEvent[])x.Deserialize(fs);
+ YukonLexer lex = new YukonLexer();
+ foreach (CEvent e in a)
+ {
+ if (e.TextData.Contains("statman") || e.TextData.Contains("UPDATE STATISTICS")) continue;
+ if (!ignorenonamesp || e.ObjectName.Length != 0)
+ {
+ if (transform)
+ {
+
+ AddEvent(cnt, e.DatabaseID, e.DatabaseName
+ , e.ObjectName.Length == 0 ? 0 : e.ObjectID
+ , e.ObjectName.Length == 0 ? "" : e.ObjectName
+ , e.ObjectName.Length == 0 ?
+ lex.StandardSql(e.TextData) : e.TextData, e.CPU, e.Reads, e.Writes, e.Duration, e.Count,e.RowCounts);
+ }
+ else
+ {
+ AddEvent(cnt, e.DatabaseID, e.DatabaseName, e.ObjectID, e.ObjectName, e.TextData, e.CPU, e.Reads, e.Writes, e.Duration, e.Count,e.RowCounts);
+ }
+ }
+ }
+ fs.Dispose();
+
+ }
+
+ public void AddEvent(int cnt, long databaseID, string databaseName, long objectID, string objectName, string textData, long cpu, long reads, long writes, long duration, long count,long rowcounts)
+ {
+ CEvent[] evt;
+ CEvent e;
+ string key = String.Format("({0}).({1}).({2}).({3})", databaseID, objectID, objectName, textData);
+ if (!EventList.TryGetValue(key, out evt))
+ {
+ evt = new CEvent[2];
+ for (int k = 0; k < evt.Length; k++)
+ {
+ evt[k] = new CEvent(databaseID, databaseName, objectID, objectName, textData);
+ }
+ EventList.Add(key, evt);
+ e = evt[cnt];
+ }
+ else
+ {
+ e = evt[cnt];
+ }
+
+ e.Count += count;
+ e.CPU += cpu;
+ e.Reads += reads;
+ e.Writes += writes;
+ e.Duration += duration;
+ e.RowCounts += rowcounts;
+ }
+ }
+}
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj b/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj new file mode 100644 index 0000000..ee8c87d --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{74D3E3A1-9DBC-4880-841C-FA5583611A73}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ExpressProfiler</RootNamespace>
+ <AssemblyName>ExpressProfiler</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <StartupObject>ExpressProfiler.Program</StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="EventList.cs" />
+ <Compile Include="ListViewNF.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="MainForm.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="MainForm.Designer.cs">
+ <DependentUpon>MainForm.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="RawTraceReader.cs" />
+ <Compile Include="RtfBuilder.cs" />
+ <Compile Include="SqlTokens.cs" />
+ <Compile Include="YukonLexer.cs" />
+ <EmbeddedResource Include="MainForm.resx">
+ <DependentUpon>MainForm.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ <DesignTime>True</DesignTime>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <PropertyGroup>
+ <PostBuildEvent>
+ </PostBuildEvent>
+ </PropertyGroup>
+</Project>
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj.vspscc b/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj.vspscc new file mode 100644 index 0000000..feffdec --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/ExpressProfiler.csproj.vspscc @@ -0,0 +1,10 @@ +""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
diff --git a/ExpressProfiler/ExpressProfiler/ListViewNF.cs b/ExpressProfiler/ExpressProfiler/ListViewNF.cs new file mode 100644 index 0000000..678ca1e --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/ListViewNF.cs @@ -0,0 +1,26 @@ +using System.Windows.Forms;
+
+namespace ExpressProfiler
+{
+ class ListViewNF : ListView
+ {
+ public ListViewNF()
+ {
+ //Activate double buffering
+ this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
+
+ //Enable the OnNotifyMessage event so we get a chance to filter out
+ // Windows messages before they get to the form's WndProc
+ this.SetStyle(ControlStyles.EnableNotifyMessage, true);
+ }
+
+ protected override void OnNotifyMessage(Message m)
+ {
+ //Filter out the WM_ERASEBKGND message
+ if (m.Msg != 0x14)
+ {
+ base.OnNotifyMessage(m);
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/MainForm.Designer.cs b/ExpressProfiler/ExpressProfiler/MainForm.Designer.cs new file mode 100644 index 0000000..0b09e45 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/MainForm.Designer.cs @@ -0,0 +1,349 @@ +namespace ExpressProfiler
+{
+ partial class MainForm
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
+ this.statusStrip1 = new System.Windows.Forms.StatusStrip();
+ this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.tbStart = new System.Windows.Forms.ToolStripButton();
+ this.tbPause = new System.Windows.Forms.ToolStripButton();
+ this.tbStop = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.tbScroll = new System.Windows.Forms.ToolStripButton();
+ this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+ this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
+ this.edServer = new System.Windows.Forms.ToolStripTextBox();
+ this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel();
+ this.edUser = new System.Windows.Forms.ToolStripTextBox();
+ this.toolStripLabel3 = new System.Windows.Forms.ToolStripLabel();
+ this.edPassword = new System.Windows.Forms.ToolStripTextBox();
+ this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
+ this.cbSelectEvents = new System.Windows.Forms.ToolStripSplitButton();
+ this.mnExistingConnection = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnLoginLogout = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
+ this.mnRPCStarting = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnRPCCompleted = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
+ this.mnBatchStarting = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnBatchCompleted = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.reTextData = new System.Windows.Forms.RichTextBox();
+ this.timer1 = new System.Windows.Forms.Timer(this.components);
+ this.toolStrip1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // statusStrip1
+ //
+ this.statusStrip1.Location = new System.Drawing.Point(0, 488);
+ this.statusStrip1.Name = "statusStrip1";
+ this.statusStrip1.Size = new System.Drawing.Size(979, 22);
+ this.statusStrip1.TabIndex = 0;
+ this.statusStrip1.Text = "statusStrip1";
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.tbStart,
+ this.tbPause,
+ this.tbStop,
+ this.toolStripSeparator1,
+ this.tbScroll,
+ this.toolStripSeparator2,
+ this.toolStripLabel1,
+ this.edServer,
+ this.toolStripLabel2,
+ this.edUser,
+ this.toolStripLabel3,
+ this.edPassword,
+ this.toolStripSeparator3,
+ this.cbSelectEvents});
+ this.toolStrip1.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.Size = new System.Drawing.Size(979, 25);
+ this.toolStrip1.TabIndex = 1;
+ this.toolStrip1.Text = "toolStrip1";
+ //
+ // tbStart
+ //
+ this.tbStart.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.tbStart.Image = ((System.Drawing.Image)(resources.GetObject("tbStart.Image")));
+ this.tbStart.ImageTransparentColor = System.Drawing.Color.Transparent;
+ this.tbStart.Name = "tbStart";
+ this.tbStart.Size = new System.Drawing.Size(23, 22);
+ this.tbStart.Text = "Start trace";
+ this.tbStart.Click += new System.EventHandler(this.toolStripButton1_Click);
+ //
+ // tbPause
+ //
+ this.tbPause.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.tbPause.Image = ((System.Drawing.Image)(resources.GetObject("tbPause.Image")));
+ this.tbPause.ImageTransparentColor = System.Drawing.Color.Transparent;
+ this.tbPause.Name = "tbPause";
+ this.tbPause.Size = new System.Drawing.Size(23, 22);
+ this.tbPause.Text = "Pause trace";
+ this.tbPause.Click += new System.EventHandler(this.tbPause_Click);
+ //
+ // tbStop
+ //
+ this.tbStop.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.tbStop.Image = ((System.Drawing.Image)(resources.GetObject("tbStop.Image")));
+ this.tbStop.ImageTransparentColor = System.Drawing.Color.Transparent;
+ this.tbStop.Name = "tbStop";
+ this.tbStop.Size = new System.Drawing.Size(23, 22);
+ this.tbStop.Text = "Stop trace";
+ this.tbStop.Click += new System.EventHandler(this.toolStripButton2_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
+ //
+ // tbScroll
+ //
+ this.tbScroll.Checked = true;
+ this.tbScroll.CheckOnClick = true;
+ this.tbScroll.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.tbScroll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.tbScroll.Image = ((System.Drawing.Image)(resources.GetObject("tbScroll.Image")));
+ this.tbScroll.ImageTransparentColor = System.Drawing.Color.Transparent;
+ this.tbScroll.Name = "tbScroll";
+ this.tbScroll.Size = new System.Drawing.Size(23, 22);
+ this.tbScroll.Text = "Auto scroll window";
+ //
+ // toolStripSeparator2
+ //
+ this.toolStripSeparator2.Name = "toolStripSeparator2";
+ this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
+ //
+ // toolStripLabel1
+ //
+ this.toolStripLabel1.Name = "toolStripLabel1";
+ this.toolStripLabel1.Size = new System.Drawing.Size(39, 22);
+ this.toolStripLabel1.Text = "Server";
+ //
+ // edServer
+ //
+ this.edServer.Name = "edServer";
+ this.edServer.Size = new System.Drawing.Size(100, 25);
+ //
+ // toolStripLabel2
+ //
+ this.toolStripLabel2.Name = "toolStripLabel2";
+ this.toolStripLabel2.Size = new System.Drawing.Size(29, 22);
+ this.toolStripLabel2.Text = "User";
+ //
+ // edUser
+ //
+ this.edUser.Name = "edUser";
+ this.edUser.Size = new System.Drawing.Size(100, 25);
+ //
+ // toolStripLabel3
+ //
+ this.toolStripLabel3.Name = "toolStripLabel3";
+ this.toolStripLabel3.Size = new System.Drawing.Size(53, 22);
+ this.toolStripLabel3.Text = "Password";
+ //
+ // edPassword
+ //
+ this.edPassword.Name = "edPassword";
+ this.edPassword.Size = new System.Drawing.Size(100, 25);
+ //
+ // toolStripSeparator3
+ //
+ this.toolStripSeparator3.Name = "toolStripSeparator3";
+ this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25);
+ //
+ // cbSelectEvents
+ //
+ this.cbSelectEvents.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+ this.cbSelectEvents.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.mnExistingConnection,
+ this.mnLoginLogout,
+ this.toolStripMenuItem1,
+ this.mnRPCStarting,
+ this.mnRPCCompleted,
+ this.toolStripMenuItem2,
+ this.mnBatchStarting,
+ this.mnBatchCompleted,
+ this.toolStripMenuItem3});
+ this.cbSelectEvents.Image = ((System.Drawing.Image)(resources.GetObject("cbSelectEvents.Image")));
+ this.cbSelectEvents.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.cbSelectEvents.Name = "cbSelectEvents";
+ this.cbSelectEvents.Size = new System.Drawing.Size(60, 22);
+ this.cbSelectEvents.Text = "Options";
+ //
+ // mnExistingConnection
+ //
+ this.mnExistingConnection.Name = "mnExistingConnection";
+ this.mnExistingConnection.Size = new System.Drawing.Size(193, 22);
+ this.mnExistingConnection.Text = "Existing connections";
+ this.mnExistingConnection.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // mnLoginLogout
+ //
+ this.mnLoginLogout.Name = "mnLoginLogout";
+ this.mnLoginLogout.Size = new System.Drawing.Size(193, 22);
+ this.mnLoginLogout.Text = "Audit login/logout";
+ this.mnLoginLogout.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // toolStripMenuItem1
+ //
+ this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+ this.toolStripMenuItem1.Size = new System.Drawing.Size(190, 6);
+ //
+ // mnRPCStarting
+ //
+ this.mnRPCStarting.Name = "mnRPCStarting";
+ this.mnRPCStarting.Size = new System.Drawing.Size(193, 22);
+ this.mnRPCStarting.Text = "RPC:Starting";
+ this.mnRPCStarting.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // mnRPCCompleted
+ //
+ this.mnRPCCompleted.Checked = true;
+ this.mnRPCCompleted.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.mnRPCCompleted.Name = "mnRPCCompleted";
+ this.mnRPCCompleted.Size = new System.Drawing.Size(193, 22);
+ this.mnRPCCompleted.Text = "RPC:Completed";
+ this.mnRPCCompleted.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // toolStripMenuItem2
+ //
+ this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+ this.toolStripMenuItem2.Size = new System.Drawing.Size(190, 6);
+ //
+ // mnBatchStarting
+ //
+ this.mnBatchStarting.Name = "mnBatchStarting";
+ this.mnBatchStarting.Size = new System.Drawing.Size(193, 22);
+ this.mnBatchStarting.Text = "Batch:Starting";
+ this.mnBatchStarting.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // mnBatchCompleted
+ //
+ this.mnBatchCompleted.Checked = true;
+ this.mnBatchCompleted.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.mnBatchCompleted.Name = "mnBatchCompleted";
+ this.mnBatchCompleted.Size = new System.Drawing.Size(193, 22);
+ this.mnBatchCompleted.Text = "Batch:Completed";
+ this.mnBatchCompleted.Click += new System.EventHandler(this.existingConnectionsToolStripMenuItem_Click);
+ //
+ // toolStripMenuItem3
+ //
+ this.toolStripMenuItem3.Name = "toolStripMenuItem3";
+ this.toolStripMenuItem3.Size = new System.Drawing.Size(190, 6);
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 25);
+ this.splitContainer1.Name = "splitContainer1";
+ this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.reTextData);
+ this.splitContainer1.Size = new System.Drawing.Size(979, 463);
+ this.splitContainer1.SplitterDistance = 297;
+ this.splitContainer1.TabIndex = 4;
+ //
+ // reTextData
+ //
+ this.reTextData.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.reTextData.Location = new System.Drawing.Point(0, 0);
+ this.reTextData.Name = "reTextData";
+ this.reTextData.ReadOnly = true;
+ this.reTextData.Size = new System.Drawing.Size(979, 162);
+ this.reTextData.TabIndex = 4;
+ this.reTextData.Text = "";
+ //
+ // timer1
+ //
+ this.timer1.Interval = 250;
+ this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(979, 510);
+ this.Controls.Add(this.splitContainer1);
+ this.Controls.Add(this.toolStrip1);
+ this.Controls.Add(this.statusStrip1);
+ this.Name = "MainForm";
+ this.Text = "Express Profiler v1.0";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
+ this.Load += new System.EventHandler(this.MainForm_Load);
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ this.splitContainer1.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.StatusStrip statusStrip1;
+ private System.Windows.Forms.ToolStrip toolStrip1;
+ private System.Windows.Forms.ToolStripButton tbStart;
+ private System.Windows.Forms.ToolStripButton tbStop;
+ private System.Windows.Forms.SplitContainer splitContainer1;
+ private System.Windows.Forms.RichTextBox reTextData;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolStripButton tbScroll;
+ private System.Windows.Forms.ToolStripButton tbPause;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+ private System.Windows.Forms.Timer timer1;
+ private System.Windows.Forms.ToolStripLabel toolStripLabel1;
+ private System.Windows.Forms.ToolStripTextBox edServer;
+ private System.Windows.Forms.ToolStripLabel toolStripLabel2;
+ private System.Windows.Forms.ToolStripTextBox edUser;
+ private System.Windows.Forms.ToolStripLabel toolStripLabel3;
+ private System.Windows.Forms.ToolStripTextBox edPassword;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+ private System.Windows.Forms.ToolStripSplitButton cbSelectEvents;
+ private System.Windows.Forms.ToolStripMenuItem mnExistingConnection;
+ private System.Windows.Forms.ToolStripMenuItem mnLoginLogout;
+ private System.Windows.Forms.ToolStripMenuItem mnRPCStarting;
+ private System.Windows.Forms.ToolStripMenuItem mnRPCCompleted;
+ private System.Windows.Forms.ToolStripMenuItem mnBatchStarting;
+ private System.Windows.Forms.ToolStripMenuItem mnBatchCompleted;
+ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
+ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
+ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
+ }
+}
+
diff --git a/ExpressProfiler/ExpressProfiler/MainForm.cs b/ExpressProfiler/ExpressProfiler/MainForm.cs new file mode 100644 index 0000000..053d7c8 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/MainForm.cs @@ -0,0 +1,548 @@ +//sample application for demonstrating Sql Server Profiling
+//writen by Locky, 2009.
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.Threading;
+using System.Windows.Forms;
+
+
+namespace ExpressProfiler
+{
+ public partial class MainForm : Form
+ {
+ class EvtInfo
+ {
+ internal long Reads, Writes, Duration, Cpu, Count, LastDuration;
+ internal string TextData,Caption;
+ }
+ private enum ProfilingStateEnum { psStopped, psProfiling, psPaused }
+ private RawTraceReader m_Rdr;
+ delegate void OnNewEventArrivedDelegate (ProfilerEvent evt);
+ private readonly OnNewEventArrivedDelegate m_NewEventArriwedDelegate;
+ private readonly YukonLexer m_Lex = new YukonLexer();
+ private SqlConnection m_Conn;
+ private readonly SqlCommand m_Cmd = new SqlCommand();
+ private Thread m_Thr;
+ private bool m_NeedStop = true;
+ private ProfilingStateEnum m_ProfilingState ;
+ private int m_EventCount;
+ private readonly ProfilerEvent m_EventStarted = new ProfilerEvent();
+ private readonly ProfilerEvent m_EventStopped = new ProfilerEvent();
+ private readonly ProfilerEvent m_EventPaused = new ProfilerEvent();
+ private readonly List<ListViewItem> m_Cached = new List<ListViewItem>(1024);
+ private readonly Dictionary<string,ListViewItem> m_itembysql = new Dictionary<string, ListViewItem>();
+ private static readonly Dictionary<string, string> cursors = new Dictionary<string, string>(50);
+ private static readonly Dictionary<string, string> statements = new Dictionary<string, string>(50);
+ private string m_servername = "";
+ private string m_username = "";
+ private string m_userpassword = "";
+ private int m_maxEvents = 1000;
+ private ListViewNF lvEvents;
+ Queue<ProfilerEvent> m_events = new Queue<ProfilerEvent>(10);
+
+ public MainForm()
+ {
+ InitializeComponent();
+ InitLV();
+ Text = "Express Profiler v1.2";
+ ParseCommandLine();
+ edServer.Text = m_servername;
+ edUser.Text = m_username;
+ edPassword.Text = m_userpassword;
+ UpdateButtons();
+ }
+
+ private void ParseCommandLine()
+ {
+ string[] args = Environment.GetCommandLineArgs();
+ int i = 1;
+ while (i < args.Length)
+ {
+ string ep = i + 1 < args.Length ? args[i + 1] : "";
+ switch (args[i].ToLower())
+ {
+ case "-s":
+ case "-server":
+ m_servername = ep;
+ i++;
+ break;
+ case "-u":
+ case "-user":
+ m_username = ep;
+ i++;
+ break;
+ case "-p":
+ case "-password":
+ m_userpassword = ep;
+ i++;
+ break;
+ case "-m":
+ case "-maxevents":
+ if (!Int32.TryParse(ep, out m_maxEvents)) m_maxEvents = 1000;
+ break;
+ }
+ i++;
+ }
+
+ if (m_servername.Length == 0)
+ {
+ m_servername = @".\sqlexpress";
+ }
+
+
+ }
+
+ private void toolStripButton1_Click(object sender, EventArgs e)
+ {
+ StartProfiling();
+ }
+
+ private void UpdateButtons()
+ {
+ tbStart.Enabled = m_ProfilingState==ProfilingStateEnum.psStopped||m_ProfilingState==ProfilingStateEnum.psPaused;
+ tbStop.Enabled = m_ProfilingState==ProfilingStateEnum.psPaused||m_ProfilingState==ProfilingStateEnum.psProfiling;
+ tbPause.Enabled = m_ProfilingState == ProfilingStateEnum.psProfiling;
+ timer1.Enabled = m_ProfilingState == ProfilingStateEnum.psProfiling;
+ edServer.Enabled = m_ProfilingState == ProfilingStateEnum.psStopped;
+ edUser.Enabled = edServer.Enabled;
+ edPassword.Enabled = edServer.Enabled;
+ cbSelectEvents.Enabled = edServer.Enabled;
+ mnBatchStarting.Enabled = mnBatchCompleted.Enabled;
+ mnExistingConnection.Enabled = mnBatchCompleted.Enabled;
+ mnRPCCompleted.Enabled = mnBatchCompleted.Enabled;
+ mnLoginLogout.Enabled = mnBatchCompleted.Enabled;
+ mnRPCStarting.Enabled = mnBatchCompleted.Enabled;
+ }
+
+
+ private void InitLV()
+ {
+ lvEvents = new ListViewNF
+ {
+ Dock = DockStyle.Fill,
+ Location = new System.Drawing.Point(0, 0),
+ Name = "lvEvents",
+ Size = new System.Drawing.Size(979, 297),
+ TabIndex = 0,
+ VirtualMode = true,
+ UseCompatibleStateImageBehavior = false,
+ BorderStyle = BorderStyle.None,
+ FullRowSelect = true,
+ View = View.Details,
+ GridLines = true,
+ HideSelection = false,
+ MultiSelect = false,
+ AllowColumnReorder = false
+ };
+ lvEvents.RetrieveVirtualItem += lvEvents_RetrieveVirtualItem;
+ lvEvents.KeyDown += lvEvents_KeyDown;
+ lvEvents.ItemSelectionChanged += listView1_ItemSelectionChanged_1;
+ lvEvents.Columns.Add("Event Class", 122);
+ lvEvents.Columns.Add("Text Data", 255);
+ lvEvents.Columns.Add("Login Name", 79);
+ lvEvents.Columns.Add("CPU", 82).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("Reads", 78).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("Writes", 78).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("Duration", 82).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("SPID", 80);
+ lvEvents.Columns.Add("#", 53);
+ lvEvents.Columns.Add("Cnt", 53).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("Avg duration", 82).TextAlign = HorizontalAlignment.Right;
+ lvEvents.Columns.Add("Last duration", 82).TextAlign = HorizontalAlignment.Right;
+ lvEvents.ColumnClick += new ColumnClickEventHandler(lvEvents_ColumnClick);
+ splitContainer1.Panel1.Controls.Add(lvEvents);
+ }
+
+ void lvEvents_ColumnClick(object sender, ColumnClickEventArgs e)
+ {
+ }
+
+ private void SetLVItemInfo(ListViewItem lvi, EvtInfo i)
+ {
+ lvi.SubItems[3].Text = i.Cpu.ToString("#,0");
+ lvi.SubItems[4].Text = i.Reads.ToString("#,0");
+ lvi.SubItems[5].Text = i.Writes.ToString("#,0");
+ lvi.SubItems[6].Text = (i.Duration / 1000).ToString("#,0");
+ lvi.SubItems[9].Text = i.Count.ToString("#,0");
+ lvi.SubItems[10].Text = (i.Count == 0 ? "" : (i.Duration / 1000.0 / i.Count).ToString("#,0"));
+ lvi.SubItems[11].Text = (i.LastDuration / 1000).ToString("#,0"); ;
+ }
+
+ private void NewEventArrived(ProfilerEvent evt,bool last)
+ {
+ {
+ m_EventCount++;
+ string caption;
+ if(evt==m_EventStarted)
+ {
+ caption = "Trace started";
+ }
+ else
+ if(evt==m_EventPaused)
+ {
+ caption = "Trace paused";
+ }
+ else
+ if(evt==m_EventStopped)
+ {
+ caption = "Trace stopped";
+ }
+ else
+ {
+ caption = ProfilerEvents.Names[evt.EventClass];
+ }
+ ListViewItem lvi = new ListViewItem(caption);
+ string textData = evt.TextData;
+ lvi.SubItems.AddRange(
+ new[]
+ {
+
+ textData, evt.LoginName, evt.CPU.ToString(), evt.Reads.ToString()
+ , evt.Writes.ToString(), (evt.Duration/1000).ToString("#,0"), evt.SPID.ToString()
+ , m_EventCount.ToString(),"","",""
+ }
+ );
+ lvi.Tag = new ProfilerEvent();
+ m_Cached.Add(lvi);
+ if (last)
+ {
+ lvEvents.VirtualListSize = m_Cached.Count;
+ if (tbScroll.Checked)
+ {
+ lvEvents.Items[m_Cached.Count - 1].Focused = true;
+ lvEvents.Items[m_Cached.Count - 1].Selected = true;
+ listView1_ItemSelectionChanged_1(lvEvents, null);
+ lvEvents.EnsureVisible(m_Cached.Count - 1);
+ }
+
+ lvEvents.Invalidate(lvi.Bounds);
+ }
+ }
+ }
+
+ private void ProfilerThread(Object state)
+ {
+ while (!m_NeedStop&&m_Rdr.TraceIsActive)
+ {
+ ProfilerEvent evt = m_Rdr.Next();
+ if (evt != null)
+ {
+ lock(this)
+ {
+ m_events.Enqueue(evt);
+ }
+ }
+ }
+ }
+
+ private SqlConnection GetConnection()
+ {
+ return new SqlConnection
+ {
+ ConnectionString =
+ edUser.Text==""?String.Format(@"Data Source = {0}; Initial Catalog = master; Integrated Security=SSPI;Application Name=Express Profiler",edServer.Text)
+ : String.Format(@"Data Source={0};Initial Catalog=master;User Id={1};Password={2};;Application Name=Express Profiler", edServer.Text, edUser.Text, edPassword.Text)
+ };
+ }
+
+ private void StartProfiling()
+ {
+ if(m_ProfilingState==ProfilingStateEnum.psPaused)
+ {
+ ResumeProfiling();
+ return;
+ }
+ if(m_Conn!=null&&m_Conn.State==ConnectionState.Open)
+ {
+ m_Conn.Close();
+ }
+ m_EventCount = 0;
+ m_Conn = GetConnection();
+ m_Conn.Open();
+ m_Rdr = new RawTraceReader(m_Conn);
+
+ m_Rdr.CreateTrace();
+ if (true)
+ {
+ if (mnLoginLogout.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.SecurityAudit.AuditLogin,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
+ ProfilerEventColumns.SPID);
+ }
+
+ if (mnExistingConnection.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.Sessions.ExistingConnection,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.SPID);
+ }
+ if (mnBatchCompleted.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.TSQL.SQLBatchCompleted,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
+ ProfilerEventColumns.CPU, ProfilerEventColumns.Reads,
+ ProfilerEventColumns.Writes, ProfilerEventColumns.Duration,
+ ProfilerEventColumns.SPID,
+ ProfilerEventColumns.StartTime);
+ }
+ if (mnBatchStarting.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.TSQL.SQLBatchStarting,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
+ ProfilerEventColumns.SPID);
+ }
+ if (mnRPCStarting.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.StoredProcedures.RPCStarting,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
+ ProfilerEventColumns.SPID);
+ }
+ }
+ if (mnRPCCompleted.Checked)
+ {
+ m_Rdr.SetEvent(ProfilerEvents.StoredProcedures.RPCCompleted,
+ ProfilerEventColumns.TextData, ProfilerEventColumns.LoginName,
+ ProfilerEventColumns.CPU, ProfilerEventColumns.Reads,
+ ProfilerEventColumns.Writes, ProfilerEventColumns.Duration,
+ ProfilerEventColumns.SPID);
+ }
+ m_Cmd.Connection = m_Conn;
+ m_Cmd.CommandTimeout = 0;
+ m_Rdr.SetFilter(ProfilerEventColumns.ApplicationName, LogicalOperators.AND, ComparisonOperators.NotLike, "Express Profiler");
+ m_Cached.Clear();
+ m_events.Clear();
+ m_itembysql.Clear();
+ lvEvents.VirtualListSize = 0;
+ StartProfilerThread();
+ UpdateButtons();
+ }
+
+ private void StartProfilerThread()
+ {
+ if(m_Rdr!=null)
+ {
+ m_Rdr.Close();
+ }
+ m_Rdr.StartTrace();
+ m_Thr = new Thread(ProfilerThread) {IsBackground = true, Priority = ThreadPriority.Lowest};
+ m_NeedStop = false;
+ m_ProfilingState = ProfilingStateEnum.psProfiling;
+ NewEventArrived(m_EventStarted,true);
+ m_Thr.Start();
+ }
+
+ private void ResumeProfiling()
+ {
+ StartProfilerThread();
+ UpdateButtons();
+ }
+
+ private void toolStripButton2_Click(object sender, EventArgs e)
+ {
+ StopProfiling();
+ }
+
+ private void StopProfiling()
+ {
+ tbStop.Enabled = false;
+ using (SqlConnection cn = GetConnection())
+ {
+ cn.Open();
+ m_Rdr.StopTrace(cn);
+ m_Rdr.CloseTrace(cn);
+ cn.Close();
+ }
+ m_NeedStop = true;
+ if (m_Thr.IsAlive)
+ {
+ m_Thr.Abort();
+ }
+ m_Thr.Join();
+ m_ProfilingState = ProfilingStateEnum.psStopped;
+ NewEventArrived(m_EventStopped,true);
+ UpdateButtons();
+ }
+
+ private void listView1_ItemSelectionChanged_1(object sender, ListViewItemSelectionChangedEventArgs e)
+ {
+ ListViewItem lvi = lvEvents.FocusedItem;
+ if (lvi == null)
+ {
+ reTextData.Text = "";
+ }
+ else
+ {
+ m_Lex.FillRichEdit(reTextData, lvi.SubItems[1].Text);
+ }
+
+ }
+
+ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ if(m_ProfilingState==ProfilingStateEnum.psPaused||m_ProfilingState==ProfilingStateEnum.psProfiling)
+ {
+ StopProfiling();
+ }
+ }
+
+ private void lvEvents_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
+ {
+ e.Item = m_Cached[e.ItemIndex];
+ }
+
+ private void tbPause_Click(object sender, EventArgs e)
+ {
+ PauseProfiling();
+ }
+
+ private void PauseProfiling()
+ {
+ using (SqlConnection cn = GetConnection())
+ {
+ cn.Open();
+ m_Rdr.StopTrace(cn);
+ cn.Close();
+ }
+ m_ProfilingState = ProfilingStateEnum.psPaused;
+ NewEventArrived(m_EventPaused,true);
+ UpdateButtons();
+ }
+
+ private void lvEvents_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Control &&e.Shift && e.KeyCode == Keys.Delete)
+ {
+ lock (lvEvents)
+ {
+ m_Cached.Clear();
+ m_itembysql.Clear();
+ lvEvents.VirtualListSize = 0;
+ listView1_ItemSelectionChanged_1(lvEvents, null);
+ lvEvents.Invalidate();
+ }
+ }
+ }
+
+ private void MainForm_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private void toolStripButton1_Click_1(object sender, EventArgs e)
+ {
+
+ }
+
+ private class EventComparer:IComparer<EvtInfo>
+ {
+ private readonly int m_idx;
+ public EventComparer(int idx)
+ {
+ m_idx = idx;
+ }
+
+ public int Compare(EvtInfo x, EvtInfo y)
+ {
+ double xa, ya;
+ switch (m_idx)
+ {
+ case 4:
+ xa = x.Reads;
+ ya = y.Reads;
+ break;
+ case 5:
+ xa = x.Writes;
+ ya = y.Writes;
+ break;
+ case 6:
+ xa = x.Duration;
+ ya = y.Duration;
+ break;
+ case 9:
+ xa = x.Count;
+ ya = y.Count;
+ break;
+ case 10:
+ xa = x.Count == 0 ? 0 : (x.Duration*1.0 / x.Count);
+ ya = y.Count == 0 ? 0 : (y.Duration*1.0 / y.Count);
+ break;
+ default:
+ return 0;
+ }
+ return xa == ya ? String.Compare(x.TextData,y.TextData) : (xa > ya ? -1 : 1);
+ }
+
+ }
+
+
+ private void Resort(int idx)
+ {
+ lock (m_Cached)
+ {
+ List<EvtInfo> lst = new List<EvtInfo>(m_itembysql.Count);
+ foreach (ListViewItem lvi in m_itembysql.Values)
+ {
+ lst.Add((EvtInfo)lvi.Tag);
+ }
+ lst.Sort(new EventComparer(idx));
+ lvEvents.Items.Clear();
+ m_Cached.Clear();
+ m_itembysql.Clear();
+
+ foreach(EvtInfo evt in lst)
+ {
+ ListViewItem lvi = new ListViewItem("");
+ m_itembysql[evt.TextData] = lvi;
+ lvi.SubItems.AddRange(
+ new[]
+ {
+
+ evt.TextData, "", evt.Cpu.ToString(), evt.Reads.ToString()
+ , evt.Writes.ToString(), (evt.Duration/1000).ToString("#,0"), ""
+ , "","1",(evt.Duration/1000).ToString("#,0"),(evt.Duration/1000).ToString("#,0")
+ }
+ );
+ m_Cached.Add(lvi);
+ lvi.Tag = evt;
+ SetLVItemInfo(lvi,evt);
+ }
+ lvEvents.Invalidate();
+ }
+ }
+
+ private void timer1_Tick(object sender, EventArgs e)
+ {
+ Queue<ProfilerEvent> saved;
+ lock (this)
+ {
+ saved = m_events;
+ m_events = new Queue<ProfilerEvent>(10);
+ }
+ lock (m_Cached)
+ {
+ while (0 != saved.Count)
+ {
+ NewEventArrived(saved.Dequeue(), 0 == saved.Count);
+ }
+ if (m_Cached.Count > m_maxEvents)
+ {
+ while (m_Cached.Count > m_maxEvents)
+ {
+ m_Cached.RemoveAt(0);
+ }
+ lvEvents.VirtualListSize = m_Cached.Count;
+ lvEvents.Invalidate();
+ }
+ }
+ }
+
+ private void existingConnectionsToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ (sender as ToolStripMenuItem).Checked = !(sender as ToolStripMenuItem).Checked;
+ UpdateButtons();
+ }
+ }
+}
diff --git a/ExpressProfiler/ExpressProfiler/MainForm.resx b/ExpressProfiler/ExpressProfiler/MainForm.resx new file mode 100644 index 0000000..9a82cb1 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/MainForm.resx @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </metadata>
+ <metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>127, 17</value>
+ </metadata>
+ <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+ <data name="tbStart.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABqSURBVDhPY2AYlGDKzLz/FDns3LUd/1t64sk3ZMrqiv/n
+ vu8l3xCQAVPu9ZBvyNwpdWADYJhk74BdAHWF/2yn/yBcke1GfJjADCBLMyj6QAaQrRnZAJKcjZxwQIFG
+ tmaQQRRppigJD4hmAP9qXIqBzBMfAAAAAElFTkSuQmCC
+</value>
+ </data>
+ <data name="tbPause.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACDSURBVDhPY2AYfkDBa9p/6+TN/1lMO/7DfAdig8RdUlfD
+ xXD6HKSwZ87//yJOk+GKQWyQmFbgfOIMqOx7gmEASIxoA5Lqz2EYABIDuY5gpIEUeWTvxAgDkBjRBmAL
+ RJAY0QaAFGKLBeSAxekVkCKwZtU8hH+BbJAYUdFIMJBGFWCEAADFoWPyjsXXjgAAAABJRU5ErkJggg==
+</value>
+ </data>
+ <data name="tbStop.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABoSURBVDhPY2AYnmCDgcX/g85ucAziwzBRPgZpfl5WhoHv
+ ZWf/J8qAy+ERWDUTbQC6C0AawTg5mTgXIBuA0Jz9/xqpBiDbDLId5DWiwgDkAmTNIJuvRZFjQDLE2TDN
+ RLuAKGeOKoKHAADj6ZD8b/5D1wAAAABJRU5ErkJggg==
+</value>
+ </data>
+ <data name="tbScroll.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFXSURBVDhPY2CgFuhY8fI/Oi6d8/J/xpQ3/zN6H/4Pbbv/
+ 37/6/n/b4idgjGEvSPOqoz//T9vxF47bVv/5D8LVS3/9z5v9HY49Sm5iGtC59Q/YBVPWPvkPshlsOxab
+ QbabpZzCNGDx1nOYglB3fv/+//97IH4GJO49+/7fyisbtwH7z977D8Mg/duPXv+/de+1/2v2XAcbsHXf
+ GfwGoAcOuu3rth4l7AKQrSAM0gyyeS3Qe8jhAgqbpHo0L6OHAbrNlX1P4LEEihmv4oOo4bB07VGwALqf
+ QQZPXX0ZHCOgKAZFadS07/+tkzejGjBn6X6wwIsXL/7fuPcGjM9fewIO0N3nXoGdDLIZpNmn9RemAVOW
+ bv1v6JWMgZH9DrMdlCK1AudjGoIrW4D8C0uJoCTtVXwOrBlkCNFZySBsAzg/gJKxR/ZO0jTDbAEZAkrG
+ JNmM7kSQIchiAA9vkk6XhwD1AAAAAElFTkSuQmCC
+</value>
+ </data>
+ <data name="cbSelectEvents.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI
+ ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9
+ HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN
+ rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K
+ TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx
+ oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8
+ 7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI
+ xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX
+ LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd
+ KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC
+</value>
+ </data>
+ <metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>226, 17</value>
+ </metadata>
+</root>
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/Program.cs b/ExpressProfiler/ExpressProfiler/Program.cs new file mode 100644 index 0000000..3a1d207 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Program.cs @@ -0,0 +1,19 @@ +using System;
+using System.Windows.Forms;
+
+namespace ExpressProfiler
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+ }
+}
diff --git a/ExpressProfiler/ExpressProfiler/Properties/AssemblyInfo.cs b/ExpressProfiler/ExpressProfiler/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ef1d24e --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Express Profiler")]
+[assembly: AssemblyDescription("Profiler for SqlExpress, restricted demo version")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Express Profiler")]
+[assembly: AssemblyCopyright("Copyright © Locky 2009-2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a4b41009-adb3-41bd-8e10-f3d6005d761a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.2.*")]
+[assembly: AssemblyFileVersion("1.2")]
diff --git a/ExpressProfiler/ExpressProfiler/Properties/Resources.Designer.cs b/ExpressProfiler/ExpressProfiler/Properties/Resources.Designer.cs new file mode 100644 index 0000000..82492c1 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.488
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ExpressProfiler.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ExpressProfiler.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/ExpressProfiler/ExpressProfiler/Properties/Resources.resx b/ExpressProfiler/ExpressProfiler/Properties/Resources.resx new file mode 100644 index 0000000..ffecec8 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Properties/Resources.resx @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/Properties/Settings.Designer.cs b/ExpressProfiler/ExpressProfiler/Properties/Settings.Designer.cs new file mode 100644 index 0000000..a474bf4 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.488
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ExpressProfiler.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/ExpressProfiler/ExpressProfiler/Properties/Settings.settings b/ExpressProfiler/ExpressProfiler/Properties/Settings.settings new file mode 100644 index 0000000..abf36c5 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/Properties/Settings.settings @@ -0,0 +1,7 @@ +<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/ExpressProfiler/ExpressProfiler/RawTraceReader.cs b/ExpressProfiler/ExpressProfiler/RawTraceReader.cs new file mode 100644 index 0000000..5b200c4 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/RawTraceReader.cs @@ -0,0 +1,1250 @@ +//Traceutils assembly
+//writen by Locky, 2009.
+using System;
+using System.Data;
+using System.Data.Common;
+using System.Data.SqlClient;
+using System.Text;
+
+namespace ExpressProfiler
+{
+ // ReSharper disable UnusedMember.Global
+ // ReSharper disable InconsistentNaming
+
+ public static class ComparisonOperators
+ {
+ public const int Equal = 0;
+ public const int NotEqual = 1;
+ public const int GreaterThan = 2;
+ public const int LessThan = 3;
+ public const int GreaterThanOrEqual = 4;
+ public const int LessThanOrEqual = 5;
+ public const int Like = 6;
+ public const int NotLike = 7;
+ }
+
+ public static class LogicalOperators
+ {
+ public const int AND = 0;
+ public const int OR = 1;
+ }
+
+ public static class ProfilerEvents
+ {
+
+ /*
+ select 'public static class '+replace(name,' ','')+'
+ {
+ }
+
+ '
+ from sys.trace_categories
+ order by category_id
+
+
+ select '/ *'+sc.name+'* / '+'public const int '+replace(replace(ev.name,' ',''),':','')+' = '+cast(trace_event_id as varchar)+';'
+ from sys.trace_categories sc inner join sys.trace_events ev on sc.category_id = ev.category_id
+ order by sc.category_id,ev.trace_event_id
+ */
+// ReSharper disable RedundantExplicitArraySize
+ public static readonly string[] Names = new string[202]
+// ReSharper restore RedundantExplicitArraySize
+ {
+ ""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,"RPC:Completed"
+ ,"RPC:Starting"
+ ,"SQL:BatchCompleted"
+ ,"SQL:BatchStarting"
+ ,"Audit Login"
+ ,"Audit Logout"
+ ,"Attention"
+ ,"ExistingConnection"
+ ,"Audit Server Starts And Stops"
+ ,"DTCTransaction"
+ ,"Audit Login Failed"
+ ,"EventLog"
+ ,"ErrorLog"
+ ,"Lock:Released"
+ ,"Lock:Acquired"
+ ,"Lock:Deadlock"
+ ,"Lock:Cancel"
+ ,"Lock:Timeout"
+ ,"Degree of Parallelism (7.0 Insert)"
+ ,""
+ ,""
+ ,""
+ ,""
+ ,"Exception"
+ ,"SP:CacheMiss"
+ ,"SP:CacheInsert"
+ ,"SP:CacheRemove"
+ ,"SP:Recompile"
+ ,"SP:CacheHit"
+ ,"Deprecated"
+ ,"SQL:StmtStarting"
+ ,"SQL:StmtCompleted"
+ ,"SP:Starting"
+ ,"SP:Completed"
+ ,"SP:StmtStarting"
+ ,"SP:StmtCompleted"
+ ,"Object:Created"
+ ,"Object:Deleted"
+ ,""
+ ,""
+ ,"SQLTransaction"
+ ,"Scan:Started"
+ ,"Scan:Stopped"
+ ,"CursorOpen"
+ ,"TransactionLog"
+ ,"Hash Warning"
+ ,""
+ ,""
+ ,"Auto Stats"
+ ,"Lock:Deadlock Chain"
+ ,"Lock:Escalation"
+ ,"OLEDB Errors"
+ ,""
+ ,""
+ ,""
+ ,""
+ ,""
+ ,"Execution Warnings"
+ ,"Showplan Text (Unencoded)"
+ ,"Sort Warnings"
+ ,"CursorPrepare"
+ ,"Prepare SQL"
+ ,"Exec Prepared SQL"
+ ,"Unprepare SQL"
+ ,"CursorExecute"
+ ,"CursorRecompile"
+ ,"CursorImplicitConversion"
+ ,"CursorUnprepare"
+ ,"CursorClose"
+ ,"Missing Column Statistics"
+ ,"Missing Join Predicate"
+ ,"Server Memory Change"
+ ,"UserConfigurable:0"
+ ,"UserConfigurable:1"
+ ,"UserConfigurable:2"
+ ,"UserConfigurable:3"
+ ,"UserConfigurable:4"
+ ,"UserConfigurable:5"
+ ,"UserConfigurable:6"
+ ,"UserConfigurable:7"
+ ,"UserConfigurable:8"
+ ,"UserConfigurable:9"
+ ,"Data File Auto Grow"
+ ,"Log File Auto Grow"
+ ,"Data File Auto Shrink"
+ ,"Log File Auto Shrink"
+ ,"Showplan Text"
+ ,"Showplan All"
+ ,"Showplan Statistics Profile"
+ ,""
+ ,"RPC Output Parameter"
+ ,""
+ ,"Audit Database Scope GDR Event"
+ ,"Audit Schema Object GDR Event"
+ ,"Audit Addlogin Event"
+ ,"Audit Login GDR Event"
+ ,"Audit Login Change Property Event"
+ ,"Audit Login Change Password Event"
+ ,"Audit Add Login to Server Role Event"
+ ,"Audit Add DB User Event"
+ ,"Audit Add Member to DB Role Event"
+ ,"Audit Add Role Event"
+ ,"Audit App Role Change Password Event"
+ ,"Audit Statement Permission Event"
+ ,"Audit Schema Object Access Event"
+ ,"Audit Backup/Restore Event"
+ ,"Audit DBCC Event"
+ ,"Audit Change Audit Event"
+ ,"Audit Object Derived Permission Event"
+ ,"OLEDB Call Event"
+ ,"OLEDB QueryInterface Event"
+ ,"OLEDB DataRead Event"
+ ,"Showplan XML"
+ ,"SQL:FullTextQuery"
+ ,"Broker:Conversation"
+ ,"Deprecation Announcement"
+ ,"Deprecation Final Support"
+ ,"Exchange Spill Event"
+ ,"Audit Database Management Event"
+ ,"Audit Database Object Management Event"
+ ,"Audit Database Principal Management Event"
+ ,"Audit Schema Object Management Event"
+ ,"Audit Server Principal Impersonation Event"
+ ,"Audit Database Principal Impersonation Event"
+ ,"Audit Server Object Take Ownership Event"
+ ,"Audit Database Object Take Ownership Event"
+ ,"Broker:Conversation Group"
+ ,"Blocked process report"
+ ,"Broker:Connection"
+ ,"Broker:Forwarded Message Sent"
+ ,"Broker:Forwarded Message Dropped"
+ ,"Broker:Message Classify"
+ ,"Broker:Transmission"
+ ,"Broker:Queue Disabled"
+ ,"Broker:Mirrored Route State Changed"
+ ,""
+ ,"Showplan XML Statistics Profile"
+ ,""
+ ,"Deadlock graph"
+ ,"Broker:Remote Message Acknowledgement"
+ ,"Trace File Close"
+ ,""
+ ,"Audit Change Database Owner"
+ ,"Audit Schema Object Take Ownership Event"
+ ,""
+ ,"FT:Crawl Started"
+ ,"FT:Crawl Stopped"
+ ,"FT:Crawl Aborted"
+ ,"Audit Broker Conversation"
+ ,"Audit Broker Login"
+ ,"Broker:Message Undeliverable"
+ ,"Broker:Corrupted Message"
+ ,"User Error Message"
+ ,"Broker:Activation"
+ ,"Object:Altered"
+ ,"Performance statistics"
+ ,"SQL:StmtRecompile"
+ ,"Database Mirroring State Change"
+ ,"Showplan XML For Query Compile"
+ ,"Showplan All For Query Compile"
+ ,"Audit Server Scope GDR Event"
+ ,"Audit Server Object GDR Event"
+ ,"Audit Database Object GDR Event"
+ ,"Audit Server Operation Event"
+ ,""
+ ,"Audit Server Alter Trace Event"
+ ,"Audit Server Object Management Event"
+ ,"Audit Server Principal Management Event"
+ ,"Audit Database Operation Event"
+ ,""
+ ,"Audit Database Object Access Event"
+ ,"TM: Begin Tran starting"
+ ,"TM: Begin Tran completed"
+ ,"TM: Promote Tran starting"
+ ,"TM: Promote Tran completed"
+ ,"TM: Commit Tran starting"
+ ,"TM: Commit Tran completed"
+ ,"TM: Rollback Tran starting"
+ ,"TM: Rollback Tran completed"
+ ,"Lock:Timeout (timeout > 0)"
+ ,"Progress Report: Online Index Operation"
+ ,"TM: Save Tran starting"
+ ,"TM: Save Tran completed"
+ ,"Background Job Error"
+ ,"OLEDB Provider Information"
+ ,"Mount Tape"
+ ,"Assembly Load"
+ ,""
+ ,"XQuery Static Type"
+ ,"QN: Subscription"
+ ,"QN: Parameter table"
+ ,"QN: Template"
+
+ }
+ ;
+ public static class Cursors
+ {
+ /*Cursors*/
+ public const int CursorOpen = 53;
+ /*Cursors*/
+ public const int CursorPrepare = 70;
+ /*Cursors*/
+ public const int CursorExecute = 74;
+ /*Cursors*/
+ public const int CursorRecompile = 75;
+ /*Cursors*/
+ public const int CursorImplicitConversion = 76;
+ /*Cursors*/
+ public const int CursorUnprepare = 77;
+ /*Cursors*/
+ public const int CursorClose = 78;
+ }
+
+ public static class Database
+ {
+ /*Database*/
+ public const int DataFileAutoGrow = 92;
+ /*Database*/
+ public const int LogFileAutoGrow = 93;
+ /*Database*/
+ public const int DataFileAutoShrink = 94;
+ /*Database*/
+ public const int LogFileAutoShrink = 95;
+ /*Database*/
+ public const int DatabaseMirroringStateChange = 167;
+ }
+
+ public static class ErrorsAndWarnings
+ {
+ /*Errors and Warnings*/
+ public const int Attention = 16;
+ /*Errors and Warnings*/
+ public const int EventLog = 21;
+ /*Errors and Warnings*/
+ public const int ErrorLog = 22;
+ /*Errors and Warnings*/
+ public const int Exception = 33;
+ /*Errors and Warnings*/
+ public const int HashWarning = 55;
+ /*Errors and Warnings*/
+ public const int ExecutionWarnings = 67;
+ /*Errors and Warnings*/
+ public const int SortWarnings = 69;
+ /*Errors and Warnings*/
+ public const int MissingColumnStatistics = 79;
+ /*Errors and Warnings*/
+ public const int MissingJoinPredicate = 80;
+ /*Errors and Warnings*/
+ public const int ExchangeSpillEvent = 127;
+ /*Errors and Warnings*/
+ public const int Blockedprocessreport = 137;
+ /*Errors and Warnings*/
+ public const int UserErrorMessage = 162;
+ /*Errors and Warnings*/
+ public const int BackgroundJobError = 193;
+ }
+
+ public static class Locks
+ {
+ /*Locks*/
+ public const int LockReleased = 23;
+ /*Locks*/
+ public const int LockAcquired = 24;
+ /*Locks*/
+ public const int LockDeadlock = 25;
+ /*Locks*/
+ public const int LockCancel = 26;
+ /*Locks*/
+ public const int LockTimeout = 27;
+ /*Locks*/
+ public const int LockDeadlockChain = 59;
+ /*Locks*/
+ public const int LockEscalation = 60;
+ /*Locks*/
+ public const int Deadlockgraph = 148;
+ /*Locks*/
+ public const int LockTimeout100 = 189;
+ }
+
+ public static class Objects
+ {
+ /*Objects*/
+ public const int ObjectCreated = 46;
+ /*Objects*/
+ public const int ObjectDeleted = 47;
+ /*Objects*/
+ public const int ObjectAltered = 164;
+ }
+
+ public static class Performance
+ {
+ /*Performance*/
+ public const int DegreeofParallelism70Insert = 28;
+ /*Performance*/
+ public const int AutoStats = 58;
+ /*Performance*/
+ public const int ShowplanTextUnencoded = 68;
+ /*Performance*/
+ public const int ShowplanText = 96;
+ /*Performance*/
+ public const int ShowplanAll = 97;
+ /*Performance*/
+ public const int ShowplanStatisticsProfile = 98;
+ /*Performance*/
+ public const int ShowplanXML = 122;
+ /*Performance*/
+ public const int SQLFullTextQuery = 123;
+ /*Performance*/
+ public const int ShowplanXMLStatisticsProfile = 146;
+ /*Performance*/
+ public const int Performancestatistics = 165;
+ /*Performance*/
+ public const int ShowplanXMLForQueryCompile = 168;
+ /*Performance*/
+ public const int ShowplanAllForQueryCompile = 169;
+ }
+
+ public static class Scans
+ {
+ /*Scans*/
+ public const int ScanStarted = 51;
+ /*Scans*/
+ public const int ScanStopped = 52;
+ }
+
+ public static class SecurityAudit
+ {
+ /*Security Audit*/
+ public const int AuditLogin = 14;
+ /*Security Audit*/
+ public const int AuditLogout = 15;
+ /*Security Audit*/
+ public const int AuditServerStartsAndStops = 18;
+ /*Security Audit*/
+ public const int AuditLoginFailed = 20;
+ /*Security Audit*/
+ public const int AuditDatabaseScopeGDREvent = 102;
+ /*Security Audit*/
+ public const int AuditSchemaObjectGDREvent = 103;
+ /*Security Audit*/
+ public const int AuditAddloginEvent = 104;
+ /*Security Audit*/
+ public const int AuditLoginGDREvent = 105;
+ /*Security Audit*/
+ public const int AuditLoginChangePropertyEvent = 106;
+ /*Security Audit*/
+ public const int AuditLoginChangePasswordEvent = 107;
+ /*Security Audit*/
+ public const int AuditAddLogintoServerRoleEvent = 108;
+ /*Security Audit*/
+ public const int AuditAddDBUserEvent = 109;
+ /*Security Audit*/
+ public const int AuditAddMembertoDBRoleEvent = 110;
+ /*Security Audit*/
+ public const int AuditAddRoleEvent = 111;
+ /*Security Audit*/
+ public const int AuditAppRoleChangePasswordEvent = 112;
+ /*Security Audit*/
+ public const int AuditStatementPermissionEvent = 113;
+ /*Security Audit*/
+ public const int AuditSchemaObjectAccessEvent = 114;
+ /*Security Audit*/
+ public const int AuditBackupRestoreEvent = 115;
+ /*Security Audit*/
+ public const int AuditDBCCEvent = 116;
+ /*Security Audit*/
+ public const int AuditChangeAuditEvent = 117;
+ /*Security Audit*/
+ public const int AuditObjectDerivedPermissionEvent = 118;
+ /*Security Audit*/
+ public const int AuditDatabaseManagementEvent = 128;
+ /*Security Audit*/
+ public const int AuditDatabaseObjectManagementEvent = 129;
+ /*Security Audit*/
+ public const int AuditDatabasePrincipalManagementEvent = 130;
+ /*Security Audit*/
+ public const int AuditSchemaObjectManagementEvent = 131;
+ /*Security Audit*/
+ public const int AuditServerPrincipalImpersonationEvent = 132;
+ /*Security Audit*/
+ public const int AuditDatabasePrincipalImpersonationEvent = 133;
+ /*Security Audit*/
+ public const int AuditServerObjectTakeOwnershipEvent = 134;
+ /*Security Audit*/
+ public const int AuditDatabaseObjectTakeOwnershipEvent = 135;
+ /*Security Audit*/
+ public const int AuditChangeDatabaseOwner = 152;
+ /*Security Audit*/
+ public const int AuditSchemaObjectTakeOwnershipEvent = 153;
+ /*Security Audit*/
+ public const int AuditBrokerConversation = 158;
+ /*Security Audit*/
+ public const int AuditBrokerLogin = 159;
+ /*Security Audit*/
+ public const int AuditServerScopeGDREvent = 170;
+ /*Security Audit*/
+ public const int AuditServerObjectGDREvent = 171;
+ /*Security Audit*/
+ public const int AuditDatabaseObjectGDREvent = 172;
+ /*Security Audit*/
+ public const int AuditServerOperationEvent = 173;
+ /*Security Audit*/
+ public const int AuditServerAlterTraceEvent = 175;
+ /*Security Audit*/
+ public const int AuditServerObjectManagementEvent = 176;
+ /*Security Audit*/
+ public const int AuditServerPrincipalManagementEvent = 177;
+ /*Security Audit*/
+ public const int AuditDatabaseOperationEvent = 178;
+ /*Security Audit*/
+ public const int AuditDatabaseObjectAccessEvent = 180;
+ }
+
+ public static class Server
+ {
+ /*Server*/
+ public const int ServerMemoryChange = 81;
+ /*Server*/
+ public const int TraceFileClose = 150;
+ /*Server*/
+ public const int MountTape = 195;
+ }
+
+ public static class Sessions
+ {
+ /*Sessions*/
+ public const int ExistingConnection = 17;
+ }
+
+ public static class StoredProcedures
+ {
+ /*Stored Procedures*/
+ public const int RPCCompleted = 10;
+ /*Stored Procedures*/
+ public const int RPCStarting = 11;
+ /*Stored Procedures*/
+ public const int SPCacheMiss = 34;
+ /*Stored Procedures*/
+ public const int SPCacheInsert = 35;
+ /*Stored Procedures*/
+ public const int SPCacheRemove = 36;
+ /*Stored Procedures*/
+ public const int SPRecompile = 37;
+ /*Stored Procedures*/
+ public const int SPCacheHit = 38;
+ /*Stored Procedures*/
+ public const int Deprecated = 39;
+ /*Stored Procedures*/
+ public const int SPStarting = 42;
+ /*Stored Procedures*/
+ public const int SPCompleted = 43;
+ /*Stored Procedures*/
+ public const int SPStmtStarting = 44;
+ /*Stored Procedures*/
+ public const int SPStmtCompleted = 45;
+ /*Stored Procedures*/
+ public const int RPCOutputParameter = 100;
+ }
+
+ public static class Transactions
+ {
+ /*Transactions*/
+ public const int DTCTransaction = 19;
+ /*Transactions*/
+ public const int SQLTransaction = 50;
+ /*Transactions*/
+ public const int TransactionLog = 54;
+ /*Transactions*/
+ public const int TMBeginTranstarting = 181;
+ /*Transactions*/
+ public const int TMBeginTrancompleted = 182;
+ /*Transactions*/
+ public const int TMPromoteTranstarting = 183;
+ /*Transactions*/
+ public const int TMPromoteTrancompleted = 184;
+ /*Transactions*/
+ public const int TMCommitTranstarting = 185;
+ /*Transactions*/
+ public const int TMCommitTrancompleted = 186;
+ /*Transactions*/
+ public const int TMRollbackTranstarting = 187;
+ /*Transactions*/
+ public const int TMRollbackTrancompleted = 188;
+ /*Transactions*/
+ public const int TMSaveTranstarting = 191;
+ /*Transactions*/
+ public const int TMSaveTrancompleted = 192;
+ }
+
+ public static class TSQL
+ {
+ /*TSQL*/
+ public const int SQLBatchCompleted = 12;
+ /*TSQL*/
+ public const int SQLBatchStarting = 13;
+ /*TSQL*/
+ public const int SQLStmtStarting = 40;
+ /*TSQL*/
+ public const int SQLStmtCompleted = 41;
+ /*TSQL*/
+ public const int PrepareSQL = 71;
+ /*TSQL*/
+ public const int ExecPreparedSQL = 72;
+ /*TSQL*/
+ public const int UnprepareSQL = 73;
+ /*TSQL*/
+ public const int SQLStmtRecompile = 166;
+ /*TSQL*/
+ public const int XQueryStaticType = 198;
+ }
+
+ public static class Userconfigurable
+ {
+ /*User configurable*/
+ public const int UserConfigurable0 = 82;
+ /*User configurable*/
+ public const int UserConfigurable1 = 83;
+ /*User configurable*/
+ public const int UserConfigurable2 = 84;
+ /*User configurable*/
+ public const int UserConfigurable3 = 85;
+ /*User configurable*/
+ public const int UserConfigurable4 = 86;
+ /*User configurable*/
+ public const int UserConfigurable5 = 87;
+ /*User configurable*/
+ public const int UserConfigurable6 = 88;
+ /*User configurable*/
+ public const int UserConfigurable7 = 89;
+ /*User configurable*/
+ public const int UserConfigurable8 = 90;
+ /*User configurable*/
+ public const int UserConfigurable9 = 91;
+ }
+
+ public static class OLEDB
+ {
+ /*OLEDB*/
+ public const int OLEDBErrors = 61;
+ /*OLEDB*/
+ public const int OLEDBCallEvent = 119;
+ /*OLEDB*/
+ public const int OLEDBQueryInterfaceEvent = 120;
+ /*OLEDB*/
+ public const int OLEDBDataReadEvent = 121;
+ /*OLEDB*/
+ public const int OLEDBProviderInformation = 194;
+ }
+
+ public static class Broker
+ {
+ /*Broker*/
+ public const int BrokerConversation = 124;
+ /*Broker*/
+ public const int BrokerConversationGroup = 136;
+ /*Broker*/
+ public const int BrokerConnection = 138;
+ /*Broker*/
+ public const int BrokerForwardedMessageSent = 139;
+ /*Broker*/
+ public const int BrokerForwardedMessageDropped = 140;
+ /*Broker*/
+ public const int BrokerMessageClassify = 141;
+ /*Broker*/
+ public const int BrokerTransmission = 142;
+ /*Broker*/
+ public const int BrokerQueueDisabled = 143;
+ /*Broker*/
+ public const int BrokerMirroredRouteStateChanged = 144;
+ /*Broker*/
+ public const int BrokerRemoteMessageAcknowledgement = 149;
+ /*Broker*/
+ public const int BrokerMessageUndeliverable = 160;
+ /*Broker*/
+ public const int BrokerCorruptedMessage = 161;
+ /*Broker*/
+ public const int BrokerActivation = 163;
+ }
+
+ public static class Fulltext
+ {
+ /*Full text*/
+ public const int FTCrawlStarted = 155;
+ /*Full text*/
+ public const int FTCrawlStopped = 156;
+ /*Full text*/
+ public const int FTCrawlAborted = 157;
+ }
+
+ public static class Deprecation
+ {
+ /*Deprecation*/
+ public const int DeprecationAnnouncement = 125;
+ /*Deprecation*/
+ public const int DeprecationFinalSupport = 126;
+ }
+
+ public static class ProgressReport
+ {
+ /*Progress Report*/
+ public const int ProgressReportOnlineIndexOperation = 190;
+ }
+
+ public static class CLR
+ {
+ /*CLR*/
+ public const int AssemblyLoad = 196;
+ }
+
+ public static class QueryNotifications
+ {
+ /*Query Notifications*/
+ public const int QNSubscription = 199;
+ /*Query Notifications*/
+ public const int QNParametertable = 200;
+ /*Query Notifications*/
+ public const int QNTemplate = 201;
+ /*Query Notifications*/
+ public const int QNDynamics = 202;
+ }
+ }
+
+ public static class ProfilerEventColumns
+ {
+ /*
+ select 'public const int '+Name + '= '+cast(trace_column_id as varchar)+';'
+ from sys.trace_columns
+ order by trace_column_id
+ */
+ public const int TextData = 1;
+ public const int BinaryData = 2;
+ public const int DatabaseID = 3;
+ public const int TransactionID = 4;
+ public const int LineNumber = 5;
+ public const int NTUserName = 6;
+ public const int NTDomainName = 7;
+ public const int HostName = 8;
+ public const int ClientProcessID = 9;
+ public const int ApplicationName = 10;
+ public const int LoginName = 11;
+ public const int SPID = 12;
+ public const int Duration = 13;
+ public const int StartTime = 14;
+ public const int EndTime = 15;
+ public const int Reads = 16;
+ public const int Writes = 17;
+ public const int CPU = 18;
+ public const int Permissions = 19;
+ public const int Severity = 20;
+ public const int EventSubClass = 21;
+ public const int ObjectID = 22;
+ public const int Success = 23;
+ public const int IndexID = 24;
+ public const int IntegerData = 25;
+ public const int ServerName = 26;
+ public const int EventClass = 27;
+ public const int ObjectType = 28;
+ public const int NestLevel = 29;
+ public const int State = 30;
+ public const int Error = 31;
+ public const int Mode = 32;
+ public const int Handle = 33;
+ public const int ObjectName = 34;
+ public const int DatabaseName = 35;
+ public const int FileName = 36;
+ public const int OwnerName = 37;
+ public const int RoleName = 38;
+ public const int TargetUserName = 39;
+ public const int DBUserName = 40;
+ public const int LoginSid = 41;
+ public const int TargetLoginName = 42;
+ public const int TargetLoginSid = 43;
+ public const int ColumnPermissions = 44;
+ public const int LinkedServerName = 45;
+ public const int ProviderName = 46;
+ public const int MethodName = 47;
+ public const int RowCounts = 48;
+ public const int RequestID = 49;
+ public const int XactSequence = 50;
+ public const int EventSequence = 51;
+ public const int BigintData1 = 52;
+ public const int BigintData2 = 53;
+ public const int GUID = 54;
+ public const int IntegerData2 = 55;
+ public const int ObjectID2 = 56;
+ public const int Type = 57;
+ public const int OwnerID = 58;
+ public const int ParentName = 59;
+ public const int IsSystem = 60;
+ public const int Offset = 61;
+ public const int SourceDatabaseID = 62;
+ public const int SqlHandle = 63;
+ public const int SessionLoginName = 64;
+ public const int PlanHandle = 65;
+ }
+ // ReSharper restore UnusedMember.Global
+ // ReSharper restore InconsistentNaming
+
+ public class ProfilerEvent
+ {
+ internal readonly Object[] m_Events = new object[65];
+ internal ulong m_ColumnMask;
+ // ReSharper disable UnusedMember.Global
+ // ReSharper disable InconsistentNaming
+
+ private int GetInt(int idx)
+ {
+ if (!ColumnIsSet(idx)) return 0;
+ return m_Events[idx] == null ? 0 : (int)m_Events[idx];
+ }
+
+ private long GetLong(int idx)
+ {
+ if (!ColumnIsSet(idx)) return 0;
+ return m_Events[idx] == null ? 0 : (long)m_Events[idx];
+ }
+
+ private string GetString(int idx)
+ {
+ if (!ColumnIsSet(idx)) return "";
+ return m_Events[idx] == null ? "" : (string)m_Events[idx];
+ }
+
+ private byte[] GetByte(int idx)
+ {
+ return ColumnIsSet(idx)?(byte[])m_Events[idx]:new byte[1];
+ }
+
+ private DateTime GetDateTime(int idx)
+ {
+ return ColumnIsSet(idx) ? (DateTime) m_Events[idx] : new DateTime(0);
+ }
+
+ private Guid GetGuid(int idx)
+ {
+ return ColumnIsSet(idx) ? (Guid) m_Events[idx] : Guid.Empty;
+ }
+
+// ReSharper disable MemberCanBePrivate.Global
+ public bool ColumnIsSet(int columnId)
+// ReSharper restore MemberCanBePrivate.Global
+ {
+ return (m_ColumnMask & (1UL << columnId)) != 0;
+ }
+
+
+ /*
+select 'public '+case Type_Name
+ when 'text' then 'string'
+ when 'int' then 'int'
+ when 'bigint' then 'long'
+ when 'nvarchar' then 'string'
+ when 'datetime' then 'DateTime'
+ when 'image' then 'byte[]'
+ when 'uniqueidentifier' then 'GUID'
+ end
++' '+Name + '{get{ return Get'+
+case Type_Name
+ when 'text' then 'String'
+ when 'int' then 'Int'
+ when 'bigint' then 'Long'
+ when 'nvarchar' then 'String'
+ when 'datetime' then 'DateTime'
+ when 'image' then 'Byte'
+ when 'uniqueidentifier' then 'Guid'
+ end
++'(ProfilerEventColumns.'+Name+');}}'
+from sys.trace_columns
+order by trace_column_id
+
+ *
+ */
+
+ public string TextData { get { return GetString(ProfilerEventColumns.TextData); } }
+ public byte[] BinaryData { get { return GetByte(ProfilerEventColumns.BinaryData); } }
+ public int DatabaseID { get { return GetInt(ProfilerEventColumns.DatabaseID); } }
+ public long TransactionID { get { return GetLong(ProfilerEventColumns.TransactionID); } }
+ public int LineNumber { get { return GetInt(ProfilerEventColumns.LineNumber); } }
+ public string NTUserName { get { return GetString(ProfilerEventColumns.NTUserName); } }
+ public string NTDomainName { get { return GetString(ProfilerEventColumns.NTDomainName); } }
+ public string HostName { get { return GetString(ProfilerEventColumns.HostName); } }
+ public int ClientProcessID { get { return GetInt(ProfilerEventColumns.ClientProcessID); } }
+ public string ApplicationName { get { return GetString(ProfilerEventColumns.ApplicationName); } }
+ public string LoginName { get { return GetString(ProfilerEventColumns.LoginName); } }
+ public int SPID { get { return GetInt(ProfilerEventColumns.SPID); } }
+ public long Duration { get { return GetLong(ProfilerEventColumns.Duration); } }
+ public DateTime StartTime { get { return GetDateTime(ProfilerEventColumns.StartTime); } }
+ public DateTime EndTime { get { return GetDateTime(ProfilerEventColumns.EndTime); } }
+ public long Reads { get { return GetLong(ProfilerEventColumns.Reads); } }
+ public long Writes { get { return GetLong(ProfilerEventColumns.Writes); } }
+ public int CPU { get { return GetInt(ProfilerEventColumns.CPU); } }
+ public long Permissions { get { return GetLong(ProfilerEventColumns.Permissions); } }
+ public int Severity { get { return GetInt(ProfilerEventColumns.Severity); } }
+ public int EventSubClass { get { return GetInt(ProfilerEventColumns.EventSubClass); } }
+ public int ObjectID { get { return GetInt(ProfilerEventColumns.ObjectID); } }
+ public int Success { get { return GetInt(ProfilerEventColumns.Success); } }
+ public int IndexID { get { return GetInt(ProfilerEventColumns.IndexID); } }
+ public int IntegerData { get { return GetInt(ProfilerEventColumns.IntegerData); } }
+ public string ServerName { get { return GetString(ProfilerEventColumns.ServerName); } }
+ public int EventClass { get { return GetInt(ProfilerEventColumns.EventClass); } }
+ public int ObjectType { get { return GetInt(ProfilerEventColumns.ObjectType); } }
+ public int NestLevel { get { return GetInt(ProfilerEventColumns.NestLevel); } }
+ public int State { get { return GetInt(ProfilerEventColumns.State); } }
+ public int Error { get { return GetInt(ProfilerEventColumns.Error); } }
+ public int Mode { get { return GetInt(ProfilerEventColumns.Mode); } }
+ public int Handle { get { return GetInt(ProfilerEventColumns.Handle); } }
+ public string ObjectName { get { return GetString(ProfilerEventColumns.ObjectName); } }
+ public string DatabaseName { get { return GetString(ProfilerEventColumns.DatabaseName); } }
+ public string FileName { get { return GetString(ProfilerEventColumns.FileName); } }
+ public string OwnerName { get { return GetString(ProfilerEventColumns.OwnerName); } }
+ public string RoleName { get { return GetString(ProfilerEventColumns.RoleName); } }
+ public string TargetUserName { get { return GetString(ProfilerEventColumns.TargetUserName); } }
+ public string DBUserName { get { return GetString(ProfilerEventColumns.DBUserName); } }
+ public byte[] LoginSid { get { return GetByte(ProfilerEventColumns.LoginSid); } }
+ public string TargetLoginName { get { return GetString(ProfilerEventColumns.TargetLoginName); } }
+ public byte[] TargetLoginSid { get { return GetByte(ProfilerEventColumns.TargetLoginSid); } }
+ public int ColumnPermissions { get { return GetInt(ProfilerEventColumns.ColumnPermissions); } }
+ public string LinkedServerName { get { return GetString(ProfilerEventColumns.LinkedServerName); } }
+ public string ProviderName { get { return GetString(ProfilerEventColumns.ProviderName); } }
+ public string MethodName { get { return GetString(ProfilerEventColumns.MethodName); } }
+ public long RowCounts { get { return GetLong(ProfilerEventColumns.RowCounts); } }
+ public int RequestID { get { return GetInt(ProfilerEventColumns.RequestID); } }
+ public long XactSequence { get { return GetLong(ProfilerEventColumns.XactSequence); } }
+ public long EventSequence { get { return GetLong(ProfilerEventColumns.EventSequence); } }
+ public long BigintData1 { get { return GetLong(ProfilerEventColumns.BigintData1); } }
+ public long BigintData2 { get { return GetLong(ProfilerEventColumns.BigintData2); } }
+ public Guid GUID { get { return GetGuid(ProfilerEventColumns.GUID); } }
+ public int IntegerData2 { get { return GetInt(ProfilerEventColumns.IntegerData2); } }
+ public long ObjectID2 { get { return GetLong(ProfilerEventColumns.ObjectID2); } }
+ public int Type { get { return GetInt(ProfilerEventColumns.Type); } }
+ public int OwnerID { get { return GetInt(ProfilerEventColumns.OwnerID); } }
+ public string ParentName { get { return GetString(ProfilerEventColumns.ParentName); } }
+ public int IsSystem { get { return GetInt(ProfilerEventColumns.IsSystem); } }
+ public int Offset { get { return GetInt(ProfilerEventColumns.Offset); } }
+ public int SourceDatabaseID { get { return GetInt(ProfilerEventColumns.SourceDatabaseID); } }
+ public byte[] SqlHandle { get { return GetByte(ProfilerEventColumns.SqlHandle); } }
+ public string SessionLoginName { get { return GetString(ProfilerEventColumns.SessionLoginName); } }
+ public byte[] PlanHandle { get { return GetByte(ProfilerEventColumns.PlanHandle); } }
+ }
+ // ReSharper restore InconsistentNaming
+ // ReSharper restore UnusedMember.Global
+
+ public class RawTraceReader
+ {
+ private delegate void SetEventDelegate(ProfilerEvent evt, int columnid);
+ private DbDataReader m_Reader;
+ private readonly byte[] m_B16 = new byte[16];
+ private readonly byte[] m_B8 = new byte[8];
+ private readonly byte[] m_B2 = new byte[2];
+ private readonly byte[] m_B4 = new byte[4];
+ private readonly SqlConnection m_Conn;
+ private int m_TraceId;
+ public int TraceId
+ {
+ get { return m_TraceId; }
+ }
+ readonly SetEventDelegate[] m_Delegates = new SetEventDelegate[66];
+ private bool m_LastRead;
+ private bool Read()
+ {
+ m_LastRead = m_Reader.Read();
+ return m_LastRead;
+ }
+
+ public bool TraceIsActive
+ {
+ get
+ {
+ return m_LastRead;
+ }
+ }
+ public void Close()
+ {
+ if(m_Reader!=null){m_Reader.Close();}
+ m_LastRead = false;
+ }
+
+ public RawTraceReader(SqlConnection con)
+ {
+ m_Conn = con;
+ SetEventDelegate evtInt = SetIntColumn;
+ SetEventDelegate evtLong = SetLongColumn;
+ SetEventDelegate evtString = SetStringColumn;
+ SetEventDelegate evtByte = SetByteColumn;
+ SetEventDelegate evtDateTime = SetDateTimeColumn;
+ SetEventDelegate evtGuid = SetGuidColumn;
+ /*
+ select 'm_Delegates[ProfilerEventColumns.'+Name+'] = evt'+
+ case Type_Name
+ when 'text' then 'String'
+ when 'int' then 'Int'
+ when 'bigint' then 'Long'
+ when 'nvarchar' then 'String'
+ when 'datetime' then 'DateTime'
+ when 'image' then 'Byte'
+ when 'uniqueidentifier' then 'Guid'
+ end+';'
+
+ from sys.trace_columns
+ order by trace_column_id
+
+ */
+ m_Delegates[ProfilerEventColumns.TextData] = evtString;
+ m_Delegates[ProfilerEventColumns.BinaryData] = evtByte;
+ m_Delegates[ProfilerEventColumns.DatabaseID] = evtInt;
+ m_Delegates[ProfilerEventColumns.TransactionID] = evtLong;
+ m_Delegates[ProfilerEventColumns.LineNumber] = evtInt;
+ m_Delegates[ProfilerEventColumns.NTUserName] = evtString;
+ m_Delegates[ProfilerEventColumns.NTDomainName] = evtString;
+ m_Delegates[ProfilerEventColumns.HostName] = evtString;
+ m_Delegates[ProfilerEventColumns.ClientProcessID] = evtInt;
+ m_Delegates[ProfilerEventColumns.ApplicationName] = evtString;
+ m_Delegates[ProfilerEventColumns.LoginName] = evtString;
+ m_Delegates[ProfilerEventColumns.SPID] = evtInt;
+ m_Delegates[ProfilerEventColumns.Duration] = evtLong;
+ m_Delegates[ProfilerEventColumns.StartTime] = evtDateTime;
+ m_Delegates[ProfilerEventColumns.EndTime] = evtDateTime;
+ m_Delegates[ProfilerEventColumns.Reads] = evtLong;
+ m_Delegates[ProfilerEventColumns.Writes] = evtLong;
+ m_Delegates[ProfilerEventColumns.CPU] = evtInt;
+ m_Delegates[ProfilerEventColumns.Permissions] = evtLong;
+ m_Delegates[ProfilerEventColumns.Severity] = evtInt;
+ m_Delegates[ProfilerEventColumns.EventSubClass] = evtInt;
+ m_Delegates[ProfilerEventColumns.ObjectID] = evtInt;
+ m_Delegates[ProfilerEventColumns.Success] = evtInt;
+ m_Delegates[ProfilerEventColumns.IndexID] = evtInt;
+ m_Delegates[ProfilerEventColumns.IntegerData] = evtInt;
+ m_Delegates[ProfilerEventColumns.ServerName] = evtString;
+ m_Delegates[ProfilerEventColumns.EventClass] = evtInt;
+ m_Delegates[ProfilerEventColumns.ObjectType] = evtInt;
+ m_Delegates[ProfilerEventColumns.NestLevel] = evtInt;
+ m_Delegates[ProfilerEventColumns.State] = evtInt;
+ m_Delegates[ProfilerEventColumns.Error] = evtInt;
+ m_Delegates[ProfilerEventColumns.Mode] = evtInt;
+ m_Delegates[ProfilerEventColumns.Handle] = evtInt;
+ m_Delegates[ProfilerEventColumns.ObjectName] = evtString;
+ m_Delegates[ProfilerEventColumns.DatabaseName] = evtString;
+ m_Delegates[ProfilerEventColumns.FileName] = evtString;
+ m_Delegates[ProfilerEventColumns.OwnerName] = evtString;
+ m_Delegates[ProfilerEventColumns.RoleName] = evtString;
+ m_Delegates[ProfilerEventColumns.TargetUserName] = evtString;
+ m_Delegates[ProfilerEventColumns.DBUserName] = evtString;
+ m_Delegates[ProfilerEventColumns.LoginSid] = evtByte;
+ m_Delegates[ProfilerEventColumns.TargetLoginName] = evtString;
+ m_Delegates[ProfilerEventColumns.TargetLoginSid] = evtByte;
+ m_Delegates[ProfilerEventColumns.ColumnPermissions] = evtInt;
+ m_Delegates[ProfilerEventColumns.LinkedServerName] = evtString;
+ m_Delegates[ProfilerEventColumns.ProviderName] = evtString;
+ m_Delegates[ProfilerEventColumns.MethodName] = evtString;
+ m_Delegates[ProfilerEventColumns.RowCounts] = evtLong;
+ m_Delegates[ProfilerEventColumns.RequestID] = evtInt;
+ m_Delegates[ProfilerEventColumns.XactSequence] = evtLong;
+ m_Delegates[ProfilerEventColumns.EventSequence] = evtLong;
+ m_Delegates[ProfilerEventColumns.BigintData1] = evtLong;
+ m_Delegates[ProfilerEventColumns.BigintData2] = evtLong;
+ m_Delegates[ProfilerEventColumns.GUID] = evtGuid;
+ m_Delegates[ProfilerEventColumns.IntegerData2] = evtInt;
+ m_Delegates[ProfilerEventColumns.ObjectID2] = evtLong;
+ m_Delegates[ProfilerEventColumns.Type] = evtInt;
+ m_Delegates[ProfilerEventColumns.OwnerID] = evtInt;
+ m_Delegates[ProfilerEventColumns.ParentName] = evtString;
+ m_Delegates[ProfilerEventColumns.IsSystem] = evtInt;
+ m_Delegates[ProfilerEventColumns.Offset] = evtInt;
+ m_Delegates[ProfilerEventColumns.SourceDatabaseID] = evtInt;
+ m_Delegates[ProfilerEventColumns.SqlHandle] = evtByte;
+ m_Delegates[ProfilerEventColumns.SessionLoginName] = evtString;
+ m_Delegates[ProfilerEventColumns.PlanHandle] = evtByte;
+
+ }
+
+ private static void SetGuidColumn(ProfilerEvent evt, int columnid)
+ {
+ throw new NotImplementedException();
+ }
+
+ private void SetDateTimeColumn(ProfilerEvent evt, int columnid)
+ {
+ //2 byte - year
+ //2 byte - month
+ //2 byte - ???
+ //2 byte - day
+ //2 byte - hour
+ //2 byte - min
+ //2 byte - sec
+ //2 byte - msec
+ m_Reader.GetBytes(2, 0, m_B16, 0, 16);
+ int year = m_B16[0]|m_B16[1]<<8;
+ int month = m_B16[2] | m_B16[3] << 8;
+ int day = m_B16[6] | m_B16[7] << 8;
+ int hour = m_B16[8] | m_B16[9] << 8;
+ int min = m_B16[10] | m_B16[11] << 8;
+ int sec = m_B16[12] | m_B16[13] << 8;
+ int msec = m_B16[14] | m_B16[15] << 8;
+ evt.m_Events[columnid] = new DateTime(year,month,day,hour,min,sec,msec);
+ evt.m_ColumnMask |= (ulong)1 << columnid;
+
+ }
+
+ private void SetByteColumn(ProfilerEvent evt, int columnid)
+ {
+ byte[] b = new byte[(int)m_Reader[1]];
+ evt.m_Events[columnid] = b;
+ evt.m_ColumnMask |= 1UL << columnid;
+ }
+
+ private void SetStringColumn(ProfilerEvent evt, int columnid)
+ {
+ evt.m_Events[columnid] = Encoding.Unicode.GetString((byte[])m_Reader[2]);
+ evt.m_ColumnMask |= 1UL << columnid;
+ }
+
+ private void SetIntColumn(ProfilerEvent evt, int columnid)
+ {
+ m_Reader.GetBytes(2, 0, m_B4, 0, 4);
+ evt.m_Events[columnid] = ToInt32(m_B4);
+ evt.m_ColumnMask |= 1UL << columnid;
+ }
+
+ private void SetLongColumn(ProfilerEvent evt, int columnid)
+ {
+ m_Reader.GetBytes(2, 0, m_B8, 0, 8);
+ evt.m_Events[columnid] = ToInt64(m_B8);
+ evt.m_ColumnMask |= 1UL << columnid;
+ }
+
+ private static long ToInt64(byte[] value)
+ {
+ int i1 = (value[0]) | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
+ int i2 = (value[4]) | (value[5] << 8) | (value[6] << 16) | (value[7] << 24);
+ return (uint)i1 | ((long)i2 << 32);
+ }
+ private static int ToInt32(byte[] value)
+ {
+ return (value[0]) | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
+ }
+ private static int ToInt16(byte[] value)
+ {
+ return (value[0]) | (value[1] << 8);
+ }
+
+// ReSharper disable UnusedMember.Global
+ public static string BuildEventSql(int traceid, int eventId, params int[] columns)
+// ReSharper restore UnusedMember.Global
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (int i in columns)
+ {
+ sb.AppendFormat("\r\n exec sp_trace_setevent {0}, {1}, {2}, @on", traceid, eventId, i);
+ }
+ return sb.ToString();
+ }
+
+ public void SetEvent(int eventId, params int[] columns)
+ {
+ SqlCommand cmd = new SqlCommand{Connection = m_Conn,CommandText = "sp_trace_setevent",CommandType = CommandType.StoredProcedure};
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Value = m_TraceId;
+ cmd.Parameters.Add("@eventid", SqlDbType.Int).Value = eventId;
+ SqlParameter p = cmd.Parameters.Add("@columnid", SqlDbType.Int);
+ cmd.Parameters.Add("@on", SqlDbType.Bit).Value = 1;
+ foreach (int i in columns)
+ {
+ p.Value = i;
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+// ReSharper disable UnusedMember.Global
+ public void SetFilter(int columnId, int logicalOperator,int comparisonOperator,int? value)
+// ReSharper restore UnusedMember.Global
+ {
+ SqlCommand cmd = new SqlCommand { Connection = m_Conn, CommandText = "sp_trace_setfilter", CommandType = CommandType.StoredProcedure };
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Value = m_TraceId;
+ cmd.Parameters.Add("@columnid", SqlDbType.Int).Value = columnId;
+ cmd.Parameters.Add("@logical_operator", SqlDbType.Int).Value = logicalOperator;
+ cmd.Parameters.Add("@comparison_operator", SqlDbType.Int).Value = comparisonOperator;
+ if (value == null)
+ {
+ cmd.Parameters.Add("@value", SqlDbType.Int).Value = DBNull.Value;
+ }
+ else
+ {
+ cmd.Parameters.Add("@value", SqlDbType.Int).Value = value;
+ }
+ cmd.ExecuteNonQuery();
+ }
+
+ public void SetFilter(int columnId, int logicalOperator, int comparisonOperator, string value)
+ {
+ SqlCommand cmd = new SqlCommand { Connection = m_Conn, CommandText = "sp_trace_setfilter", CommandType = CommandType.StoredProcedure };
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Value = m_TraceId;
+ cmd.Parameters.Add("@columnid", SqlDbType.Int).Value = columnId;
+ cmd.Parameters.Add("@logical_operator", SqlDbType.Int).Value = logicalOperator;
+ cmd.Parameters.Add("@comparison_operator", SqlDbType.Int).Value = comparisonOperator;
+ if (value == null)
+ {
+ cmd.Parameters.Add("@value", SqlDbType.NVarChar).Value = DBNull.Value;
+ }
+ else
+ {
+ cmd.Parameters.Add("@value", SqlDbType.NVarChar,value.Length).Value = value;
+ }
+ cmd.ExecuteNonQuery();
+ }
+
+
+ public void CreateTrace()
+ {
+ SqlCommand cmd = new SqlCommand { Connection = m_Conn, CommandText = "sp_trace_create", CommandType = CommandType.StoredProcedure };
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Direction = ParameterDirection.Output;
+ cmd.Parameters.Add("@options", SqlDbType.Int).Value = 1;
+ cmd.Parameters.Add("@trace_file", SqlDbType.NVarChar, 245).Value=DBNull.Value;
+ cmd.Parameters.Add("@maxfilesize", SqlDbType.BigInt).Value = DBNull.Value;
+ cmd.Parameters.Add("@stoptime", SqlDbType.DateTime).Value = DBNull.Value;
+ cmd.Parameters.Add("@filecount", SqlDbType.Int).Value = DBNull.Value;
+ cmd.Parameters.Add("@result", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
+ cmd.ExecuteNonQuery();
+ int result = (int)cmd.Parameters["@result"].Value;
+ m_TraceId = result != 0 ? -result : (int)cmd.Parameters["@traceid"].Value;
+ }
+
+ private void ControlTrace(SqlConnection con,int status)
+ {
+ SqlCommand cmd = new SqlCommand { Connection = con, CommandText = "sp_trace_setstatus", CommandType = CommandType.StoredProcedure,CommandTimeout = 0};
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Value = m_TraceId;
+ cmd.Parameters.Add("@status", SqlDbType.Int).Value = status;
+ cmd.ExecuteNonQuery();
+ }
+
+ public void CloseTrace(SqlConnection con)
+ {
+ ControlTrace(con,2);
+ }
+
+ public void StopTrace(SqlConnection con)
+ {
+ ControlTrace(con,0);
+ }
+
+ public void StartTrace()
+ {
+ ControlTrace(m_Conn,1);
+ GetReader();
+ Read();
+ }
+
+ private void GetReader()
+ {
+ SqlCommand cmd = new SqlCommand { Connection = m_Conn, CommandText = "sp_trace_getdata", CommandType = CommandType.StoredProcedure,CommandTimeout = 0};
+ cmd.Parameters.Add("@traceid", SqlDbType.Int).Value = m_TraceId;
+ cmd.Parameters.Add("@records", SqlDbType.Int).Value = 0;
+ m_Reader = cmd.ExecuteReader(CommandBehavior.SingleResult);
+ }
+
+ public ProfilerEvent Next()
+ {
+ if (!TraceIsActive) return null;
+ int columnid = (int)m_Reader[0];
+ //skip to begin of new event
+ while (columnid != 65526 && Read() && TraceIsActive)
+ {
+ columnid = (int)m_Reader[0];
+ }
+ //start of new event
+ if (columnid != 65526) return null;
+ if (!TraceIsActive) return null;
+ //get potential event class
+ m_Reader.GetBytes(2, 0, m_B2, 0, 2);
+ int eventClass = ToInt16(m_B2);
+
+ //we got new event
+ if (eventClass >= 0 && eventClass < 255)
+ {
+ ProfilerEvent evt = new ProfilerEvent();
+ evt.m_Events[27] = eventClass;
+ evt.m_ColumnMask |= 1 << 27;
+ while (Read())
+ {
+ columnid = (int)m_Reader[0];
+ if (columnid > 64) return evt;
+ m_Delegates[columnid](evt, columnid);
+ }
+ }
+ Read();
+ return null;
+ }
+
+ }
+}
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/RtfBuilder.cs b/ExpressProfiler/ExpressProfiler/RtfBuilder.cs new file mode 100644 index 0000000..d620750 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/RtfBuilder.cs @@ -0,0 +1,155 @@ +//Traceutils assembly
+//writen by Locky, 2009.
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Drawing;
+using System.Text;
+
+namespace ExpressProfiler
+{
+ class RTFBuilder
+ {
+
+ private readonly StringBuilder m_Sb = new StringBuilder();
+ private readonly List<Color> m_Colortable = new List<Color>();
+ private readonly StringCollection m_Fonttable = new StringCollection();
+ private Color m_Forecolor;
+ public Color ForeColor
+ {
+ set
+ {
+ if (!m_Colortable.Contains(value)) { m_Colortable.Add(value); }
+ if (value != m_Forecolor)
+ {
+ m_Sb.Append(String.Format("\\cf{0} ", m_Colortable.IndexOf(value) + 1));
+ }
+ m_Forecolor = value;
+ }
+ }
+
+
+ private Color m_Backcolor;
+ public Color BackColor
+ {
+ set
+ {
+ if (!m_Colortable.Contains(value)) { m_Colortable.Add(value); }
+ if (value != m_Backcolor)
+ {
+ m_Sb.Append(String.Format("\\highlight{0} ", m_Colortable.IndexOf(value) + 1));
+ }
+ m_Backcolor = value;
+ }
+ }
+
+
+ public RTFBuilder()
+ {
+ ForeColor = Color.FromKnownColor(KnownColor.WindowText);
+ BackColor = Color.FromKnownColor(KnownColor.Window);
+ m_DefaultFontSize = 20F;
+ }
+
+ public void AppendLine()
+ {
+ m_Sb.AppendLine("\\line");
+ }
+
+ public void Append(string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ value = CheckChar(value);
+ if (value.IndexOf(Environment.NewLine) >= 0)
+ {
+ string[] lines = value.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
+ foreach (string line in lines)
+ {
+ m_Sb.Append(line);
+ m_Sb.Append("\\line ");
+ }
+ }
+ else
+ {
+ m_Sb.Append(value);
+ }
+
+ }
+ }
+ private static readonly char[] Slashable = new[] { '{', '}', '\\' };
+ private readonly float m_DefaultFontSize;
+
+ private static string CheckChar(string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ if (value.IndexOfAny(Slashable) >= 0)
+ {
+ value = value.Replace("{", "\\{").Replace("}", "\\}").Replace("\\", "\\\\");
+ }
+ bool replaceuni = false;
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (value[i] > 255)
+ {
+ replaceuni = true;
+ break;
+ }
+ }
+ if (replaceuni)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (value[i] <= 255)
+ {
+ sb.Append(value[i]);
+ }
+ else
+ {
+ sb.Append("\\u");
+ sb.Append((int)value[i]);
+ sb.Append("?");
+ }
+ }
+ value = sb.ToString();
+ }
+ }
+
+
+ return value;
+ }
+
+ public new string ToString()
+ {
+ StringBuilder result = new StringBuilder();
+ result.Append("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang3081");
+ result.Append("{\\fonttbl");
+ for (int i = 0; i < m_Fonttable.Count; i++)
+ {
+ try
+ {
+ result.Append(string.Format(m_Fonttable[i], i));
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ result.AppendLine("}");
+ result.Append("{\\colortbl ;");
+ foreach (Color item in m_Colortable)
+ {
+ result.AppendFormat("\\red{0}\\green{1}\\blue{2};", item.R, item.G, item.B);
+ }
+ result.AppendLine("}");
+ result.Append("\\viewkind4\\uc1\\pard\\plain\\f0");
+ result.AppendFormat("\\fs{0} ", m_DefaultFontSize);
+ result.AppendLine();
+ result.Append(m_Sb.ToString());
+ result.Append("}");
+ return result.ToString();
+ }
+ }
+}
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/SqlTokens.cs b/ExpressProfiler/ExpressProfiler/SqlTokens.cs new file mode 100644 index 0000000..90e5af1 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/SqlTokens.cs @@ -0,0 +1,120 @@ +//Traceutils assembly
+//writen by Locky, 2009.
+using System.Collections.Generic;
+using System.Text;
+
+namespace ExpressProfiler
+{
+ class Sqltokens
+ {
+ #region Keywords
+ private const string Keywords = "ADD,ALTER,AS,ASC,AUTHORIZATION,BACKUP," +
+ "BEGIN,BREAK,BROWSE,BULK,BY,CASCADE," +
+ "CHECK,CHECKPOINT,CLOSE,CLUSTERED,COLLATE," +
+ "COLUMN,COMMIT,COMPUTE,CONSTRAINT,CONTAINS,CONTAINSTABLE," +
+ "CONTINUE,CREATE,CURRENT,CURSOR,DATABASE," +
+ "DBCC,DEALLOCATE,DECLARE,DEFAULT,DELETE,DENY,DESC,DISK," +
+ "DISTINCT,DISTRIBUTED,DOUBLE,DROP,DUMMY,DUMP,ELSE,END," +
+ "ERRLVL,ESCAPE,EXCEPT,EXEC,EXECUTE,EXIT,FETCH,FILE," +
+ "FILLFACTOR,FOR,FOREIGN,FORMSOF,FREETEXT,FREETEXTTABLE,FROM,FULL," +
+ "FUNCTION,GOTO,GRANT,GROUP,HAVING,HOLDLOCK,IDENTITY," +
+ "IDENTITYCOL,IDENTITY_INSERT,IF,INFLECTIONAL,INDEX,INNER,INSERT," +
+ "INTERSECT,INTO,IS,ISABOUT,KEY,KILL,LINENO,LOAD," +
+ "NATIONAL,NOCHECK,NONCLUSTERED,OF,OFF," +
+ "OFFSETS,ON,OPEN,OPENDATASOURCE,OPENQUERY,OPENROWSET,OPENXML," +
+ "OPTION,ORDER,OVER,PERCENT,PLAN,PRECISION," +
+ "PRIMARY,PRINT,PROC,PROCEDURE,PUBLIC,RAISERROR,READ," +
+ "READTEXT,RECONFIGURE,REFERENCES,REPLICATION,RESTORE," +
+ "RESTRICT,RETURN,REVOKE,ROLLBACK,ROWCOUNT,ROWGUIDCOL," +
+ "RULE,SAVE,SCHEMA,SELECT,SET,SETUSER,SHUTDOWN," +
+ "STATISTICS,TABLE,TEXTSIZE,THEN,TO,TOP,TRAN,TRANSACTION," +
+ "TRIGGER,TRUNCATE,TSEQUAL,UNION,UNIQUE,UPDATE,UPDATETEXT," +
+ "USE,VALUES,VARYING,VIEW,WAITFOR,WEIGHT,WHEN,WHERE,WHILE," +
+ "WITH,WRITETEXT,CURRENT_DATE,CURRENT_TIME" +
+ ",OUT,NEXT,PRIOR,RETURNS,ABSOLUTE,ACTION,PARTIAL,FALSE" +
+ ",PREPARE,FIRST,PRIVILEGES,AT,GLOBAL,RELATIVE,ROWS,HOUR,MIN,MAX" +
+ ",SCROLL,SECOND,SECTION,SIZE,INSENSITIVE,CONNECT,CONNECTION" +
+ ",ISOLATION,LEVEL,LOCAL,DATE,MINUTE,TRANSLATION" +
+ ",TRUE,NO,ONLY,WORK,OUTPUT" +
+ ",ABSOLUTE,ACTION,FREE,PRIOR,PRIVILEGES,AFTER,GLOBAL" +
+ ",HOUR,RELATIVE,IGNORE,AT,RETURNS,ROLLUP,ROWS,SCROLL" +
+ ",ISOLATION,SECOND,SECTION,SEQUENCE,LAST,SIZE,LEVEL" +
+ ",CONNECT,CONNECTION,LOCAL,CUBE,MINUTE,MODIFY,STATIC" +
+ ",DATE,TEMPORARY,TIME,NEXT,NO,TRANSLATION,TRUE,ONLY" +
+ ",OUT,DYNAMIC,OUTPUT,PARTIAL,WORK,FALSE,FIRST,PREPARE,GROUPING,FORMAT,INIT,STATS" +
+ "FORMAT,INIT,STATS,NOCOUNT,FORWARD_ONLY,KEEPFIXED,FORCE,KEEP,MERGE,HASH,LOOP,maxdop,nolock" +
+ ",updlock,tablock,tablockx,paglock,readcommitted,readpast,readuncommitted,repeatableread,rowlock,serializable,xlock"
+ + ",delay";
+
+ #endregion
+ #region Functions
+ private const string Functions = "@@CONNECTIONS,@@CPU_BUSY,@@CURSOR_ROWS,@@DATEFIRST,@@DBTS,@@ERROR," +
+ "@@FETCH_STATUS,@@IDENTITY,@@IDLE,@@IO_BUSY,@@LANGID,@@LANGUAGE," +
+ "@@LOCK_TIMEOUT,@@MAX_CONNECTIONS,@@MAX_PRECISION,@@NESTLEVEL,@@OPTIONS," +
+ "@@PACKET_ERRORS,@@PACK_RECEIVED,@@PACK_SENT,@@PROCID,@@REMSERVER," +
+ "@@ROWCOUNT,@@SERVERNAME,@@SERVICENAME,@@SPID,@@TEXTSIZE,@@TIMETICKS," +
+ "@@TOTAL_ERRORS,@@TOTAL_READ,@@TOTAL_WRITE,@@TRANCOUNT,@@VERSION," +
+ "ABS,ACOS,APP_NAME,ASCII,ASIN,ATAN,ATN2,AVG,BINARY_CHECKSUM,CAST," +
+ "CEILING,CHARINDEX,CHECKSUM,CHECKSUM_AGG,COLLATIONPROPERTY," +
+ "COLUMNPROPERTY,COL_LENGTH,COL_NAME,COS,COT,COUNT," +
+ "COUNT_BIG," +
+ "CURSOR_STATUS,DATABASEPROPERTY,DATABASEPROPERTYEX," +
+ "DATALENGTH,DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,DB_ID,DB_NAME,DEGREES," +
+ "DIFFERENCE,EXP,FILEGROUPPROPERTY,FILEGROUP_ID,FILEGROUP_NAME,FILEPROPERTY," +
+ "FILE_ID,FILE_NAME,FLOOR" +
+ "" +
+ "FORMATMESSAGE,FULLTEXTCATALOGPROPERTY,FULLTEXTSERVICEPROPERTY," +
+ "GETANSINULL,GETDATE,GETUTCDATE,HAS_DBACCESS,HOST_ID,HOST_NAME," +
+ "IDENT_CURRENT,IDENT_INCR,IDENT_SEED,INDEXKEY_PROPERTY,INDEXPROPERTY," +
+ "INDEX_COL,ISDATE,ISNULL,ISNUMERIC,IS_MEMBER,IS_SRVROLEMEMBER,LEN,LOG," +
+ "LOG10,LOWER,LTRIM,MONTH,NEWID,OBJECTPROPERTY,OBJECT_ID," +
+ "OBJECT_NAME,PARSENAME,PATINDEX," +
+ "PERMISSIONS,PI,POWER,QUOTENAME,RADIANS,RAND,REPLACE,REPLICATE,REVERSE," +
+ "ROUND,ROWCOUNT_BIG,RTRIM,SCOPE_IDENTITY,SERVERPROPERTY,SESSIONPROPERTY," +
+ "SIGN,SIN,SOUNDEX,SPACE,SQL_VARIANT_PROPERTY,SQRT,SQUARE," +
+ "STATS_DATE,STDEV,STDEVP,STR,STUFF,SUBSTRING,SUM,SUSER_SID,SUSER_SNAME," +
+ "TAN,TEXTPTR,TEXTVALID,TYPEPROPERTY,UNICODE,UPPER," +
+ "USER_ID,USER_NAME,VAR,VARP,YEAR";
+
+ #endregion
+ #region Types
+ private const string Types = "bigint,binary,bit,char,character,datetime," +
+ "dec,decimal,float,image,int," +
+ "integer,money,nchar,ntext,nvarchar,real," +
+ "rowversion,smalldatetime,smallint,smallmoney," +
+ "sql_variant,sysname,text,timestamp,tinyint,uniqueidentifier," +
+ "varbinary,varchar,NUMERIC";
+ #endregion
+ private const string Greykeywords = "AND,EXISTS,ALL,ANY,BETWEEN,IN,SOME,JOIN,CROSS,OR,NULL,OUTER,NOT,LIKE";
+ private const string Fukeywords = "CASE,RIGHT,COALESCE,SESSION_USER,CONVERT,SYSTEM_USER,LEFT,CURRENT_TIMESTAMP,CURRENT_USER,NULLIF,USER";
+ private readonly Dictionary<string, YukonLexer.TokenKind> m_Words = new Dictionary<string, YukonLexer.TokenKind>();
+ public YukonLexer.TokenKind this[string token] { get { token = token.ToLower(); return m_Words.ContainsKey(token) ? m_Words[token] : YukonLexer.TokenKind.tkUnknown; } }
+ private void AddTokens(string tokens, YukonLexer.TokenKind tokenkind)
+ {
+ StringBuilder curtoken = new StringBuilder();
+ for (int i = 0; i < tokens.Length; i++)
+ {
+ if (tokens[i] == ',')
+ {
+ string s = curtoken.ToString().ToLower();
+ if (!m_Words.ContainsKey(s))
+ m_Words.Add(s, tokenkind);
+ curtoken = new StringBuilder();
+ }
+ else
+ {
+ curtoken.Append(tokens[i]);
+ }
+ }
+ if (curtoken.Length != 0) m_Words.Add(curtoken.ToString(), tokenkind);
+ }
+ public Sqltokens()
+ {
+ AddTokens(Keywords, YukonLexer.TokenKind.tkKey);
+ AddTokens(Functions, YukonLexer.TokenKind.tkFunction);
+ AddTokens(Types, YukonLexer.TokenKind.tkDatatype);
+ AddTokens(Greykeywords, YukonLexer.TokenKind.tkGreyKeyword);
+ AddTokens(Fukeywords, YukonLexer.TokenKind.tkFuKeyword);
+ }
+ }
+}
\ No newline at end of file diff --git a/ExpressProfiler/ExpressProfiler/YukonLexer.cs b/ExpressProfiler/ExpressProfiler/YukonLexer.cs new file mode 100644 index 0000000..23eb500 --- /dev/null +++ b/ExpressProfiler/ExpressProfiler/YukonLexer.cs @@ -0,0 +1,413 @@ +//Traceutils assembly
+//writen by Locky, 2009.
+using System;
+using System.Drawing;
+using System.Text;
+
+namespace ExpressProfiler
+{
+ public class YukonLexer
+ {
+ public enum TokenKind
+ {
+ tkComment, tkDatatype,
+ tkFunction, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace, tkString, tkSymbol, tkUnknown, tkVariable, tkGreyKeyword, tkFuKeyword
+ }
+
+ private enum SqlRange { rsUnknown, rsComment, rsString }
+ private readonly Sqltokens m_Tokens = new Sqltokens();
+
+ const string IdentifierStr = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_#$";
+ private readonly char[] m_IdentifiersArray = IdentifierStr.ToCharArray();
+ const string HexDigits = "1234567890abcdefABCDEF";
+ const string NumberStr = "1234567890.-";
+ private int m_StringLen;
+ private int m_TokenPos;
+ private string m_Token = "";
+ private TokenKind m_TokenId;
+ private string m_Line;
+ private int m_Run;
+
+ private TokenKind TokenId
+ {
+ get { return m_TokenId; }
+ }
+
+ private string Token { get { /*int len = m_Run - m_TokenPos; return m_Line.Substring(m_TokenPos, len);*/return m_Token; } }
+ private SqlRange Range { get; set; }
+
+ private char GetChar(int idx)
+ {
+ return idx >= m_Line.Length ? '\x00' : m_Line[idx];
+ }
+ public string StandardSql(string sql)
+ {
+ StringBuilder result = new StringBuilder();
+ Line = sql;
+ while (TokenId != TokenKind.tkNull)
+ {
+ switch (TokenId)
+ {
+ case TokenKind.tkNumber:
+ case TokenKind.tkString: result.Append("<??>"); break;
+ default: result.Append(Token); break;
+ }
+ Next();
+ }
+ return result.ToString();
+ }
+ public YukonLexer() { Array.Sort(m_IdentifiersArray); }
+ public void FillRichEdit(System. Windows.Forms.RichTextBox rich, string value)
+ {
+
+ rich.Text = "";
+ Line = value;
+
+ RTFBuilder sb = new RTFBuilder { BackColor = rich.BackColor };
+ while (TokenId != TokenKind.tkNull)
+ {
+ Color forecolor;
+ switch (TokenId)
+ {
+ case TokenKind.tkKey: forecolor = Color.Blue;
+ break;
+ case TokenKind.tkFunction: forecolor = Color.Fuchsia; break;
+ case TokenKind.tkGreyKeyword: forecolor = Color.Gray; break;
+ case TokenKind.tkFuKeyword: forecolor = Color.Fuchsia; break;
+ case TokenKind.tkDatatype: forecolor = Color.Blue; break;
+ case TokenKind.tkNumber: forecolor = Color.Red; break;
+ case TokenKind.tkString: forecolor = Color.Red; break;
+ case TokenKind.tkComment: forecolor = Color.DarkGreen;
+ break;
+ default: forecolor = Color.Black; break;
+ }
+ sb.ForeColor = forecolor;
+ if (Token == Environment.NewLine || Token == "\r" || Token == "\n")
+ {
+ sb.AppendLine();
+ }
+ else
+ {
+ sb.Append(Token);
+ }
+ Next();
+ }
+ rich.Rtf = sb.ToString();
+ }
+
+ private string Line
+ {
+ set { Range = SqlRange.rsUnknown; m_Line = value; m_Run = 0; Next(); }
+ }
+ private void NullProc() { m_TokenId = TokenKind.tkNull; }
+ // ReSharper disable InconsistentNaming
+ private void LFProc() { m_TokenId = TokenKind.tkSpace; m_Run++; }
+ private void CRProc() { m_TokenId = TokenKind.tkSpace; m_Run++; if (GetChar(m_Run) == '\x0A')m_Run++; }
+ // ReSharper restore InconsistentNaming
+
+ private void AnsiCProc()
+ {
+ switch (GetChar(m_Run))
+ {
+ case '\x00': NullProc(); break;
+ case '\x0A': LFProc(); break;
+ case '\x0D': CRProc(); break;
+
+ default:
+ {
+ m_TokenId = TokenKind.tkComment;
+ char c;
+ do
+ {
+ if (GetChar(m_Run) == '*' && GetChar(m_Run + 1) == '/')
+ {
+ Range = SqlRange.rsUnknown; m_Run += 2; break;
+ }
+ m_Run++;
+ c = GetChar(m_Run);
+ }
+ while (!(c == '\x00' || c == '\x0A' || c == '\x0D'));
+ break;
+ }
+
+
+
+ }
+ }
+
+ private void AsciiCharProc()
+ {
+ if (GetChar(m_Run) == '\x00') { NullProc(); }
+ else
+ {
+ m_TokenId = TokenKind.tkString;
+ if (m_Run > 0 || Range != SqlRange.rsString || GetChar(m_Run) != '\x27')
+ {
+ Range = SqlRange.rsString;
+ char c;
+ do { m_Run++; c = GetChar(m_Run); } while (!(c == '\x00' || c == '\x0A' || c == '\x0D' || c == '\x27'));
+ if (GetChar(m_Run) == '\x27')
+ {
+ m_Run++;
+ Range = SqlRange.rsUnknown;
+ }
+ }
+ }
+ }
+
+ private void DoProcTable(char chr)
+ {
+ switch (chr)
+ {
+ case '\x00': NullProc(); break;
+ case '\x0A': LFProc(); break;
+ case '\x0D': CRProc(); break;
+ case '\x27': AsciiCharProc(); break;
+
+ case '=': EqualProc(); break;
+ case '>': GreaterProc(); break;
+ case '<': LowerProc(); break;
+ case '-': MinusProc(); break;
+ case '|': OrSymbolProc(); break;
+ case '+': PlusProc(); break;
+ case '/': SlashProc(); break;
+ case '&': AndSymbolProc(); break;
+ case '\x22': QuoteProc(); break;
+ case ':':
+ case '@': VariableProc(); break;
+ case '^':
+ case '%':
+ case '*':
+ case '!': SymbolAssignProc(); break;
+ case '{':
+ case '}':
+ case '.':
+ case ',':
+ case ';':
+ case '?':
+ case '(':
+ case ')':
+ case ']':
+ case '~': SymbolProc(); break;
+ case '[': BracketProc(); break;
+ default:
+ DoInsideProc(chr); break;
+
+ }
+ }
+
+ private void DoInsideProc(char chr)
+ {
+
+ if ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z') || (chr == '_') || (chr == '#')) { IdentProc(); return; }
+ if (chr >= '0' && chr <= '9') { NumberProc(); return; }
+ if ((chr >= '\x00' && chr <= '\x09') || (chr >= '\x0B' && chr <= '\x0C') || (chr >= '\x0E' && chr <= '\x20')) { SpaceProc(); return; }
+ UnknownProc();
+ }
+
+ private void SpaceProc()
+ {
+ m_TokenId = TokenKind.tkSpace;
+ char c;
+ do { m_Run++; c = GetChar(m_Run); }
+ while (!(c > '\x20' || c == '\x00' || c == '\x0A' || c == '\x0D'));
+ }
+
+ private void UnknownProc()
+ {
+ m_Run++;
+ m_TokenId = TokenKind.tkUnknown;
+ }
+
+ private void NumberProc()
+ {
+ m_TokenId = TokenKind.tkNumber;
+ if (GetChar(m_Run) == '0' && (GetChar(m_Run) == 'X' || GetChar(m_Run) == 'x'))
+ {
+ m_Run += 2;
+ while (HexDigits.IndexOf(GetChar(m_Run)) != -1) m_Run++;
+ return;
+ }
+ m_Run++;
+ m_TokenId = TokenKind.tkNumber;
+ while (NumberStr.IndexOf(GetChar(m_Run)) != -1)
+ {
+ if (GetChar(m_Run) == '.' && GetChar(m_Run + 1) == '.') break;
+ m_Run++;
+ }
+
+ }
+
+ private void QuoteProc()
+ {
+ m_TokenId = TokenKind.tkIdentifier;
+ m_Run++;
+ while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D'))
+ {
+ if (GetChar(m_Run) == '\x22') { m_Run++; break; }
+ m_Run++;
+ }
+ }
+
+ private void BracketProc()
+ {
+
+ m_TokenId = TokenKind.tkIdentifier;
+ m_Run++;
+ while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D'))
+ {
+ if (GetChar(m_Run) == ']') { m_Run++; break; }
+ m_Run++;
+ }
+
+ }
+
+ private void SymbolProc()
+ {
+ m_Run++;
+ m_TokenId = TokenKind.tkSymbol;
+ }
+
+ private void SymbolAssignProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=') m_Run++;
+ }
+
+ private void KeyHash(int pos)
+ {
+ m_StringLen = 0;
+ while (Array.BinarySearch(m_IdentifiersArray, GetChar(pos)) >= 0) { m_StringLen++; pos++; }
+ return;
+ }
+ private TokenKind IdentKind()
+ {
+ KeyHash(m_Run);
+ return m_Tokens[m_Line.Substring(m_TokenPos, m_Run + m_StringLen - m_TokenPos)];
+ }
+ private void IdentProc()
+ {
+ m_TokenId = IdentKind();
+ m_Run += m_StringLen;
+ if (m_TokenId == TokenKind.tkComment)
+ {
+ while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0A' || GetChar(m_Run) == '\x0D')) { m_Run++; }
+ }
+ else
+ {
+ while (IdentifierStr.IndexOf(GetChar(m_Run)) != -1) m_Run++;
+ }
+ }
+ private void VariableProc()
+ {
+ if (GetChar(m_Run) == '@' && GetChar(m_Run + 1) == '@') { m_Run += 2; IdentProc(); }
+ else
+ {
+ m_TokenId = TokenKind.tkVariable;
+ int i = m_Run;
+ do { i++; } while (!(IdentifierStr.IndexOf(GetChar(i)) == -1));
+ m_Run = i;
+ }
+ }
+
+ private void AndSymbolProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=' || GetChar(m_Run) == '&') m_Run++;
+ }
+
+ private void SlashProc()
+ {
+ m_Run++;
+ switch (GetChar(m_Run))
+ {
+ case '*':
+ {
+ Range = SqlRange.rsComment;
+ m_TokenId = TokenKind.tkComment;
+ do
+ {
+ m_Run++;
+ if (GetChar(m_Run) == '*' && GetChar(m_Run + 1) == '/') { Range = SqlRange.rsUnknown; m_Run += 2; break; }
+ } while (!(GetChar(m_Run) == '\x00' || GetChar(m_Run) == '\x0D' || GetChar(m_Run) == '\x0A'));
+ }
+ break;
+ case '=': m_Run++; m_TokenId = TokenKind.tkSymbol; break;
+ default: m_TokenId = TokenKind.tkSymbol; break;
+
+ }
+ }
+
+ private void PlusProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=' || GetChar(m_Run) == '=') m_Run++;
+
+ }
+
+ private void OrSymbolProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=' || GetChar(m_Run) == '|') m_Run++;
+ }
+
+ private void MinusProc()
+ {
+ m_Run++;
+ if (GetChar(m_Run) == '-')
+ {
+ m_TokenId = TokenKind.tkComment;
+ char c;
+ do
+ {
+ m_Run++;
+ c = GetChar(m_Run);
+ } while (!(c == '\x00' || c == '\x0A' || c == '\x0D'));
+ }
+ else { m_TokenId = TokenKind.tkSymbol; }
+ }
+
+ private void LowerProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ switch (GetChar(m_Run))
+ {
+ case '=': m_Run++; break;
+ case '<': m_Run++; if (GetChar(m_Run) == '=') m_Run++; break;
+ }
+
+ }
+
+ private void GreaterProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=' || GetChar(m_Run) == '>') m_Run++;
+ }
+
+ private void EqualProc()
+ {
+ m_TokenId = TokenKind.tkSymbol;
+ m_Run++;
+ if (GetChar(m_Run) == '=' || GetChar(m_Run) == '>') m_Run++;
+ }
+
+ private void Next()
+ {
+ m_TokenPos = m_Run;
+ switch (Range)
+ {
+ case SqlRange.rsComment: AnsiCProc(); break;
+ case SqlRange.rsString: AsciiCharProc(); break;
+ default: DoProcTable(GetChar(m_Run)); break;
+ }
+ m_Token = m_Line.Substring(m_TokenPos, m_Run - m_TokenPos);
+ }
+
+ }
+}
\ No newline at end of file |