From b8cb73d36569d3c25c2dca9a84eb2dcc81487228 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 13 Mar 2024 22:45:10 -0400 Subject: [PATCH] Added error table support. --- .../SourceGeneratorHelper.cs | 2 + .../SQuiL/Generator/SQuiLGenerator.cs | 66 +- .../SQuiL/Models/SQuiLDataContext.cs | 115 +++- .../SQuiL/Models/SQuiLModel.cs | 50 +- .../SQuiL/Models/SQuiLProperty.cs | 5 + .../SQuiL/Parser/SQuiLParser.cs | 38 +- .../SQuiL/Tokenizer/SQuiLTokenizer.cs | 2 +- .../ErrorQueryTests/ErrorQueryTests.cs | 83 +++ ...QueryHasErrorListDataContext.g.verified.cs | 184 ++++++ ...ist#QueryHasErrorListRequest.g.verified.cs | 13 + ...st#QueryHasErrorListResponse.g.verified.cs | 15 + ...rorList#SQuiLBaseDataContext.g.verified.cs | 48 ++ ...ueryHasErrorList#SQuiLErrors.g.verified.cs | 14 + ...HasErrorList#SQuiLExtensions.g.verified.cs | 19 + ...rrorList#SQuiLQueryAttribute.g.verified.cs | 22 + ...rrorList#SQuiLQueryFilesEnum.g.verified.cs | 11 + ...sErrorList#SQuiLTableAttribute.verified.cs | 17 + ...ErrorList#SQuiLTableTypeEnum.g.verified.cs | 12 + ...ErrorList#SampleEntityObject.g.verified.cs | 9 + ...eryHasErrorList#SamplesTable.g.verified.cs | 9 + ...rQueryTests.QueryHasErrorList.verified.txt | 584 ++++++++++++++++++ ...eryHasErrorObjectDataContext.g.verified.cs | 184 ++++++ ...t#QueryHasErrorObjectRequest.g.verified.cs | 13 + ...#QueryHasErrorObjectResponse.g.verified.cs | 15 + ...rObject#SQuiLBaseDataContext.g.verified.cs | 48 ++ ...eryHasErrorObject#SQuiLError.g.verified.cs | 14 + ...sErrorObject#SQuiLExtensions.g.verified.cs | 19 + ...orObject#SQuiLQueryAttribute.g.verified.cs | 22 + ...orObject#SQuiLQueryFilesEnum.g.verified.cs | 11 + ...rrorObject#SQuiLTableAttribute.verified.cs | 17 + ...rorObject#SQuiLTableTypeEnum.g.verified.cs | 12 + ...rorObject#SampleEntityObject.g.verified.cs | 9 + ...orObject#SamplesSamplesTable.g.verified.cs | 1 + ...yHasErrorObject#SamplesTable.g.verified.cs | 9 + ...ueryTests.QueryHasErrorObject.verified.txt | 584 ++++++++++++++++++ 35 files changed, 2206 insertions(+), 70 deletions(-) create mode 100644 SQuiL.Tests/ErrorQueryTests/ErrorQueryTests.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListDataContext.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListRequest.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListResponse.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLBaseDataContext.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLErrors.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLExtensions.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryAttribute.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryFilesEnum.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableAttribute.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableTypeEnum.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SampleEntityObject.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SamplesTable.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList.verified.txt create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectDataContext.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectRequest.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectResponse.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLBaseDataContext.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLError.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLExtensions.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryAttribute.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryFilesEnum.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableAttribute.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableTypeEnum.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SampleEntityObject.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesSamplesTable.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesTable.g.verified.cs create mode 100644 SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject.verified.txt diff --git a/SQuiL.SourceGenerator/Microsoft.CodeAnalysis/SourceGeneratorHelper.cs b/SQuiL.SourceGenerator/Microsoft.CodeAnalysis/SourceGeneratorHelper.cs index 64946a3..7880cb5 100644 --- a/SQuiL.SourceGenerator/Microsoft.CodeAnalysis/SourceGeneratorHelper.cs +++ b/SQuiL.SourceGenerator/Microsoft.CodeAnalysis/SourceGeneratorHelper.cs @@ -10,6 +10,8 @@ public static class SourceGeneratorHelper public static string TableTypeAttributeName { get; } = $"{NamespaceName}TableAttribute"; + public static string ResultTypeAttributeName { get; } = $"{NamespaceName}ResultType"; + public static string BaseDataContextClassName { get; } = $"{NamespaceName}BaseDataContext"; public static string DefaultConnectionStringAppSettingName { get; } = $"{NamespaceName}Database"; diff --git a/SQuiL.SourceGenerator/SQuiL/Generator/SQuiLGenerator.cs b/SQuiL.SourceGenerator/SQuiL/Generator/SQuiLGenerator.cs index 77a21ff..337e87a 100644 --- a/SQuiL.SourceGenerator/SQuiL/Generator/SQuiLGenerator.cs +++ b/SQuiL.SourceGenerator/SQuiL/Generator/SQuiLGenerator.cs @@ -16,8 +16,20 @@ public class SQuiLGenerator(bool ShowDebugMessages) : IIncrementalGenerator { public static string Debug { get; } = nameof(Debug); + public static string Error { get; } = nameof(Error); + public static string EnvironmentName { get; } = nameof(EnvironmentName); + public static bool IsError(string value) + => Error.Equals(value) || $"{Error}s".Equals(value); + + public static bool IsSpecial(string value) + { + if (Debug.Equals(value)) return true; + if (EnvironmentName.Equals(value)) return true; + return IsError(value); + } + public SQuiLGenerator() : this(false) { } public void Initialize(IncrementalGeneratorInitializationContext context) @@ -225,7 +237,7 @@ private void Execute(Compilation _, ImmutableArray dependencies .Where(p => p is not null)) { var table = attribute!.ToString(); - + if (!table.StartsWith("TableType.")) continue; @@ -313,6 +325,11 @@ private void Execute(Compilation _, ImmutableArray dependencies generation.FilePath = file.Path; } + if (tableMap.TableNames + .Where(p => p.StartsWith(NamespaceName)) + .Select(p => p[NamespaceName.Length..]) + .Any(IsError)) + GenerateResultType(); GenerateDependencyInjectionCode(contexts); GenerateTablesEnum(context, tableMap); @@ -326,6 +343,51 @@ private void Execute(Compilation _, ImmutableArray dependencies _ => ("", default(Location)) }; + void GenerateResultType() + { + context.AddSource($"{ResultTypeAttributeName}.g.cs", SourceText.From($$"""" + {{FileHeader}} + namespace {{NamespaceName}}; + + using System.Collections.Generic; + using System; + + public sealed record {{ResultTypeAttributeName}} + { + public bool IsValue { get; } + private T Value { get; } = default!; + public SQuiLResultType(T value) + { + Value = value; + IsValue = true; + } + + public bool HasErrors { get; } + private IReadOnlyList Errors { get; } = default!; + public SQuiLResultType(IReadOnlyList errors) + { + Errors = errors; + HasErrors = true; + } + + public bool TryGetValue(out T value, out IReadOnlyList errors) + { + value = default!; + errors = default!; + + if (IsValue) + { + value = Value; + return true; + } + + errors = Errors; + return false; + } + } + """", Encoding.UTF8)); + } + void GenerateBaseDataContextClass() { if (missingConfiguration) @@ -458,6 +520,8 @@ public enum TableType var comma = ""; foreach (var table in tableMap.TableNames) { + if (IsError(table)) continue; + sb.AppendLine(comma); sb.Append($"\t{table}"); comma = ","; diff --git a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLDataContext.cs b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLDataContext.cs index 79c8bfd..7f90d4f 100644 --- a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLDataContext.cs +++ b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLDataContext.cs @@ -6,6 +6,7 @@ using SQuiL.SourceGenerator.Parser; using System.CodeDom.Compiler; +using System.Diagnostics; namespace SQuiL.Models; @@ -38,12 +39,18 @@ public ExceptionOrValue GenerateCode(SQuiLFileGeneration generation) .ToList(); var outputs = Blocks - .Where(p => (p.CodeType & CodeType.OUTPUT) == CodeType.OUTPUT) + .Where(p => (p.CodeType & CodeType.OUTPUT) == CodeType.OUTPUT + && !SQuiLGenerator.IsError(p.Name)) .Select(p => (CodeBlock: p, Query: p.CodeType == CodeType.OUTPUT_VARIABLE ? $"Declare {p.DatabaseType.Original};" : TableDeclaration(p.DatabaseType.Original!, p))) .ToList(); + var errors = Blocks + .Where(p => SQuiLGenerator.IsError(p.Name)) + .Select(p => (CodeBlock: p, Query: TableDeclaration(p.DatabaseType.Original!, p))) + .ToList(); + writer.WriteLine($$""" {{SourceGeneratorHelper.FileHeader}} using Microsoft.Data.SqlClient; @@ -61,8 +68,12 @@ void Process() { writer.Block($$"""partial class {{ClassName}} : {{SourceGeneratorHelper.BaseDataContextClassName}}""", () => { + var returnType = generation.Response.ModelName; + if (errors.Count > 0) + returnType = $"{SourceGeneratorHelper.ResultTypeAttributeName}<{returnType}>"; + writer.Block($$""" - public async Task<{{generation.Response.ModelName}}> Process{{Method}}Async( + public async Task<{{returnType}}> Process{{Method}}Async( {{generation.Request.ModelName}} request, CancellationToken cancellationToken = default!) """, () => @@ -93,6 +104,11 @@ void Process() writer.WriteLine($"{generation.Response.ModelName} response = new();"); writer.WriteLine(); VariableSetTracking(); + if (errors.Count > 0) + { + writer.WriteLine(); + writer.WriteLine($"List errors = [];"); + } writer.Block(""" using var reader = await command.ExecuteReaderAsync(cancellationToken); @@ -124,7 +140,12 @@ void Process() writer.WriteLine(); } - writer.WriteLine("return response;"); + writer.WriteLine("if(errors.Count == 0)"); + writer.Indent++; + writer.WriteLine("return new(response);"); + writer.Indent--; + writer.WriteLine(); + writer.WriteLine("return new(errors);"); } InsertQueries(); writer.Block($"""" @@ -156,6 +177,12 @@ void QueryDeclareStatements() writer.Block(output.Query); writer.WriteLine(); } + + foreach (var error in errors) + { + writer.Block(error.Query); + writer.WriteLine(); + } } void VariableSetTracking() @@ -169,6 +196,15 @@ void VariableSetTracking() void SwitchStatements() { + writer.Block($"""case "{SQuiLTableTypeDatabaseTagName}Error__":""", () => + { + writer.WriteLine("if (!await reader.ReadAsync(cancellationToken)) break;"); + foreach (var error in errors) + LoopProperties("Error", "errors", error.CodeBlock.Properties); + writer.WriteLine(); + writer.WriteLine("break;"); + }); + try { foreach (var (block, query) in outputs) @@ -192,29 +228,7 @@ void SwitchStatements() writer.WriteLine("if (!await reader.ReadAsync(cancellationToken)) break;"); if (block.IsTable) { - writer.WriteLine(); - - foreach (var item in block.Properties) - writer.WriteLine($"""var index{item.Identifier.Value} = reader.GetOrdinal("{item.Identifier.Value}");"""); - - writer.WriteLine(); - writer.Block("do", () => - { - writer.Block($"""if (reader.GetString(0) == "{switchCase}")""", () => - { - writer.Write($"response.{block.Name}.Add(new("); - writer.Indent++; - var comma = ""; - foreach (var item in block.Properties) - { - writer.WriteLine(comma); - writer.Write($"""{item.DataReader()}(index{item.Identifier.Value})"""); - comma = ","; - } - writer.Indent--; - writer.WriteLine("));"); - }); - }, $"""while (await reader.ReadAsync(cancellationToken));"""); + LoopProperties(switchCase, $"response.{block.Name}", block.Properties); } else if (block.IsObject) { @@ -269,6 +283,33 @@ void SwitchStatements() { //writer.WriteLine("""//default: throw new Exception($"Invalid Table `{reader.GetString(0)}`");"""); } + + void LoopProperties(string switchCase, string model, List properties) + { + writer.WriteLine(); + + foreach (var item in properties) + writer.WriteLine($"""var index{item.Identifier.Value} = reader.GetOrdinal("{item.Identifier.Value}");"""); + + writer.WriteLine(); + writer.Block("do", () => + { + writer.Block($"""if (reader.GetString(0) == "{switchCase}")""", () => + { + writer.Write($"{model}.Add(new("); + writer.Indent++; + var comma = ""; + foreach (var item in properties) + { + writer.WriteLine(comma); + writer.Write($"""{item.DataReader()}(index{item.Identifier.Value})"""); + comma = ","; + } + writer.Indent--; + writer.WriteLine("));"); + }); + }, $"""while (await reader.ReadAsync(cancellationToken));"""); + } } void InsertQueries() @@ -367,12 +408,19 @@ void AddParams(string param, string index, string item) } } - string TableDeclaration(string name, CodeBlock block) => $""" - Declare {block.DatabaseType.Original}( - [{SQuiLTableTypeDatabaseTagName}{name[1..^6]}__] varchar(max) default('{name[1..^6]}'), - {string.Join($",{writer.NewLine}\t", block.Properties.Select(p - => $"{p.Identifier.Value} {p.Type.Original}"))}); - """; + string TableDeclaration(string name, CodeBlock block) + { + name = name[1..^6].Trim(); + if (name == "Errors") + name = "Error"; + + return $""" + Declare {block.DatabaseType.Original}( + [{SQuiLTableTypeDatabaseTagName}{name}__] varchar(max) default('{name}'), + {string.Join($",{writer.NewLine}\t", block.Properties.Select(p + => $"[{p.Identifier.Value}] {p.Type.Original}"))}); + """; + } void CommandParameters() { @@ -398,8 +446,7 @@ void CommandParameters() var comma = $""; foreach (var parameter in parameters) { - if (parameter.Name.Equals(SQuiLGenerator.EnvironmentName)) continue; - if (parameter.Name.Equals(SQuiLGenerator.Debug)) continue; + if (SQuiLGenerator.IsSpecial(parameter.Name)) continue; writer.WriteLine(comma); writer.Write($$"""new("@Param_{{parameter.Name}}", {{parameter.SqlDbType()}}) """); diff --git a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLModel.cs b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLModel.cs index 79a8a7a..f590da9 100644 --- a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLModel.cs +++ b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLModel.cs @@ -8,6 +8,7 @@ using System.CodeDom.Compiler; using System.Collections.Immutable; +using System.Diagnostics; namespace SQuiL.Models; @@ -78,21 +79,11 @@ private SQuiLModel Build(IEnumerable blocks) { foreach (var block in blocks) { - if (block.Name == SQuiLGenerator.Debug - || block.Name == SQuiLGenerator.EnvironmentName + if (SQuiLGenerator.IsSpecial(block.Name) || InheritsProperty(ModelName, block.Name)) - continue; - - if (block.IsTable) - Create(block, (p, q) => new(NameSpace, Modifier(p), p, block, TableMap, Records) - { - HasParameterizedConstructor = q - }); - else if (block.IsObject) - Create(block, (p, q) => new(NameSpace, Modifier(p), p, block, TableMap, Records) - { - HasParameterizedConstructor = q - }); + CreateSpecial(block); + else if (block.IsTable || block.IsObject) + CreateTableObject(block); else Properties.Add(new(block, TableMap)); } @@ -100,21 +91,40 @@ private SQuiLModel Build(IEnumerable blocks) return this; } - private void Create(CodeBlock block, Func callback) where T : SQuiLTable + private void CreateSpecial(CodeBlock block) + { + if (!SQuiLGenerator.IsError(block.Name)) return; + CreateTableObject(block, false); + } + + private void CreateTableObject(CodeBlock block, bool addProperty = true) { - var type = typeof(T).Name[5..]; + var type = (addProperty + ? (block.IsTable ? typeof(SQuiLTable) : typeof(SQuiLObject)) + : typeof(SQuiLProperty)).Name[5..]; if (block.Properties is null) throw new DiagnosticException( $"Cannot generate {type} `{block.Name}` for {ModelName}"); - //type = $"{Scope}{block.Name}{type}"; - var hasParameterizedConstructor = !Records.TryGetValue(type, out var partial) || partial.Syntax.ParameterList?.Parameters.Count == 0; - var table = callback(type, hasParameterizedConstructor); - Properties.Add(table); + var name = $"{block.Name}{type}"; + + if (addProperty) name = $"{NameSpace}{block.Name}"; else type = ""; + + SQuiLTable table = block.IsTable + ? new SQuiLTable(NameSpace, Modifier(name), type, block, TableMap, Records) + { + HasParameterizedConstructor = hasParameterizedConstructor + } + : new SQuiLObject(NameSpace, Modifier(name), type, block, TableMap, Records) + { + HasParameterizedConstructor = hasParameterizedConstructor + }; + + if (addProperty) Properties.Add(table); TableMap.Add(table); if (hasParameterizedConstructor) diff --git a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLProperty.cs b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLProperty.cs index c6df93d..c293983 100644 --- a/SQuiL.SourceGenerator/SQuiL/Models/SQuiLProperty.cs +++ b/SQuiL.SourceGenerator/SQuiL/Models/SQuiLProperty.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; +using SQuiL.Generator; using SQuiL.SourceGenerator.Parser; using System.CodeDom.Compiler; @@ -21,8 +22,12 @@ public class SQuiLProperty( public string TableName() { + if (SQuiLGenerator.IsError(OriginalName)) + return $"SQuiL{OriginalName}"; + if (!TableMap.TryGetName(OriginalName, out var tableName)) tableName = $"{OriginalName}{Type}"; + return tableName; } diff --git a/SQuiL.SourceGenerator/SQuiL/Parser/SQuiLParser.cs b/SQuiL.SourceGenerator/SQuiL/Parser/SQuiLParser.cs index 57f004f..2bad3f5 100644 --- a/SQuiL.SourceGenerator/SQuiL/Parser/SQuiLParser.cs +++ b/SQuiL.SourceGenerator/SQuiL/Parser/SQuiLParser.cs @@ -4,6 +4,7 @@ using SQuiL.Models; using SQuiL.Tokenizer; +using System.Diagnostics; using System.Text; namespace SQuiL.SourceGenerator.Parser; @@ -50,9 +51,19 @@ public List ParseTokens() var token = Expect(TokenType.VARIABLE); var parts = token.Value.Split(['_'], 2); - if (parts[0].Equals(SQuiLGenerator.EnvironmentName) - || parts[0].Equals(SQuiLGenerator.Debug)) - return new(token, CodeType.INPUT_ARGUMENT, false, false, parts[0]); + if (SQuiLGenerator.IsSpecial(parts[0])) + { + if (!SQuiLGenerator.IsError(parts[0])) + return new(token, CodeType.INPUT_ARGUMENT, false, false, parts[0]); + + if (Current.Type != TokenType.TYPE_TABLE) + ThrowError(); + + if(parts[0].Last() == 's') + return new(token, CodeType.OUTPUT_TABLE, false, true, parts[0]); + + return new(token, CodeType.OUTPUT_OBJECT, true, false, parts[0]); + } if (parts[0].StartsWith("param", StringComparison.CurrentCultureIgnoreCase)) { @@ -74,19 +85,18 @@ public List ParseTokens() return new(token, type, type == CodeType.OUTPUT_OBJECT, type == CodeType.OUTPUT_TABLE, parts[1]); } - if (declaring) - throw new DiagnosticException( - $"Expected a declare with @Param_, @Params_, " + - $"@Return_, or/and @Returns_, " + - $"but found @{token.Value} instead."); + if (declaring) ThrowError(); - string name; - if (parts.Length == 1 || parts[1].IsNullOrWhiteSpace()) - name = $"Result{++resultIndex}"; - else - name = parts[1]; + var name = parts.Length == 1 || parts[1].IsNullOrWhiteSpace() + ? $"Result{++resultIndex}" + : parts[1]; return new(token, CodeType.OUTPUT, false, Current.Type == TokenType.TYPE_TABLE, name); + + void ThrowError() => throw new DiagnosticException( + $"Expected a declare with @Param_, @Params_, " + + $"@Return_, or/and @Returns_, " + + $"but found @{token.Value} instead."); }; } @@ -190,7 +200,7 @@ void ProcessBodyStatement() injected.Add(name); sb.AppendLine() - .AppendLine($"Select{T(name)} {table.Token.Original}"); + .AppendLine($"Select{T(name)} {table.Token.Original};"); } CodeBlocks.Add(new(CodeType.BODY, Current with diff --git a/SQuiL.SourceGenerator/SQuiL/Tokenizer/SQuiLTokenizer.cs b/SQuiL.SourceGenerator/SQuiL/Tokenizer/SQuiLTokenizer.cs index a6e551b..60dfd3f 100644 --- a/SQuiL.SourceGenerator/SQuiL/Tokenizer/SQuiLTokenizer.cs +++ b/SQuiL.SourceGenerator/SQuiL/Tokenizer/SQuiLTokenizer.cs @@ -419,7 +419,7 @@ void Throw(string type) { var length = Word.IndexOfAny([' ', '\t', '\r', '\n']); if (length < 1) throw DE(Word.Length, $"Invalid {type}: `{Word}`"); - throw DE(length, $"Invalid {type}: `{Word.Substring(0, length)}`"); + throw DE(length, $"Invalid {type}: `{Word[..length]}`"); } } diff --git a/SQuiL.Tests/ErrorQueryTests/ErrorQueryTests.cs b/SQuiL.Tests/ErrorQueryTests/ErrorQueryTests.cs new file mode 100644 index 0000000..ae9727d --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/ErrorQueryTests.cs @@ -0,0 +1,83 @@ +using System.Runtime.CompilerServices; + +using static Microsoft.CodeAnalysis.SourceGeneratorHelper; + +namespace SQuiL.Tests; + +public class ErrorQueryTests +{ + private static string TestHeader( + IEnumerable attributes = default!, + Func callback = default!, + [CallerMemberName] string name = default!) + { + attributes ??= [name]; + callback ??= p => $$""" + [{{QueryAttributeName}}(QueryFiles.{{p}})] + """; + + return $$""" + using Microsoft.Extensions.Configuration; + using {{NamespaceName}}; + + namespace TestCase; + + {{string.Join("", attributes.Select(callback))}} + public partial class {{name}}DataContext(IConfiguration Configuration) : {{BaseDataContextClassName}}(Configuration) + { + } + """; + } + + [Fact] + public Task QueryHasErrorObject() + { + var name = nameof(QueryHasErrorObject); + return TestHelper.Verify([TestHeader([name])], [$$""" + --Name: {{name}} + Declare @Debug bit = 1; + Declare @Param_Elapsed int; + + Declare @Return_SampleID int; + Declare @Return_SampleEntity table(ID int); + Declare @Returns_Samples table(ID int); + + Declare @Error table( + Number int, + Severity int, + [State] int, + Line int, + [Procedure] varchar(max), + [Message] varchar(max) + ); + + Use DataRepository; + """]); + } + + [Fact] + public Task QueryHasErrorList() + { + var name = nameof(QueryHasErrorList); + return TestHelper.Verify([TestHeader([name])], [$$""" + --Name: {{name}} + Declare @Debug bit = 1; + Declare @Param_Elapsed int; + + Declare @Return_SampleID int; + Declare @Return_SampleEntity table(ID int); + Declare @Returns_Samples table(ID int); + + Declare @Errors table( + Number int, + Severity int, + [State] int, + Line int, + [Procedure] varchar(max), + [Message] varchar(max) + ); + + Use DataRepository; + """]); + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListDataContext.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListDataContext.g.verified.cs new file mode 100644 index 0000000..8d49d90 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListDataContext.g.verified.cs @@ -0,0 +1,184 @@ +//HintName: QueryHasErrorListDataContext.g.cs +// + +#nullable enable + +using Microsoft.Data.SqlClient; + +using SQuiL; + +namespace TestCase; + +partial class QueryHasErrorListDataContext : SQuiLBaseDataContext +{ + public async Task> ProcessQueryHasErrorListAsync( + QueryHasErrorListRequest request, + CancellationToken cancellationToken = default!) + { + var builder = ConnectionStringBuilder("SQuiLDatabase"); + using SqlConnection connection = new(builder.ConnectionString); + var command = connection.CreateCommand(); + + List parameters = new() + { + new("@EnvironmentName", System.Data.SqlDbType.VarChar, EnvironmentName.Length) { Value = EnvironmentName }, + new("@Debug", System.Data.SqlDbType.Bit) { Value = EnvironmentName != "Production" }, + new("@Param_Elapsed", System.Data.SqlDbType.BigInt) + { + IsNullable = true, + Value = request.Elapsed ?? (object)System.DBNull.Value + } + }; + + command.CommandText = Query(parameters); + command.Parameters.AddRange(parameters.ToArray()); + + await connection.OpenAsync(cancellationToken); + + QueryHasErrorListResponse response = new(); + + var isSampleID = false; + var isSampleEntity = false; + var isSamples = false; + + List errors = []; + + using var reader = await command.ExecuteReaderAsync(cancellationToken); + + do + { + var tableTag = reader.GetName(0); + if(tableTag.StartsWith("__SQuiL__Table__Type__")) + { + switch (tableTag) + { + case "__SQuiL__Table__Type__Error__": + { + if (!await reader.ReadAsync(cancellationToken)) break; + + var indexNumber = reader.GetOrdinal("Number"); + var indexSeverity = reader.GetOrdinal("Severity"); + var indexState = reader.GetOrdinal("State"); + var indexLine = reader.GetOrdinal("Line"); + var indexProcedure = reader.GetOrdinal("Procedure"); + var indexMessage = reader.GetOrdinal("Message"); + + do + { + if (reader.GetString(0) == "Error") + { + errors.Add(new( + reader.GetInt32(indexNumber), + reader.GetInt32(indexSeverity), + reader.GetInt32(indexState), + reader.GetInt32(indexLine), + reader.GetString(indexProcedure), + reader.GetString(indexMessage))); + } + } + while (await reader.ReadAsync(cancellationToken)); + + break; + } + case "__SQuiL__Table__Type__Return_SampleID__": + { + if (isSampleID) throw new Exception( + "Already returned value for `SampleID`"); + + isSampleID = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + response.SampleID = !reader.IsDBNull(1) ? reader.GetInt32(1) : null; + break; + } + case "__SQuiL__Table__Type__Return_SampleEntity__": + { + if (isSampleEntity) throw new Exception( + "Already returned value for `SampleEntity`"); + + isSampleEntity = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + if (response.SampleEntity is not null) + throw new Exception("SampleEntity was already set."); + + if (reader.GetString(0) == "Return_SampleEntity") + { + response.SampleEntity = new( + reader.GetInt32(reader.GetOrdinal("ID"))); + } + else + { + continue; + } + + if (await reader.ReadAsync(cancellationToken)) + throw new Exception( + "Return object results in more than one object. Consider using a return table instead."); + + break; + } + case "__SQuiL__Table__Type__Returns_Samples__": + { + isSamples = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + var indexID = reader.GetOrdinal("ID"); + + do + { + if (reader.GetString(0) == "Returns_Samples") + { + response.Samples.Add(new( + reader.GetInt32(indexID))); + } + } + while (await reader.ReadAsync(cancellationToken)); + break; + } + } + } + } + while (await reader.NextResultAsync(cancellationToken)); + + if (!isSampleID) throw new Exception("Expected return scaler `SampleID`)"); + if (!isSampleEntity) throw new Exception("Expected return object `SampleEntity`)"); + if (!isSamples) throw new Exception("Expected return table `Samples`)"); + + if(errors.Count == 0) + return new(response); + + return new(errors); + + string Query(List parameters) => $""" + Declare @Return_SampleID int; + + Declare @Return_SampleEntity table( + [__SQuiL__Table__Type__Return_SampleEntity__] varchar(max) default('Return_SampleEntity'), + [ID] int); + + Declare @Returns_Samples table( + [__SQuiL__Table__Type__Returns_Samples__] varchar(max) default('Returns_Samples'), + [ID] int); + + Declare @Errors table( + [__SQuiL__Table__Type__Error__] varchar(max) default('Error'), + [Number] int, + [Severity] int, + [State] int, + [Line] int, + [Procedure] varchar(max), + [Message] varchar(max)); + + Use [{builder.InitialCatalog}]; + + + + Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; + + """; + } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListRequest.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListRequest.g.verified.cs new file mode 100644 index 0000000..42ef944 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListRequest.g.verified.cs @@ -0,0 +1,13 @@ +//HintName: QueryHasErrorListRequest.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record QueryHasErrorListRequest +{ + public bool Debug { get; set; } + + public int? Elapsed { get; set; } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListResponse.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListResponse.g.verified.cs new file mode 100644 index 0000000..dec05da --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#QueryHasErrorListResponse.g.verified.cs @@ -0,0 +1,15 @@ +//HintName: QueryHasErrorListResponse.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record QueryHasErrorListResponse +{ + public int? SampleID { get; set; } + + public SampleEntityObject? SampleEntity { get; set; } = default!; + + public System.Collections.Generic.List Samples { get; set; } = []; +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLBaseDataContext.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLBaseDataContext.g.verified.cs new file mode 100644 index 0000000..df75b9a --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLBaseDataContext.g.verified.cs @@ -0,0 +1,48 @@ +//HintName: SQuiLBaseDataContext.g.cs +// + +#nullable enable + +namespace SQuiL; + +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; + +using System.Collections.Generic; +using System; + +public abstract class SQuiLBaseDataContext(IConfiguration Configuration) +{ + //public virtual string SettingName { get; } = "SQuiLDatabase"; + + protected string EnvironmentName { get; } = Configuration.GetSection("EnvironmentName")?.Value + ?? Environment.GetEnvironmentVariable(Configuration.GetSection("EnvironmentVariable")?.Value ?? "ASPNETCORE_ENVIRONMENT") + ?? "Development"; + + protected SqlConnectionStringBuilder ConnectionStringBuilder(string settingName) + { + return new SqlConnectionStringBuilder(Configuration.GetConnectionString(settingName) + ?? throw new Exception($"Cannot find a connection string in the appsettings for {settingName}.")); + } + + protected void AddParams(System.Text.StringBuilder query, List parameters, int index, string table, string name, System.Data.SqlDbType type, object value, int size = 0) + { + var parameter = $"@{table}_{index}_{name}"; + query.Append($"[{parameter}]"); + + if (size == 0) + { + parameters.Add(new(parameter, type) { Value = value }); + return; + } + + parameters.Add(new(parameter, type, size) { + Value = value is null || ((string)value).Length <= size + ? (value ?? "Null") + : throw new Exception($""" + ParamsTable model table property at index [2] has a string property [{name}] + with more than {size} characters. + """) + }); + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLErrors.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLErrors.g.verified.cs new file mode 100644 index 0000000..334bc6e --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLErrors.g.verified.cs @@ -0,0 +1,14 @@ +//HintName: SQuiLErrors.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SQuiLErrors( + int Number, + int Severity, + int State, + int Line, + string Procedure, + string Message); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLExtensions.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLExtensions.g.verified.cs new file mode 100644 index 0000000..8084aca --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLExtensions.g.verified.cs @@ -0,0 +1,19 @@ +//HintName: SQuiLExtensions.g.cs +// + +#nullable enable + +namespace Microsoft.Extensions.DependencyInjection; + +public static class SQuiLExtensions +{ + public static bool IsLoaded => true; + + public static IServiceCollection AddSQuiL( + this IServiceCollection services) + { + services.AddSingleton(); + + return services; + } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryAttribute.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryAttribute.g.verified.cs new file mode 100644 index 0000000..4322a14 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: SQuiLQueryAttribute.g.cs +// + +#nullable enable + +namespace SQuiL; + +[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] +public class SQuiLQueryAttribute : System.Attribute +{ + public QueryFiles Type { get; } + + public string Setting { get; } + + public SQuiLQueryAttribute( + QueryFiles type, + string setting = "SQuiLDatabase") + { + Type = type; + Setting = setting; + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryFilesEnum.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryFilesEnum.g.verified.cs new file mode 100644 index 0000000..269f23f --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLQueryFilesEnum.g.verified.cs @@ -0,0 +1,11 @@ +//HintName: SQuiLQueryFilesEnum.g.cs +// + +#nullable enable + +namespace SQuiL; + +public enum QueryFiles +{ + QueryHasErrorList +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableAttribute.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableAttribute.verified.cs new file mode 100644 index 0000000..c9d0cd7 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableAttribute.verified.cs @@ -0,0 +1,17 @@ +//HintName: SQuiLTableAttribute.cs +// + +#nullable enable + +namespace SQuiL; + +[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] +public class SQuiLTableAttribute : System.Attribute +{ + public TableType Type { get; } + + public SQuiLTableAttribute(TableType type) + { + Type = type; + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableTypeEnum.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableTypeEnum.g.verified.cs new file mode 100644 index 0000000..690aa8d --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SQuiLTableTypeEnum.g.verified.cs @@ -0,0 +1,12 @@ +//HintName: SQuiLTableTypeEnum.g.cs +// + +#nullable enable + +namespace SQuiL; + +public enum TableType +{ + SampleEntity, + Samples +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SampleEntityObject.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SampleEntityObject.g.verified.cs new file mode 100644 index 0000000..e6b53f4 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SampleEntityObject.g.verified.cs @@ -0,0 +1,9 @@ +//HintName: SampleEntityObject.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SampleEntityObject( + int ID); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SamplesTable.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SamplesTable.g.verified.cs new file mode 100644 index 0000000..b00c6bf --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList#SamplesTable.g.verified.cs @@ -0,0 +1,9 @@ +//HintName: SamplesTable.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SamplesTable( + int ID); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList.verified.txt b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList.verified.txt new file mode 100644 index 0000000..852f377 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorList/ErrorQueryTests.QueryHasErrorList.verified.txt @@ -0,0 +1,584 @@ +{ + Diagnostics: [ + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_BOOLEAN, Offset = 15, Value = , Original = @Debug bit }, Name = Debug, DefaultValue = 1, IsObject = False, IsTable = False, IsRequired = False, IsNullable = False, Size = , Properties = }, + Message: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_BOOLEAN, Offset = 15, Value = , Original = @Debug bit }, Name = Debug, DefaultValue = 1, IsObject = False, IsTable = False, IsRequired = False, IsNullable = False, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_INT, Offset = 48, Value = Elapsed, Original = @Param_Elapsed int }, Name = Elapsed, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_INT, Offset = 48, Value = Elapsed, Original = @Param_Elapsed int }, Name = Elapsed, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_VARIABLE, DatabaseType = Token { Type = TYPE_INT, Offset = 81, Value = SampleID, Original = @Return_SampleID int }, Name = SampleID, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = OUTPUT_VARIABLE, DatabaseType = Token { Type = TYPE_INT, Offset = 81, Value = SampleID, Original = @Return_SampleID int }, Name = SampleID, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 87, Value = SampleEntity, Original = @Return_SampleEntity table }, Name = SampleEntity, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 87, Value = SampleEntity, Original = @Return_SampleEntity table }, Name = SampleEntity, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 132, Value = Samples, Original = @Returns_Samples table }, Name = Samples, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 132, Value = Samples, Original = @Returns_Samples table }, Name = Samples, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 175, Value = Errors, Original = @Errors table }, Name = Errors, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 175, Value = Errors, Original = @Errors table }, Name = Errors, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = USING, DatabaseType = Token { Type = IDENTIFIER, Offset = 319, Value = DataRepository, Original = DataRepository }, Name = DataRepository, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = USING, DatabaseType = Token { Type = IDENTIFIER, Offset = 319, Value = DataRepository, Original = DataRepository }, Name = DataRepository, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = BODY, DatabaseType = Token { Type = BODY, Offset = 334, Value = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , Original = }, Name = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = BODY, DatabaseType = Token { Type = BODY, Offset = 334, Value = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , Original = }, Name = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Debug, + Message: VARIABLE => Debug, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_BOOLEAN => , + Message: TYPE_BOOLEAN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_EQUAL => , + Message: SYMBOL_EQUAL => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: LITERAL_NUMBER => 1, + Message: LITERAL_NUMBER => 1, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Param_Elapsed, + Message: VARIABLE => Param_Elapsed, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Return_SampleID, + Message: VARIABLE => Return_SampleID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Return_SampleEntity, + Message: VARIABLE => Return_SampleEntity, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => ID, + Message: IDENTIFIER => ID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Returns_Samples, + Message: VARIABLE => Returns_Samples, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => ID, + Message: IDENTIFIER => ID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Errors, + Message: VARIABLE => Errors, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Number, + Message: IDENTIFIER => Number, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Severity, + Message: IDENTIFIER => Severity, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => State, + Message: IDENTIFIER => State, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Line, + Message: IDENTIFIER => Line, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Procedure, + Message: IDENTIFIER => Procedure, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_STRING => 4096, + Message: TYPE_STRING => 4096, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Message, + Message: IDENTIFIER => Message, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_STRING => 4096, + Message: TYPE_STRING => 4096, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_USE => , + Message: KEYWORD_USE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => DataRepository, + Message: IDENTIFIER => DataRepository, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: BODY => , + Message: BODY => , + Category: Logger + } + ] +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectDataContext.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectDataContext.g.verified.cs new file mode 100644 index 0000000..be3265f --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectDataContext.g.verified.cs @@ -0,0 +1,184 @@ +//HintName: QueryHasErrorObjectDataContext.g.cs +// + +#nullable enable + +using Microsoft.Data.SqlClient; + +using SQuiL; + +namespace TestCase; + +partial class QueryHasErrorObjectDataContext : SQuiLBaseDataContext +{ + public async Task> ProcessQueryHasErrorObjectAsync( + QueryHasErrorObjectRequest request, + CancellationToken cancellationToken = default!) + { + var builder = ConnectionStringBuilder("SQuiLDatabase"); + using SqlConnection connection = new(builder.ConnectionString); + var command = connection.CreateCommand(); + + List parameters = new() + { + new("@EnvironmentName", System.Data.SqlDbType.VarChar, EnvironmentName.Length) { Value = EnvironmentName }, + new("@Debug", System.Data.SqlDbType.Bit) { Value = EnvironmentName != "Production" }, + new("@Param_Elapsed", System.Data.SqlDbType.BigInt) + { + IsNullable = true, + Value = request.Elapsed ?? (object)System.DBNull.Value + } + }; + + command.CommandText = Query(parameters); + command.Parameters.AddRange(parameters.ToArray()); + + await connection.OpenAsync(cancellationToken); + + QueryHasErrorObjectResponse response = new(); + + var isSampleID = false; + var isSampleEntity = false; + var isSamples = false; + + List errors = []; + + using var reader = await command.ExecuteReaderAsync(cancellationToken); + + do + { + var tableTag = reader.GetName(0); + if(tableTag.StartsWith("__SQuiL__Table__Type__")) + { + switch (tableTag) + { + case "__SQuiL__Table__Type__Error__": + { + if (!await reader.ReadAsync(cancellationToken)) break; + + var indexNumber = reader.GetOrdinal("Number"); + var indexSeverity = reader.GetOrdinal("Severity"); + var indexState = reader.GetOrdinal("State"); + var indexLine = reader.GetOrdinal("Line"); + var indexProcedure = reader.GetOrdinal("Procedure"); + var indexMessage = reader.GetOrdinal("Message"); + + do + { + if (reader.GetString(0) == "Error") + { + errors.Add(new( + reader.GetInt32(indexNumber), + reader.GetInt32(indexSeverity), + reader.GetInt32(indexState), + reader.GetInt32(indexLine), + reader.GetString(indexProcedure), + reader.GetString(indexMessage))); + } + } + while (await reader.ReadAsync(cancellationToken)); + + break; + } + case "__SQuiL__Table__Type__Return_SampleID__": + { + if (isSampleID) throw new Exception( + "Already returned value for `SampleID`"); + + isSampleID = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + response.SampleID = !reader.IsDBNull(1) ? reader.GetInt32(1) : null; + break; + } + case "__SQuiL__Table__Type__Return_SampleEntity__": + { + if (isSampleEntity) throw new Exception( + "Already returned value for `SampleEntity`"); + + isSampleEntity = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + if (response.SampleEntity is not null) + throw new Exception("SampleEntity was already set."); + + if (reader.GetString(0) == "Return_SampleEntity") + { + response.SampleEntity = new( + reader.GetInt32(reader.GetOrdinal("ID"))); + } + else + { + continue; + } + + if (await reader.ReadAsync(cancellationToken)) + throw new Exception( + "Return object results in more than one object. Consider using a return table instead."); + + break; + } + case "__SQuiL__Table__Type__Returns_Samples__": + { + isSamples = true; + + if (!await reader.ReadAsync(cancellationToken)) break; + + var indexID = reader.GetOrdinal("ID"); + + do + { + if (reader.GetString(0) == "Returns_Samples") + { + response.Samples.Add(new( + reader.GetInt32(indexID))); + } + } + while (await reader.ReadAsync(cancellationToken)); + break; + } + } + } + } + while (await reader.NextResultAsync(cancellationToken)); + + if (!isSampleID) throw new Exception("Expected return scaler `SampleID`)"); + if (!isSampleEntity) throw new Exception("Expected return object `SampleEntity`)"); + if (!isSamples) throw new Exception("Expected return table `Samples`)"); + + if(errors.Count == 0) + return new(response); + + return new(errors); + + string Query(List parameters) => $""" + Declare @Return_SampleID int; + + Declare @Return_SampleEntity table( + [__SQuiL__Table__Type__Return_SampleEntity__] varchar(max) default('Return_SampleEntity'), + [ID] int); + + Declare @Returns_Samples table( + [__SQuiL__Table__Type__Returns_Samples__] varchar(max) default('Returns_Samples'), + [ID] int); + + Declare @Error table( + [__SQuiL__Table__Type__Error__] varchar(max) default('Error'), + [Number] int, + [Severity] int, + [State] int, + [Line] int, + [Procedure] varchar(max), + [Message] varchar(max)); + + Use [{builder.InitialCatalog}]; + + + + Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; + + """; + } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectRequest.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectRequest.g.verified.cs new file mode 100644 index 0000000..0b145c6 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectRequest.g.verified.cs @@ -0,0 +1,13 @@ +//HintName: QueryHasErrorObjectRequest.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record QueryHasErrorObjectRequest +{ + public bool Debug { get; set; } + + public int? Elapsed { get; set; } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectResponse.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectResponse.g.verified.cs new file mode 100644 index 0000000..9d4a366 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#QueryHasErrorObjectResponse.g.verified.cs @@ -0,0 +1,15 @@ +//HintName: QueryHasErrorObjectResponse.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record QueryHasErrorObjectResponse +{ + public int? SampleID { get; set; } + + public SampleEntityObject? SampleEntity { get; set; } = default!; + + public System.Collections.Generic.List Samples { get; set; } = []; +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLBaseDataContext.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLBaseDataContext.g.verified.cs new file mode 100644 index 0000000..df75b9a --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLBaseDataContext.g.verified.cs @@ -0,0 +1,48 @@ +//HintName: SQuiLBaseDataContext.g.cs +// + +#nullable enable + +namespace SQuiL; + +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; + +using System.Collections.Generic; +using System; + +public abstract class SQuiLBaseDataContext(IConfiguration Configuration) +{ + //public virtual string SettingName { get; } = "SQuiLDatabase"; + + protected string EnvironmentName { get; } = Configuration.GetSection("EnvironmentName")?.Value + ?? Environment.GetEnvironmentVariable(Configuration.GetSection("EnvironmentVariable")?.Value ?? "ASPNETCORE_ENVIRONMENT") + ?? "Development"; + + protected SqlConnectionStringBuilder ConnectionStringBuilder(string settingName) + { + return new SqlConnectionStringBuilder(Configuration.GetConnectionString(settingName) + ?? throw new Exception($"Cannot find a connection string in the appsettings for {settingName}.")); + } + + protected void AddParams(System.Text.StringBuilder query, List parameters, int index, string table, string name, System.Data.SqlDbType type, object value, int size = 0) + { + var parameter = $"@{table}_{index}_{name}"; + query.Append($"[{parameter}]"); + + if (size == 0) + { + parameters.Add(new(parameter, type) { Value = value }); + return; + } + + parameters.Add(new(parameter, type, size) { + Value = value is null || ((string)value).Length <= size + ? (value ?? "Null") + : throw new Exception($""" + ParamsTable model table property at index [2] has a string property [{name}] + with more than {size} characters. + """) + }); + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLError.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLError.g.verified.cs new file mode 100644 index 0000000..c74681c --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLError.g.verified.cs @@ -0,0 +1,14 @@ +//HintName: SQuiLError.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SQuiLError( + int Number, + int Severity, + int State, + int Line, + string Procedure, + string Message); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLExtensions.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLExtensions.g.verified.cs new file mode 100644 index 0000000..b455aa2 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLExtensions.g.verified.cs @@ -0,0 +1,19 @@ +//HintName: SQuiLExtensions.g.cs +// + +#nullable enable + +namespace Microsoft.Extensions.DependencyInjection; + +public static class SQuiLExtensions +{ + public static bool IsLoaded => true; + + public static IServiceCollection AddSQuiL( + this IServiceCollection services) + { + services.AddSingleton(); + + return services; + } +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryAttribute.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryAttribute.g.verified.cs new file mode 100644 index 0000000..4322a14 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: SQuiLQueryAttribute.g.cs +// + +#nullable enable + +namespace SQuiL; + +[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] +public class SQuiLQueryAttribute : System.Attribute +{ + public QueryFiles Type { get; } + + public string Setting { get; } + + public SQuiLQueryAttribute( + QueryFiles type, + string setting = "SQuiLDatabase") + { + Type = type; + Setting = setting; + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryFilesEnum.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryFilesEnum.g.verified.cs new file mode 100644 index 0000000..c68994d --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLQueryFilesEnum.g.verified.cs @@ -0,0 +1,11 @@ +//HintName: SQuiLQueryFilesEnum.g.cs +// + +#nullable enable + +namespace SQuiL; + +public enum QueryFiles +{ + QueryHasErrorObject +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableAttribute.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableAttribute.verified.cs new file mode 100644 index 0000000..c9d0cd7 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableAttribute.verified.cs @@ -0,0 +1,17 @@ +//HintName: SQuiLTableAttribute.cs +// + +#nullable enable + +namespace SQuiL; + +[System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] +public class SQuiLTableAttribute : System.Attribute +{ + public TableType Type { get; } + + public SQuiLTableAttribute(TableType type) + { + Type = type; + } +} \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableTypeEnum.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableTypeEnum.g.verified.cs new file mode 100644 index 0000000..690aa8d --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SQuiLTableTypeEnum.g.verified.cs @@ -0,0 +1,12 @@ +//HintName: SQuiLTableTypeEnum.g.cs +// + +#nullable enable + +namespace SQuiL; + +public enum TableType +{ + SampleEntity, + Samples +} diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SampleEntityObject.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SampleEntityObject.g.verified.cs new file mode 100644 index 0000000..e6b53f4 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SampleEntityObject.g.verified.cs @@ -0,0 +1,9 @@ +//HintName: SampleEntityObject.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SampleEntityObject( + int ID); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesSamplesTable.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesSamplesTable.g.verified.cs new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesSamplesTable.g.verified.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesTable.g.verified.cs b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesTable.g.verified.cs new file mode 100644 index 0000000..b00c6bf --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject#SamplesTable.g.verified.cs @@ -0,0 +1,9 @@ +//HintName: SamplesTable.g.cs +// + +#nullable enable + +namespace TestCase; + +public partial record SamplesTable( + int ID); diff --git a/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject.verified.txt b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject.verified.txt new file mode 100644 index 0000000..6ca8902 --- /dev/null +++ b/SQuiL.Tests/ErrorQueryTests/QueryHasErrorObject/ErrorQueryTests.QueryHasErrorObject.verified.txt @@ -0,0 +1,584 @@ +{ + Diagnostics: [ + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_BOOLEAN, Offset = 15, Value = , Original = @Debug bit }, Name = Debug, DefaultValue = 1, IsObject = False, IsTable = False, IsRequired = False, IsNullable = False, Size = , Properties = }, + Message: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_BOOLEAN, Offset = 15, Value = , Original = @Debug bit }, Name = Debug, DefaultValue = 1, IsObject = False, IsTable = False, IsRequired = False, IsNullable = False, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_INT, Offset = 48, Value = Elapsed, Original = @Param_Elapsed int }, Name = Elapsed, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = INPUT_ARGUMENT, DatabaseType = Token { Type = TYPE_INT, Offset = 48, Value = Elapsed, Original = @Param_Elapsed int }, Name = Elapsed, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_VARIABLE, DatabaseType = Token { Type = TYPE_INT, Offset = 81, Value = SampleID, Original = @Return_SampleID int }, Name = SampleID, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = OUTPUT_VARIABLE, DatabaseType = Token { Type = TYPE_INT, Offset = 81, Value = SampleID, Original = @Return_SampleID int }, Name = SampleID, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 87, Value = SampleEntity, Original = @Return_SampleEntity table }, Name = SampleEntity, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 87, Value = SampleEntity, Original = @Return_SampleEntity table }, Name = SampleEntity, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 132, Value = Samples, Original = @Returns_Samples table }, Name = Samples, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_TABLE, DatabaseType = Token { Type = TYPE_TABLE, Offset = 132, Value = Samples, Original = @Returns_Samples table }, Name = Samples, DefaultValue = , IsObject = False, IsTable = True, IsRequired = False, IsNullable = False, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 175, Value = Error, Original = @Error table }, Name = Error, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Message: CodeBlock { CodeType = OUTPUT_OBJECT, DatabaseType = Token { Type = TYPE_OBJECT, Offset = 175, Value = Error, Original = @Error table }, Name = Error, DefaultValue = , IsObject = True, IsTable = False, IsRequired = False, IsNullable = True, Size = , Properties = System.Collections.Generic.List`1[SQuiL.SourceGenerator.Parser.CodeItem] }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = USING, DatabaseType = Token { Type = IDENTIFIER, Offset = 318, Value = DataRepository, Original = DataRepository }, Name = DataRepository, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = USING, DatabaseType = Token { Type = IDENTIFIER, Offset = 318, Value = DataRepository, Original = DataRepository }, Name = DataRepository, DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: CodeBlock { CodeType = BODY, DatabaseType = Token { Type = BODY, Offset = 333, Value = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , Original = }, Name = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Message: CodeBlock { CodeType = BODY, DatabaseType = Token { Type = BODY, Offset = 333, Value = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , Original = }, Name = Select 'Return_SampleID' As [__SQuiL__Table__Type__Return_SampleID__], @Return_SampleID; , DefaultValue = , IsObject = False, IsTable = False, IsRequired = True, IsNullable = True, Size = , Properties = }, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Debug, + Message: VARIABLE => Debug, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_BOOLEAN => , + Message: TYPE_BOOLEAN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_EQUAL => , + Message: SYMBOL_EQUAL => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: LITERAL_NUMBER => 1, + Message: LITERAL_NUMBER => 1, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Param_Elapsed, + Message: VARIABLE => Param_Elapsed, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Return_SampleID, + Message: VARIABLE => Return_SampleID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Return_SampleEntity, + Message: VARIABLE => Return_SampleEntity, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => ID, + Message: IDENTIFIER => ID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Returns_Samples, + Message: VARIABLE => Returns_Samples, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => ID, + Message: IDENTIFIER => ID, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_DECLARE => , + Message: KEYWORD_DECLARE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: VARIABLE => Error, + Message: VARIABLE => Error, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_TABLE => , + Message: TYPE_TABLE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_LPREN => , + Message: SYMBOL_LPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Number, + Message: IDENTIFIER => Number, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Severity, + Message: IDENTIFIER => Severity, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => State, + Message: IDENTIFIER => State, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Line, + Message: IDENTIFIER => Line, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_INT => , + Message: TYPE_INT => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Procedure, + Message: IDENTIFIER => Procedure, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_STRING => 4096, + Message: TYPE_STRING => 4096, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_COMMA => , + Message: SYMBOL_COMMA => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => Message, + Message: IDENTIFIER => Message, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: TYPE_STRING => 4096, + Message: TYPE_STRING => 4096, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: SYMBOL_RPREN => , + Message: SYMBOL_RPREN => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: KEYWORD_USE => , + Message: KEYWORD_USE => , + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: IDENTIFIER => DataRepository, + Message: IDENTIFIER => DataRepository, + Category: Logger + }, + { + Id: SP0000, + Title: Development Data, + Severity: Warning, + WarningLevel: 1, + Location: : (0,0)-(0,0), + MessageFormat: BODY => , + Message: BODY => , + Category: Logger + } + ] +} \ No newline at end of file