diff --git a/.gitignore b/.gitignore index fd5204b..0c9b35f 100644 --- a/.gitignore +++ b/.gitignore @@ -181,3 +181,5 @@ UpgradeLog*.htm # Microsoft Fakes FakesAssemblies/ +*.bak +/Scripts diff --git a/SQLCC.Core/Objects/DbCodeSegment.cs b/SQLCC.Core/Objects/DbCodeSegment.cs index bc0c7fc..fe190d7 100644 --- a/SQLCC.Core/Objects/DbCodeSegment.cs +++ b/SQLCC.Core/Objects/DbCodeSegment.cs @@ -2,6 +2,8 @@ namespace SQLCC.Core.Objects { public class DbCodeSegment { + public string SchemaName { get; set; } + public string ObjectName { get; set; } public int LinesOfCode { get; set; } diff --git a/SQLCC.Impl.HtmlCodeHighlighter/HtmlOutputProvider.cs b/SQLCC.Impl.HtmlCodeHighlighter/HtmlOutputProvider.cs index 8422cfa..51c5007 100644 --- a/SQLCC.Impl.HtmlCodeHighlighter/HtmlOutputProvider.cs +++ b/SQLCC.Impl.HtmlCodeHighlighter/HtmlOutputProvider.cs @@ -57,7 +57,7 @@ private void WriteAllDbObjectFiles(List objects, string baseLocation, foreach (var obj in objects) { - File.WriteAllText(Path.Combine(codeCoverageLocation, obj.Name + ".html"), template.Replace("[CODE]", obj.CodeHighlighted)); + File.WriteAllText(Path.Combine(codeCoverageLocation, $"{obj.Name}.html"), template.Replace("[CODE]", obj.CodeHighlighted)); } } diff --git a/SQLCC.Impl.HtmlCodeHighlighter/code.html b/SQLCC.Impl.HtmlCodeHighlighter/code.html new file mode 100644 index 0000000..f2d592c --- /dev/null +++ b/SQLCC.Impl.HtmlCodeHighlighter/code.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + +
+
+ Main + + + + + + + diff --git a/SQLCC.Impl.HtmlCodeHighlighter/sqlcc_output.zip b/SQLCC.Impl.HtmlCodeHighlighter/sqlcc_output.zip index 4f672da..979a6b7 100644 Binary files a/SQLCC.Impl.HtmlCodeHighlighter/sqlcc_output.zip and b/SQLCC.Impl.HtmlCodeHighlighter/sqlcc_output.zip differ diff --git a/SQLCC.Impl.MsSqlProvider/MsSqlDbTraceCodeFormatter.cs b/SQLCC.Impl.MsSqlProvider/MsSqlDbTraceCodeFormatter.cs index 10badd9..331c89d 100644 --- a/SQLCC.Impl.MsSqlProvider/MsSqlDbTraceCodeFormatter.cs +++ b/SQLCC.Impl.MsSqlProvider/MsSqlDbTraceCodeFormatter.cs @@ -25,8 +25,15 @@ public override string FormatCodeWithHighlights(string code, List { codeContents.Insert((lineOfCode.StartByte / 2) + offset, this.StartHighlightMarkUp); offset += this.StartHighlightMarkUp.Length; - codeContents.Insert((lineOfCode.EndByte / 2) + offset, this.EndHighlightMarkUp); - offset += this.EndHighlightMarkUp.Length; + if (lineOfCode.EndByte == -1) + { + codeContents.Append(this.EndHighlightMarkUp); + } + else + { + codeContents.Insert((lineOfCode.EndByte / 2) + offset, this.EndHighlightMarkUp); + offset += this.EndHighlightMarkUp.Length; + } } return _dataScrubber.Scrub(codeContents.ToString(), "format.scrub"); } diff --git a/SQLCC.Impl.MsSqlProvider/MsSqlProvider.cs b/SQLCC.Impl.MsSqlProvider/MsSqlProvider.cs index 8224900..8998447 100644 --- a/SQLCC.Impl.MsSqlProvider/MsSqlProvider.cs +++ b/SQLCC.Impl.MsSqlProvider/MsSqlProvider.cs @@ -116,10 +116,13 @@ public override void StopTrace(string traceName) public override List GetTraceCodeSegments(string traceName) { var trace = Path.Combine(_traceDir, string.Format(TraceFileFormat, traceName)); - var codeTrace = _db.Fetch(@"SELECT DISTINCT LineNumber, Offset as StartByte, IntegerData2 as EndByte, ObjectName + var codeTrace = _db.Fetch(@"SELECT LineNumber, StartByte, EndByte, ObjectName, OBJECT_SCHEMA_NAME(ObjectID) SchemaName +FROM ( + SELECT DISTINCT LineNumber, Offset as StartByte, IntegerData2 as EndByte, ObjectName, ObjectID FROM ::fn_trace_gettable('" + trace + @"', default) -WHERE EventClass IN (40,41,42,43,44) AND Offset IS NOT NULL AND ObjectName IS NOT NULL -ORDER BY ObjectName, LineNumber ASC, StartByte ASC, IntegerData2 ASC;"); + WHERE EventClass IN (40,41,42,43,44) AND Offset IS NOT NULL AND ObjectName IS NOT NULL + ) cs +ORDER BY SchemaName, ObjectName, LineNumber ASC, StartByte ASC, EndByte ASC;"); return codeTrace; } diff --git a/SQLCC/CodeCoverageProcessor.cs b/SQLCC/CodeCoverageProcessor.cs index 1df267c..8950ea3 100644 --- a/SQLCC/CodeCoverageProcessor.cs +++ b/SQLCC/CodeCoverageProcessor.cs @@ -89,7 +89,7 @@ public void ProcessAllCoverage(DbCodeCoverage codeCover) { foreach (var obj in codeCover.TotalObjects) { - obj.CoveredSegments = codeCover.TraceCodeSegments.Where(p => p.ObjectName.Equals(obj.Name)).ToList(); + obj.CoveredSegments = codeCover.TraceCodeSegments.Where(p => p.ObjectName.Equals(obj.Name.Split('.')[1]) && p.SchemaName.Equals(obj.Schema)).ToList(); obj.Set(ProcessObjectCoverage(obj)); obj.CodeHighlighted = _highlightCodeProvider.HighlightCode(obj.Code, obj.CoveredSegments); diff --git a/SQLCC/Commands/GenerateOutputCommand.cs b/SQLCC/Commands/GenerateOutputCommand.cs index a676df7..a573a86 100644 --- a/SQLCC/Commands/GenerateOutputCommand.cs +++ b/SQLCC/Commands/GenerateOutputCommand.cs @@ -28,11 +28,16 @@ public GenerateOutputCommand(DbProvider dbProvider, DbTraceCodeFormatter dbCodeF public void Execute() { + var objects = _dbProvider.GetAllObjects(); + foreach (var o in objects) + { + o.Name = $"{o.Schema}.{o.Name}"; + } var codeCoverageProcessor = new CodeCoverageProcessor(_dbCodeFormatter, _codeHighlighter); var codeCover = new DbCodeCoverage(); codeCover.Name = _traceName; - codeCover.TotalObjects = _dbProvider.GetAllObjects(); + codeCover.TotalObjects = objects; codeCover.TraceCodeSegments = _dbProvider.GetTraceCodeSegments(_traceName); codeCoverageProcessor.ProcessAllCoverage(codeCover); diff --git a/SQLCC/Commands/StartCommand.cs b/SQLCC/Commands/StartCommand.cs index 8b6d997..bbee816 100644 --- a/SQLCC/Commands/StartCommand.cs +++ b/SQLCC/Commands/StartCommand.cs @@ -27,7 +27,6 @@ public void Execute() throw new ApplicationException("You cannot start more than one trace at a time!"); } - _outputProvider.SetUp(_traceName); _dbProvider.StartTrace(_traceName); } } diff --git a/SQLCC/Program.cs b/SQLCC/Program.cs index aa25c65..3e533c0 100644 --- a/SQLCC/Program.cs +++ b/SQLCC/Program.cs @@ -31,36 +31,56 @@ static void Main(string[] args) var command = arguments["action"].ToLower().Trim(); - var traceName = arguments.ContainsKey("traceFileName") ? arguments["traceFileName"] : null; + var traceName = arguments.ContainsKey("traceFileName") ? arguments["traceFileName"] : null; switch (command) { - case "generate": + case "generate": + { + RequiredAttributes(arguments, + "traceFileName" + ); + + var generateCommand = new GenerateOutputCommand(dbProvider, dbCodeFormatter, codeHighlighter, outputProvider, traceName); + generateCommand.Execute(); + break; + } + + case "start": + { + traceName = traceName ?? DateTime.Now.ToString("yyyyMMddHHmmss"); + var startCommand = new StartCommand(outputProvider, dbProvider, traceName); + startCommand.Execute(); + + break; + } + + case "stop": + { + traceName = traceName ?? DateTime.Now.ToString("yyyyMMddHHmmss"); + var stopCommand = new StopCommand(dbProvider, outputProvider, traceName); + stopCommand.Execute(); + break; + } + + case "execute": + { RequiredAttributes(arguments, - "traceFileName" - ); - - var generateCommand = new GenerateOutputCommand(dbProvider, dbCodeFormatter, codeHighlighter, outputProvider, traceName); - generateCommand.Execute(); - break; - - case "execute": - - RequiredAttributes(arguments, - "target" - ); - - traceName = traceName ?? DateTime.Now.ToString("yyyyMMddHHmmss"); - var startCommand = new StartCommand(outputProvider, dbProvider, traceName); - startCommand.Execute(); + "target" + ); + + traceName = traceName ?? DateTime.Now.ToString("yyyyMMddHHmmss"); + var startCommand = new StartCommand(outputProvider, dbProvider, traceName); + startCommand.Execute(); var executeCommand = new ExecuteCommand(arguments["target"], arguments.ContainsKey("targetArgs") ? arguments["targetArgs"] : string.Empty); executeCommand.Execute(); - + var stopCommand = new StopCommand(dbProvider, outputProvider, traceName); stopCommand.Execute(); - break; + break; + } } } diff --git a/SQLCC/floc.scrub b/SQLCC/floc.scrub index 5ed64c5..3b57b6d 100644 --- a/SQLCC/floc.scrub +++ b/SQLCC/floc.scrub @@ -1,4 +1,4 @@ ([\n\r][\s]+) \n Erase white space at beginning of file. ([\t]+|[ ]+) Erase extra spaces -/\*(?>(?:(?!\*/|/\*).)*)(?>(?:/\*(?>(?:(?!\*/|/\*).)*)\*/(?>(?:(?!\*/|/\*).)*))*).*?\*/|--.*?\r?[\n] Erase comments +/\*(?>(?:(?!\*/|/\*).)*)(?>(?:/\*(?>(?:(?!\*/|/\*).)*)\*/(?>(?:(?!\*/|/\*).)*))*).*?\*/|--(?!).*?\r?[\n] Erase comments [\r\n]+ \n Replace extra new lines \ No newline at end of file diff --git a/SQLCC/format.scrub b/SQLCC/format.scrub index fa6cb24..3ec6085 100644 --- a/SQLCC/format.scrub +++ b/SQLCC/format.scrub @@ -4,8 +4,8 @@ ([\s]*END(;)*[\s]*\z) {0}$1{1} Last end statement. ([\s]*BEGIN[\s]*)({0}) $2$1 If there is a BEGIN statement near the start of coverage, include BEGIN. ({1})([\s]*END[\s]*) $2$1 If there is an END statement near the end of coverage, include END. -{1}([\s]*(--.*)*[\s]*(begin|end)*[\s]*(--.*)*[\s]*){0} $1 Include begin/end if it is surrounded by comments or just white-space. Also include comments. -(end)([\s]*(--.*)*[\s]*){0} $1{0}$2 Cover up until end statement. +{1}([\s]*(--.*)[\s]*(begin|end)*[\s]*(--.*)[\s]*){0} $1 Include begin/end if it is surrounded by comments or just white-space. Also include comments. +(\bend\b)([\s]|(--.*$)|(/\*.*\*/))*{0} $1{0}$2 Cover up until end statement. (([\s]*ELSE[\s]*)[\s]*(--.*)*[\s]*){0} {0}$1 If there is an ELSE statemenet that was hit, cover this as well. {1}([\s]*(declare[\s]+.+)+[\n\r]+([\s]*declare[\s]+.+)*[\s]*) $1{1} DECLARE statements are not covered since profiler does not capture them if there is no default value. ([\s]*(declare[\s]+.+)+[\n\r]+([\s]*declare[\s]+.+)*[\s]*){0} {0}$1 DECLARE statements are not covered since profiler does not capture them if there is no default value.