diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc0d5d55..dd31b3c9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -126,4 +126,4 @@ jobs: - name: Verify pushed codegen requests are synced run: | dotnet publish LocalRunner -c release --output dist/ - sqlc -f sqlc.local.yaml diff \ No newline at end of file + sqlc -f sqlc.requests.yaml diff \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..0c4ca5ac --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: +- repo: https://github.com/sqlfluff/sqlfluff + rev: 3.4.1 + hooks: + - id: sqlfluff-fix + args: [--FIX-EVEN-UNPARSABLE] \ No newline at end of file diff --git a/.sqlfluff b/.sqlfluff new file mode 100644 index 00000000..87b6f0ae --- /dev/null +++ b/.sqlfluff @@ -0,0 +1,17 @@ +[sqlfluff] +exclude_rules = AM04,AL03,RF02,RF04,AM05,AL01,ST06 +dialect = ansi + +[sqlfluff:rules] + +[sqlfluff:rules:LT02] +capitalisation_policy = upper + +[sqlfluff:paths:examples/config/postgresql/] +dialect = postgres + +[sqlfluff:paths:examples/config/mysql/] +dialect = mysql + +[sqlfluff:paths:examples/config/sqlite/] +dialect = sqlite diff --git a/CodeGenerator/Generators/DataClassesGen.cs b/CodeGenerator/Generators/DataClassesGen.cs index ee52840a..f2cf451d 100644 --- a/CodeGenerator/Generators/DataClassesGen.cs +++ b/CodeGenerator/Generators/DataClassesGen.cs @@ -10,24 +10,24 @@ namespace SqlcGenCsharp.Generators; internal class DataClassesGen(DbDriver dbDriver) { - public MemberDeclarationSyntax Generate(string name, ClassMember? classMember, IList columns, Options options) + public MemberDeclarationSyntax Generate(string name, ClassMember? classMember, IList columns, Options options, Query? query) { var className = classMember is null ? name : classMember.Value.Name(name); if (options.DotnetFramework.IsDotnetCore() && !options.UseDapper) - return GenerateAsRecord(className, columns); - return GenerateAsCLass(className, columns); + return GenerateAsRecord(className, columns, query); + return GenerateAsCLass(className, columns, query); } - private MemberDeclarationSyntax GenerateAsRecord(string className, IList columns) + private MemberDeclarationSyntax GenerateAsRecord(string className, IList columns, Query? query) { var seenEmbed = new Dictionary(); var recordParameters = columns - .Select(column => $"{dbDriver.GetCsharpType(column)} {GetFieldName(column, seenEmbed)}") + .Select(column => $"{dbDriver.GetCsharpType(column, query)} {GetFieldName(column, seenEmbed)}") .JoinByComma(); return ParseMemberDeclaration($"public readonly record struct {className} ({recordParameters});")!; } - private ClassDeclarationSyntax GenerateAsCLass(string className, IList columns) + private ClassDeclarationSyntax GenerateAsCLass(string className, IList columns, Query? query) { var modernDotnetSupported = dbDriver.Options.DotnetFramework.IsDotnetCore(); return ClassDeclaration(className) @@ -40,7 +40,7 @@ MemberDeclarationSyntax[] ColumnsToProperties() var seenEmbed = new Dictionary(); return columns.Select(column => { - var csharpType = dbDriver.GetCsharpType(column); + var csharpType = dbDriver.GetCsharpType(column, query); var optionalRequiredModifier = RequiredModifierNeeded(column) ? "required" : string.Empty; var setterMethod = modernDotnetSupported ? "init" : "set"; return ParseMemberDeclaration( @@ -58,7 +58,7 @@ bool RequiredModifierNeeded(Column column) return false; if (column.EmbedTable != null) return true; - return column.NotNull; + return dbDriver.IsColumnNotNull(column, query); } } diff --git a/CodeGenerator/Generators/ModelsGen.cs b/CodeGenerator/Generators/ModelsGen.cs index 1cb8cf82..9e397bdd 100644 --- a/CodeGenerator/Generators/ModelsGen.cs +++ b/CodeGenerator/Generators/ModelsGen.cs @@ -46,7 +46,7 @@ private MemberDeclarationSyntax[] GenerateDataClasses(Dictionary GetMembersForSingleQuery(Query quer private MemberDeclarationSyntax? GetQueryColumnsDataclass(Query query) { if (query.Columns.Count <= 0) return null; - return DataClassesGen.Generate(query.Name, ClassMember.Row, query.Columns, dbDriver.Options); + return DataClassesGen.Generate(query.Name, ClassMember.Row, query.Columns, dbDriver.Options, query); } private MemberDeclarationSyntax? GetQueryParamsDataclass(Query query) { if (query.Params.Count <= 0) return null; - var columns = query.Params.Select(dbDriver.GetColumnFromParam).ToList(); - return DataClassesGen.Generate(query.Name, ClassMember.Args, columns, dbDriver.Options); + var columns = query.Params.Select(p => dbDriver.GetColumnFromParam(p, query)).ToList(); + return DataClassesGen.Generate(query.Name, ClassMember.Args, columns, dbDriver.Options, query); } private MemberDeclarationSyntax? GetQueryTextConstant(Query query) diff --git a/CodegenTests/CodegenTypeOverrideTests.cs b/CodegenTests/CodegenTypeOverrideTests.cs new file mode 100644 index 00000000..afe70395 --- /dev/null +++ b/CodegenTests/CodegenTypeOverrideTests.cs @@ -0,0 +1,44 @@ +using Google.Protobuf; +using Plugin; +using SqlcGenCsharp; +using System.Text; +using System.Xml; + +namespace CodegenTests; + +public class CodegenTypeOverrideTests +{ + private readonly Settings _postgresSettings = new() + { + Engine = "postgresql", + Codegen = new Codegen { Out = "DummyProject" } + }; + + private readonly Catalog _emptyCatalog = new() + { + Schemas = + { + new Schema + { + Name = string.Empty, + Tables = { Capacity = 0 }, + Enums = { Capacity = 0 }, + } + } + }; + + private CodeGenerator CodeGenerator { get; } = new(); + + [Test] + public void TestOverrideQueryColumnDataType() + { + var request = new GenerateRequest + { + Settings = _postgresSettings, + Catalog = _emptyCatalog, + PluginOptions = ByteString.CopyFrom("{\"overrides\":[{\"column\":\"GetPostgresFunctions:max_integer\",\"csharp_type\":{\"type\":\"int\"}},{\"column\":\"GetPostgresFunctions:max_varchar\",\"csharp_type\":{\"type\":\"string\"}},{\"column\":\"GetPostgresFunctions:max_timestamp\",\"csharp_type\":{\"type\":\"DateTime\"}}]}", Encoding.UTF8) + }; + + var response = CodeGenerator.Generate(request); + } +} \ No newline at end of file diff --git a/CodegenTests/test-requests/DefaultSchemaEnum/query.sql b/CodegenTests/test-requests/DefaultSchemaEnum/query.sql index 214153a8..d57f9fac 100644 --- a/CodegenTests/test-requests/DefaultSchemaEnum/query.sql +++ b/CodegenTests/test-requests/DefaultSchemaEnum/query.sql @@ -2,4 +2,4 @@ SELECT * FROM dummy_table LIMIT 1; -- name: TestInsert :exec -INSERT INTO dummy_table (dummy_column) VALUES (?); \ No newline at end of file +INSERT INTO dummy_table (dummy_column) VALUES (?); diff --git a/CodegenTests/test-requests/DefaultSchemaEnum/schema.sql b/CodegenTests/test-requests/DefaultSchemaEnum/schema.sql index d9582408..fb53a06c 100644 --- a/CodegenTests/test-requests/DefaultSchemaEnum/schema.sql +++ b/CodegenTests/test-requests/DefaultSchemaEnum/schema.sql @@ -1,4 +1,4 @@ CREATE TABLE dummy_table ( - dummy_column ENUM ('x', 'y') -); \ No newline at end of file + dummy_column ENUM('x', 'y') +); diff --git a/CodegenTests/test-requests/SchemaScopedEnum/schema.sql b/CodegenTests/test-requests/SchemaScopedEnum/schema.sql index fe188c4b..288ddd25 100644 --- a/CodegenTests/test-requests/SchemaScopedEnum/schema.sql +++ b/CodegenTests/test-requests/SchemaScopedEnum/schema.sql @@ -2,5 +2,5 @@ CREATE SCHEMA dummy_schema; CREATE TABLE dummy_schema.dummy_table ( - dummy_column ENUM ('x', 'y') -); \ No newline at end of file + dummy_column ENUM('x', 'y') +); diff --git a/Drivers/DbDriver.cs b/Drivers/DbDriver.cs index 38539f96..46c3f310 100644 --- a/Drivers/DbDriver.cs +++ b/Drivers/DbDriver.cs @@ -130,13 +130,13 @@ public string AddNullableSuffixIfNeeded(string csharpType, bool notNull) return IsTypeNullable(csharpType) ? $"{csharpType}?" : csharpType; } - public string GetCsharpType(Column column) + public string GetCsharpType(Column column, Query? query) { - var csharpType = GetCsharpTypeWithoutNullableSuffix(column); - return AddNullableSuffixIfNeeded(csharpType, column.NotNull); + var csharpType = GetCsharpTypeWithoutNullableSuffix(column, query); + return AddNullableSuffixIfNeeded(csharpType, IsColumnNotNull(column, query)); } - private string GetCsharpTypeWithoutNullableSuffix(Column column) + private string GetCsharpTypeWithoutNullableSuffix(Column column, Query? query) { if (column.EmbedTable != null) return column.EmbedTable.Name.ToModelName(column.EmbedTable.Schema, DefaultSchema); @@ -147,6 +147,13 @@ private string GetCsharpTypeWithoutNullableSuffix(Column column) if (IsEnumType(column)) return column.Type.Name.ToModelName(column.Table.Schema, DefaultSchema); + if (query is not null) + { + var foundOverride = FindOverrideForQueryColumn(query, column); + if (foundOverride is not null) + return foundOverride.CsharpType.Type; + } + foreach (var columnMapping in ColumnMappings .Where(columnMapping => DoesColumnMappingApply(columnMapping, column))) { @@ -177,7 +184,15 @@ private static bool DoesColumnMappingApply(ColumnMapping columnMapping, Column c return typeInfo.Length.Value == column.Length; } - public string GetColumnReader(Column column, int ordinal) + private string GetColumnReader(OverrideOption overrideOption, int ordinal) + { + var columnMapping = ColumnMappings.Find(c => c.CsharpType == overrideOption.CsharpType.Type); + if (columnMapping is not null) + return columnMapping.ReaderFn(ordinal); + throw new NotSupportedException($"Column {overrideOption.Column} has unsupported column type: {overrideOption.CsharpType.Type}"); + } + + public string GetColumnReader(Column column, int ordinal, Query? query) { if (IsEnumType(column)) { @@ -185,6 +200,13 @@ public string GetColumnReader(Column column, int ordinal) return $"{Variable.Reader.AsVarName()}.GetString({ordinal}).To{enumName}()"; } + if (query is not null) + { + var foundOverride = FindOverrideForQueryColumn(query, column); + if (foundOverride is not null) + return GetColumnReader(foundOverride, ordinal); + } + foreach (var columnMapping in ColumnMappings .Where(columnMapping => DoesColumnMappingApply(columnMapping, column))) { @@ -227,10 +249,10 @@ public string GetIdColumnType(Query query) var tableColumns = Tables[query.InsertIntoTable.Schema][query.InsertIntoTable.Name].Columns; var idColumn = tableColumns.First(c => c.Name.Equals("id", StringComparison.OrdinalIgnoreCase)); if (idColumn is not null) - return GetCsharpType(idColumn); + return GetCsharpType(idColumn, query); idColumn = tableColumns.First(c => c.Name.Contains("id", StringComparison.CurrentCultureIgnoreCase)); - return GetCsharpType(idColumn ?? tableColumns[0]); + return GetCsharpType(idColumn ?? tableColumns[0], query); } public virtual string[] GetLastIdStatement(Query query) @@ -243,10 +265,10 @@ public virtual string[] GetLastIdStatement(Query query) ]; } - public Column GetColumnFromParam(Parameter queryParam) + public Column GetColumnFromParam(Parameter queryParam, Query query) { if (string.IsNullOrEmpty(queryParam.Column.Name)) - queryParam.Column.Name = $"{GetCsharpType(queryParam.Column).Replace("[]", "Arr")}_{queryParam.Number}"; + queryParam.Column.Name = $"{GetCsharpType(queryParam.Column, query).Replace("[]", "Arr")}_{queryParam.Number}"; return queryParam.Column; } @@ -262,4 +284,25 @@ protected bool BatchQueryExists() { return Queries.Any(q => q.Cmd is ":copyfrom"); } + + public OverrideOption? FindOverrideForQueryColumn(Query query, Column column) + { + return Options.Overrides.FirstOrDefault(o => o.Column.Equals($"{query.Name}:{column.Name}")); + } + + /// + /// If the column data type is overridden, we need to check for nulls in generated code + /// + /// + /// + /// Adjusted not null value + public bool IsColumnNotNull(Column column, Query? query) + { + if (query is null) + return column.NotNull; + var overrideColumn = FindOverrideForQueryColumn(query, column); + if (overrideColumn is not null) + return overrideColumn.CsharpType.NotNull; + return column.NotNull; + } } \ No newline at end of file diff --git a/Drivers/Generators/CommonGen.cs b/Drivers/Generators/CommonGen.cs index cfdea6d0..6297ecd9 100644 --- a/Drivers/Generators/CommonGen.cs +++ b/Drivers/Generators/CommonGen.cs @@ -92,7 +92,7 @@ public static string GetSqlTransformations(Query query, string queryTextConstant """; } - public string InstantiateDataclass(Column[] columns, string returnInterface) + public string InstantiateDataclass(Column[] columns, string returnInterface, Query? query) { var columnsInit = new List(); var actualOrdinal = 0; @@ -102,7 +102,7 @@ public string InstantiateDataclass(Column[] columns, string returnInterface) { if (column.EmbedTable is null) { - columnsInit.Add(GetAsSimpleAssignment(column, actualOrdinal)); + columnsInit.Add(GetAsSimpleAssignment(column, actualOrdinal, query)); actualOrdinal++; continue; } @@ -113,47 +113,28 @@ public string InstantiateDataclass(Column[] columns, string returnInterface) seenEmbed.TryAdd(tableFieldType, 1); seenEmbed[tableFieldType]++; - var tableColumnsInit = GetAsEmbeddedTableColumnAssignment(column, actualOrdinal); + var tableColumnsInit = GetAsEmbeddedTableColumnAssignment(column, actualOrdinal, query); columnsInit.Add($"{tableFieldName} = {InstantiateDataclassInternal(tableFieldType, tableColumnsInit)}"); actualOrdinal += tableColumnsInit.Length; } return InstantiateDataclassInternal(returnInterface, columnsInit); - string[] GetAsEmbeddedTableColumnAssignment(Column tableColumn, int ordinal) + string[] GetAsEmbeddedTableColumnAssignment(Column tableColumn, int ordinal, Query? query) { var schemaName = tableColumn.EmbedTable.Schema == dbDriver.DefaultSchema ? string.Empty : tableColumn.EmbedTable.Schema; var tableColumns = dbDriver.Tables[schemaName][tableColumn.EmbedTable.Name].Columns; return tableColumns - .Select((c, o) => GetAsSimpleAssignment(c, o + ordinal)) + .Select((c, o) => GetAsSimpleAssignment(c, o + ordinal, query)) .ToArray(); } - string GetAsSimpleAssignment(Column column, int ordinal) + string GetAsSimpleAssignment(Column column, int ordinal, Query query) { - var readExpression = GetReadExpression(column, ordinal); + var readExpression = GetReadExpression(column, ordinal, query); return $"{column.Name.ToPascalCase()} = {readExpression}"; } - string GetReadExpression(Column column, int ordinal) - { - return column.NotNull - ? dbDriver.GetColumnReader(column, ordinal) - : $"{CheckNullExpression(ordinal)} ? {GetNullExpression(column)} : {dbDriver.GetColumnReader(column, ordinal)}"; - } - - string GetNullExpression(Column column) - { - var csharpType = dbDriver.GetCsharpType(column); - if (dbDriver.Options.DotnetFramework.IsDotnetCore()) return "null"; - return dbDriver.IsTypeNullable(csharpType) ? $"({csharpType}) null" : "null"; - } - - string CheckNullExpression(int ordinal) - { - return $"{Variable.Reader.AsVarName()}.IsDBNull({ordinal})"; - } - string InstantiateDataclassInternal(string name, IEnumerable fieldsInit) { return $$""" @@ -164,4 +145,23 @@ string InstantiateDataclassInternal(string name, IEnumerable fieldsInit) """; } } + + private string GetNullExpression(Column column, Query? query) + { + var csharpType = dbDriver.GetCsharpType(column, query); + if (dbDriver.Options.DotnetFramework.IsDotnetCore()) return "null"; + return dbDriver.IsTypeNullable(csharpType) ? $"({csharpType}) null" : "null"; + } + + private static string CheckNullExpression(int ordinal) + { + return $"{Variable.Reader.AsVarName()}.IsDBNull({ordinal})"; + } + + private string GetReadExpression(Column column, int ordinal, Query query) + { + if (dbDriver.IsColumnNotNull(column, query)) + return dbDriver.GetColumnReader(column, ordinal, query); + return $"{CheckNullExpression(ordinal)} ? {GetNullExpression(column, query)} : {dbDriver.GetColumnReader(column, ordinal, query)}"; + } } \ No newline at end of file diff --git a/Drivers/Generators/ManyDeclareGen.cs b/Drivers/Generators/ManyDeclareGen.cs index 61484bbd..d7dba854 100644 --- a/Drivers/Generators/ManyDeclareGen.cs +++ b/Drivers/Generators/ManyDeclareGen.cs @@ -54,7 +54,7 @@ string GetAsDriver() var commandParameters = CommonGen.AddParametersToCommand(query.Params); var initDataReader = CommonGen.InitDataReader(); var awaitReaderRow = CommonGen.AwaitReaderRow(); - var dataclassInit = CommonGen.InstantiateDataclass(query.Columns.ToArray(), returnInterface); + var dataclassInit = CommonGen.InstantiateDataclass(query.Columns.ToArray(), returnInterface, query); var readWhileExists = $$""" while ({{awaitReaderRow}}) { diff --git a/Drivers/Generators/OneDeclareGen.cs b/Drivers/Generators/OneDeclareGen.cs index d28a6a41..1156e7b1 100644 --- a/Drivers/Generators/OneDeclareGen.cs +++ b/Drivers/Generators/OneDeclareGen.cs @@ -54,7 +54,7 @@ string GetAsDriver() var commandParameters = CommonGen.AddParametersToCommand(query.Params); var initDataReader = CommonGen.InitDataReader(); var awaitReaderRow = CommonGen.AwaitReaderRow(); - var returnDataclass = CommonGen.InstantiateDataclass(query.Columns.ToArray(), returnInterface); + var returnDataclass = CommonGen.InstantiateDataclass(query.Columns.ToArray(), returnInterface, query); return $$""" using ({{establishConnection}}) { diff --git a/Drivers/MySqlConnectorDriver.cs b/Drivers/MySqlConnectorDriver.cs index db741492..084fac04 100644 --- a/Drivers/MySqlConnectorDriver.cs +++ b/Drivers/MySqlConnectorDriver.cs @@ -92,7 +92,13 @@ public partial class MySqlConnectorDriver( new Dictionary { { "decimal", new DbTypeInfo() } - }, ordinal => $"reader.GetDecimal({ordinal})") + }, ordinal => $"reader.GetDecimal({ordinal})"), + // last item in the dictionary - enforce TODO + new("object", + new Dictionary + { + { "any", new DbTypeInfo() } + }, ordinal => $"reader.GetValue({ordinal})") ]; public override UsingDirectiveSyntax[] GetUsingDirectivesForQueries() diff --git a/Drivers/NpgsqlDriver.cs b/Drivers/NpgsqlDriver.cs index d0d68a25..7a053ce4 100644 --- a/Drivers/NpgsqlDriver.cs +++ b/Drivers/NpgsqlDriver.cs @@ -150,7 +150,13 @@ public NpgsqlDriver( new Dictionary { { "circle", new DbTypeInfo(NpgsqlTypeOverride: "NpgsqlDbType.Circle") } - }, ordinal => $"reader.GetFieldValue({ordinal})") + }, ordinal => $"reader.GetFieldValue({ordinal})"), + // last item in the dictionary - enforce TODO + new("object", + new Dictionary + { + { "anyarray", new DbTypeInfo() } + }, ordinal => $"reader.GetValue({ordinal})") ]; public override UsingDirectiveSyntax[] GetUsingDirectivesForQueries() @@ -286,7 +292,7 @@ public override string TransformQueryText(Query query) for (var i = 0; i < query.Params.Count; i++) { var currentParameter = query.Params[i]; - var column = GetColumnFromParam(currentParameter); + var column = GetColumnFromParam(currentParameter, query); queryText = Regex.Replace(queryText, $@"\$\s*{i + 1}\b", $"@{column.Name}"); } diff --git a/Drivers/SqliteDriver.cs b/Drivers/SqliteDriver.cs index dccfdf7e..b720dba4 100644 --- a/Drivers/SqliteDriver.cs +++ b/Drivers/SqliteDriver.cs @@ -37,6 +37,12 @@ public partial class SqliteDriver( { {"real", new DbTypeInfo()} }, ordinal => $"reader.GetDecimal({ordinal})"), + // last item in the dictionary - enforce TODO + new("object", + new Dictionary + { + { "any", new DbTypeInfo() } + }, ordinal => $"reader.GetValue({ordinal})") ]; public override UsingDirectiveSyntax[] GetUsingDirectivesForQueries() diff --git a/Makefile b/Makefile index 8aa56a69..a64a276a 100644 --- a/Makefile +++ b/Makefile @@ -18,30 +18,26 @@ unit-tests: generate-end2end-tests: ./end2end/scripts/generate_tests.sh -run-end2end-tests: generate-end2end-tests +run-end2end-tests: ./end2end/scripts/run_tests.sh # process type plugin -dotnet-build-process: protobuf-generate dotnet-format - dotnet build LocalRunner -c Release - -dotnet-publish-process: dotnet-build-process +dotnet-publish-process: dotnet publish LocalRunner -c release --output dist/ -sqlc-generate-process: dotnet-publish-process - sqlc -f sqlc.local.yaml generate +sync-sqlc-options: + ./scripts/sync_sqlc_options.sh + +sqlc-generate-requests: + SQLCCACHE=./; sqlc -f sqlc.requests.yaml generate + +sqlc-generate: + SQLCCACHE=./; sqlc -f sqlc.local.yaml generate -test-process-plugin: unit-tests sqlc-generate-process dotnet-build run-end2end-tests +test-plugin: protobuf-generate sync-sqlc-options dotnet-publish-process sqlc-generate-requests unit-tests sqlc-generate generate-end2end-tests dotnet-build run-end2end-tests update-wasm-plugin # WASM type plugin -dotnet-publish-wasm: protobuf-generate +setup-ci-wasm-plugin: dotnet publish WasmRunner -c release --output dist/ ./scripts/wasm/copy_plugin_to.sh dist - -update-wasm-plugin: ./scripts/wasm/update_sha.sh sqlc.ci.yaml - -sqlc-generate-wasm: dotnet-publish-wasm update-wasm-plugin - SQLCCACHE=./; sqlc -f sqlc.ci.yaml generate - -test-wasm-plugin: unit-tests sqlc-generate-wasm update-wasm-plugin dotnet-build run-end2end-tests \ No newline at end of file diff --git a/PluginOptions/Options.cs b/PluginOptions/Options.cs index 744711a1..77da0dce 100644 --- a/PluginOptions/Options.cs +++ b/PluginOptions/Options.cs @@ -20,6 +20,7 @@ public Options(GenerateRequest generateRequest) OverrideDapperVersion = rawOptions.OverrideDapperVersion; NamespaceName = rawOptions.NamespaceName; DotnetFramework = DotnetFrameworkExtensions.ParseName(rawOptions.TargetFramework); + Overrides = rawOptions.Overrides ?? []; if (rawOptions.DebugRequest && generateRequest.Settings.Codegen.Wasm is not null) throw new ArgumentException("Debug request mode cannot be used with WASM plugin"); @@ -40,6 +41,10 @@ public Options(GenerateRequest generateRequest) public string NamespaceName { get; } + public bool NotNull { get; } + + public List Overrides { get; } + public bool DebugRequest { get; } private static readonly Dictionary EngineToDriverMapping = new() diff --git a/PluginOptions/RawOptions.cs b/PluginOptions/RawOptions.cs index 3e9e6277..00cd335c 100644 --- a/PluginOptions/RawOptions.cs +++ b/PluginOptions/RawOptions.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json.Serialization; namespace SqlcGenCsharp; @@ -22,6 +23,27 @@ internal class RawOptions [JsonPropertyName("overrideDapperVersion")] public string OverrideDapperVersion { get; init; } = string.Empty; + [JsonPropertyName("overrides")] + public List? Overrides { get; init; } + [JsonPropertyName("debugRequest")] public bool DebugRequest { get; init; } +} + +public class OverrideOption +{ + [JsonPropertyName("column")] + public string Column { get; init; } = string.Empty; + + [JsonPropertyName("csharp_type")] + public CsharpTypeOption CsharpType { get; init; } = new(); +} + +public class CsharpTypeOption +{ + [JsonPropertyName("type")] + public string Type { get; init; } = string.Empty; + + [JsonPropertyName("notNull")] + public bool NotNull { get; init; } = false; } \ No newline at end of file diff --git a/README.md b/README.md index 0560e7da..13702d92 100644 --- a/README.md +++ b/README.md @@ -39,14 +39,25 @@ sql: ``` # Usage ## Options -| Option | Possible values | Optional | Info | -|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| overrideDriverVersion | default:
`2.3.6` for MySqlConnector (mysql)
`8.0.3` for Npgsql (postgresql)
`8.0.10` for Microsoft.Data.Sqlite (sqlite)

values: The desired driver version | Yes | Allows you to override the version of DB driver to be used. | -| targetFramework | default: `net8.0`
values: `netstandard2.0`, `netstandard2.1`, `net8.0` | Yes | Determines the target framework for your generated code, meaning the generated code will be compiled to the specified runtime.
For more information and help deciding on the right value, refer to the [Microsoft .NET Standard documentation](https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-1-0). | -| generateCsproj | default: `true`
values: `false`,`true` | Yes | Assists you with the integration of SQLC and csharp by generating a `.csproj` file. This converts the generated output to a .dll, a project that you can easily incorporate into your build process. | -| namespaceName | default: the generated project name | Yes | Allows you to override the namespace name to be different than the project name | -| useDapper | default: `false`
values: `false`,`true` | Yes | Enables Dapper as a thin wrapper for the generated code. For more information, please refer to the [Dapper documentation](https://github.com/DapperLib/Dapper). | -| overrideDapperVersion | default:
`2.1.35`
values: The desired Dapper version | Yes | If `useDapper` is set to `true`, this option allows you to override the version of Dapper to be used. | +| Option | Possible values | Optional | Info | +|--------------------- |----------------------------------------------------------------------------------------------|----------|------| +| overrideDriverVersion| default:
`2.3.6` for MySqlConnector (mysql)
`8.0.3` for Npgsql (postgresql)
`8.0.10` for Microsoft.Data.Sqlite (sqlite)

values: The desired driver version | Yes | Allows you to override the version of DB driver to be used. | +| targetFramework | default: `net8.0`
values: `netstandard2.0`, `netstandard2.1`, `net8.0` | Yes | Determines the target framework for your generated code, meaning the generated code will be compiled to the specified runtime.
For more information and help deciding on the right value, refer to the [Microsoft .NET Standard documentation](https://learn.microsoft.com/en-us/dotnet/standard/net-standard?tabs=net-standard-1-0). | +| generateCsproj | default: `true`
values: `false`,`true` | Yes | Assists you with the integration of SQLC and csharp by generating a `.csproj` file. This converts the generated output to a .dll, a project that you can easily incorporate into your build process. | +| namespaceName | default: the generated project name | Yes | Allows you to override the namespace name to be different than the project name | +| useDapper | default: `false`
values: `false`,`true` | Yes | Enables Dapper as a thin wrapper for the generated code. For more information, please refer to the [Dapper documentation](https://github.com/DapperLib/Dapper). | +| overrideDapperVersion| default:
`2.1.35`
values: The desired Dapper version | Yes | If `useDapper` is set to `true`, this option allows you to override the version of Dapper to be used. | +| Override | values: A nested override value like [this](#override-option). | Yes | Allows you to override the generated C# data types for specific columns in specific queries. This option accepts a `query_name:column_name` mapping and the overriden data type. | + +### Override option +``` +yaml +overrides: + - column: ":" + csharp_type: + type: "" + notNull: true|false +``` ## Supported Features - ✅ means the feature is fully supported. @@ -287,6 +298,15 @@ Follow the instructions in each of these: - Buf build - [Buf Build](https://buf.build/docs/installation)
- WASM (follow this guide) - [WASM libs](https://www.strathweb.com/2023/09/dotnet-wasi-applications-in-net-8-0/) +## Pre-commit Setup + +This repository uses [pre-commit](https://pre-commit.com/). To set up pre-commit hooks, run: + +```sh +pip install pre-commit +pre-commit install +``` + ### Protobuf SQLC protobuf are defined in sqlc-dev/sqlc repository. Generating C# code from protocol buffer files: @@ -319,172 +339,172 @@ By default, the release script will bump the patch version. Adding `[release]` t ### Release structure The new created tag will create a draft release with it, in the release there will be the wasm plugin embedded in the release.
-# Examples -
-Npgsql - -## Engine `postgresql`: [NpgsqlExample](examples/NpgsqlExample) -### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTests/NpgsqlTester.cs) -### Config -```yaml +# Examples +
+Npgsql + +## Engine `postgresql`: [NpgsqlExample](examples/NpgsqlExample) +### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTests/NpgsqlTester.cs) +### Config +```yaml useDapper: false targetFramework: net8.0 generateCsproj: true namespaceName: NpgsqlExampleGen -``` - +``` +
-
-NpgsqlDapper - -## Engine `postgresql`: [NpgsqlDapperExample](examples/NpgsqlDapperExample) -### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTests/NpgsqlDapperTester.cs) -### Config -```yaml +
+NpgsqlDapper + +## Engine `postgresql`: [NpgsqlDapperExample](examples/NpgsqlDapperExample) +### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTests/NpgsqlDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: net8.0 generateCsproj: true namespaceName: NpgsqlDapperExampleGen -``` - +``` +
-
-NpgsqlLegacy - -## Engine `postgresql`: [NpgsqlLegacyExample](examples/NpgsqlLegacyExample) -### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/NpgsqlTester.cs) -### Config -```yaml +
+NpgsqlLegacy + +## Engine `postgresql`: [NpgsqlLegacyExample](examples/NpgsqlLegacyExample) +### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/NpgsqlTester.cs) +### Config +```yaml useDapper: false targetFramework: netstandard2.0 generateCsproj: true namespaceName: NpgsqlLegacyExampleGen -``` - +``` +
-
-NpgsqlDapperLegacy - -## Engine `postgresql`: [NpgsqlDapperLegacyExample](examples/NpgsqlDapperLegacyExample) -### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/NpgsqlDapperTester.cs) -### Config -```yaml +
+NpgsqlDapperLegacy + +## Engine `postgresql`: [NpgsqlDapperLegacyExample](examples/NpgsqlDapperLegacyExample) +### [Schema](examples/config/postgresql/schema.sql) | [Queries](examples/config/postgresql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/NpgsqlDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: netstandard2.0 generateCsproj: true namespaceName: NpgsqlDapperLegacyExampleGen -``` - +``` +
-
-MySqlConnector - -## Engine `mysql`: [MySqlConnectorExample](examples/MySqlConnectorExample) -### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTests/MySqlConnectorTester.cs) -### Config -```yaml +
+MySqlConnector + +## Engine `mysql`: [MySqlConnectorExample](examples/MySqlConnectorExample) +### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTests/MySqlConnectorTester.cs) +### Config +```yaml useDapper: false targetFramework: net8.0 generateCsproj: true namespaceName: MySqlConnectorExampleGen -``` - +``` +
-
-MySqlConnectorDapper - -## Engine `mysql`: [MySqlConnectorDapperExample](examples/MySqlConnectorDapperExample) -### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTests/MySqlConnectorDapperTester.cs) -### Config -```yaml +
+MySqlConnectorDapper + +## Engine `mysql`: [MySqlConnectorDapperExample](examples/MySqlConnectorDapperExample) +### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTests/MySqlConnectorDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: net8.0 generateCsproj: true namespaceName: MySqlConnectorDapperExampleGen -``` - +``` +
-
-MySqlConnectorLegacy - -## Engine `mysql`: [MySqlConnectorLegacyExample](examples/MySqlConnectorLegacyExample) -### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/MySqlConnectorTester.cs) -### Config -```yaml +
+MySqlConnectorLegacy + +## Engine `mysql`: [MySqlConnectorLegacyExample](examples/MySqlConnectorLegacyExample) +### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/MySqlConnectorTester.cs) +### Config +```yaml useDapper: false targetFramework: netstandard2.0 generateCsproj: true namespaceName: MySqlConnectorLegacyExampleGen -``` - +``` +
-
-MySqlConnectorDapperLegacy - -## Engine `mysql`: [MySqlConnectorDapperLegacyExample](examples/MySqlConnectorDapperLegacyExample) -### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.cs) -### Config -```yaml +
+MySqlConnectorDapperLegacy + +## Engine `mysql`: [MySqlConnectorDapperLegacyExample](examples/MySqlConnectorDapperLegacyExample) +### [Schema](examples/config/mysql/schema.sql) | [Queries](examples/config/mysql/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: netstandard2.0 generateCsproj: true namespaceName: MySqlConnectorDapperLegacyExampleGen -``` - +``` +
-
-Sqlite - -## Engine `sqlite`: [SqliteExample](examples/SqliteExample) -### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTests/SqliteTester.cs) -### Config -```yaml +
+Sqlite + +## Engine `sqlite`: [SqliteExample](examples/SqliteExample) +### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTests/SqliteTester.cs) +### Config +```yaml useDapper: false targetFramework: net8.0 generateCsproj: true namespaceName: SqliteExampleGen -``` - +``` +
-
-SqliteDapper - -## Engine `sqlite`: [SqliteDapperExample](examples/SqliteDapperExample) -### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTests/SqliteDapperTester.cs) -### Config -```yaml +
+SqliteDapper + +## Engine `sqlite`: [SqliteDapperExample](examples/SqliteDapperExample) +### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTests/SqliteDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: net8.0 generateCsproj: true namespaceName: SqliteDapperExampleGen -``` - +``` +
-
-SqliteLegacy - -## Engine `sqlite`: [SqliteLegacyExample](examples/SqliteLegacyExample) -### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/SqliteTester.cs) -### Config -```yaml +
+SqliteLegacy + +## Engine `sqlite`: [SqliteLegacyExample](examples/SqliteLegacyExample) +### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/SqliteTester.cs) +### Config +```yaml useDapper: false targetFramework: netstandard2.0 generateCsproj: true namespaceName: SqliteLegacyExampleGen -``` - +``` +
-
-SqliteDapperLegacy - -## Engine `sqlite`: [SqliteDapperLegacyExample](examples/SqliteDapperLegacyExample) -### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/SqliteDapperTester.cs) -### Config -```yaml +
+SqliteDapperLegacy + +## Engine `sqlite`: [SqliteDapperLegacyExample](examples/SqliteDapperLegacyExample) +### [Schema](examples/config/sqlite/schema.sql) | [Queries](examples/config/sqlite/query.sql) | [End2End Test](end2end/EndToEndTestsLegacy/SqliteDapperTester.cs) +### Config +```yaml useDapper: true targetFramework: netstandard2.0 generateCsproj: true namespaceName: SqliteDapperLegacyExampleGen -``` - +``` +
\ No newline at end of file diff --git a/end2end/EndToEndScaffold/Config.cs b/end2end/EndToEndScaffold/Config.cs index b47cf491..6f6fc214 100644 --- a/end2end/EndToEndScaffold/Config.cs +++ b/end2end/EndToEndScaffold/Config.cs @@ -28,6 +28,7 @@ public enum KnownTestType // Sqlite SqliteDataTypes, + SqliteDataTypesOverride, SqliteCopyFrom, // Postgres @@ -36,6 +37,7 @@ public enum KnownTestType PostgresFloatingPointDataTypes, PostgresDateTimeDataTypes, PostgresArrayDataTypes, + PostgresDataTypesOverride, PostgresStringCopyFrom, PostgresIntegerCopyFrom, @@ -54,6 +56,7 @@ public enum KnownTestType MySqlDateTimeDataTypes, MySqlBinaryDataTypes, MySqlEnumDataType, + MySqlDataTypesOverride, MySqlScopedSchemaEnum, MySqlStringCopyFrom, @@ -94,6 +97,7 @@ internal static class Config KnownTestType.MySqlBinaryDataTypes, KnownTestType.MySqlEnumDataType, KnownTestType.MySqlScopedSchemaEnum, + KnownTestType.MySqlDataTypesOverride, KnownTestType.MySqlStringCopyFrom, KnownTestType.MySqlIntegerCopyFrom, @@ -129,6 +133,7 @@ internal static class Config KnownTestType.MySqlBinaryDataTypes, KnownTestType.MySqlEnumDataType, KnownTestType.MySqlScopedSchemaEnum, + KnownTestType.MySqlDataTypesOverride, KnownTestType.MySqlStringCopyFrom, KnownTestType.MySqlIntegerCopyFrom, @@ -163,6 +168,7 @@ internal static class Config KnownTestType.PostgresDateTimeDataTypes, KnownTestType.PostgresArrayDataTypes, KnownTestType.PostgresGeoDataTypes, + KnownTestType.PostgresDataTypesOverride, KnownTestType.PostgresStringCopyFrom, KnownTestType.PostgresIntegerCopyFrom, @@ -196,6 +202,7 @@ internal static class Config KnownTestType.PostgresDateTimeDataTypes, KnownTestType.PostgresArrayDataTypes, KnownTestType.PostgresGeoDataTypes, + KnownTestType.PostgresDataTypesOverride, KnownTestType.PostgresStringCopyFrom, KnownTestType.PostgresIntegerCopyFrom, @@ -223,7 +230,8 @@ internal static class Config KnownTestType.NargNull, KnownTestType.NargNotNull, KnownTestType.SqliteDataTypes, - KnownTestType.SqliteCopyFrom + KnownTestType.SqliteCopyFrom, + KnownTestType.SqliteDataTypesOverride ] } }, @@ -245,7 +253,8 @@ internal static class Config KnownTestType.NargNull, KnownTestType.NargNotNull, KnownTestType.SqliteDataTypes, - KnownTestType.SqliteCopyFrom + KnownTestType.SqliteCopyFrom, + KnownTestType.SqliteDataTypesOverride ] } }, diff --git a/end2end/EndToEndScaffold/Templates/MySqlTests.cs b/end2end/EndToEndScaffold/Templates/MySqlTests.cs index 06d1ea2e..99b0e400 100644 --- a/end2end/EndToEndScaffold/Templates/MySqlTests.cs +++ b/end2end/EndToEndScaffold/Templates/MySqlTests.cs @@ -293,7 +293,7 @@ public async Task TestStringCopyFrom( }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -305,7 +305,7 @@ public async Task TestStringCopyFrom( CText = cText, CLongtext = cLongtext, }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CChar, Is.EqualTo(expected.CChar)); @@ -350,7 +350,7 @@ public async Task TestIntegerCopyFrom( }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBool = cBool, @@ -362,7 +362,7 @@ public async Task TestIntegerCopyFrom( CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CBool, Is.EqualTo(expected.CBool)); @@ -405,7 +405,7 @@ public async Task TestFloatingPointCopyFrom( }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CFloat = cFloat, @@ -416,7 +416,7 @@ public async Task TestFloatingPointCopyFrom( CDouble = cDouble, CDoublePrecision = cDoublePrecision }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CFloat, Is.EqualTo(expected.CFloat)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CNumeric, Is.EqualTo(expected.CNumeric)); @@ -451,7 +451,7 @@ public async Task TestDateTimeCopyFrom( }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CYear = cYear, @@ -459,7 +459,7 @@ public async Task TestDateTimeCopyFrom( CDatetime = cDatetime, CTimestamp = cTimestamp }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CYear, Is.EqualTo(expected.CYear)); @@ -499,7 +499,7 @@ public async Task TestBinaryCopyFrom( }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBit = cBit, @@ -510,7 +510,7 @@ public async Task TestBinaryCopyFrom( CMediumblob = cMediumblob, CLongblob = cLongblob }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CBit, Is.EqualTo(expected.CBit)); @@ -539,12 +539,12 @@ public async Task TestCopyFrom(int batchSize, MysqlTypesCEnum? cEnum) }) .ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CEnum = cEnum }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CEnum, Is.EqualTo(expected.CEnum)); } """ @@ -580,6 +580,46 @@ private static bool SingularEquals(QuerySql.GetFirstExtendedBioByTypeRow x, Quer return x.AuthorName.Equals(y.AuthorName) && x.Name.Equals(y.Name) && x.BioType.Equals(y.BioType); } """ + }, + [KnownTestType.MySqlDataTypesOverride] = new TestImpl + { + Impl = $$""" + [Test] + [TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")] + [TestCase(null, 0, null, "1971-01-01 00:00:00")] + public async Task TestMySqlDataTypesOverride( + int? cInt, + long cBigint, + string cVarchar, + DateTime cTimestamp) + { + await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs + { + CInt = cInt, + CBigint = cBigint, + CVarchar = cVarchar, + CTimestamp = cTimestamp + }); + var expected = new QuerySql.GetMysqlFunctionsRow + { + MaxInt = cInt, + MaxBigint = cBigint, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + + var actual = await QuerySql.GetMysqlFunctions(); + AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}}); + } + + private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual) + { + Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt)); + Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + """ } }; } \ No newline at end of file diff --git a/end2end/EndToEndScaffold/Templates/PostgresTests.cs b/end2end/EndToEndScaffold/Templates/PostgresTests.cs index fd756d22..1d93d048 100644 --- a/end2end/EndToEndScaffold/Templates/PostgresTests.cs +++ b/end2end/EndToEndScaffold/Templates/PostgresTests.cs @@ -210,7 +210,7 @@ public async Task TestStringCopyFrom( }) .ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -218,7 +218,7 @@ public async Task TestStringCopyFrom( CCharacterVarying = cCharacterVarying, CText = cText }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CChar, Is.EqualTo(expected.CChar)); @@ -251,7 +251,7 @@ public async Task TestIntegerCopyFrom( }) .ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBoolean = cBoolean, @@ -259,7 +259,7 @@ public async Task TestIntegerCopyFrom( CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CBoolean, Is.EqualTo(expected.CBoolean)); @@ -268,7 +268,7 @@ public async Task TestIntegerCopyFrom( Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CBigint, Is.EqualTo(expected.CBigint)); } - private static void AssertSingularEquals(QuerySql.GetPostgresTypesAggRow expected, QuerySql.GetPostgresTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetPostgresTypesCntRow expected, QuerySql.GetPostgresTypesCntRow actual) { } @@ -299,7 +299,7 @@ public async Task TestFloatingPointCopyFrom( }) .ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CReal = cReal, @@ -308,7 +308,7 @@ public async Task TestFloatingPointCopyFrom( CDoublePrecision = cDoublePrecision, CMoney = cMoney }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CReal, Is.EqualTo(expected.CReal)); @@ -346,7 +346,7 @@ public async Task TestDateTimeCopyFrom( }) .ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CDate = cDate, @@ -354,7 +354,7 @@ public async Task TestDateTimeCopyFrom( CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTz, }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CDate, Is.EqualTo(expected.CDate)); @@ -382,12 +382,12 @@ public async Task TestArrayCopyFrom( }) .ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBytea = cBytea }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual{{Consts.UnknownRecordValuePlaceholder}}.CBytea, Is.EqualTo(expected.CBytea)); @@ -484,6 +484,42 @@ public async Task TestPostgresGeoTypes(NpgsqlPoint? cPoint, NpgsqlLine? cLine, N } """ }, + [KnownTestType.PostgresDataTypesOverride] = new TestImpl + { + Impl = $$""" + [Test] + [TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")] + [TestCase(null, null, "1970-01-01 00:00:00")] + public async Task TestPostgresDataTypesOverride( + int? cInteger, + string cVarchar, + DateTime cTimestamp) + { + await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs + { + CInteger = cInteger, + CVarchar = cVarchar, + CTimestamp = cTimestamp + }); + + var expected = new QuerySql.GetPostgresFunctionsRow + { + MaxInteger = cInteger, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + + var actual = await QuerySql.GetPostgresFunctions(); + AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}}); + } + private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + """ + } }; } \ No newline at end of file diff --git a/end2end/EndToEndScaffold/Templates/SqliteTests.cs b/end2end/EndToEndScaffold/Templates/SqliteTests.cs index 00844445..6a20b829 100644 --- a/end2end/EndToEndScaffold/Templates/SqliteTests.cs +++ b/end2end/EndToEndScaffold/Templates/SqliteTests.cs @@ -14,7 +14,7 @@ public static class SqliteTests [TestCase(null, null, null, new byte[] { })] [TestCase(null, null, null, null)] public async Task TestSqliteTypes( - int cInteger, + int? cInteger, decimal? cReal, string cText, byte[] cBlob) @@ -69,18 +69,18 @@ public async Task TestCopyFrom( }) .ToList(); await QuerySql.InsertSqliteTypesBatch(batchArgs); - var expected = new QuerySql.GetSqliteTypesAggRow + var expected = new QuerySql.GetSqliteTypesCntRow { Cnt = batchSize, CInteger = cInteger, CReal = cReal, CText = cText }; - var actual = await QuerySql.GetSqliteTypesAgg(); + var actual = await QuerySql.GetSqliteTypesCnt(); AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}}); } - private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, QuerySql.GetSqliteTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected, QuerySql.GetSqliteTypesCntRow actual) { Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CInteger, Is.EqualTo(expected.CInteger)); @@ -89,5 +89,41 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, } """ }, + [KnownTestType.SqliteDataTypesOverride] = new TestImpl + { + Impl = $$""" + [Test] + [TestCase(-54355, 9787.66, "Have One On Me")] + [TestCase(null, 0.0, null)] + public async Task TestSqliteDataTypesOverride( + int? cInteger, + decimal cReal, + string cText) + { + await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs + { + CInteger = cInteger, + CReal = cReal, + CText = cText + }); + + var expected = new QuerySql.GetSqliteFunctionsRow + { + MaxInteger = cInteger, + MaxReal = cReal, + MaxText = cText + }; + var actual = await QuerySql.GetSqliteFunctions(); + AssertSingularEquals(expected, actual{{Consts.UnknownRecordValuePlaceholder}}); + } + + private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal)); + Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText)); + } + """ + } }; } \ No newline at end of file diff --git a/end2end/EndToEndTests/MySqlConnectorDapperTester.generated.cs b/end2end/EndToEndTests/MySqlConnectorDapperTester.generated.cs index a9de91c1..f195ae6c 100644 --- a/end2end/EndToEndTests/MySqlConnectorDapperTester.generated.cs +++ b/end2end/EndToEndTests/MySqlConnectorDapperTester.generated.cs @@ -446,6 +446,31 @@ public async Task TestMySqlStringTypes(MysqlTypesCEnum? cEnum) Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } + [Test] + [TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")] + [TestCase(null, 0, null, "1971-01-01 00:00:00")] + public async Task TestMySqlDataTypesOverride(int? cInt, long cBigint, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs { CInt = cInt, CBigint = cBigint, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetMysqlFunctionsRow + { + MaxInt = cInt, + MaxBigint = cBigint, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetMysqlFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual) + { + Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt)); + Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] public async Task TestMySqlScopedSchemaEnum() { @@ -472,7 +497,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CChar = cChar, CNchar = cNchar, CNationalChar = cNationalChar, CVarchar = cVarchar, CTinytext = cTinytext, CMediumtext = cMediumtext, CText = cText, CLongtext = cLongtext }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -484,7 +509,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, CText = cText, CLongtext = cLongtext, }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CNchar, Is.EqualTo(expected.CNchar)); @@ -503,7 +528,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBool = cBool, CBoolean = cBoolean, CTinyint = cTinyint, CSmallint = cSmallint, CMediumint = cMediumint, CInt = cInt, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBool = cBool, @@ -515,7 +540,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBool, Is.EqualTo(expected.CBool)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); @@ -534,7 +559,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CFloat = cFloat, CNumeric = cNumeric, CDecimal = cDecimal, CDec = cDec, CFixed = cFixed, CDouble = cDouble, CDoublePrecision = cDoublePrecision }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CFloat = cFloat, @@ -545,7 +570,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima CDouble = cDouble, CDoublePrecision = cDoublePrecision }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CFloat, Is.EqualTo(expected.CFloat)); Assert.That(actual.CNumeric, Is.EqualTo(expected.CNumeric)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -562,7 +587,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CYear = cYear, CDate = cDate, CDatetime = cDatetime, CTimestamp = cTimestamp }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CYear = cYear, @@ -570,7 +595,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD CDatetime = cDatetime, CTimestamp = cTimestamp }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CYear, Is.EqualTo(expected.CYear)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); @@ -586,7 +611,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBit = cBit, CBinary = cBinary, CVarbinary = cVarbinary, CTinyblob = cTinyblob, CBlob = cBlob, CMediumblob = cMediumblob, CLongblob = cLongblob }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBit = cBit, @@ -597,7 +622,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, CMediumblob = cMediumblob, CLongblob = cLongblob }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBit, Is.EqualTo(expected.CBit)); Assert.That(actual.CBinary, Is.EqualTo(expected.CBinary)); @@ -616,12 +641,12 @@ public async Task TestCopyFrom(int batchSize, MysqlTypesCEnum? cEnum) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CEnum = cEnum }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CEnum = cEnum }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } } diff --git a/end2end/EndToEndTests/MySqlConnectorTester.generated.cs b/end2end/EndToEndTests/MySqlConnectorTester.generated.cs index c943a2ff..b9747a47 100644 --- a/end2end/EndToEndTests/MySqlConnectorTester.generated.cs +++ b/end2end/EndToEndTests/MySqlConnectorTester.generated.cs @@ -446,6 +446,31 @@ public async Task TestMySqlStringTypes(MysqlTypesCEnum? cEnum) Assert.That(actual.Value.CEnum, Is.EqualTo(expected.CEnum)); } + [Test] + [TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")] + [TestCase(null, 0, null, "1971-01-01 00:00:00")] + public async Task TestMySqlDataTypesOverride(int? cInt, long cBigint, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs { CInt = cInt, CBigint = cBigint, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetMysqlFunctionsRow + { + MaxInt = cInt, + MaxBigint = cBigint, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetMysqlFunctions(); + AssertSingularEquals(expected, actual.Value); + } + + private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual) + { + Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt)); + Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] public async Task TestMySqlScopedSchemaEnum() { @@ -472,7 +497,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CChar = cChar, CNchar = cNchar, CNationalChar = cNationalChar, CVarchar = cVarchar, CTinytext = cTinytext, CMediumtext = cMediumtext, CText = cText, CLongtext = cLongtext }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -484,7 +509,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, CText = cText, CLongtext = cLongtext, }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.Value.CNchar, Is.EqualTo(expected.CNchar)); @@ -503,7 +528,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBool = cBool, CBoolean = cBoolean, CTinyint = cTinyint, CSmallint = cSmallint, CMediumint = cMediumint, CInt = cInt, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBool = cBool, @@ -515,7 +540,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CBool, Is.EqualTo(expected.CBool)); Assert.That(actual.Value.CBoolean, Is.EqualTo(expected.CBoolean)); @@ -534,7 +559,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CFloat = cFloat, CNumeric = cNumeric, CDecimal = cDecimal, CDec = cDec, CFixed = cFixed, CDouble = cDouble, CDoublePrecision = cDoublePrecision }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CFloat = cFloat, @@ -545,7 +570,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima CDouble = cDouble, CDoublePrecision = cDoublePrecision }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.CFloat, Is.EqualTo(expected.CFloat)); Assert.That(actual.Value.CNumeric, Is.EqualTo(expected.CNumeric)); Assert.That(actual.Value.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -562,7 +587,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CYear = cYear, CDate = cDate, CDatetime = cDatetime, CTimestamp = cTimestamp }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CYear = cYear, @@ -570,7 +595,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD CDatetime = cDatetime, CTimestamp = cTimestamp }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CYear, Is.EqualTo(expected.CYear)); Assert.That(actual.Value.CDate, Is.EqualTo(expected.CDate)); @@ -586,7 +611,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBit = cBit, CBinary = cBinary, CVarbinary = cVarbinary, CTinyblob = cTinyblob, CBlob = cBlob, CMediumblob = cMediumblob, CLongblob = cLongblob }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBit = cBit, @@ -597,7 +622,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, CMediumblob = cMediumblob, CLongblob = cLongblob }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CBit, Is.EqualTo(expected.CBit)); Assert.That(actual.Value.CBinary, Is.EqualTo(expected.CBinary)); @@ -616,12 +641,12 @@ public async Task TestCopyFrom(int batchSize, MysqlTypesCEnum? cEnum) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CEnum = cEnum }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CEnum = cEnum }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Value.CEnum, Is.EqualTo(expected.CEnum)); } } diff --git a/end2end/EndToEndTests/NpgsqlDapperTester.generated.cs b/end2end/EndToEndTests/NpgsqlDapperTester.generated.cs index cdbdddb5..28188d5a 100644 --- a/end2end/EndToEndTests/NpgsqlDapperTester.generated.cs +++ b/end2end/EndToEndTests/NpgsqlDapperTester.generated.cs @@ -389,6 +389,29 @@ public async Task TestPostgresArrayTypes(byte[] cBytea, string[] cTextArray, int Assert.That(actual.CIntegerArray, Is.EqualTo(expected.CIntegerArray)); } + [Test] + [TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")] + [TestCase(null, null, "1970-01-01 00:00:00")] + public async Task TestPostgresDataTypesOverride(int? cInteger, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs { CInteger = cInteger, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetPostgresFunctionsRow + { + MaxInteger = cInteger, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetPostgresFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] [TestCase(100, "z", "Sex Pistols", "Anarchy in the U.K", "Never Mind the Bollocks...")] [TestCase(10, null, null, null, null)] @@ -396,7 +419,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CChar = cChar, CVarchar = cVarchar, CCharacterVarying = cCharacterVarying, CText = cText }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -404,7 +427,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha CCharacterVarying = cCharacterVarying, CText = cText }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CVarchar, Is.EqualTo(expected.CVarchar)); @@ -419,7 +442,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBoolean = cBoolean, CSmallint = cSmallint, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBoolean = cBoolean, @@ -427,7 +450,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); Assert.That(actual.CSmallint, Is.EqualTo(expected.CSmallint)); @@ -435,7 +458,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma Assert.That(actual.CBigint, Is.EqualTo(expected.CBigint)); } - private static void AssertSingularEquals(QuerySql.GetPostgresTypesAggRow expected, QuerySql.GetPostgresTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetPostgresTypesCntRow expected, QuerySql.GetPostgresTypesCntRow actual) { } @@ -446,7 +469,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CReal = cReal, CDecimal = cDecimal, CNumeric = cNumeric, CDoublePrecision = cDoublePrecision, CMoney = cMoney }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CReal = cReal, @@ -455,7 +478,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal CDoublePrecision = cDoublePrecision, CMoney = cMoney }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CReal, Is.EqualTo(expected.CReal)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -474,7 +497,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? cTimestampWithTzAsUtc = DateTime.SpecifyKind(cTimestampWithTz.Value, DateTimeKind.Utc); var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CDate = cDate, CTime = cTime, CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTzAsUtc }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CDate = cDate, @@ -482,7 +505,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTz, }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); Assert.That(actual.CTime, Is.EqualTo(expected.CTime)); @@ -498,12 +521,12 @@ public async Task TestArrayCopyFrom(int batchSize, byte[] cBytea) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBytea = cBytea }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBytea = cBytea }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBytea, Is.EqualTo(expected.CBytea)); } diff --git a/end2end/EndToEndTests/NpgsqlTester.generated.cs b/end2end/EndToEndTests/NpgsqlTester.generated.cs index 69b41877..b70f16d8 100644 --- a/end2end/EndToEndTests/NpgsqlTester.generated.cs +++ b/end2end/EndToEndTests/NpgsqlTester.generated.cs @@ -389,6 +389,29 @@ public async Task TestPostgresArrayTypes(byte[] cBytea, string[] cTextArray, int Assert.That(actual.Value.CIntegerArray, Is.EqualTo(expected.CIntegerArray)); } + [Test] + [TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")] + [TestCase(null, null, "1970-01-01 00:00:00")] + public async Task TestPostgresDataTypesOverride(int? cInteger, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs { CInteger = cInteger, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetPostgresFunctionsRow + { + MaxInteger = cInteger, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetPostgresFunctions(); + AssertSingularEquals(expected, actual.Value); + } + + private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] [TestCase(100, "z", "Sex Pistols", "Anarchy in the U.K", "Never Mind the Bollocks...")] [TestCase(10, null, null, null, null)] @@ -396,7 +419,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CChar = cChar, CVarchar = cVarchar, CCharacterVarying = cCharacterVarying, CText = cText }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -404,7 +427,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha CCharacterVarying = cCharacterVarying, CText = cText }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.Value.CVarchar, Is.EqualTo(expected.CVarchar)); @@ -419,7 +442,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBoolean = cBoolean, CSmallint = cSmallint, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBoolean = cBoolean, @@ -427,7 +450,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CBoolean, Is.EqualTo(expected.CBoolean)); Assert.That(actual.Value.CSmallint, Is.EqualTo(expected.CSmallint)); @@ -435,7 +458,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma Assert.That(actual.Value.CBigint, Is.EqualTo(expected.CBigint)); } - private static void AssertSingularEquals(QuerySql.GetPostgresTypesAggRow expected, QuerySql.GetPostgresTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetPostgresTypesCntRow expected, QuerySql.GetPostgresTypesCntRow actual) { } @@ -446,7 +469,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CReal = cReal, CDecimal = cDecimal, CNumeric = cNumeric, CDoublePrecision = cDoublePrecision, CMoney = cMoney }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CReal = cReal, @@ -455,7 +478,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal CDoublePrecision = cDoublePrecision, CMoney = cMoney }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CReal, Is.EqualTo(expected.CReal)); Assert.That(actual.Value.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -474,7 +497,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? cTimestampWithTzAsUtc = DateTime.SpecifyKind(cTimestampWithTz.Value, DateTimeKind.Utc); var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CDate = cDate, CTime = cTime, CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTzAsUtc }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CDate = cDate, @@ -482,7 +505,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTz, }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CDate, Is.EqualTo(expected.CDate)); Assert.That(actual.Value.CTime, Is.EqualTo(expected.CTime)); @@ -498,12 +521,12 @@ public async Task TestArrayCopyFrom(int batchSize, byte[] cBytea) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBytea = cBytea }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBytea = cBytea }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Value.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.Value.CBytea, Is.EqualTo(expected.CBytea)); } diff --git a/end2end/EndToEndTests/SqliteDapperTester.generated.cs b/end2end/EndToEndTests/SqliteDapperTester.generated.cs index 4763c177..c6e3a3bd 100644 --- a/end2end/EndToEndTests/SqliteDapperTester.generated.cs +++ b/end2end/EndToEndTests/SqliteDapperTester.generated.cs @@ -309,7 +309,7 @@ public async Task TestNargNotNull() [TestCase(-54355, 9787.66, "Songs of Love and Hate", new byte[] { 0x15, 0x20, 0x33 })] [TestCase(null, null, null, new byte[] { })] [TestCase(null, null, null, null)] - public async Task TestSqliteTypes(int cInteger, decimal? cReal, string cText, byte[] cBlob) + public async Task TestSqliteTypes(int? cInteger, decimal? cReal, string cText, byte[] cBlob) { await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText, CBlob = cBlob }); var expected = new QuerySql.GetSqliteTypesRow @@ -331,6 +331,29 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesRow expected, Qu Assert.That(actual.CBlob, Is.EqualTo(expected.CBlob)); } + [Test] + [TestCase(-54355, 9787.66, "Have One On Me")] + [TestCase(null, 0.0, null)] + public async Task TestSqliteDataTypesOverride(int? cInteger, decimal cReal, string cText) + { + await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText }); + var expected = new QuerySql.GetSqliteFunctionsRow + { + MaxInteger = cInteger, + MaxReal = cReal, + MaxText = cText + }; + var actual = await QuerySql.GetSqliteFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal)); + Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText)); + } + [Test] [TestCase(100, 312, -7541.3309, "Johnny B. Good")] [TestCase(500, -768, 8453.5678, "Bad to the Bone")] @@ -339,18 +362,18 @@ public async Task TestCopyFrom(int batchSize, int? cInteger, decimal? cReal, str { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertSqliteTypesBatchArgs { CInteger = cInteger, CReal = cReal, CText = cText }).ToList(); await QuerySql.InsertSqliteTypesBatch(batchArgs); - var expected = new QuerySql.GetSqliteTypesAggRow + var expected = new QuerySql.GetSqliteTypesCntRow { Cnt = batchSize, CInteger = cInteger, CReal = cReal, CText = cText }; - var actual = await QuerySql.GetSqliteTypesAgg(); + var actual = await QuerySql.GetSqliteTypesCnt(); AssertSingularEquals(expected, actual); } - private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, QuerySql.GetSqliteTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected, QuerySql.GetSqliteTypesCntRow actual) { Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CInteger, Is.EqualTo(expected.CInteger)); diff --git a/end2end/EndToEndTests/SqliteTester.generated.cs b/end2end/EndToEndTests/SqliteTester.generated.cs index 2695a577..d0fedd23 100644 --- a/end2end/EndToEndTests/SqliteTester.generated.cs +++ b/end2end/EndToEndTests/SqliteTester.generated.cs @@ -309,7 +309,7 @@ public async Task TestNargNotNull() [TestCase(-54355, 9787.66, "Songs of Love and Hate", new byte[] { 0x15, 0x20, 0x33 })] [TestCase(null, null, null, new byte[] { })] [TestCase(null, null, null, null)] - public async Task TestSqliteTypes(int cInteger, decimal? cReal, string cText, byte[] cBlob) + public async Task TestSqliteTypes(int? cInteger, decimal? cReal, string cText, byte[] cBlob) { await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText, CBlob = cBlob }); var expected = new QuerySql.GetSqliteTypesRow @@ -331,6 +331,29 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesRow expected, Qu Assert.That(actual.CBlob, Is.EqualTo(expected.CBlob)); } + [Test] + [TestCase(-54355, 9787.66, "Have One On Me")] + [TestCase(null, 0.0, null)] + public async Task TestSqliteDataTypesOverride(int? cInteger, decimal cReal, string cText) + { + await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText }); + var expected = new QuerySql.GetSqliteFunctionsRow + { + MaxInteger = cInteger, + MaxReal = cReal, + MaxText = cText + }; + var actual = await QuerySql.GetSqliteFunctions(); + AssertSingularEquals(expected, actual.Value); + } + + private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal)); + Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText)); + } + [Test] [TestCase(100, 312, -7541.3309, "Johnny B. Good")] [TestCase(500, -768, 8453.5678, "Bad to the Bone")] @@ -339,18 +362,18 @@ public async Task TestCopyFrom(int batchSize, int? cInteger, decimal? cReal, str { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertSqliteTypesBatchArgs { CInteger = cInteger, CReal = cReal, CText = cText }).ToList(); await QuerySql.InsertSqliteTypesBatch(batchArgs); - var expected = new QuerySql.GetSqliteTypesAggRow + var expected = new QuerySql.GetSqliteTypesCntRow { Cnt = batchSize, CInteger = cInteger, CReal = cReal, CText = cText }; - var actual = await QuerySql.GetSqliteTypesAgg(); + var actual = await QuerySql.GetSqliteTypesCnt(); AssertSingularEquals(expected, actual.Value); } - private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, QuerySql.GetSqliteTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected, QuerySql.GetSqliteTypesCntRow actual) { Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CInteger, Is.EqualTo(expected.CInteger)); diff --git a/end2end/EndToEndTestsLegacy/GlobalSetup.cs b/end2end/EndToEndTestsLegacy/GlobalSetup.cs index 34164c8a..28a165d3 100644 --- a/end2end/EndToEndTestsLegacy/GlobalSetup.cs +++ b/end2end/EndToEndTestsLegacy/GlobalSetup.cs @@ -1,4 +1,3 @@ -using EndToEndTests; using NUnit.Framework; namespace EndToEndTests diff --git a/end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.generated.cs b/end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.generated.cs index 2af4e2f8..ca83b51e 100644 --- a/end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/MySqlConnectorDapperTester.generated.cs @@ -446,6 +446,31 @@ public async Task TestMySqlStringTypes(MysqlTypesCEnum? cEnum) Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } + [Test] + [TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")] + [TestCase(null, 0, null, "1971-01-01 00:00:00")] + public async Task TestMySqlDataTypesOverride(int? cInt, long cBigint, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs { CInt = cInt, CBigint = cBigint, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetMysqlFunctionsRow + { + MaxInt = cInt, + MaxBigint = cBigint, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetMysqlFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual) + { + Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt)); + Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] public async Task TestMySqlScopedSchemaEnum() { @@ -472,7 +497,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CChar = cChar, CNchar = cNchar, CNationalChar = cNationalChar, CVarchar = cVarchar, CTinytext = cTinytext, CMediumtext = cMediumtext, CText = cText, CLongtext = cLongtext }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -484,7 +509,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, CText = cText, CLongtext = cLongtext, }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CNchar, Is.EqualTo(expected.CNchar)); @@ -503,7 +528,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBool = cBool, CBoolean = cBoolean, CTinyint = cTinyint, CSmallint = cSmallint, CMediumint = cMediumint, CInt = cInt, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBool = cBool, @@ -515,7 +540,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBool, Is.EqualTo(expected.CBool)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); @@ -534,7 +559,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CFloat = cFloat, CNumeric = cNumeric, CDecimal = cDecimal, CDec = cDec, CFixed = cFixed, CDouble = cDouble, CDoublePrecision = cDoublePrecision }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CFloat = cFloat, @@ -545,7 +570,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima CDouble = cDouble, CDoublePrecision = cDoublePrecision }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CFloat, Is.EqualTo(expected.CFloat)); Assert.That(actual.CNumeric, Is.EqualTo(expected.CNumeric)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -562,7 +587,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CYear = cYear, CDate = cDate, CDatetime = cDatetime, CTimestamp = cTimestamp }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CYear = cYear, @@ -570,7 +595,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD CDatetime = cDatetime, CTimestamp = cTimestamp }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CYear, Is.EqualTo(expected.CYear)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); @@ -586,7 +611,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBit = cBit, CBinary = cBinary, CVarbinary = cVarbinary, CTinyblob = cTinyblob, CBlob = cBlob, CMediumblob = cMediumblob, CLongblob = cLongblob }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBit = cBit, @@ -597,7 +622,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, CMediumblob = cMediumblob, CLongblob = cLongblob }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBit, Is.EqualTo(expected.CBit)); Assert.That(actual.CBinary, Is.EqualTo(expected.CBinary)); @@ -616,12 +641,12 @@ public async Task TestCopyFrom(int batchSize, MysqlTypesCEnum? cEnum) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CEnum = cEnum }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CEnum = cEnum }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } } diff --git a/end2end/EndToEndTestsLegacy/MySqlConnectorTester.generated.cs b/end2end/EndToEndTestsLegacy/MySqlConnectorTester.generated.cs index eeb3b2a2..8b34b643 100644 --- a/end2end/EndToEndTestsLegacy/MySqlConnectorTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/MySqlConnectorTester.generated.cs @@ -446,6 +446,31 @@ public async Task TestMySqlStringTypes(MysqlTypesCEnum? cEnum) Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } + [Test] + [TestCase(-54355, 9787876578, "Scream of the Butterfly", "2025-06-29 12:00:00")] + [TestCase(null, 0, null, "1971-01-01 00:00:00")] + public async Task TestMySqlDataTypesOverride(int? cInt, long cBigint, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertMysqlTypes(new QuerySql.InsertMysqlTypesArgs { CInt = cInt, CBigint = cBigint, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetMysqlFunctionsRow + { + MaxInt = cInt, + MaxBigint = cBigint, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetMysqlFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetMysqlFunctionsRow expected, QuerySql.GetMysqlFunctionsRow actual) + { + Assert.That(actual.MaxInt, Is.EqualTo(expected.MaxInt)); + Assert.That(actual.MaxBigint, Is.EqualTo(expected.MaxBigint)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] public async Task TestMySqlScopedSchemaEnum() { @@ -472,7 +497,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CChar = cChar, CNchar = cNchar, CNationalChar = cNationalChar, CVarchar = cVarchar, CTinytext = cTinytext, CMediumtext = cMediumtext, CText = cText, CLongtext = cLongtext }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -484,7 +509,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cNchar, CText = cText, CLongtext = cLongtext, }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CNchar, Is.EqualTo(expected.CNchar)); @@ -503,7 +528,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBool = cBool, CBoolean = cBoolean, CTinyint = cTinyint, CSmallint = cSmallint, CMediumint = cMediumint, CInt = cInt, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBool = cBool, @@ -515,7 +540,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBool, bool? cBoolean CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBool, Is.EqualTo(expected.CBool)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); @@ -534,7 +559,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CFloat = cFloat, CNumeric = cNumeric, CDecimal = cDecimal, CDec = cDec, CFixed = cFixed, CDouble = cDouble, CDoublePrecision = cDoublePrecision }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CFloat = cFloat, @@ -545,7 +570,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cFloat, decima CDouble = cDouble, CDoublePrecision = cDoublePrecision }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CFloat, Is.EqualTo(expected.CFloat)); Assert.That(actual.CNumeric, Is.EqualTo(expected.CNumeric)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -562,7 +587,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CYear = cYear, CDate = cDate, CDatetime = cDatetime, CTimestamp = cTimestamp }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CYear = cYear, @@ -570,7 +595,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, short? cYear, DateTime? cD CDatetime = cDatetime, CTimestamp = cTimestamp }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CYear, Is.EqualTo(expected.CYear)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); @@ -586,7 +611,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CBit = cBit, CBinary = cBinary, CVarbinary = cVarbinary, CTinyblob = cTinyblob, CBlob = cBlob, CMediumblob = cMediumblob, CLongblob = cLongblob }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CBit = cBit, @@ -597,7 +622,7 @@ public async Task TestBinaryCopyFrom(int batchSize, byte? cBit, byte[] cBinary, CMediumblob = cMediumblob, CLongblob = cLongblob }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBit, Is.EqualTo(expected.CBit)); Assert.That(actual.CBinary, Is.EqualTo(expected.CBinary)); @@ -616,12 +641,12 @@ public async Task TestCopyFrom(int batchSize, MysqlTypesCEnum? cEnum) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertMysqlTypesBatchArgs { CEnum = cEnum }).ToList(); await QuerySql.InsertMysqlTypesBatch(batchArgs); - var expected = new QuerySql.GetMysqlTypesAggRow + var expected = new QuerySql.GetMysqlTypesCntRow { Cnt = batchSize, CEnum = cEnum }; - var actual = await QuerySql.GetMysqlTypesAgg(); + var actual = await QuerySql.GetMysqlTypesCnt(); Assert.That(actual.CEnum, Is.EqualTo(expected.CEnum)); } } diff --git a/end2end/EndToEndTestsLegacy/NpgsqlDapperTester.generated.cs b/end2end/EndToEndTestsLegacy/NpgsqlDapperTester.generated.cs index ed636326..0e312af0 100644 --- a/end2end/EndToEndTestsLegacy/NpgsqlDapperTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/NpgsqlDapperTester.generated.cs @@ -389,6 +389,29 @@ public async Task TestPostgresArrayTypes(byte[] cBytea, string[] cTextArray, int Assert.That(actual.CIntegerArray, Is.EqualTo(expected.CIntegerArray)); } + [Test] + [TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")] + [TestCase(null, null, "1970-01-01 00:00:00")] + public async Task TestPostgresDataTypesOverride(int? cInteger, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs { CInteger = cInteger, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetPostgresFunctionsRow + { + MaxInteger = cInteger, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetPostgresFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] [TestCase(100, "z", "Sex Pistols", "Anarchy in the U.K", "Never Mind the Bollocks...")] [TestCase(10, null, null, null, null)] @@ -396,7 +419,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CChar = cChar, CVarchar = cVarchar, CCharacterVarying = cCharacterVarying, CText = cText }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -404,7 +427,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha CCharacterVarying = cCharacterVarying, CText = cText }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CVarchar, Is.EqualTo(expected.CVarchar)); @@ -419,7 +442,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBoolean = cBoolean, CSmallint = cSmallint, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBoolean = cBoolean, @@ -427,7 +450,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); Assert.That(actual.CSmallint, Is.EqualTo(expected.CSmallint)); @@ -435,7 +458,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma Assert.That(actual.CBigint, Is.EqualTo(expected.CBigint)); } - private static void AssertSingularEquals(QuerySql.GetPostgresTypesAggRow expected, QuerySql.GetPostgresTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetPostgresTypesCntRow expected, QuerySql.GetPostgresTypesCntRow actual) { } @@ -446,7 +469,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CReal = cReal, CDecimal = cDecimal, CNumeric = cNumeric, CDoublePrecision = cDoublePrecision, CMoney = cMoney }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CReal = cReal, @@ -455,7 +478,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal CDoublePrecision = cDoublePrecision, CMoney = cMoney }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CReal, Is.EqualTo(expected.CReal)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -474,7 +497,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? cTimestampWithTzAsUtc = DateTime.SpecifyKind(cTimestampWithTz.Value, DateTimeKind.Utc); var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CDate = cDate, CTime = cTime, CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTzAsUtc }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CDate = cDate, @@ -482,7 +505,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTz, }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); Assert.That(actual.CTime, Is.EqualTo(expected.CTime)); @@ -498,12 +521,12 @@ public async Task TestArrayCopyFrom(int batchSize, byte[] cBytea) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBytea = cBytea }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBytea = cBytea }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBytea, Is.EqualTo(expected.CBytea)); } diff --git a/end2end/EndToEndTestsLegacy/NpgsqlTester.generated.cs b/end2end/EndToEndTestsLegacy/NpgsqlTester.generated.cs index 1c43f210..1e26d580 100644 --- a/end2end/EndToEndTestsLegacy/NpgsqlTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/NpgsqlTester.generated.cs @@ -389,6 +389,29 @@ public async Task TestPostgresArrayTypes(byte[] cBytea, string[] cTextArray, int Assert.That(actual.CIntegerArray, Is.EqualTo(expected.CIntegerArray)); } + [Test] + [TestCase(-54355, "White Light from the Mouth of Infinity", "2022-10-2 15:44:01+09:00")] + [TestCase(null, null, "1970-01-01 00:00:00")] + public async Task TestPostgresDataTypesOverride(int? cInteger, string cVarchar, DateTime cTimestamp) + { + await QuerySql.InsertPostgresTypes(new QuerySql.InsertPostgresTypesArgs { CInteger = cInteger, CVarchar = cVarchar, CTimestamp = cTimestamp }); + var expected = new QuerySql.GetPostgresFunctionsRow + { + MaxInteger = cInteger, + MaxVarchar = cVarchar, + MaxTimestamp = cTimestamp + }; + var actual = await QuerySql.GetPostgresFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetPostgresFunctionsRow expected, QuerySql.GetPostgresFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxVarchar, Is.EqualTo(expected.MaxVarchar)); + Assert.That(actual.MaxTimestamp, Is.EqualTo(expected.MaxTimestamp)); + } + [Test] [TestCase(100, "z", "Sex Pistols", "Anarchy in the U.K", "Never Mind the Bollocks...")] [TestCase(10, null, null, null, null)] @@ -396,7 +419,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CChar = cChar, CVarchar = cVarchar, CCharacterVarying = cCharacterVarying, CText = cText }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CChar = cChar, @@ -404,7 +427,7 @@ public async Task TestStringCopyFrom(int batchSize, string cChar, string cVarcha CCharacterVarying = cCharacterVarying, CText = cText }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CChar, Is.EqualTo(expected.CChar)); Assert.That(actual.CVarchar, Is.EqualTo(expected.CVarchar)); @@ -419,7 +442,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBoolean = cBoolean, CSmallint = cSmallint, CInteger = cInteger, CBigint = cBigint }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBoolean = cBoolean, @@ -427,7 +450,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma CInteger = cInteger, CBigint = cBigint }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBoolean, Is.EqualTo(expected.CBoolean)); Assert.That(actual.CSmallint, Is.EqualTo(expected.CSmallint)); @@ -435,7 +458,7 @@ public async Task TestIntegerCopyFrom(int batchSize, bool? cBoolean, short? cSma Assert.That(actual.CBigint, Is.EqualTo(expected.CBigint)); } - private static void AssertSingularEquals(QuerySql.GetPostgresTypesAggRow expected, QuerySql.GetPostgresTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetPostgresTypesCntRow expected, QuerySql.GetPostgresTypesCntRow actual) { } @@ -446,7 +469,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CReal = cReal, CDecimal = cDecimal, CNumeric = cNumeric, CDoublePrecision = cDoublePrecision, CMoney = cMoney }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CReal = cReal, @@ -455,7 +478,7 @@ public async Task TestFloatingPointCopyFrom(int batchSize, float? cReal, decimal CDoublePrecision = cDoublePrecision, CMoney = cMoney }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CReal, Is.EqualTo(expected.CReal)); Assert.That(actual.CDecimal, Is.EqualTo(expected.CDecimal)); @@ -474,7 +497,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? cTimestampWithTzAsUtc = DateTime.SpecifyKind(cTimestampWithTz.Value, DateTimeKind.Utc); var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CDate = cDate, CTime = cTime, CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTzAsUtc }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CDate = cDate, @@ -482,7 +505,7 @@ public async Task TestDateTimeCopyFrom(int batchSize, DateTime? cDate, TimeSpan? CTimestamp = cTimestamp, CTimestampWithTz = cTimestampWithTz, }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CDate, Is.EqualTo(expected.CDate)); Assert.That(actual.CTime, Is.EqualTo(expected.CTime)); @@ -498,12 +521,12 @@ public async Task TestArrayCopyFrom(int batchSize, byte[] cBytea) { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertPostgresTypesBatchArgs { CBytea = cBytea }).ToList(); await QuerySql.InsertPostgresTypesBatch(batchArgs); - var expected = new QuerySql.GetPostgresTypesAggRow + var expected = new QuerySql.GetPostgresTypesCntRow { Cnt = batchSize, CBytea = cBytea }; - var actual = await QuerySql.GetPostgresTypesAgg(); + var actual = await QuerySql.GetPostgresTypesCnt(); Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CBytea, Is.EqualTo(expected.CBytea)); } diff --git a/end2end/EndToEndTestsLegacy/SqliteDapperTester.generated.cs b/end2end/EndToEndTestsLegacy/SqliteDapperTester.generated.cs index 81545761..d83f2692 100644 --- a/end2end/EndToEndTestsLegacy/SqliteDapperTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/SqliteDapperTester.generated.cs @@ -309,7 +309,7 @@ public async Task TestNargNotNull() [TestCase(-54355, 9787.66, "Songs of Love and Hate", new byte[] { 0x15, 0x20, 0x33 })] [TestCase(null, null, null, new byte[] { })] [TestCase(null, null, null, null)] - public async Task TestSqliteTypes(int cInteger, decimal? cReal, string cText, byte[] cBlob) + public async Task TestSqliteTypes(int? cInteger, decimal? cReal, string cText, byte[] cBlob) { await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText, CBlob = cBlob }); var expected = new QuerySql.GetSqliteTypesRow @@ -331,6 +331,29 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesRow expected, Qu Assert.That(actual.CBlob, Is.EqualTo(expected.CBlob)); } + [Test] + [TestCase(-54355, 9787.66, "Have One On Me")] + [TestCase(null, 0.0, null)] + public async Task TestSqliteDataTypesOverride(int? cInteger, decimal cReal, string cText) + { + await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText }); + var expected = new QuerySql.GetSqliteFunctionsRow + { + MaxInteger = cInteger, + MaxReal = cReal, + MaxText = cText + }; + var actual = await QuerySql.GetSqliteFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal)); + Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText)); + } + [Test] [TestCase(100, 312, -7541.3309, "Johnny B. Good")] [TestCase(500, -768, 8453.5678, "Bad to the Bone")] @@ -339,18 +362,18 @@ public async Task TestCopyFrom(int batchSize, int? cInteger, decimal? cReal, str { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertSqliteTypesBatchArgs { CInteger = cInteger, CReal = cReal, CText = cText }).ToList(); await QuerySql.InsertSqliteTypesBatch(batchArgs); - var expected = new QuerySql.GetSqliteTypesAggRow + var expected = new QuerySql.GetSqliteTypesCntRow { Cnt = batchSize, CInteger = cInteger, CReal = cReal, CText = cText }; - var actual = await QuerySql.GetSqliteTypesAgg(); + var actual = await QuerySql.GetSqliteTypesCnt(); AssertSingularEquals(expected, actual); } - private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, QuerySql.GetSqliteTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected, QuerySql.GetSqliteTypesCntRow actual) { Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CInteger, Is.EqualTo(expected.CInteger)); diff --git a/end2end/EndToEndTestsLegacy/SqliteTester.generated.cs b/end2end/EndToEndTestsLegacy/SqliteTester.generated.cs index 9e1b7cc1..77d7dae6 100644 --- a/end2end/EndToEndTestsLegacy/SqliteTester.generated.cs +++ b/end2end/EndToEndTestsLegacy/SqliteTester.generated.cs @@ -309,7 +309,7 @@ public async Task TestNargNotNull() [TestCase(-54355, 9787.66, "Songs of Love and Hate", new byte[] { 0x15, 0x20, 0x33 })] [TestCase(null, null, null, new byte[] { })] [TestCase(null, null, null, null)] - public async Task TestSqliteTypes(int cInteger, decimal? cReal, string cText, byte[] cBlob) + public async Task TestSqliteTypes(int? cInteger, decimal? cReal, string cText, byte[] cBlob) { await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText, CBlob = cBlob }); var expected = new QuerySql.GetSqliteTypesRow @@ -331,6 +331,29 @@ private static void AssertSingularEquals(QuerySql.GetSqliteTypesRow expected, Qu Assert.That(actual.CBlob, Is.EqualTo(expected.CBlob)); } + [Test] + [TestCase(-54355, 9787.66, "Have One On Me")] + [TestCase(null, 0.0, null)] + public async Task TestSqliteDataTypesOverride(int? cInteger, decimal cReal, string cText) + { + await QuerySql.InsertSqliteTypes(new QuerySql.InsertSqliteTypesArgs { CInteger = cInteger, CReal = cReal, CText = cText }); + var expected = new QuerySql.GetSqliteFunctionsRow + { + MaxInteger = cInteger, + MaxReal = cReal, + MaxText = cText + }; + var actual = await QuerySql.GetSqliteFunctions(); + AssertSingularEquals(expected, actual); + } + + private static void AssertSingularEquals(QuerySql.GetSqliteFunctionsRow expected, QuerySql.GetSqliteFunctionsRow actual) + { + Assert.That(actual.MaxInteger, Is.EqualTo(expected.MaxInteger)); + Assert.That(actual.MaxReal, Is.EqualTo(expected.MaxReal)); + Assert.That(actual.MaxText, Is.EqualTo(expected.MaxText)); + } + [Test] [TestCase(100, 312, -7541.3309, "Johnny B. Good")] [TestCase(500, -768, 8453.5678, "Bad to the Bone")] @@ -339,18 +362,18 @@ public async Task TestCopyFrom(int batchSize, int? cInteger, decimal? cReal, str { var batchArgs = Enumerable.Range(0, batchSize).Select(_ => new QuerySql.InsertSqliteTypesBatchArgs { CInteger = cInteger, CReal = cReal, CText = cText }).ToList(); await QuerySql.InsertSqliteTypesBatch(batchArgs); - var expected = new QuerySql.GetSqliteTypesAggRow + var expected = new QuerySql.GetSqliteTypesCntRow { Cnt = batchSize, CInteger = cInteger, CReal = cReal, CText = cText }; - var actual = await QuerySql.GetSqliteTypesAgg(); + var actual = await QuerySql.GetSqliteTypesCnt(); AssertSingularEquals(expected, actual); } - private static void AssertSingularEquals(QuerySql.GetSqliteTypesAggRow expected, QuerySql.GetSqliteTypesAggRow actual) + private static void AssertSingularEquals(QuerySql.GetSqliteTypesCntRow expected, QuerySql.GetSqliteTypesCntRow actual) { Assert.That(actual.Cnt, Is.EqualTo(expected.Cnt)); Assert.That(actual.CInteger, Is.EqualTo(expected.CInteger)); diff --git a/examples/MySqlConnectorDapperExample/QuerySql.cs b/examples/MySqlConnectorDapperExample/QuerySql.cs index af71692a..fe20c9f0 100644 --- a/examples/MySqlConnectorDapperExample/QuerySql.cs +++ b/examples/MySqlConnectorDapperExample/QuerySql.cs @@ -49,7 +49,7 @@ public class GetAuthorArgs } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name; SELECT LAST_INSERT_ID()"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name ; SELECT LAST_INSERT_ID ( ) "; public class ListAuthorsRow { public required long Id { get; init; } @@ -123,7 +123,7 @@ public class GetAuthorByIdArgs } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%'); SELECT LAST_INSERT_ID()"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) ; SELECT LAST_INSERT_ID ( ) "; public class GetAuthorByNamePatternRow { public required long Id { get; init; } @@ -145,7 +145,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name; SELECT LAST_INSERT_ID()"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name ; SELECT LAST_INSERT_ID ( ) "; public class DeleteAuthorArgs { public required string Name { get; init; } @@ -574,8 +574,8 @@ public class GetMysqlTypesRow } } - private const string GetMysqlTypesAggSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 ; SELECT LAST_INSERT_ID ( ) "; - public class GetMysqlTypesAggRow + private const string GetMysqlTypesCntSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 ; SELECT LAST_INSERT_ID ( ) "; + public class GetMysqlTypesCntRow { public required long Cnt { get; init; } public bool? CBool { get; init; } @@ -614,11 +614,28 @@ public class GetMysqlTypesAggRow public byte[]? CMediumblob { get; init; } public byte[]? CLongblob { get; init; } }; - public async Task GetMysqlTypesAgg() + public async Task GetMysqlTypesCnt() { using (var connection = new MySqlConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetMysqlTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetMysqlTypesCntSql); + return result; + } + } + + private const string GetMysqlFunctionsSql = "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint FROM mysql_types ; SELECT LAST_INSERT_ID ( ) "; + public class GetMysqlFunctionsRow + { + public int? MaxInt { get; init; } + public string? MaxVarchar { get; init; } + public required DateTime MaxTimestamp { get; init; } + public required long MaxBigint { get; init; } + }; + public async Task GetMysqlFunctions() + { + using (var connection = new MySqlConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetMysqlFunctionsSql); return result; } } diff --git a/examples/MySqlConnectorDapperExample/request.json b/examples/MySqlConnectorDapperExample/request.json index 8a3c7079..22c8a7db 100644 --- a/examples/MySqlConnectorDapperExample/request.json +++ b/examples/MySqlConnectorDapperExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/MySqlConnectorDapperExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JEYXBwZXJFeGFtcGxlR2VuIiwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JEYXBwZXJFeGFtcGxlR2VuIiwib3ZlcnJpZGVzIjpbeyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfaW50IiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfdmFyY2hhciIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOmZhbHNlLCJ0eXBlIjoic3RyaW5nIn19LHsiY29sdW1uIjoiR2V0TXlzcWxGdW5jdGlvbnM6bWF4X3RpbWVzdGFtcCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJEYXRlVGltZSJ9fSx7ImNvbHVtbiI6IkdldE15c3FsRnVuY3Rpb25zOm1heF9iaWdpbnQiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjp0cnVlLCJ0eXBlIjoibG9uZyJ9fV0sInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6dHJ1ZX0=", "process": { "cmd": "./dist/LocalRunner" } @@ -609,7 +609,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -812,7 +812,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -872,7 +872,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -2702,7 +2702,7 @@ }, { "text": "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nFROM mysql_types\nGROUP BY c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nLIMIT 1", - "name": "GetMysqlTypesAgg", + "name": "GetMysqlTypesCnt", "cmd": ":one", "columns": [ { @@ -3102,6 +3102,50 @@ ], "filename": "query.sql" }, + { + "text": "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint\nFROM mysql_types", + "name": "GetMysqlFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_int", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_bigint", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + } + ], + "filename": "query.sql" + }, { "text": "TRUNCATE TABLE mysql_types", "name": "TruncateMysqlTypes", diff --git a/examples/MySqlConnectorDapperLegacyExample/QuerySql.cs b/examples/MySqlConnectorDapperLegacyExample/QuerySql.cs index 41d699ac..5165c5af 100644 --- a/examples/MySqlConnectorDapperLegacyExample/QuerySql.cs +++ b/examples/MySqlConnectorDapperLegacyExample/QuerySql.cs @@ -50,7 +50,7 @@ public async Task GetAuthor(GetAuthorArgs args) } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name; SELECT LAST_INSERT_ID()"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name ; SELECT LAST_INSERT_ID ( ) "; public class ListAuthorsRow { public long Id { get; set; } @@ -124,7 +124,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%'); SELECT LAST_INSERT_ID()"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) ; SELECT LAST_INSERT_ID ( ) "; public class GetAuthorByNamePatternRow { public long Id { get; set; } @@ -146,7 +146,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name; SELECT LAST_INSERT_ID()"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name ; SELECT LAST_INSERT_ID ( ) "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -574,8 +574,8 @@ public async Task GetMysqlTypes() } } - private const string GetMysqlTypesAggSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 ; SELECT LAST_INSERT_ID ( ) "; - public class GetMysqlTypesAggRow + private const string GetMysqlTypesCntSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 ; SELECT LAST_INSERT_ID ( ) "; + public class GetMysqlTypesCntRow { public long Cnt { get; set; } public bool? CBool { get; set; } @@ -614,11 +614,28 @@ public class GetMysqlTypesAggRow public byte[] CMediumblob { get; set; } public byte[] CLongblob { get; set; } }; - public async Task GetMysqlTypesAgg() + public async Task GetMysqlTypesCnt() { using (var connection = new MySqlConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetMysqlTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetMysqlTypesCntSql); + return result; + } + } + + private const string GetMysqlFunctionsSql = "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint FROM mysql_types ; SELECT LAST_INSERT_ID ( ) "; + public class GetMysqlFunctionsRow + { + public int? MaxInt { get; set; } + public string MaxVarchar { get; set; } + public DateTime MaxTimestamp { get; set; } + public long MaxBigint { get; set; } + }; + public async Task GetMysqlFunctions() + { + using (var connection = new MySqlConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetMysqlFunctionsSql); return result; } } diff --git a/examples/MySqlConnectorDapperLegacyExample/request.json b/examples/MySqlConnectorDapperLegacyExample/request.json index 2dd58e28..0472d073 100644 --- a/examples/MySqlConnectorDapperLegacyExample/request.json +++ b/examples/MySqlConnectorDapperLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/MySqlConnectorDapperLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JEYXBwZXJMZWdhY3lFeGFtcGxlR2VuIiwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOnRydWV9", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JEYXBwZXJMZWdhY3lFeGFtcGxlR2VuIiwib3ZlcnJpZGVzIjpbeyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfaW50IiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfdmFyY2hhciIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOmZhbHNlLCJ0eXBlIjoic3RyaW5nIn19LHsiY29sdW1uIjoiR2V0TXlzcWxGdW5jdGlvbnM6bWF4X3RpbWVzdGFtcCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJEYXRlVGltZSJ9fSx7ImNvbHVtbiI6IkdldE15c3FsRnVuY3Rpb25zOm1heF9iaWdpbnQiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjp0cnVlLCJ0eXBlIjoibG9uZyJ9fV0sInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", "process": { "cmd": "./dist/LocalRunner" } @@ -609,7 +609,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -812,7 +812,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -872,7 +872,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -2702,7 +2702,7 @@ }, { "text": "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nFROM mysql_types\nGROUP BY c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nLIMIT 1", - "name": "GetMysqlTypesAgg", + "name": "GetMysqlTypesCnt", "cmd": ":one", "columns": [ { @@ -3102,6 +3102,50 @@ ], "filename": "query.sql" }, + { + "text": "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint\nFROM mysql_types", + "name": "GetMysqlFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_int", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_bigint", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + } + ], + "filename": "query.sql" + }, { "text": "TRUNCATE TABLE mysql_types", "name": "TruncateMysqlTypes", diff --git a/examples/MySqlConnectorExample/QuerySql.cs b/examples/MySqlConnectorExample/QuerySql.cs index a30e423e..1a5a7a27 100644 --- a/examples/MySqlConnectorExample/QuerySql.cs +++ b/examples/MySqlConnectorExample/QuerySql.cs @@ -54,7 +54,7 @@ public QuerySql(string connectionString) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public readonly record struct ListAuthorsRow(long Id, string Name, string? Bio); public async Task> ListAuthors() { @@ -140,7 +140,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public readonly record struct GetAuthorByNamePatternRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorByNamePatternArgs(string? NamePattern); public async Task> GetAuthorByNamePattern(GetAuthorByNamePatternArgs args) @@ -165,7 +165,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public readonly record struct DeleteAuthorArgs(string Name); public async Task DeleteAuthor(DeleteAuthorArgs args) { @@ -526,20 +526,20 @@ public async Task InsertMysqlTypesBatch(List args) return null; } - private const string GetMysqlTypesAggSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 "; - public readonly record struct GetMysqlTypesAggRow(long Cnt, bool? CBool, bool? CBoolean, byte? CBit, short? CTinyint, short? CSmallint, int? CMediumint, int? CInt, int? CInteger, long? CBigint, double? CFloat, decimal? CNumeric, decimal? CDecimal, decimal? CDec, decimal? CFixed, double? CDouble, double? CDoublePrecision, string? CChar, string? CNchar, string? CNationalChar, string? CVarchar, string? CTinytext, string? CMediumtext, string? CText, string? CLongtext, MysqlTypesCEnum? CEnum, short? CYear, DateTime? CDate, DateTime? CDatetime, DateTime? CTimestamp, byte[]? CBinary, byte[]? CVarbinary, byte[]? CTinyblob, byte[]? CBlob, byte[]? CMediumblob, byte[]? CLongblob); - public async Task GetMysqlTypesAgg() + private const string GetMysqlTypesCntSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 "; + public readonly record struct GetMysqlTypesCntRow(long Cnt, bool? CBool, bool? CBoolean, byte? CBit, short? CTinyint, short? CSmallint, int? CMediumint, int? CInt, int? CInteger, long? CBigint, double? CFloat, decimal? CNumeric, decimal? CDecimal, decimal? CDec, decimal? CFixed, double? CDouble, double? CDoublePrecision, string? CChar, string? CNchar, string? CNationalChar, string? CVarchar, string? CTinytext, string? CMediumtext, string? CText, string? CLongtext, MysqlTypesCEnum? CEnum, short? CYear, DateTime? CDate, DateTime? CDatetime, DateTime? CTimestamp, byte[]? CBinary, byte[]? CVarbinary, byte[]? CTinyblob, byte[]? CBlob, byte[]? CMediumblob, byte[]? CLongblob); + public async Task GetMysqlTypesCnt() { using (var connection = new MySqlConnection(ConnectionString)) { await connection.OpenAsync(); - using (var command = new MySqlCommand(GetMysqlTypesAggSql, connection)) + using (var command = new MySqlCommand(GetMysqlTypesCntSql, connection)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetMysqlTypesAggRow + return new GetMysqlTypesCntRow { Cnt = reader.GetInt64(0), CBool = reader.IsDBNull(1) ? null : reader.GetBoolean(1), @@ -586,6 +586,34 @@ public async Task InsertMysqlTypesBatch(List args) return null; } + private const string GetMysqlFunctionsSql = "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint FROM mysql_types "; + public readonly record struct GetMysqlFunctionsRow(int? MaxInt, string? MaxVarchar, DateTime MaxTimestamp, long MaxBigint); + public async Task GetMysqlFunctions() + { + using (var connection = new MySqlConnection(ConnectionString)) + { + await connection.OpenAsync(); + using (var command = new MySqlCommand(GetMysqlFunctionsSql, connection)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetMysqlFunctionsRow + { + MaxInt = reader.IsDBNull(0) ? null : reader.GetInt32(0), + MaxVarchar = reader.IsDBNull(1) ? null : reader.GetString(1), + MaxTimestamp = reader.GetDateTime(2), + MaxBigint = reader.GetInt64(3) + }; + } + } + } + } + + return null; + } + private const string TruncateMysqlTypesSql = "TRUNCATE TABLE mysql_types"; public async Task TruncateMysqlTypes() { diff --git a/examples/MySqlConnectorExample/request.json b/examples/MySqlConnectorExample/request.json index 1d439ddc..ab760399 100644 --- a/examples/MySqlConnectorExample/request.json +++ b/examples/MySqlConnectorExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/MySqlConnectorExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JFeGFtcGxlR2VuIiwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JFeGFtcGxlR2VuIiwib3ZlcnJpZGVzIjpbeyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfaW50IiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfdmFyY2hhciIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOmZhbHNlLCJ0eXBlIjoic3RyaW5nIn19LHsiY29sdW1uIjoiR2V0TXlzcWxGdW5jdGlvbnM6bWF4X3RpbWVzdGFtcCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJEYXRlVGltZSJ9fSx7ImNvbHVtbiI6IkdldE15c3FsRnVuY3Rpb25zOm1heF9iaWdpbnQiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjp0cnVlLCJ0eXBlIjoibG9uZyJ9fV0sInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6ZmFsc2V9", "process": { "cmd": "./dist/LocalRunner" } @@ -609,7 +609,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -812,7 +812,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -872,7 +872,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -2702,7 +2702,7 @@ }, { "text": "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nFROM mysql_types\nGROUP BY c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nLIMIT 1", - "name": "GetMysqlTypesAgg", + "name": "GetMysqlTypesCnt", "cmd": ":one", "columns": [ { @@ -3102,6 +3102,50 @@ ], "filename": "query.sql" }, + { + "text": "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint\nFROM mysql_types", + "name": "GetMysqlFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_int", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_bigint", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + } + ], + "filename": "query.sql" + }, { "text": "TRUNCATE TABLE mysql_types", "name": "TruncateMysqlTypes", diff --git a/examples/MySqlConnectorLegacyExample/QuerySql.cs b/examples/MySqlConnectorLegacyExample/QuerySql.cs index a1199951..b0119b74 100644 --- a/examples/MySqlConnectorLegacyExample/QuerySql.cs +++ b/examples/MySqlConnectorLegacyExample/QuerySql.cs @@ -63,7 +63,7 @@ public async Task GetAuthor(GetAuthorArgs args) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public long Id { get; set; } @@ -171,7 +171,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public long Id { get; set; } @@ -204,7 +204,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -720,8 +720,8 @@ public async Task GetMysqlTypes() return null; } - private const string GetMysqlTypesAggSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 "; - public class GetMysqlTypesAggRow + private const string GetMysqlTypesCntSql = "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float , c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob FROM mysql_types GROUP BY c_bool , c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, c_year, c_date, c_datetime, c_timestamp, c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1 "; + public class GetMysqlTypesCntRow { public long Cnt { get; set; } public bool? CBool { get; set; } @@ -760,18 +760,18 @@ public class GetMysqlTypesAggRow public byte[] CMediumblob { get; set; } public byte[] CLongblob { get; set; } }; - public async Task GetMysqlTypesAgg() + public async Task GetMysqlTypesCnt() { using (var connection = new MySqlConnection(ConnectionString)) { await connection.OpenAsync(); - using (var command = new MySqlCommand(GetMysqlTypesAggSql, connection)) + using (var command = new MySqlCommand(GetMysqlTypesCntSql, connection)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetMysqlTypesAggRow + return new GetMysqlTypesCntRow { Cnt = reader.GetInt64(0), CBool = reader.IsDBNull(1) ? (bool? )null : reader.GetBoolean(1), @@ -818,6 +818,40 @@ public async Task GetMysqlTypesAgg() return null; } + private const string GetMysqlFunctionsSql = "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint FROM mysql_types "; + public class GetMysqlFunctionsRow + { + public int? MaxInt { get; set; } + public string MaxVarchar { get; set; } + public DateTime MaxTimestamp { get; set; } + public long MaxBigint { get; set; } + }; + public async Task GetMysqlFunctions() + { + using (var connection = new MySqlConnection(ConnectionString)) + { + await connection.OpenAsync(); + using (var command = new MySqlCommand(GetMysqlFunctionsSql, connection)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetMysqlFunctionsRow + { + MaxInt = reader.IsDBNull(0) ? (int? )null : reader.GetInt32(0), + MaxVarchar = reader.IsDBNull(1) ? null : reader.GetString(1), + MaxTimestamp = reader.GetDateTime(2), + MaxBigint = reader.GetInt64(3) + }; + } + } + } + } + + return null; + } + private const string TruncateMysqlTypesSql = "TRUNCATE TABLE mysql_types"; public async Task TruncateMysqlTypes() { diff --git a/examples/MySqlConnectorLegacyExample/request.json b/examples/MySqlConnectorLegacyExample/request.json index 7228093e..a5075cff 100644 --- a/examples/MySqlConnectorLegacyExample/request.json +++ b/examples/MySqlConnectorLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/MySqlConnectorLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JMZWdhY3lFeGFtcGxlR2VuIiwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOmZhbHNlfQ==", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTXlTcWxDb25uZWN0b3JMZWdhY3lFeGFtcGxlR2VuIiwib3ZlcnJpZGVzIjpbeyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfaW50IiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRNeXNxbEZ1bmN0aW9uczptYXhfdmFyY2hhciIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOmZhbHNlLCJ0eXBlIjoic3RyaW5nIn19LHsiY29sdW1uIjoiR2V0TXlzcWxGdW5jdGlvbnM6bWF4X3RpbWVzdGFtcCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJEYXRlVGltZSJ9fSx7ImNvbHVtbiI6IkdldE15c3FsRnVuY3Rpb25zOm1heF9iaWdpbnQiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjp0cnVlLCJ0eXBlIjoibG9uZyJ9fV0sInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", "process": { "cmd": "./dist/LocalRunner" } @@ -609,7 +609,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -812,7 +812,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -872,7 +872,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -2702,7 +2702,7 @@ }, { "text": "SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nFROM mysql_types\nGROUP BY c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, \n c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, \n c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum,\n c_year, c_date, c_datetime, c_timestamp, \n c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob\nLIMIT 1", - "name": "GetMysqlTypesAgg", + "name": "GetMysqlTypesCnt", "cmd": ":one", "columns": [ { @@ -3102,6 +3102,50 @@ ], "filename": "query.sql" }, + { + "text": "SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint\nFROM mysql_types", + "name": "GetMysqlFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_int", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_bigint", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + } + ], + "filename": "query.sql" + }, { "text": "TRUNCATE TABLE mysql_types", "name": "TruncateMysqlTypes", diff --git a/examples/NpgsqlDapperExample/QuerySql.cs b/examples/NpgsqlDapperExample/QuerySql.cs index fe6cc961..a871c1d8 100644 --- a/examples/NpgsqlDapperExample/QuerySql.cs +++ b/examples/NpgsqlDapperExample/QuerySql.cs @@ -24,7 +24,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public required long Id { get; init; } @@ -46,7 +46,7 @@ public class GetAuthorArgs } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public required long Id { get; init; } @@ -109,7 +109,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public required long Id { get; init; } @@ -131,7 +131,7 @@ public class GetAuthorByIdArgs } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public required long Id { get; init; } @@ -153,7 +153,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public required string Name { get; init; } @@ -177,7 +177,7 @@ public async Task TruncateAuthors() } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string? Bio { get; init; } @@ -192,7 +192,7 @@ public async Task UpdateAuthors(UpdateAuthorsArgs args) } } - private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[])"; + private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) "; public class GetAuthorsByIdsRow { public required long Id { get; init; } @@ -214,7 +214,7 @@ public async Task> GetAuthorsByIds(GetAuthorsByIdsArgs } } - private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[]) AND name = ANY(@stringArr_2::TEXT[])"; + private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) AND name = ANY ( @stringArr_2 :: TEXT [ ] ) "; public class GetAuthorsByIdsAndNamesRow { public required long Id { get; init; } @@ -259,7 +259,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name"; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public required Author? Author { get; init; } @@ -285,7 +285,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public required Author? Author { get; init; } @@ -311,7 +311,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public required long Id { get; init; } @@ -344,7 +344,7 @@ public async Task> GetAuthorsByBookName(GetAuthors } } - private const string InsertPostgresTypesSql = "INSERT INTO postgres_types (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; + private const string InsertPostgresTypesSql = "INSERT INTO postgres_types(c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; public class InsertPostgresTypesArgs { public bool? CBoolean { get; init; } @@ -494,10 +494,9 @@ public class GetPostgresTypesRow } } - private const string GetPostgresTypesAggSql = "SELECT COUNT(1) AS cnt , c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea FROM postgres_types GROUP BY c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; - public class GetPostgresTypesAggRow + private const string GetPostgresTypesCntSql = "SELECT c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, COUNT (* ) AS cnt FROM postgres_types GROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; + public class GetPostgresTypesCntRow { - public required long Cnt { get; init; } public short? CSmallint { get; init; } public bool? CBoolean { get; init; } public int? CInteger { get; init; } @@ -516,17 +515,34 @@ public class GetPostgresTypesAggRow public string? CCharacterVarying { get; init; } public string? CText { get; init; } public byte[]? CBytea { get; init; } + public required long Cnt { get; init; } + }; + public async Task GetPostgresTypesCnt() + { + using (var connection = new NpgsqlConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetPostgresTypesCntSql); + return result; + } + } + + private const string GetPostgresFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_varchar ) AS max_varchar, MAX (c_timestamp ) AS max_timestamp FROM postgres_types "; + public class GetPostgresFunctionsRow + { + public int? MaxInteger { get; init; } + public string? MaxVarchar { get; init; } + public required DateTime MaxTimestamp { get; init; } }; - public async Task GetPostgresTypesAgg() + public async Task GetPostgresFunctions() { using (var connection = new NpgsqlConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetPostgresTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetPostgresFunctionsSql); return result; } } - private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle) VALUES ( @c_point , @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; + private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types ( c_point , c_line, c_lseg, c_box, c_path, c_polygon, c_circle ) VALUES ( @c_point, @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; public class InsertPostgresGeoTypesArgs { public NpgsqlPoint? CPoint { get; init; } diff --git a/examples/NpgsqlDapperExample/request.json b/examples/NpgsqlDapperExample/request.json index a11a5179..3b2afcd3 100644 --- a/examples/NpgsqlDapperExample/request.json +++ b/examples/NpgsqlDapperExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/NpgsqlDapperExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRGFwcGVyRXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6dHJ1ZX0=", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRGFwcGVyRXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0UG9zdGdyZXNGdW5jdGlvbnM6bWF4X2ludGVnZXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6ImludCJ9fSx7ImNvbHVtbiI6IkdldFBvc3RncmVzRnVuY3Rpb25zOm1heF92YXJjaGFyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJzdHJpbmcifX0seyJjb2x1bW4iOiJHZXRQb3N0Z3Jlc0Z1bmN0aW9uczptYXhfdGltZXN0YW1wIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6dHJ1ZSwidHlwZSI6IkRhdGVUaW1lIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", "process": { "cmd": "./dist/LocalRunner" } @@ -32285,7 +32285,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = $1 LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -32345,7 +32345,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -32539,7 +32539,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = $1 LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -32599,7 +32599,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE($1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE($1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -32659,7 +32659,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = $1", + "text": "DELETE FROM authors\nWHERE name = $1", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -32688,7 +32688,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \n SET bio = $1\n WHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = $1\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -32711,7 +32711,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[])", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ANY($1::BIGINT [])", "name": "GetAuthorsByIds", "cmd": ":many", "columns": [ @@ -32769,7 +32769,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[]) AND name = ANY($2::TEXT[])", + "text": "SELECT id, name, bio\nFROM authors\nWHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT [])", "name": "GetAuthorsByIdsAndNames", "cmd": ":many", "columns": [ @@ -32896,7 +32896,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors\nINNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -32920,7 +32920,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -32944,7 +32944,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -33012,7 +33012,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money,\n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea, c_text_array, c_integer_array)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, \n $11, $12, $13, $14, $15, $16, $17, $18, $19, \n $20, $21)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_bit,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea, c_text_array, c_integer_array\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10,\n $11, $12, $13, $14, $15, $16, $17, $18, $19,\n $20, $21\n)", "name": "InsertPostgresTypes", "cmd": ":exec", "parameters": [ @@ -33342,7 +33342,7 @@ } }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, \n $10, $11, $12, $13, $14, $15, $16, $17, $18)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9,\n $10, $11, $12, $13, $14, $15, $16, $17, $18\n)", "name": "InsertPostgresTypesBatch", "cmd": ":copyfrom", "parameters": [ @@ -33893,19 +33893,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , \n c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nFROM postgres_types\nGROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nLIMIT 1", - "name": "GetPostgresTypesAgg", + "text": "SELECT\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea,\n COUNT(*) AS cnt\nFROM postgres_types\nGROUP BY\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\nLIMIT 1", + "name": "GetPostgresTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "bigint" - } - }, { "name": "c_smallint", "length": -1, @@ -34117,12 +34108,56 @@ "name": "bytea" }, "originalName": "c_bytea" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "bigint" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_varchar) AS max_varchar,\n MAX(c_timestamp) AS max_timestamp\nFROM postgres_types", + "name": "GetPostgresFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } } ], "filename": "query.sql" }, { - "text": "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", + "text": "INSERT INTO postgres_geometric_types (\n c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle\n)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", "name": "InsertPostgresGeoTypes", "cmd": ":exec", "parameters": [ diff --git a/examples/NpgsqlDapperLegacyExample/QuerySql.cs b/examples/NpgsqlDapperLegacyExample/QuerySql.cs index eeed396d..f4e186d7 100644 --- a/examples/NpgsqlDapperLegacyExample/QuerySql.cs +++ b/examples/NpgsqlDapperLegacyExample/QuerySql.cs @@ -25,7 +25,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public long Id { get; set; } @@ -47,7 +47,7 @@ public async Task GetAuthor(GetAuthorArgs args) } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public long Id { get; set; } @@ -110,7 +110,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public long Id { get; set; } @@ -132,7 +132,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public long Id { get; set; } @@ -154,7 +154,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -178,7 +178,7 @@ public async Task TruncateAuthors() } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string Bio { get; set; } @@ -193,7 +193,7 @@ public async Task UpdateAuthors(UpdateAuthorsArgs args) } } - private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[])"; + private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) "; public class GetAuthorsByIdsRow { public long Id { get; set; } @@ -215,7 +215,7 @@ public async Task> GetAuthorsByIds(GetAuthorsByIdsArgs } } - private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[]) AND name = ANY(@stringArr_2::TEXT[])"; + private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) AND name = ANY ( @stringArr_2 :: TEXT [ ] ) "; public class GetAuthorsByIdsAndNamesRow { public long Id { get; set; } @@ -260,7 +260,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name"; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public Author Author { get; set; } @@ -286,7 +286,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public Author Author { get; set; } @@ -312,7 +312,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public long Id { get; set; } @@ -345,7 +345,7 @@ public async Task> GetAuthorsByBookName(GetAuthors } } - private const string InsertPostgresTypesSql = "INSERT INTO postgres_types (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; + private const string InsertPostgresTypesSql = "INSERT INTO postgres_types(c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; public class InsertPostgresTypesArgs { public bool? CBoolean { get; set; } @@ -495,10 +495,9 @@ public async Task GetPostgresTypes() } } - private const string GetPostgresTypesAggSql = "SELECT COUNT(1) AS cnt , c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea FROM postgres_types GROUP BY c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; - public class GetPostgresTypesAggRow + private const string GetPostgresTypesCntSql = "SELECT c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, COUNT (* ) AS cnt FROM postgres_types GROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; + public class GetPostgresTypesCntRow { - public long Cnt { get; set; } public short? CSmallint { get; set; } public bool? CBoolean { get; set; } public int? CInteger { get; set; } @@ -517,17 +516,34 @@ public class GetPostgresTypesAggRow public string CCharacterVarying { get; set; } public string CText { get; set; } public byte[] CBytea { get; set; } + public long Cnt { get; set; } + }; + public async Task GetPostgresTypesCnt() + { + using (var connection = new NpgsqlConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetPostgresTypesCntSql); + return result; + } + } + + private const string GetPostgresFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_varchar ) AS max_varchar, MAX (c_timestamp ) AS max_timestamp FROM postgres_types "; + public class GetPostgresFunctionsRow + { + public int? MaxInteger { get; set; } + public string MaxVarchar { get; set; } + public DateTime MaxTimestamp { get; set; } }; - public async Task GetPostgresTypesAgg() + public async Task GetPostgresFunctions() { using (var connection = new NpgsqlConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetPostgresTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetPostgresFunctionsSql); return result; } } - private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle) VALUES ( @c_point , @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; + private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types ( c_point , c_line, c_lseg, c_box, c_path, c_polygon, c_circle ) VALUES ( @c_point, @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; public class InsertPostgresGeoTypesArgs { public NpgsqlPoint? CPoint { get; set; } diff --git a/examples/NpgsqlDapperLegacyExample/request.json b/examples/NpgsqlDapperLegacyExample/request.json index 39d5e60d..89ae6051 100644 --- a/examples/NpgsqlDapperLegacyExample/request.json +++ b/examples/NpgsqlDapperLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/NpgsqlDapperLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRGFwcGVyTGVnYWN5RXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRGFwcGVyTGVnYWN5RXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0UG9zdGdyZXNGdW5jdGlvbnM6bWF4X2ludGVnZXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6ImludCJ9fSx7ImNvbHVtbiI6IkdldFBvc3RncmVzRnVuY3Rpb25zOm1heF92YXJjaGFyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJzdHJpbmcifX0seyJjb2x1bW4iOiJHZXRQb3N0Z3Jlc0Z1bmN0aW9uczptYXhfdGltZXN0YW1wIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6dHJ1ZSwidHlwZSI6IkRhdGVUaW1lIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOnRydWV9", "process": { "cmd": "./dist/LocalRunner" } @@ -32285,7 +32285,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = $1 LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -32345,7 +32345,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -32539,7 +32539,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = $1 LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -32599,7 +32599,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE($1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE($1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -32659,7 +32659,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = $1", + "text": "DELETE FROM authors\nWHERE name = $1", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -32688,7 +32688,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \n SET bio = $1\n WHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = $1\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -32711,7 +32711,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[])", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ANY($1::BIGINT [])", "name": "GetAuthorsByIds", "cmd": ":many", "columns": [ @@ -32769,7 +32769,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[]) AND name = ANY($2::TEXT[])", + "text": "SELECT id, name, bio\nFROM authors\nWHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT [])", "name": "GetAuthorsByIdsAndNames", "cmd": ":many", "columns": [ @@ -32896,7 +32896,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors\nINNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -32920,7 +32920,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -32944,7 +32944,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -33012,7 +33012,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money,\n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea, c_text_array, c_integer_array)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, \n $11, $12, $13, $14, $15, $16, $17, $18, $19, \n $20, $21)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_bit,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea, c_text_array, c_integer_array\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10,\n $11, $12, $13, $14, $15, $16, $17, $18, $19,\n $20, $21\n)", "name": "InsertPostgresTypes", "cmd": ":exec", "parameters": [ @@ -33342,7 +33342,7 @@ } }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, \n $10, $11, $12, $13, $14, $15, $16, $17, $18)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9,\n $10, $11, $12, $13, $14, $15, $16, $17, $18\n)", "name": "InsertPostgresTypesBatch", "cmd": ":copyfrom", "parameters": [ @@ -33893,19 +33893,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , \n c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nFROM postgres_types\nGROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nLIMIT 1", - "name": "GetPostgresTypesAgg", + "text": "SELECT\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea,\n COUNT(*) AS cnt\nFROM postgres_types\nGROUP BY\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\nLIMIT 1", + "name": "GetPostgresTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "bigint" - } - }, { "name": "c_smallint", "length": -1, @@ -34117,12 +34108,56 @@ "name": "bytea" }, "originalName": "c_bytea" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "bigint" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_varchar) AS max_varchar,\n MAX(c_timestamp) AS max_timestamp\nFROM postgres_types", + "name": "GetPostgresFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } } ], "filename": "query.sql" }, { - "text": "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", + "text": "INSERT INTO postgres_geometric_types (\n c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle\n)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", "name": "InsertPostgresGeoTypes", "cmd": ":exec", "parameters": [ diff --git a/examples/NpgsqlExample/QuerySql.cs b/examples/NpgsqlExample/QuerySql.cs index 2d0e1c7a..80053c00 100644 --- a/examples/NpgsqlExample/QuerySql.cs +++ b/examples/NpgsqlExample/QuerySql.cs @@ -21,7 +21,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public readonly record struct GetAuthorRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorArgs(string Name); public async Task GetAuthor(GetAuthorArgs args) @@ -49,7 +49,7 @@ public QuerySql(string connectionString) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public readonly record struct ListAuthorsRow(long Id, string Name, string? Bio); public async Task> ListAuthors() { @@ -118,7 +118,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public readonly record struct GetAuthorByIdRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorByIdArgs(long Id); public async Task GetAuthorById(GetAuthorByIdArgs args) @@ -146,7 +146,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public readonly record struct GetAuthorByNamePatternRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorByNamePatternArgs(string? NamePattern); public async Task> GetAuthorByNamePattern(GetAuthorByNamePatternArgs args) @@ -170,7 +170,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public readonly record struct DeleteAuthorArgs(string Name); public async Task DeleteAuthor(DeleteAuthorArgs args) { @@ -196,7 +196,7 @@ public async Task TruncateAuthors() } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public readonly record struct UpdateAuthorsArgs(string? Bio); public async Task UpdateAuthors(UpdateAuthorsArgs args) { @@ -210,7 +210,7 @@ public async Task UpdateAuthors(UpdateAuthorsArgs args) } } - private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[])"; + private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) "; public readonly record struct GetAuthorsByIdsRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorsByIdsArgs(long[] LongArr1); public async Task> GetAuthorsByIds(GetAuthorsByIdsArgs args) @@ -234,7 +234,7 @@ public async Task> GetAuthorsByIds(GetAuthorsByIdsArgs } } - private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[]) AND name = ANY(@stringArr_2::TEXT[])"; + private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) AND name = ANY ( @stringArr_2 :: TEXT [ ] ) "; public readonly record struct GetAuthorsByIdsAndNamesRow(long Id, string Name, string? Bio); public readonly record struct GetAuthorsByIdsAndNamesArgs(long[] LongArr1, string[] StringArr2); public async Task> GetAuthorsByIdsAndNames(GetAuthorsByIdsAndNamesArgs args) @@ -276,7 +276,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name"; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public readonly record struct ListAllAuthorsBooksRow(Author? Author, Book? Book); public async Task> ListAllAuthorsBooks() { @@ -298,7 +298,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public readonly record struct GetDuplicateAuthorsRow(Author? Author, Author? Author2); public async Task> GetDuplicateAuthors() { @@ -320,7 +320,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public readonly record struct GetAuthorsByBookNameRow(long Id, string Name, string? Bio, Book? Book); public readonly record struct GetAuthorsByBookNameArgs(string Name); public async Task> GetAuthorsByBookName(GetAuthorsByBookNameArgs args) @@ -344,7 +344,7 @@ public async Task> GetAuthorsByBookName(GetAuthors } } - private const string InsertPostgresTypesSql = "INSERT INTO postgres_types (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; + private const string InsertPostgresTypesSql = "INSERT INTO postgres_types(c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; public readonly record struct InsertPostgresTypesArgs(bool? CBoolean, byte[]? CBit, short? CSmallint, int? CInteger, long? CBigint, float? CReal, decimal? CNumeric, decimal? CDecimal, double? CDoublePrecision, decimal? CMoney, DateTime? CDate, TimeSpan? CTime, DateTime? CTimestamp, DateTime? CTimestampWithTz, string? CChar, string? CVarchar, string? CCharacterVarying, string? CText, byte[]? CBytea, string[]? CTextArray, int[]? CIntegerArray); public async Task InsertPostgresTypes(InsertPostgresTypesArgs args) { @@ -463,39 +463,65 @@ public async Task InsertPostgresTypesBatch(List ar return null; } - private const string GetPostgresTypesAggSql = "SELECT COUNT(1) AS cnt , c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea FROM postgres_types GROUP BY c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; - public readonly record struct GetPostgresTypesAggRow(long Cnt, short? CSmallint, bool? CBoolean, int? CInteger, long? CBigint, float? CReal, decimal? CNumeric, decimal? CDecimal, double? CDoublePrecision, decimal? CMoney, DateTime? CDate, TimeSpan? CTime, DateTime? CTimestamp, DateTime? CTimestampWithTz, string? CChar, string? CVarchar, string? CCharacterVarying, string? CText, byte[]? CBytea); - public async Task GetPostgresTypesAgg() + private const string GetPostgresTypesCntSql = "SELECT c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, COUNT (* ) AS cnt FROM postgres_types GROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; + public readonly record struct GetPostgresTypesCntRow(short? CSmallint, bool? CBoolean, int? CInteger, long? CBigint, float? CReal, decimal? CNumeric, decimal? CDecimal, double? CDoublePrecision, decimal? CMoney, DateTime? CDate, TimeSpan? CTime, DateTime? CTimestamp, DateTime? CTimestampWithTz, string? CChar, string? CVarchar, string? CCharacterVarying, string? CText, byte[]? CBytea, long Cnt); + public async Task GetPostgresTypesCnt() { using (var connection = NpgsqlDataSource.Create(ConnectionString)) { - using (var command = connection.CreateCommand(GetPostgresTypesAggSql)) + using (var command = connection.CreateCommand(GetPostgresTypesCntSql)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetPostgresTypesAggRow + return new GetPostgresTypesCntRow { - Cnt = reader.GetInt64(0), - CSmallint = reader.IsDBNull(1) ? null : reader.GetInt16(1), - CBoolean = reader.IsDBNull(2) ? null : reader.GetBoolean(2), - CInteger = reader.IsDBNull(3) ? null : reader.GetInt32(3), - CBigint = reader.IsDBNull(4) ? null : reader.GetInt64(4), - CReal = reader.IsDBNull(5) ? null : reader.GetFloat(5), - CNumeric = reader.IsDBNull(6) ? null : reader.GetDecimal(6), - CDecimal = reader.IsDBNull(7) ? null : reader.GetDecimal(7), - CDoublePrecision = reader.IsDBNull(8) ? null : reader.GetDouble(8), - CMoney = reader.IsDBNull(9) ? null : reader.GetDecimal(9), - CDate = reader.IsDBNull(10) ? null : reader.GetDateTime(10), - CTime = reader.IsDBNull(11) ? null : reader.GetFieldValue(11), - CTimestamp = reader.IsDBNull(12) ? null : reader.GetDateTime(12), - CTimestampWithTz = reader.IsDBNull(13) ? null : reader.GetDateTime(13), - CChar = reader.IsDBNull(14) ? null : reader.GetString(14), - CVarchar = reader.IsDBNull(15) ? null : reader.GetString(15), - CCharacterVarying = reader.IsDBNull(16) ? null : reader.GetString(16), - CText = reader.IsDBNull(17) ? null : reader.GetString(17), - CBytea = reader.IsDBNull(18) ? null : reader.GetFieldValue(18) + CSmallint = reader.IsDBNull(0) ? null : reader.GetInt16(0), + CBoolean = reader.IsDBNull(1) ? null : reader.GetBoolean(1), + CInteger = reader.IsDBNull(2) ? null : reader.GetInt32(2), + CBigint = reader.IsDBNull(3) ? null : reader.GetInt64(3), + CReal = reader.IsDBNull(4) ? null : reader.GetFloat(4), + CNumeric = reader.IsDBNull(5) ? null : reader.GetDecimal(5), + CDecimal = reader.IsDBNull(6) ? null : reader.GetDecimal(6), + CDoublePrecision = reader.IsDBNull(7) ? null : reader.GetDouble(7), + CMoney = reader.IsDBNull(8) ? null : reader.GetDecimal(8), + CDate = reader.IsDBNull(9) ? null : reader.GetDateTime(9), + CTime = reader.IsDBNull(10) ? null : reader.GetFieldValue(10), + CTimestamp = reader.IsDBNull(11) ? null : reader.GetDateTime(11), + CTimestampWithTz = reader.IsDBNull(12) ? null : reader.GetDateTime(12), + CChar = reader.IsDBNull(13) ? null : reader.GetString(13), + CVarchar = reader.IsDBNull(14) ? null : reader.GetString(14), + CCharacterVarying = reader.IsDBNull(15) ? null : reader.GetString(15), + CText = reader.IsDBNull(16) ? null : reader.GetString(16), + CBytea = reader.IsDBNull(17) ? null : reader.GetFieldValue(17), + Cnt = reader.GetInt64(18) + }; + } + } + } + } + + return null; + } + + private const string GetPostgresFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_varchar ) AS max_varchar, MAX (c_timestamp ) AS max_timestamp FROM postgres_types "; + public readonly record struct GetPostgresFunctionsRow(int? MaxInteger, string? MaxVarchar, DateTime MaxTimestamp); + public async Task GetPostgresFunctions() + { + using (var connection = NpgsqlDataSource.Create(ConnectionString)) + { + using (var command = connection.CreateCommand(GetPostgresFunctionsSql)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetPostgresFunctionsRow + { + MaxInteger = reader.IsDBNull(0) ? null : reader.GetInt32(0), + MaxVarchar = reader.IsDBNull(1) ? null : reader.GetString(1), + MaxTimestamp = reader.GetDateTime(2) }; } } @@ -505,7 +531,7 @@ public async Task InsertPostgresTypesBatch(List ar return null; } - private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle) VALUES ( @c_point , @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; + private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types ( c_point , c_line, c_lseg, c_box, c_path, c_polygon, c_circle ) VALUES ( @c_point, @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; public readonly record struct InsertPostgresGeoTypesArgs(NpgsqlPoint? CPoint, NpgsqlLine? CLine, NpgsqlLSeg? CLseg, NpgsqlBox? CBox, NpgsqlPath? CPath, NpgsqlPolygon? CPolygon, NpgsqlCircle? CCircle); public async Task InsertPostgresGeoTypes(InsertPostgresGeoTypesArgs args) { diff --git a/examples/NpgsqlExample/request.json b/examples/NpgsqlExample/request.json index 9e0ad46f..aa8fa3b3 100644 --- a/examples/NpgsqlExample/request.json +++ b/examples/NpgsqlExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/NpgsqlExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6ZmFsc2V9", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsRXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0UG9zdGdyZXNGdW5jdGlvbnM6bWF4X2ludGVnZXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6ImludCJ9fSx7ImNvbHVtbiI6IkdldFBvc3RncmVzRnVuY3Rpb25zOm1heF92YXJjaGFyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJzdHJpbmcifX0seyJjb2x1bW4iOiJHZXRQb3N0Z3Jlc0Z1bmN0aW9uczptYXhfdGltZXN0YW1wIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6dHJ1ZSwidHlwZSI6IkRhdGVUaW1lIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", "process": { "cmd": "./dist/LocalRunner" } @@ -32285,7 +32285,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = $1 LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -32345,7 +32345,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -32539,7 +32539,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = $1 LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -32599,7 +32599,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE($1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE($1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -32659,7 +32659,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = $1", + "text": "DELETE FROM authors\nWHERE name = $1", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -32688,7 +32688,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \n SET bio = $1\n WHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = $1\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -32711,7 +32711,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[])", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ANY($1::BIGINT [])", "name": "GetAuthorsByIds", "cmd": ":many", "columns": [ @@ -32769,7 +32769,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[]) AND name = ANY($2::TEXT[])", + "text": "SELECT id, name, bio\nFROM authors\nWHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT [])", "name": "GetAuthorsByIdsAndNames", "cmd": ":many", "columns": [ @@ -32896,7 +32896,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors\nINNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -32920,7 +32920,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -32944,7 +32944,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -33012,7 +33012,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money,\n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea, c_text_array, c_integer_array)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, \n $11, $12, $13, $14, $15, $16, $17, $18, $19, \n $20, $21)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_bit,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea, c_text_array, c_integer_array\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10,\n $11, $12, $13, $14, $15, $16, $17, $18, $19,\n $20, $21\n)", "name": "InsertPostgresTypes", "cmd": ":exec", "parameters": [ @@ -33342,7 +33342,7 @@ } }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, \n $10, $11, $12, $13, $14, $15, $16, $17, $18)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9,\n $10, $11, $12, $13, $14, $15, $16, $17, $18\n)", "name": "InsertPostgresTypesBatch", "cmd": ":copyfrom", "parameters": [ @@ -33893,19 +33893,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , \n c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nFROM postgres_types\nGROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nLIMIT 1", - "name": "GetPostgresTypesAgg", + "text": "SELECT\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea,\n COUNT(*) AS cnt\nFROM postgres_types\nGROUP BY\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\nLIMIT 1", + "name": "GetPostgresTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "bigint" - } - }, { "name": "c_smallint", "length": -1, @@ -34117,12 +34108,56 @@ "name": "bytea" }, "originalName": "c_bytea" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "bigint" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_varchar) AS max_varchar,\n MAX(c_timestamp) AS max_timestamp\nFROM postgres_types", + "name": "GetPostgresFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } } ], "filename": "query.sql" }, { - "text": "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", + "text": "INSERT INTO postgres_geometric_types (\n c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle\n)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", "name": "InsertPostgresGeoTypes", "cmd": ":exec", "parameters": [ diff --git a/examples/NpgsqlLegacyExample/QuerySql.cs b/examples/NpgsqlLegacyExample/QuerySql.cs index 6b8fbaa0..8097ad0f 100644 --- a/examples/NpgsqlLegacyExample/QuerySql.cs +++ b/examples/NpgsqlLegacyExample/QuerySql.cs @@ -22,7 +22,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public long Id { get; set; } @@ -58,7 +58,7 @@ public async Task GetAuthor(GetAuthorArgs args) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public long Id { get; set; } @@ -149,7 +149,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public long Id { get; set; } @@ -185,7 +185,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public long Id { get; set; } @@ -217,7 +217,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -246,7 +246,7 @@ public async Task TruncateAuthors() } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string Bio { get; set; } @@ -263,7 +263,7 @@ public async Task UpdateAuthors(UpdateAuthorsArgs args) } } - private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[])"; + private const string GetAuthorsByIdsSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) "; public class GetAuthorsByIdsRow { public long Id { get; set; } @@ -295,7 +295,7 @@ public async Task> GetAuthorsByIds(GetAuthorsByIdsArgs } } - private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY(@longArr_1::BIGINT[]) AND name = ANY(@stringArr_2::TEXT[])"; + private const string GetAuthorsByIdsAndNamesSql = "SELECT id, name, bio FROM authors WHERE id = ANY ( @longArr_1 :: BIGINT [ ] ) AND name = ANY ( @stringArr_2 :: TEXT [ ] ) "; public class GetAuthorsByIdsAndNamesRow { public long Id { get; set; } @@ -353,7 +353,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name"; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public Author Author { get; set; } @@ -379,7 +379,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public Author Author { get; set; } @@ -405,7 +405,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public long Id { get; set; } @@ -438,7 +438,7 @@ public async Task> GetAuthorsByBookName(GetAuthors } } - private const string InsertPostgresTypesSql = "INSERT INTO postgres_types (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; + private const string InsertPostgresTypesSql = "INSERT INTO postgres_types(c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, c_text_array, c_integer_array) VALUES ( @c_boolean, @c_bit, @c_smallint, @c_integer, @c_bigint, @c_real, @c_numeric, @c_decimal, @c_double_precision, @c_money, @c_date, @c_time, @c_timestamp, @c_timestamp_with_tz, @c_char, @c_varchar, @c_character_varying, @c_text, @c_bytea, @c_text_array, @c_integer_array ) "; public class InsertPostgresTypesArgs { public bool? CBoolean { get; set; } @@ -624,10 +624,9 @@ public async Task GetPostgresTypes() return null; } - private const string GetPostgresTypesAggSql = "SELECT COUNT(1) AS cnt , c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea FROM postgres_types GROUP BY c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; - public class GetPostgresTypesAggRow + private const string GetPostgresTypesCntSql = "SELECT c_smallint , c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea, COUNT (* ) AS cnt FROM postgres_types GROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, c_bytea LIMIT 1 "; + public class GetPostgresTypesCntRow { - public long Cnt { get; set; } public short? CSmallint { get; set; } public bool? CBoolean { get; set; } public int? CInteger { get; set; } @@ -646,38 +645,70 @@ public class GetPostgresTypesAggRow public string CCharacterVarying { get; set; } public string CText { get; set; } public byte[] CBytea { get; set; } + public long Cnt { get; set; } }; - public async Task GetPostgresTypesAgg() + public async Task GetPostgresTypesCnt() { using (var connection = NpgsqlDataSource.Create(ConnectionString)) { - using (var command = connection.CreateCommand(GetPostgresTypesAggSql)) + using (var command = connection.CreateCommand(GetPostgresTypesCntSql)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetPostgresTypesAggRow + return new GetPostgresTypesCntRow { - Cnt = reader.GetInt64(0), - CSmallint = reader.IsDBNull(1) ? (short? )null : reader.GetInt16(1), - CBoolean = reader.IsDBNull(2) ? (bool? )null : reader.GetBoolean(2), - CInteger = reader.IsDBNull(3) ? (int? )null : reader.GetInt32(3), - CBigint = reader.IsDBNull(4) ? (long? )null : reader.GetInt64(4), - CReal = reader.IsDBNull(5) ? (float? )null : reader.GetFloat(5), - CNumeric = reader.IsDBNull(6) ? (decimal? )null : reader.GetDecimal(6), - CDecimal = reader.IsDBNull(7) ? (decimal? )null : reader.GetDecimal(7), - CDoublePrecision = reader.IsDBNull(8) ? (double? )null : reader.GetDouble(8), - CMoney = reader.IsDBNull(9) ? (decimal? )null : reader.GetDecimal(9), - CDate = reader.IsDBNull(10) ? (DateTime? )null : reader.GetDateTime(10), - CTime = reader.IsDBNull(11) ? (TimeSpan? )null : reader.GetFieldValue(11), - CTimestamp = reader.IsDBNull(12) ? (DateTime? )null : reader.GetDateTime(12), - CTimestampWithTz = reader.IsDBNull(13) ? (DateTime? )null : reader.GetDateTime(13), - CChar = reader.IsDBNull(14) ? null : reader.GetString(14), - CVarchar = reader.IsDBNull(15) ? null : reader.GetString(15), - CCharacterVarying = reader.IsDBNull(16) ? null : reader.GetString(16), - CText = reader.IsDBNull(17) ? null : reader.GetString(17), - CBytea = reader.IsDBNull(18) ? null : reader.GetFieldValue(18) + CSmallint = reader.IsDBNull(0) ? (short? )null : reader.GetInt16(0), + CBoolean = reader.IsDBNull(1) ? (bool? )null : reader.GetBoolean(1), + CInteger = reader.IsDBNull(2) ? (int? )null : reader.GetInt32(2), + CBigint = reader.IsDBNull(3) ? (long? )null : reader.GetInt64(3), + CReal = reader.IsDBNull(4) ? (float? )null : reader.GetFloat(4), + CNumeric = reader.IsDBNull(5) ? (decimal? )null : reader.GetDecimal(5), + CDecimal = reader.IsDBNull(6) ? (decimal? )null : reader.GetDecimal(6), + CDoublePrecision = reader.IsDBNull(7) ? (double? )null : reader.GetDouble(7), + CMoney = reader.IsDBNull(8) ? (decimal? )null : reader.GetDecimal(8), + CDate = reader.IsDBNull(9) ? (DateTime? )null : reader.GetDateTime(9), + CTime = reader.IsDBNull(10) ? (TimeSpan? )null : reader.GetFieldValue(10), + CTimestamp = reader.IsDBNull(11) ? (DateTime? )null : reader.GetDateTime(11), + CTimestampWithTz = reader.IsDBNull(12) ? (DateTime? )null : reader.GetDateTime(12), + CChar = reader.IsDBNull(13) ? null : reader.GetString(13), + CVarchar = reader.IsDBNull(14) ? null : reader.GetString(14), + CCharacterVarying = reader.IsDBNull(15) ? null : reader.GetString(15), + CText = reader.IsDBNull(16) ? null : reader.GetString(16), + CBytea = reader.IsDBNull(17) ? null : reader.GetFieldValue(17), + Cnt = reader.GetInt64(18) + }; + } + } + } + } + + return null; + } + + private const string GetPostgresFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_varchar ) AS max_varchar, MAX (c_timestamp ) AS max_timestamp FROM postgres_types "; + public class GetPostgresFunctionsRow + { + public int? MaxInteger { get; set; } + public string MaxVarchar { get; set; } + public DateTime MaxTimestamp { get; set; } + }; + public async Task GetPostgresFunctions() + { + using (var connection = NpgsqlDataSource.Create(ConnectionString)) + { + using (var command = connection.CreateCommand(GetPostgresFunctionsSql)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetPostgresFunctionsRow + { + MaxInteger = reader.IsDBNull(0) ? (int? )null : reader.GetInt32(0), + MaxVarchar = reader.IsDBNull(1) ? null : reader.GetString(1), + MaxTimestamp = reader.GetDateTime(2) }; } } @@ -687,7 +718,7 @@ public async Task GetPostgresTypesAgg() return null; } - private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle) VALUES ( @c_point , @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; + private const string InsertPostgresGeoTypesSql = "INSERT INTO postgres_geometric_types ( c_point , c_line, c_lseg, c_box, c_path, c_polygon, c_circle ) VALUES ( @c_point, @c_line, @c_lseg, @c_box, @c_path, @c_polygon, @c_circle ) "; public class InsertPostgresGeoTypesArgs { public NpgsqlPoint? CPoint { get; set; } diff --git a/examples/NpgsqlLegacyExample/request.json b/examples/NpgsqlLegacyExample/request.json index a3f044d4..6633090d 100644 --- a/examples/NpgsqlLegacyExample/request.json +++ b/examples/NpgsqlLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/NpgsqlLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsTGVnYWN5RXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiTnBnc3FsTGVnYWN5RXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0UG9zdGdyZXNGdW5jdGlvbnM6bWF4X2ludGVnZXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6ImludCJ9fSx7ImNvbHVtbiI6IkdldFBvc3RncmVzRnVuY3Rpb25zOm1heF92YXJjaGFyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJzdHJpbmcifX0seyJjb2x1bW4iOiJHZXRQb3N0Z3Jlc0Z1bmN0aW9uczptYXhfdGltZXN0YW1wIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6dHJ1ZSwidHlwZSI6IkRhdGVUaW1lIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOmZhbHNlfQ==", "process": { "cmd": "./dist/LocalRunner" } @@ -32285,7 +32285,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = $1 LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -32345,7 +32345,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -32539,7 +32539,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = $1 LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = $1 LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -32599,7 +32599,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE($1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE($1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -32659,7 +32659,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = $1", + "text": "DELETE FROM authors\nWHERE name = $1", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -32688,7 +32688,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \n SET bio = $1\n WHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = $1\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -32711,7 +32711,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[])", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ANY($1::BIGINT [])", "name": "GetAuthorsByIds", "cmd": ":many", "columns": [ @@ -32769,7 +32769,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ANY($1::BIGINT[]) AND name = ANY($2::TEXT[])", + "text": "SELECT id, name, bio\nFROM authors\nWHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT [])", "name": "GetAuthorsByIdsAndNames", "cmd": ":many", "columns": [ @@ -32896,7 +32896,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors\nINNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -32920,7 +32920,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -32944,7 +32944,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = $1", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -33012,7 +33012,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money,\n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea, c_text_array, c_integer_array)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, \n $11, $12, $13, $14, $15, $16, $17, $18, $19, \n $20, $21)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_bit,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea, c_text_array, c_integer_array\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10,\n $11, $12, $13, $14, $15, $16, $17, $18, $19,\n $20, $21\n)", "name": "InsertPostgresTypes", "cmd": ":exec", "parameters": [ @@ -33342,7 +33342,7 @@ } }, { - "text": "INSERT INTO postgres_types \n (c_boolean, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, \n $10, $11, $12, $13, $14, $15, $16, $17, $18)", + "text": "INSERT INTO postgres_types\n(\n c_boolean,\n c_smallint,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\n)\nVALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9,\n $10, $11, $12, $13, $14, $15, $16, $17, $18\n)", "name": "InsertPostgresTypesBatch", "cmd": ":copyfrom", "parameters": [ @@ -33893,19 +33893,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , \n c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nFROM postgres_types\nGROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, \n c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, \n c_bytea\nLIMIT 1", - "name": "GetPostgresTypesAgg", + "text": "SELECT\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea,\n COUNT(*) AS cnt\nFROM postgres_types\nGROUP BY\n c_smallint,\n c_boolean,\n c_integer,\n c_bigint,\n c_real,\n c_numeric,\n c_decimal,\n c_double_precision,\n c_money,\n c_date,\n c_time,\n c_timestamp,\n c_timestamp_with_tz,\n c_char,\n c_varchar,\n c_character_varying,\n c_text,\n c_bytea\nLIMIT 1", + "name": "GetPostgresTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "bigint" - } - }, { "name": "c_smallint", "length": -1, @@ -34117,12 +34108,56 @@ "name": "bytea" }, "originalName": "c_bytea" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "bigint" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_varchar) AS max_varchar,\n MAX(c_timestamp) AS max_timestamp\nFROM postgres_types", + "name": "GetPostgresFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_varchar", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } + }, + { + "name": "max_timestamp", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "anyarray" + } } ], "filename": "query.sql" }, { - "text": "INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", + "text": "INSERT INTO postgres_geometric_types (\n c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle\n)\nVALUES ($1, $2, $3, $4, $5, $6, $7)", "name": "InsertPostgresGeoTypes", "cmd": ":exec", "parameters": [ diff --git a/examples/SqliteDapperExample/QuerySql.cs b/examples/SqliteDapperExample/QuerySql.cs index 8acc4c2f..b0cc960e 100644 --- a/examples/SqliteDapperExample/QuerySql.cs +++ b/examples/SqliteDapperExample/QuerySql.cs @@ -21,7 +21,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public required int Id { get; init; } @@ -43,7 +43,7 @@ public class GetAuthorArgs } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public required int Id { get; init; } @@ -99,7 +99,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public required int Id { get; init; } @@ -121,7 +121,7 @@ public class GetAuthorByIdArgs } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public required int Id { get; init; } @@ -143,7 +143,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string? Bio { get; init; } @@ -212,7 +212,7 @@ public async Task> GetAuthorsByIdsAndNames(GetA } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public required string Name { get; init; } @@ -248,7 +248,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id ORDER BY authors . name "; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public required Author? Author { get; init; } @@ -275,7 +275,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public required Author? Author { get; init; } @@ -302,7 +302,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public required int Id { get; init; } @@ -345,7 +345,7 @@ public async Task DeleteAllAuthors() } } - private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (@c_integer, @c_real, @c_text, @c_blob)"; + private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES ( @c_integer , @c_real, @c_text, @c_blob ) "; public class InsertSqliteTypesArgs { public int? CInteger { get; init; } @@ -410,20 +410,36 @@ public class GetSqliteTypesRow } } - private const string GetSqliteTypesAggSql = "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob FROM types_sqlite GROUP BY c_integer , c_real, c_text, c_blob LIMIT 1 "; - public class GetSqliteTypesAggRow + private const string GetSqliteTypesCntSql = "SELECT c_integer , c_real, c_text, c_blob, COUNT (* ) AS cnt FROM types_sqlite GROUP BY c_integer, c_real, c_text, c_blob LIMIT 1 "; + public class GetSqliteTypesCntRow { - public required int Cnt { get; init; } public int? CInteger { get; init; } public decimal? CReal { get; init; } public string? CText { get; init; } public byte[]? CBlob { get; init; } + public required int Cnt { get; init; } + }; + public async Task GetSqliteTypesCnt() + { + using (var connection = new SqliteConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetSqliteTypesCntSql); + return result; + } + } + + private const string GetSqliteFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_real ) AS max_real, MAX (c_text ) AS max_text FROM types_sqlite "; + public class GetSqliteFunctionsRow + { + public int? MaxInteger { get; init; } + public required decimal MaxReal { get; init; } + public object? MaxText { get; init; } }; - public async Task GetSqliteTypesAgg() + public async Task GetSqliteFunctions() { using (var connection = new SqliteConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetSqliteTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetSqliteFunctionsSql); return result; } } diff --git a/examples/SqliteDapperExample/request.json b/examples/SqliteDapperExample/request.json index c8c33988..f958376e 100644 --- a/examples/SqliteDapperExample/request.json +++ b/examples/SqliteDapperExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/SqliteDapperExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRGFwcGVyRXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6dHJ1ZX0=", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRGFwcGVyRXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0U3FsaXRlRnVuY3Rpb25zOm1heF9pbnRlZ2VyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRTcWxpdGVGdW5jdGlvbnM6bWF4X3ZhcmNoYXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6InN0cmluZyJ9fSx7ImNvbHVtbiI6IkdldFNxbGl0ZUZ1bmN0aW9uczptYXhfcmVhbCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJkZWNpbWFsIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", "process": { "cmd": "./dist/LocalRunner" } @@ -165,7 +165,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = ? LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -225,7 +225,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -382,7 +382,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -442,7 +442,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -502,7 +502,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \nSET bio = ?\nWHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = ?\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -666,7 +666,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -746,7 +746,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description \nFROM authors JOIN books ON authors.id = books.author_id \nORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -770,7 +770,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -794,7 +794,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -868,7 +868,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (?, ?, ?, ?)", + "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (\n ?, ?, ?, ?\n)", "name": "InsertSqliteTypes", "cmd": ":exec", "parameters": [ @@ -1047,19 +1047,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", - "name": "GetSqliteTypesAgg", + "text": "SELECT\n c_integer,\n c_real,\n c_text,\n c_blob,\n COUNT(*) AS cnt\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", + "name": "GetSqliteTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "integer" - } - }, { "name": "c_integer", "length": -1, @@ -1103,6 +1094,47 @@ "name": "BLOB" }, "originalName": "c_blob" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "integer" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_real) AS max_real,\n MAX(c_text) AS max_text\nFROM types_sqlite", + "name": "GetSqliteFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_real", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_text", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } } ], "filename": "query.sql" diff --git a/examples/SqliteDapperLegacyExample/QuerySql.cs b/examples/SqliteDapperLegacyExample/QuerySql.cs index 7a7735b7..cbb5f959 100644 --- a/examples/SqliteDapperLegacyExample/QuerySql.cs +++ b/examples/SqliteDapperLegacyExample/QuerySql.cs @@ -22,7 +22,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public int Id { get; set; } @@ -44,7 +44,7 @@ public async Task GetAuthor(GetAuthorArgs args) } } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public int Id { get; set; } @@ -100,7 +100,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public int Id { get; set; } @@ -122,7 +122,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) } } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public int Id { get; set; } @@ -144,7 +144,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string Bio { get; set; } @@ -213,7 +213,7 @@ public async Task> GetAuthorsByIdsAndNames(GetA } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -249,7 +249,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id ORDER BY authors . name "; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public Author Author { get; set; } @@ -276,7 +276,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public Author Author { get; set; } @@ -303,7 +303,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public int Id { get; set; } @@ -346,7 +346,7 @@ public async Task DeleteAllAuthors() } } - private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (@c_integer, @c_real, @c_text, @c_blob)"; + private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES ( @c_integer , @c_real, @c_text, @c_blob ) "; public class InsertSqliteTypesArgs { public int? CInteger { get; set; } @@ -411,20 +411,36 @@ public async Task GetSqliteTypes() } } - private const string GetSqliteTypesAggSql = "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob FROM types_sqlite GROUP BY c_integer , c_real, c_text, c_blob LIMIT 1 "; - public class GetSqliteTypesAggRow + private const string GetSqliteTypesCntSql = "SELECT c_integer , c_real, c_text, c_blob, COUNT (* ) AS cnt FROM types_sqlite GROUP BY c_integer, c_real, c_text, c_blob LIMIT 1 "; + public class GetSqliteTypesCntRow { - public int Cnt { get; set; } public int? CInteger { get; set; } public decimal? CReal { get; set; } public string CText { get; set; } public byte[] CBlob { get; set; } + public int Cnt { get; set; } + }; + public async Task GetSqliteTypesCnt() + { + using (var connection = new SqliteConnection(ConnectionString)) + { + var result = await connection.QueryFirstOrDefaultAsync(GetSqliteTypesCntSql); + return result; + } + } + + private const string GetSqliteFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_real ) AS max_real, MAX (c_text ) AS max_text FROM types_sqlite "; + public class GetSqliteFunctionsRow + { + public int? MaxInteger { get; set; } + public decimal MaxReal { get; set; } + public object MaxText { get; set; } }; - public async Task GetSqliteTypesAgg() + public async Task GetSqliteFunctions() { using (var connection = new SqliteConnection(ConnectionString)) { - var result = await connection.QueryFirstOrDefaultAsync(GetSqliteTypesAggSql); + var result = await connection.QueryFirstOrDefaultAsync(GetSqliteFunctionsSql); return result; } } diff --git a/examples/SqliteDapperLegacyExample/request.json b/examples/SqliteDapperLegacyExample/request.json index 03eeeb7a..c90996aa 100644 --- a/examples/SqliteDapperLegacyExample/request.json +++ b/examples/SqliteDapperLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/SqliteDapperLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRGFwcGVyTGVnYWN5RXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjp0cnVlfQ==", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRGFwcGVyTGVnYWN5RXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0U3FsaXRlRnVuY3Rpb25zOm1heF9pbnRlZ2VyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRTcWxpdGVGdW5jdGlvbnM6bWF4X3ZhcmNoYXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6InN0cmluZyJ9fSx7ImNvbHVtbiI6IkdldFNxbGl0ZUZ1bmN0aW9uczptYXhfcmVhbCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJkZWNpbWFsIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOnRydWV9", "process": { "cmd": "./dist/LocalRunner" } @@ -165,7 +165,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = ? LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -225,7 +225,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -382,7 +382,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -442,7 +442,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -502,7 +502,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \nSET bio = ?\nWHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = ?\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -666,7 +666,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -746,7 +746,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description \nFROM authors JOIN books ON authors.id = books.author_id \nORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -770,7 +770,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -794,7 +794,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -868,7 +868,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (?, ?, ?, ?)", + "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (\n ?, ?, ?, ?\n)", "name": "InsertSqliteTypes", "cmd": ":exec", "parameters": [ @@ -1047,19 +1047,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", - "name": "GetSqliteTypesAgg", + "text": "SELECT\n c_integer,\n c_real,\n c_text,\n c_blob,\n COUNT(*) AS cnt\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", + "name": "GetSqliteTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "integer" - } - }, { "name": "c_integer", "length": -1, @@ -1103,6 +1094,47 @@ "name": "BLOB" }, "originalName": "c_blob" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "integer" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_real) AS max_real,\n MAX(c_text) AS max_text\nFROM types_sqlite", + "name": "GetSqliteFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_real", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_text", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } } ], "filename": "query.sql" diff --git a/examples/SqliteExample/QuerySql.cs b/examples/SqliteExample/QuerySql.cs index e8201b25..fdf44081 100644 --- a/examples/SqliteExample/QuerySql.cs +++ b/examples/SqliteExample/QuerySql.cs @@ -19,7 +19,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public readonly record struct GetAuthorRow(int Id, string Name, string? Bio); public readonly record struct GetAuthorArgs(string Name); public async Task GetAuthor(GetAuthorArgs args) @@ -48,7 +48,7 @@ public QuerySql(string connectionString) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public readonly record struct ListAuthorsRow(int Id, string Name, string? Bio); public async Task> ListAuthors() { @@ -106,7 +106,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public readonly record struct GetAuthorByIdRow(int Id, string Name, string? Bio); public readonly record struct GetAuthorByIdArgs(int Id); public async Task GetAuthorById(GetAuthorByIdArgs args) @@ -135,7 +135,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public readonly record struct GetAuthorByNamePatternRow(int Id, string Name, string? Bio); public readonly record struct GetAuthorByNamePatternArgs(string? NamePattern); public async Task> GetAuthorByNamePattern(GetAuthorByNamePatternArgs args) @@ -160,7 +160,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public readonly record struct UpdateAuthorsArgs(string? Bio); public async Task UpdateAuthors(UpdateAuthorsArgs args) { @@ -234,7 +234,7 @@ public async Task> GetAuthorsByIdsAndNames(GetA } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public readonly record struct DeleteAuthorArgs(string Name); public async Task DeleteAuthor(DeleteAuthorArgs args) { @@ -267,7 +267,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id ORDER BY authors . name "; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public readonly record struct ListAllAuthorsBooksRow(Author? Author, Book? Book); public async Task> ListAllAuthorsBooks() { @@ -290,7 +290,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public readonly record struct GetDuplicateAuthorsRow(Author? Author, Author? Author2); public async Task> GetDuplicateAuthors() { @@ -313,7 +313,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public readonly record struct GetAuthorsByBookNameRow(int Id, string Name, string? Bio, Book? Book); public readonly record struct GetAuthorsByBookNameArgs(string Name); public async Task> GetAuthorsByBookName(GetAuthorsByBookNameArgs args) @@ -351,7 +351,7 @@ public async Task DeleteAllAuthors() } } - private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (@c_integer, @c_real, @c_text, @c_blob)"; + private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES ( @c_integer , @c_real, @c_text, @c_blob ) "; public readonly record struct InsertSqliteTypesArgs(int? CInteger, decimal? CReal, string? CText, byte[]? CBlob); public async Task InsertSqliteTypes(InsertSqliteTypesArgs args) { @@ -419,26 +419,53 @@ public async Task InsertSqliteTypesBatch(List args) return null; } - private const string GetSqliteTypesAggSql = "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob FROM types_sqlite GROUP BY c_integer , c_real, c_text, c_blob LIMIT 1 "; - public readonly record struct GetSqliteTypesAggRow(int Cnt, int? CInteger, decimal? CReal, string? CText, byte[]? CBlob); - public async Task GetSqliteTypesAgg() + private const string GetSqliteTypesCntSql = "SELECT c_integer , c_real, c_text, c_blob, COUNT (* ) AS cnt FROM types_sqlite GROUP BY c_integer, c_real, c_text, c_blob LIMIT 1 "; + public readonly record struct GetSqliteTypesCntRow(int? CInteger, decimal? CReal, string? CText, byte[]? CBlob, int Cnt); + public async Task GetSqliteTypesCnt() { using (var connection = new SqliteConnection(ConnectionString)) { await connection.OpenAsync(); - using (var command = new SqliteCommand(GetSqliteTypesAggSql, connection)) + using (var command = new SqliteCommand(GetSqliteTypesCntSql, connection)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetSqliteTypesAggRow + return new GetSqliteTypesCntRow { - Cnt = reader.GetInt32(0), - CInteger = reader.IsDBNull(1) ? null : reader.GetInt32(1), - CReal = reader.IsDBNull(2) ? null : reader.GetDecimal(2), - CText = reader.IsDBNull(3) ? null : reader.GetString(3), - CBlob = reader.IsDBNull(4) ? null : reader.GetFieldValue(4) + CInteger = reader.IsDBNull(0) ? null : reader.GetInt32(0), + CReal = reader.IsDBNull(1) ? null : reader.GetDecimal(1), + CText = reader.IsDBNull(2) ? null : reader.GetString(2), + CBlob = reader.IsDBNull(3) ? null : reader.GetFieldValue(3), + Cnt = reader.GetInt32(4) + }; + } + } + } + } + + return null; + } + + private const string GetSqliteFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_real ) AS max_real, MAX (c_text ) AS max_text FROM types_sqlite "; + public readonly record struct GetSqliteFunctionsRow(int? MaxInteger, decimal MaxReal, object? MaxText); + public async Task GetSqliteFunctions() + { + using (var connection = new SqliteConnection(ConnectionString)) + { + await connection.OpenAsync(); + using (var command = new SqliteCommand(GetSqliteFunctionsSql, connection)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetSqliteFunctionsRow + { + MaxInteger = reader.IsDBNull(0) ? null : reader.GetInt32(0), + MaxReal = reader.GetDecimal(1), + MaxText = reader.IsDBNull(2) ? null : reader.GetValue(2) }; } } diff --git a/examples/SqliteExample/request.json b/examples/SqliteExample/request.json index cc98b659..e5ad7239 100644 --- a/examples/SqliteExample/request.json +++ b/examples/SqliteExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/SqliteExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldDguMCIsInVzZURhcHBlciI6ZmFsc2V9", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlRXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0U3FsaXRlRnVuY3Rpb25zOm1heF9pbnRlZ2VyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRTcWxpdGVGdW5jdGlvbnM6bWF4X3ZhcmNoYXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6InN0cmluZyJ9fSx7ImNvbHVtbiI6IkdldFNxbGl0ZUZ1bmN0aW9uczptYXhfcmVhbCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJkZWNpbWFsIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0OC4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", "process": { "cmd": "./dist/LocalRunner" } @@ -165,7 +165,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = ? LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -225,7 +225,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -382,7 +382,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -442,7 +442,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -502,7 +502,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \nSET bio = ?\nWHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = ?\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -666,7 +666,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -746,7 +746,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description \nFROM authors JOIN books ON authors.id = books.author_id \nORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -770,7 +770,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -794,7 +794,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -868,7 +868,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (?, ?, ?, ?)", + "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (\n ?, ?, ?, ?\n)", "name": "InsertSqliteTypes", "cmd": ":exec", "parameters": [ @@ -1047,19 +1047,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", - "name": "GetSqliteTypesAgg", + "text": "SELECT\n c_integer,\n c_real,\n c_text,\n c_blob,\n COUNT(*) AS cnt\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", + "name": "GetSqliteTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "integer" - } - }, { "name": "c_integer", "length": -1, @@ -1103,6 +1094,47 @@ "name": "BLOB" }, "originalName": "c_blob" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "integer" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_real) AS max_real,\n MAX(c_text) AS max_text\nFROM types_sqlite", + "name": "GetSqliteFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_real", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_text", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } } ], "filename": "query.sql" diff --git a/examples/SqliteLegacyExample/QuerySql.cs b/examples/SqliteLegacyExample/QuerySql.cs index 64ed75db..fc5f16c4 100644 --- a/examples/SqliteLegacyExample/QuerySql.cs +++ b/examples/SqliteLegacyExample/QuerySql.cs @@ -20,7 +20,7 @@ public QuerySql(string connectionString) private string ConnectionString { get; } - private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1"; + private const string GetAuthorSql = "SELECT id, name, bio FROM authors WHERE name = @name LIMIT 1 "; public class GetAuthorRow { public int Id { get; set; } @@ -57,7 +57,7 @@ public async Task GetAuthor(GetAuthorArgs args) return null; } - private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name"; + private const string ListAuthorsSql = "SELECT id, name, bio FROM authors ORDER BY name "; public class ListAuthorsRow { public int Id { get; set; } @@ -132,7 +132,7 @@ public async Task CreateAuthorReturnId(CreateAuthorReturnIdArgs args) } } - private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1"; + private const string GetAuthorByIdSql = "SELECT id, name, bio FROM authors WHERE id = @id LIMIT 1 "; public class GetAuthorByIdRow { public int Id { get; set; } @@ -169,7 +169,7 @@ public async Task GetAuthorById(GetAuthorByIdArgs args) return null; } - private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(@name_pattern, '%')"; + private const string GetAuthorByNamePatternSql = "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE ( @name_pattern , '%' ) "; public class GetAuthorByNamePatternRow { public int Id { get; set; } @@ -202,7 +202,7 @@ public async Task> GetAuthorByNamePattern(GetAut } } - private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; + private const string UpdateAuthorsSql = "UPDATE authors SET bio = @bio WHERE bio IS NOT NULL "; public class UpdateAuthorsArgs { public string Bio { get; set; } @@ -296,7 +296,7 @@ public async Task> GetAuthorsByIdsAndNames(GetA } } - private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name"; + private const string DeleteAuthorSql = "DELETE FROM authors WHERE name = @name "; public class DeleteAuthorArgs { public string Name { get; set; } @@ -339,7 +339,7 @@ public async Task CreateBook(CreateBookArgs args) } } - private const string ListAllAuthorsBooksSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id ORDER BY authors . name "; + private const string ListAllAuthorsBooksSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id ORDER BY authors . name "; public class ListAllAuthorsBooksRow { public Author Author { get; set; } @@ -366,7 +366,7 @@ public async Task> ListAllAuthorsBooks() } } - private const string GetDuplicateAuthorsSql = "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio FROM authors authors1 JOIN authors authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; + private const string GetDuplicateAuthorsSql = "SELECT authors1 . id , authors1 . name, authors1 . bio, authors2 . id, authors2 . name, authors2 . bio FROM authors AS authors1 INNER JOIN authors AS authors2 ON authors1 . name = authors2 . name WHERE authors1 . id < authors2 . id "; public class GetDuplicateAuthorsRow { public Author Author { get; set; } @@ -393,7 +393,7 @@ public async Task> GetDuplicateAuthors() } } - private const string GetAuthorsByBookNameSql = "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description FROM authors JOIN books ON authors . id = books . author_id WHERE books . name = @name "; + private const string GetAuthorsByBookNameSql = "SELECT authors . id , authors . name, authors . bio, books . id, books . name, books . author_id, books . description FROM authors INNER JOIN books ON authors . id = books . author_id WHERE books . name = @name "; public class GetAuthorsByBookNameRow { public int Id { get; set; } @@ -440,7 +440,7 @@ public async Task DeleteAllAuthors() } } - private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (@c_integer, @c_real, @c_text, @c_blob)"; + private const string InsertSqliteTypesSql = "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES ( @c_integer , @c_real, @c_text, @c_blob ) "; public class InsertSqliteTypesArgs { public int? CInteger { get; set; } @@ -525,33 +525,65 @@ public async Task GetSqliteTypes() return null; } - private const string GetSqliteTypesAggSql = "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob FROM types_sqlite GROUP BY c_integer , c_real, c_text, c_blob LIMIT 1 "; - public class GetSqliteTypesAggRow + private const string GetSqliteTypesCntSql = "SELECT c_integer , c_real, c_text, c_blob, COUNT (* ) AS cnt FROM types_sqlite GROUP BY c_integer, c_real, c_text, c_blob LIMIT 1 "; + public class GetSqliteTypesCntRow { - public int Cnt { get; set; } public int? CInteger { get; set; } public decimal? CReal { get; set; } public string CText { get; set; } public byte[] CBlob { get; set; } + public int Cnt { get; set; } + }; + public async Task GetSqliteTypesCnt() + { + using (var connection = new SqliteConnection(ConnectionString)) + { + await connection.OpenAsync(); + using (var command = new SqliteCommand(GetSqliteTypesCntSql, connection)) + { + using (var reader = await command.ExecuteReaderAsync()) + { + if (await reader.ReadAsync()) + { + return new GetSqliteTypesCntRow + { + CInteger = reader.IsDBNull(0) ? (int? )null : reader.GetInt32(0), + CReal = reader.IsDBNull(1) ? (decimal? )null : reader.GetDecimal(1), + CText = reader.IsDBNull(2) ? null : reader.GetString(2), + CBlob = reader.IsDBNull(3) ? null : reader.GetFieldValue(3), + Cnt = reader.GetInt32(4) + }; + } + } + } + } + + return null; + } + + private const string GetSqliteFunctionsSql = "SELECT MAX ( c_integer ) AS max_integer , MAX (c_real ) AS max_real, MAX (c_text ) AS max_text FROM types_sqlite "; + public class GetSqliteFunctionsRow + { + public int? MaxInteger { get; set; } + public decimal MaxReal { get; set; } + public object MaxText { get; set; } }; - public async Task GetSqliteTypesAgg() + public async Task GetSqliteFunctions() { using (var connection = new SqliteConnection(ConnectionString)) { await connection.OpenAsync(); - using (var command = new SqliteCommand(GetSqliteTypesAggSql, connection)) + using (var command = new SqliteCommand(GetSqliteFunctionsSql, connection)) { using (var reader = await command.ExecuteReaderAsync()) { if (await reader.ReadAsync()) { - return new GetSqliteTypesAggRow + return new GetSqliteFunctionsRow { - Cnt = reader.GetInt32(0), - CInteger = reader.IsDBNull(1) ? (int? )null : reader.GetInt32(1), - CReal = reader.IsDBNull(2) ? (decimal? )null : reader.GetDecimal(2), - CText = reader.IsDBNull(3) ? null : reader.GetString(3), - CBlob = reader.IsDBNull(4) ? null : reader.GetFieldValue(4) + MaxInteger = reader.IsDBNull(0) ? (int? )null : reader.GetInt32(0), + MaxReal = reader.GetDecimal(1), + MaxText = reader.IsDBNull(2) ? null : reader.GetValue(2) }; } } diff --git a/examples/SqliteLegacyExample/request.json b/examples/SqliteLegacyExample/request.json index 910a5f3b..68939a2d 100644 --- a/examples/SqliteLegacyExample/request.json +++ b/examples/SqliteLegacyExample/request.json @@ -11,7 +11,7 @@ "codegen": { "out": "examples/SqliteLegacyExample", "plugin": "csharp", - "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlTGVnYWN5RXhhbXBsZUdlbiIsInRhcmdldEZyYW1ld29yayI6Im5ldHN0YW5kYXJkMi4wIiwidXNlRGFwcGVyIjpmYWxzZX0=", + "options": "eyJkZWJ1Z1JlcXVlc3QiOnRydWUsImdlbmVyYXRlQ3Nwcm9qIjp0cnVlLCJuYW1lc3BhY2VOYW1lIjoiU3FsaXRlTGVnYWN5RXhhbXBsZUdlbiIsIm92ZXJyaWRlcyI6W3siY29sdW1uIjoiR2V0U3FsaXRlRnVuY3Rpb25zOm1heF9pbnRlZ2VyIiwiY3NoYXJwX3R5cGUiOnsibm90TnVsbCI6ZmFsc2UsInR5cGUiOiJpbnQifX0seyJjb2x1bW4iOiJHZXRTcWxpdGVGdW5jdGlvbnM6bWF4X3ZhcmNoYXIiLCJjc2hhcnBfdHlwZSI6eyJub3ROdWxsIjpmYWxzZSwidHlwZSI6InN0cmluZyJ9fSx7ImNvbHVtbiI6IkdldFNxbGl0ZUZ1bmN0aW9uczptYXhfcmVhbCIsImNzaGFycF90eXBlIjp7Im5vdE51bGwiOnRydWUsInR5cGUiOiJkZWNpbWFsIn19XSwidGFyZ2V0RnJhbWV3b3JrIjoibmV0c3RhbmRhcmQyLjAiLCJ1c2VEYXBwZXIiOmZhbHNlfQ==", "process": { "cmd": "./dist/LocalRunner" } @@ -165,7 +165,7 @@ }, "queries": [ { - "text": "SELECT id, name, bio FROM authors WHERE name = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE name = ? LIMIT 1", "name": "GetAuthor", "cmd": ":one", "columns": [ @@ -225,7 +225,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors ORDER BY name", + "text": "SELECT id, name, bio FROM authors\nORDER BY name", "name": "ListAuthors", "cmd": ":many", "columns": [ @@ -382,7 +382,7 @@ } }, { - "text": "SELECT id, name, bio FROM authors WHERE id = ? LIMIT 1", + "text": "SELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1", "name": "GetAuthorById", "cmd": ":one", "columns": [ @@ -442,7 +442,7 @@ "filename": "query.sql" }, { - "text": "SELECT id, name, bio FROM authors WHERE name LIKE COALESCE(?1, '%')", + "text": "SELECT id, name, bio FROM authors\nWHERE name LIKE COALESCE(?1, '%')", "name": "GetAuthorByNamePattern", "cmd": ":many", "columns": [ @@ -502,7 +502,7 @@ "filename": "query.sql" }, { - "text": "UPDATE authors \nSET bio = ?\nWHERE bio IS NOT NULL", + "text": "UPDATE authors\nSET bio = ?\nWHERE bio IS NOT NULL", "name": "UpdateAuthors", "cmd": ":execrows", "parameters": [ @@ -666,7 +666,7 @@ "filename": "query.sql" }, { - "text": "DELETE FROM authors WHERE name = ?", + "text": "DELETE FROM authors\nWHERE name = ?", "name": "DeleteAuthor", "cmd": ":exec", "parameters": [ @@ -746,7 +746,7 @@ } }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description \nFROM authors JOIN books ON authors.id = books.author_id \nORDER BY authors.name", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nORDER BY authors.name", "name": "ListAllAuthorsBooks", "cmd": ":many", "columns": [ @@ -770,7 +770,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors1.id, authors1.name, authors1.bio, authors2.id, authors2.name, authors2.bio\nFROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", + "text": "SELECT\n authors1.id, authors1.name, authors1.bio,\n authors2.id, authors2.name, authors2.bio\nFROM authors AS authors1\nINNER JOIN authors AS authors2 ON authors1.name = authors2.name\nWHERE authors1.id \u003c authors2.id", "name": "GetDuplicateAuthors", "cmd": ":many", "columns": [ @@ -794,7 +794,7 @@ "filename": "query.sql" }, { - "text": "SELECT authors.id, authors.name, authors.bio, books.id, books.name, books.author_id, books.description\nFROM authors JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", + "text": "SELECT\n authors.id, authors.name, authors.bio,\n books.id, books.name, books.author_id, books.description\nFROM authors INNER JOIN books ON authors.id = books.author_id\nWHERE books.name = ?", "name": "GetAuthorsByBookName", "cmd": ":many", "columns": [ @@ -868,7 +868,7 @@ "filename": "query.sql" }, { - "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (?, ?, ?, ?)", + "text": "INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (\n ?, ?, ?, ?\n)", "name": "InsertSqliteTypes", "cmd": ":exec", "parameters": [ @@ -1047,19 +1047,10 @@ "filename": "query.sql" }, { - "text": "SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", - "name": "GetSqliteTypesAgg", + "text": "SELECT\n c_integer,\n c_real,\n c_text,\n c_blob,\n COUNT(*) AS cnt\nFROM types_sqlite\nGROUP BY c_integer, c_real, c_text, c_blob\nLIMIT 1", + "name": "GetSqliteTypesCnt", "cmd": ":one", "columns": [ - { - "name": "cnt", - "notNull": true, - "length": -1, - "isFuncCall": true, - "type": { - "name": "integer" - } - }, { "name": "c_integer", "length": -1, @@ -1103,6 +1094,47 @@ "name": "BLOB" }, "originalName": "c_blob" + }, + { + "name": "cnt", + "notNull": true, + "length": -1, + "isFuncCall": true, + "type": { + "name": "integer" + } + } + ], + "filename": "query.sql" + }, + { + "text": "SELECT\n MAX(c_integer) AS max_integer,\n MAX(c_real) AS max_real,\n MAX(c_text) AS max_text\nFROM types_sqlite", + "name": "GetSqliteFunctions", + "cmd": ":one", + "columns": [ + { + "name": "max_integer", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_real", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } + }, + { + "name": "max_text", + "length": -1, + "isFuncCall": true, + "type": { + "name": "any" + } } ], "filename": "query.sql" diff --git a/examples/config/mysql/query.sql b/examples/config/mysql/query.sql index 942a93bf..8c3682f1 100644 --- a/examples/config/mysql/query.sql +++ b/examples/config/mysql/query.sql @@ -2,7 +2,8 @@ SELECT * FROM authors WHERE name = ? LIMIT 1; -- name: ListAuthors :many -SELECT * FROM authors ORDER BY name; +SELECT * FROM authors +ORDER BY name; -- name: CreateAuthor :exec INSERT INTO authors (id, name, bio) VALUES (?, ?, ?); @@ -14,10 +15,12 @@ INSERT INTO authors (name, bio) VALUES (?, ?); SELECT * FROM authors WHERE id = ? LIMIT 1; -- name: GetAuthorByNamePattern :many -SELECT * FROM authors WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); +SELECT * FROM authors +WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); -- name: DeleteAuthor :exec -DELETE FROM authors WHERE name = ?; +DELETE FROM authors +WHERE name = ?; -- name: DeleteAllAuthors :exec DELETE FROM authors; @@ -72,7 +75,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, -- name: GetMysqlTypes :one SELECT * FROM mysql_types LIMIT 1; --- name: GetMysqlTypesAgg :one +-- name: GetMysqlTypesCnt :one SELECT COUNT(1) AS cnt, c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_integer, c_bigint, c_float, c_numeric, c_decimal, c_dec, c_fixed, c_double, c_double_precision, c_char, c_nchar, c_national_char, c_varchar, c_tinytext, c_mediumtext, c_text, c_longtext, c_enum, @@ -86,6 +89,10 @@ GROUP BY c_bool, c_boolean, c_bit, c_tinyint, c_smallint, c_mediumint, c_int, c_ c_binary, c_varbinary, c_tinyblob, c_blob, c_mediumblob, c_longblob LIMIT 1; +-- name: GetMysqlFunctions :one +SELECT MAX(c_int) AS max_int, MAX(c_varchar) AS max_varchar, MAX(c_timestamp) AS max_timestamp, max(c_bigint) as max_bigint +FROM mysql_types; + -- name: TruncateMysqlTypes :exec TRUNCATE TABLE mysql_types; diff --git a/examples/config/mysql/schema.sql b/examples/config/mysql/schema.sql index 8f9ca6d5..56fd99fa 100644 --- a/examples/config/mysql/schema.sql +++ b/examples/config/mysql/schema.sql @@ -1,15 +1,15 @@ CREATE TABLE authors ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - name TEXT NOT NULL, - bio TEXT + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name TEXT NOT NULL, + bio TEXT ); CREATE TABLE books ( - id BIGINT PRIMARY KEY AUTO_INCREMENT, - name TEXT NOT NULL, - author_id BIGINT NOT NULL, - description TEXT, - FOREIGN KEY (author_id) REFERENCES authors (id) ON DELETE CASCADE + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name TEXT NOT NULL, + author_id BIGINT NOT NULL, + description TEXT, + FOREIGN KEY (author_id) REFERENCES authors (id) ON DELETE CASCADE ); CREATE TABLE mysql_types ( diff --git a/examples/config/postgresql/query.sql b/examples/config/postgresql/query.sql index 70e42348..146217e2 100644 --- a/examples/config/postgresql/query.sql +++ b/examples/config/postgresql/query.sql @@ -1,8 +1,10 @@ -- name: GetAuthor :one -SELECT * FROM authors WHERE name = $1 LIMIT 1; +SELECT * FROM authors +WHERE name = $1 LIMIT 1; -- name: ListAuthors :many -SELECT * FROM authors ORDER BY name; +SELECT * FROM authors +ORDER BY name; -- name: CreateAuthor :one INSERT INTO authors (id, name, bio) VALUES ($1, $2, $3) RETURNING *; @@ -11,77 +13,173 @@ INSERT INTO authors (id, name, bio) VALUES ($1, $2, $3) RETURNING *; INSERT INTO authors (name, bio) VALUES ($1, $2) RETURNING id; -- name: GetAuthorById :one -SELECT * FROM authors WHERE id = $1 LIMIT 1; +SELECT * FROM authors +WHERE id = $1 LIMIT 1; -- name: GetAuthorByNamePattern :many -SELECT * FROM authors WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); +SELECT * FROM authors +WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); -- name: DeleteAuthor :exec -DELETE FROM authors WHERE name = $1; +DELETE FROM authors +WHERE name = $1; -- name: TruncateAuthors :exec TRUNCATE TABLE authors CASCADE; -- name: UpdateAuthors :execrows -UPDATE authors - SET bio = $1 - WHERE bio IS NOT NULL; +UPDATE authors +SET bio = $1 +WHERE bio IS NOT NULL; -- name: GetAuthorsByIds :many -SELECT * FROM authors WHERE id = ANY($1::BIGINT[]); +SELECT * FROM authors +WHERE id = ANY($1::BIGINT []); -- name: GetAuthorsByIdsAndNames :many -SELECT * FROM authors WHERE id = ANY($1::BIGINT[]) AND name = ANY($2::TEXT[]);; +SELECT * +FROM authors +WHERE id = ANY($1::BIGINT []) AND name = ANY($2::TEXT []);; -- name: CreateBook :execlastid INSERT INTO books (name, author_id) VALUES ($1, $2) RETURNING id; -- name: ListAllAuthorsBooks :many -SELECT sqlc.embed(authors), sqlc.embed(books) FROM authors JOIN books ON authors.id = books.author_id ORDER BY authors.name; +SELECT + sqlc.embed(authors), + sqlc.embed(books) +FROM authors +INNER JOIN books ON authors.id = books.author_id +ORDER BY authors.name; -- name: GetDuplicateAuthors :many -SELECT sqlc.embed(authors1), sqlc.embed(authors2) -FROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name +SELECT + sqlc.embed(authors1), + sqlc.embed(authors2) +FROM authors AS authors1 +INNER JOIN authors AS authors2 ON authors1.name = authors2.name WHERE authors1.id < authors2.id; -- name: GetAuthorsByBookName :many -SELECT authors.*, sqlc.embed(books) -FROM authors JOIN books ON authors.id = books.author_id +SELECT + authors.*, + sqlc.embed(books) +FROM authors INNER JOIN books ON authors.id = books.author_id WHERE books.name = $1; -- name: InsertPostgresTypes :exec -INSERT INTO postgres_types - (c_boolean, c_bit, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, - c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, - c_bytea, c_text_array, c_integer_array) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, - $11, $12, $13, $14, $15, $16, $17, $18, $19, - $20, $21); +INSERT INTO postgres_types +( + c_boolean, + c_bit, + c_smallint, + c_integer, + c_bigint, + c_real, + c_numeric, + c_decimal, + c_double_precision, + c_money, + c_date, + c_time, + c_timestamp, + c_timestamp_with_tz, + c_char, + c_varchar, + c_character_varying, + c_text, + c_bytea, c_text_array, c_integer_array +) +VALUES ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, + $11, $12, $13, $14, $15, $16, $17, $18, $19, + $20, $21 +); -- name: InsertPostgresTypesBatch :copyfrom -INSERT INTO postgres_types - (c_boolean, c_smallint, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, - c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, - c_bytea) -VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, - $10, $11, $12, $13, $14, $15, $16, $17, $18); +INSERT INTO postgres_types +( + c_boolean, + c_smallint, + c_integer, + c_bigint, + c_real, + c_numeric, + c_decimal, + c_double_precision, + c_money, + c_date, + c_time, + c_timestamp, + c_timestamp_with_tz, + c_char, + c_varchar, + c_character_varying, + c_text, + c_bytea +) +VALUES ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, + $10, $11, $12, $13, $14, $15, $16, $17, $18 +); -- name: GetPostgresTypes :one SELECT * FROM postgres_types LIMIT 1; --- name: GetPostgresTypesAgg :one -SELECT COUNT(1) AS cnt , - c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, - c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, - c_bytea +-- name: GetPostgresTypesCnt :one +SELECT + c_smallint, + c_boolean, + c_integer, + c_bigint, + c_real, + c_numeric, + c_decimal, + c_double_precision, + c_money, + c_date, + c_time, + c_timestamp, + c_timestamp_with_tz, + c_char, + c_varchar, + c_character_varying, + c_text, + c_bytea, + COUNT(*) AS cnt FROM postgres_types -GROUP BY c_smallint, c_boolean, c_integer, c_bigint, c_real, c_numeric, c_decimal, c_double_precision, c_money, - c_date, c_time, c_timestamp, c_timestamp_with_tz, c_char, c_varchar, c_character_varying, c_text, - c_bytea +GROUP BY + c_smallint, + c_boolean, + c_integer, + c_bigint, + c_real, + c_numeric, + c_decimal, + c_double_precision, + c_money, + c_date, + c_time, + c_timestamp, + c_timestamp_with_tz, + c_char, + c_varchar, + c_character_varying, + c_text, + c_bytea LIMIT 1; +-- name: GetPostgresFunctions :one +SELECT + MAX(c_integer) AS max_integer, + MAX(c_varchar) AS max_varchar, + MAX(c_timestamp) AS max_timestamp +FROM postgres_types; + -- name: InsertPostgresGeoTypes :exec -INSERT INTO postgres_geometric_types (c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle) +INSERT INTO postgres_geometric_types ( + c_point, c_line, c_lseg, c_box, c_path, c_polygon, c_circle +) VALUES ($1, $2, $3, $4, $5, $6, $7); -- name: GetPostgresGeoTypes :one @@ -92,4 +190,3 @@ TRUNCATE TABLE postgres_types; -- name: TruncatePostgresGeoTypes :exec TRUNCATE TABLE postgres_geometric_types; - diff --git a/examples/config/postgresql/schema.sql b/examples/config/postgresql/schema.sql index edbb7f9a..9a5bd834 100644 --- a/examples/config/postgresql/schema.sql +++ b/examples/config/postgresql/schema.sql @@ -1,56 +1,56 @@ CREATE TABLE authors ( - id BIGSERIAL PRIMARY KEY, - name TEXT NOT NULL, - bio TEXT + id BIGSERIAL PRIMARY KEY, + name TEXT NOT NULL, + bio TEXT ); CREATE TABLE books ( - id BIGSERIAL PRIMARY KEY, - name TEXT NOT NULL, - author_id BIGINT NOT NULL, - description TEXT, + id BIGSERIAL PRIMARY KEY, + name TEXT NOT NULL, + author_id BIGINT NOT NULL, + description TEXT, FOREIGN KEY (author_id) REFERENCES authors (id) ON DELETE CASCADE ); CREATE TABLE postgres_types ( /* Numeric Data Types */ - c_boolean BOOLEAN, - c_bit BIT(10), - c_smallint SMALLINT, - c_integer INTEGER, - c_bigint BIGINT, - c_decimal DECIMAL(10,7), - c_numeric NUMERIC(10,7), - c_real REAL, - c_double_precision DOUBLE PRECISION, - c_money MONEY, - + c_boolean BOOLEAN, + c_bit BIT(10), + c_smallint SMALLINT, + c_integer INTEGER, + c_bigint BIGINT, + c_decimal DECIMAL(10, 7), + c_numeric NUMERIC(10, 7), + c_real REAL, + c_double_precision DOUBLE PRECISION, + c_money MONEY, + /* Date and Time Data Types */ - c_date DATE, - c_time TIME, - c_timestamp TIMESTAMP, + c_date DATE, + c_time TIME, + c_timestamp TIMESTAMP, c_timestamp_with_tz TIMESTAMP WITH TIME ZONE, - + /* String Data Type Syntax */ - c_char CHAR, - c_varchar VARCHAR(100), + c_char CHAR, + c_varchar VARCHAR(100), c_character_varying CHARACTER VARYING(100), - c_bytea BYTEA, - c_text TEXT, - c_json JSON, + c_bytea BYTEA, + c_text TEXT, + c_json JSON, /* Array Data Types */ - c_text_array TEXT[], - c_integer_array INTEGER[] + c_text_array TEXT [], + c_integer_array INTEGER [] ); CREATE TABLE postgres_geometric_types ( - c_point POINT, - c_line LINE, - c_lseg LSEG, - c_box BOX, - c_path PATH, - c_polygon POLYGON, - c_circle CIRCLE -); \ No newline at end of file + c_point POINT, + c_line LINE, + c_lseg LSEG, + c_box BOX, + c_path PATH, + c_polygon POLYGON, + c_circle CIRCLE +); diff --git a/examples/config/sqlite/query.sql b/examples/config/sqlite/query.sql index 325838e1..9e9c8803 100644 --- a/examples/config/sqlite/query.sql +++ b/examples/config/sqlite/query.sql @@ -1,8 +1,10 @@ -- name: GetAuthor :one -SELECT * FROM authors WHERE name = ? LIMIT 1; +SELECT * FROM authors +WHERE name = ? LIMIT 1; -- name: ListAuthors :many -SELECT * FROM authors ORDER BY name; +SELECT * FROM authors +ORDER BY name; -- name: CreateAuthor :exec INSERT INTO authors (id, name, bio) VALUES (?, ?, ?); @@ -11,13 +13,15 @@ INSERT INTO authors (id, name, bio) VALUES (?, ?, ?); INSERT INTO authors (name, bio) VALUES (?, ?) RETURNING id; -- name: GetAuthorById :one -SELECT * FROM authors WHERE id = ? LIMIT 1; +SELECT * FROM authors +WHERE id = ? LIMIT 1; -- name: GetAuthorByNamePattern :many -SELECT * FROM authors WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); +SELECT * FROM authors +WHERE name LIKE COALESCE(sqlc.narg('name_pattern'), '%'); -- name: UpdateAuthors :execrows -UPDATE authors +UPDATE authors SET bio = ? WHERE bio IS NOT NULL; @@ -28,31 +32,41 @@ SELECT * FROM authors WHERE id IN (sqlc.slice('ids')); SELECT * FROM authors WHERE id IN (sqlc.slice('ids')) AND name IN (sqlc.slice('names')); -- name: DeleteAuthor :exec -DELETE FROM authors WHERE name = ?; +DELETE FROM authors +WHERE name = ?; -- name: CreateBook :execlastid INSERT INTO books (name, author_id) VALUES (?, ?) RETURNING id; -- name: ListAllAuthorsBooks :many -SELECT sqlc.embed(authors), sqlc.embed(books) -FROM authors JOIN books ON authors.id = books.author_id +SELECT + sqlc.embed(authors), + sqlc.embed(books) +FROM authors INNER JOIN books ON authors.id = books.author_id ORDER BY authors.name; -- name: GetDuplicateAuthors :many -SELECT sqlc.embed(authors1), sqlc.embed(authors2) -FROM authors authors1 JOIN authors authors2 ON authors1.name = authors2.name +SELECT + sqlc.embed(authors1), + sqlc.embed(authors2) +FROM authors AS authors1 +INNER JOIN authors AS authors2 ON authors1.name = authors2.name WHERE authors1.id < authors2.id; -- name: GetAuthorsByBookName :many -SELECT authors.*, sqlc.embed(books) -FROM authors JOIN books ON authors.id = books.author_id +SELECT + authors.*, + sqlc.embed(books) +FROM authors INNER JOIN books ON authors.id = books.author_id WHERE books.name = ?; -- name: DeleteAllAuthors :exec DELETE FROM authors; -- name: InsertSqliteTypes :exec -INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES (?, ?, ?, ?); +INSERT INTO types_sqlite (c_integer, c_real, c_text, c_blob) VALUES ( + ?, ?, ?, ? +); -- name: InsertSqliteTypesBatch :copyfrom INSERT INTO types_sqlite (c_integer, c_real, c_text) VALUES (?, ?, ?); @@ -60,11 +74,23 @@ INSERT INTO types_sqlite (c_integer, c_real, c_text) VALUES (?, ?, ?); -- name: GetSqliteTypes :one SELECT * FROM types_sqlite LIMIT 1; --- name: GetSqliteTypesAgg :one -SELECT COUNT(1) AS cnt , c_integer, c_real, c_text, c_blob +-- name: GetSqliteTypesCnt :one +SELECT + c_integer, + c_real, + c_text, + c_blob, + COUNT(*) AS cnt FROM types_sqlite GROUP BY c_integer, c_real, c_text, c_blob LIMIT 1; +-- name: GetSqliteFunctions :one +SELECT + MAX(c_integer) AS max_integer, + MAX(c_real) AS max_real, + MAX(c_text) AS max_text +FROM types_sqlite; + -- name: DeleteAllSqliteTypes :exec -DELETE FROM types_sqlite; \ No newline at end of file +DELETE FROM types_sqlite; diff --git a/examples/config/sqlite/schema.sql b/examples/config/sqlite/schema.sql index 96eec4bc..1e4e85eb 100644 --- a/examples/config/sqlite/schema.sql +++ b/examples/config/sqlite/schema.sql @@ -1,20 +1,20 @@ CREATE TABLE authors ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - bio TEXT + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + bio TEXT ); CREATE TABLE books ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - author_id INTEGER NOT NULL, - description TEXT, + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + author_id INTEGER NOT NULL, + description TEXT, FOREIGN KEY (author_id) REFERENCES authors (id) ON DELETE CASCADE ); CREATE TABLE types_sqlite ( - c_integer INTEGER, - c_real REAL, - c_text TEXT, - c_blob BLOB + c_integer INTEGER, + c_real REAL, + c_text TEXT, + c_blob BLOB ); diff --git a/scripts/sync_sqlc_options.sh b/scripts/sync_sqlc_options.sh new file mode 100755 index 00000000..0c40e388 --- /dev/null +++ b/scripts/sync_sqlc_options.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -e + +CI_YAML="sqlc.ci.yaml" +REQUESTS_YAML="sqlc.requests.yaml" +LOCAL_YAML="sqlc.local.yaml" +TMP_REQUESTS_YML="${REQUESTS_YAML}.tmp" +TMP_LOCAL_YML="${LOCAL_YAML}.tmp" + +cp "$REQUESTS_YAML" "$TMP_REQUESTS_YML" +cp "$LOCAL_YAML" "$TMP_LOCAL_YML" + +sql_count=$(yq '.sql | length' "$CI_YAML") +for ((i=0; i