with and without parameters works

This commit is contained in:
Wolfgang Hottgenroth 2021-11-25 14:49:08 +01:00
parent 66d222e0bf
commit 10c3cab432
Signed by: wn
GPG Key ID: E49AF3B9EF6DD469
5 changed files with 163 additions and 88 deletions

View File

@ -1,3 +1,5 @@
#pragma warning disable 1591
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
@ -7,39 +9,47 @@ using de.hottis.genericdatabaseapiservice.Models;
namespace de.hottis.genericdatabaseapiservice.Services {
public interface IDbService {
Task<List<T>> JustDoSomething<T>(string msg);
Task<List<TOUT>> ReadBySelect<TIN, TOUT>(string selectStatement, TIN input);
}
public class DbService : IDbService {
async public Task<List<T>> JustDoSomething<T>(string msg) {
Console.WriteLine(msg);
var itemList = new List<T>();
async public Task<List<TOUT>> ReadBySelect<TIN, TOUT>(string selectStatement, TIN input) {
var itemList = new List<TOUT>();
using (var conn = new MySqlConnection("Server=172.16.10.18;User ID=apiservicetestdb;Password=geheim123;Database=apiservicetestdb")) {
await conn.OpenAsync();
using (var cmd = conn.CreateCommand()) {
// cmd.CommandText = "INSERT INTO test1 (txt, nr) VALUES (@txt, @nr)";
// cmd.Parameters.AddWithValue("txt", "txt1");
// cmd.Parameters.AddWithValue("nr", 12);
// await cmd.ExecuteNonQueryAsync();
cmd.CommandText = "SELECT id, txt, nr FROM test1";
cmd.CommandText = selectStatement;
if (input != null){
foreach (var propertyInfo in typeof(TIN).GetProperties()) {
Console.WriteLine("Input Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), true);
var dma = (DataMemberAttribute)attributes[0];
Console.WriteLine("Input DataMember name: {0} {1} ", dma.Name, dma.TypeId);
var value = propertyInfo.GetValue(input);
Console.WriteLine("Input Value: {0}", value);
cmd.Parameters.AddWithValue(dma.Name, propertyInfo.GetValue(input));
}
} else {
Console.WriteLine("no input data");
}
using (var reader = await cmd.ExecuteReaderAsync()) {
while (await reader.ReadAsync()) {
var item = Activator.CreateInstance<T>();
foreach (var propertyInfo in typeof(T).GetProperties()) {
Console.WriteLine("Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
var item = Activator.CreateInstance<TOUT>();
foreach (var propertyInfo in typeof(TOUT).GetProperties()) {
Console.WriteLine("Output Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), true);
var dma = (DataMemberAttribute)attributes[0];
Console.WriteLine("DataMember name: {0} {1} ", dma.Name, dma.TypeId);
Console.WriteLine("Output DataMember name: {0} {1} ", dma.Name, dma.TypeId);
if (propertyInfo.PropertyType == typeof(System.String)) {
propertyInfo.SetValue(item, reader.GetString(dma.Name));
Console.WriteLine("Value:{0}", reader.GetString(dma.Name));
Console.WriteLine("Output Value:{0}", reader.GetString(dma.Name));
} else if (propertyInfo.PropertyType == typeof(System.Int32)) {
propertyInfo.SetValue(item, reader.GetInt32(dma.Name));
Console.WriteLine("Value:{0}", reader.GetInt32(dma.Name));
Console.WriteLine("Output Value:{0}", reader.GetInt32(dma.Name));
}
}
itemList.Add(item);
@ -51,3 +61,5 @@ namespace de.hottis.genericdatabaseapiservice.Services {
}
}
}
#pragma warning restore 1591

View File

@ -95,12 +95,14 @@ for path in apiDefinition['paths'].values():
if 'requestBody' in operation:
bodyInputTypeName = OpenApiExtractRefType(operation['requestBody']['content']['application/json']['schema']['$ref'])
bodyInputType = { 'apiName': bodyInputTypeName, 'csName': CsOperationNameConverter(bodyInputTypeName) }
paramsInputTypes =[]
paramInputTypes = []
if 'parameters' in operation:
for paramsInputType in operation['parameters']:
paramsInputType['type'] = CsTypeConverter(paramsInputType['schema']['type'])
del paramsInputType['schema']
paramsInputTypes.append(paramsInputType)
paramsInputType['csName'] = CsOperationNameConverter(paramsInputType['name'])
paramInputTypes.append(paramsInputType)
operations.append({
@ -113,7 +115,7 @@ for path in apiDefinition['paths'].values():
'byIdSelector': operation['operationId'].endswith('byid'),
'statement': statement,
'bodyInputType': bodyInputType,
'paramsInputTypes': paramsInputTypes
'paramInputTypes': paramInputTypes
})
#print(f"{operations=}")
apiDefinition["operations"] = operations

View File

@ -4,14 +4,19 @@
REMOVE="0"
BUILD="0"
EXECUTE="0"
while getopts rxbh flag
STAGE1="0"
STAGE2="0"
while getopts rxbh12 flag
do
case "${flag}" in
h)
echo "1 ... generator stage 1 (implementation generator)";
echo "2 ... generator stage 2 (openapi generator)";
echo "r ... remove output directory";
echo "b ... build after generating";
echo "x ... execute after building";
echo "h ... show help";
;;
b)
BUILD="1"
@ -22,6 +27,12 @@ do
x)
EXECUTE="1"
;;
1)
STAGE1="1"
;;
2)
STAGE2="1"
;;
esac
done
@ -41,31 +52,38 @@ fi
# PACKAGE_NAME will be loaded here
. ENV
echo "generate server code and endpoint stubs from openapi.yaml"
docker run -it --rm -v $PWD:/work -u $UID openapitools/openapi-generator-cli:v5.3.0 \
generate -i /work/openapi.yaml -g aspnetcore -o /work/output \
--package-name $PACKAGE_NAME \
--additional-properties="packageVersion=0.0.1,aspnetCoreVersion=5.0,operationIsAsync=false,operationResultTask=true,\
generateBody=false,classModifier=abstract,operationModifier=abstract"
if [ "$STAGE1" = "1" ]; then
echo "generate endpoint code from openapi.yaml"
python3.10 generate.py
fi
echo "patch DbService registering into generated startup code"
sed -i output/src/$PACKAGE_NAME/Startup.cs \
-e 's#\(using '$PACKAGE_NAME'.OpenApi;\)#\1\n\n// added by post-processor\nusing '$PACKAGE_NAME'.Services;\n#' \
-e 's#^\([[:space:]]*\)\(// Add framework services.\)#\1// added by post-processor\n\1services.AddTransient<IDbService, DbService>();\n\n\1\2#'
if [ "$STAGE2" = "1" ]; then
echo "generate server code and endpoint stubs from openapi.yaml"
docker run -it --rm -v $PWD:/work -u $UID openapitools/openapi-generator-cli:v5.3.0 \
generate -i /work/openapi.yaml -g aspnetcore -o /work/output \
--package-name $PACKAGE_NAME \
--additional-properties="packageVersion=0.0.1,aspnetCoreVersion=5.0,operationIsAsync=false,operationResultTask=true,\
generateBody=false,classModifier=abstract,operationModifier=abstract"
echo "create directories for manually developed code"
mkdir output/src/$PACKAGE_NAME/Implementations
mkdir output/src/$PACKAGE_NAME/Services
echo "patch DbService registering into generated startup code"
sed -i output/src/$PACKAGE_NAME/Startup.cs \
-e 's#\(using '$PACKAGE_NAME'.OpenApi;\)#\1\n\n// added by post-processor\nusing '$PACKAGE_NAME'.Services;\n#' \
-e 's#^\([[:space:]]*\)\(// Add framework services.\)#\1// added by post-processor\n\1services.AddTransient<IDbService, DbService>();\n\n\1\2#'
echo "copy database service into source code try"
cp DbService.cs output/src/$PACKAGE_NAME/Services
echo "create directories for manually developed code"
mkdir output/src/$PACKAGE_NAME/Implementations
mkdir output/src/$PACKAGE_NAME/Services
echo "generate endpoint code from openapi.yaml"
python3.10 generate.py
echo "copy endpoint code into source code tree"
cp regular.cs output/src/$PACKAGE_NAME/Implementations
echo "copy database service into source code try"
cp DbService.cs output/src/$PACKAGE_NAME/Services
if [ -f regular.cs ]; then
echo "copy endpoint code into source code tree"
cp regular.cs output/src/$PACKAGE_NAME/Implementations
else
echo "implementation not available, forgot to run stage 1?"
fi
fi
if [ "$BUILD" = "1" ]; then
echo "build service"

View File

@ -34,26 +34,6 @@ paths:
# responses:
# 201:
# description: Your items has been inserted
/pdb/v2/test1/{id}:
get:
tags: [ "Regular" ]
operationId: Regular.test1byid
summary: Returns one entry from table test1 by id
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
200:
description: Here is your test1 item
content:
application/json:
schema:
$ref: "#/components/schemas/test1"
404:
description: No such test1 item available
/pdb/v2/test1/specificSelectName:
get:
tags: [ "Regular" ]
@ -63,7 +43,7 @@ paths:
STATEMENTBEGIN
select txt
from test1
where nr = ?
where nr = @nr
STATEMENTEND
INPUTMAPPINGBEGIN
nr = Nummer
@ -76,12 +56,12 @@ paths:
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo
dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem
ipsum dolor sit amet.
requestBody:
description: specificSelectNameType
content:
application/json:
schema:
$ref: "#/components/schemas/specificSelectNameType"
parameters:
- name: nr
in: query
required: true
schema:
type: integer
responses:
200:
description: Here are your test1 items
@ -108,14 +88,6 @@ components:
type: string
nr:
type: integer
specificSelectNameType:
description: Specific type to defintion select condition
type: object
required:
- nr
properties:
nr:
type: integer
specificResultType:
description: Specific result type to defintion select clause
type: object

View File

@ -1,9 +1,12 @@
$GENERATED_CS_COMMENT
\#pragma warning disable 1591
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Microsoft.AspNetCore.Authorization;
@ -16,6 +19,29 @@ using ${env['packagename']}.Services;
namespace ${env['packagename']}.Implementations
{
#for $operation in $operations
#if $operation['paramInputTypes']
// $operation['func']
[DataContract]
public class ${operation['func']}InputType
{
#for $inputType in $operation['paramInputTypes']
// $inputType['in']
// $inputType['name']
// $inputType['required']
// $inputType['type']
#if $inputType['required']
[Required]
#end if
[DataMember(Name="$inputType['name']")]
public int $inputType['csName'] { get; set; }
#end for
}
#end if
#end for
/// <summary>
/// </summary>
public class RegularApiImplementation : RegularApiController
@ -31,22 +57,66 @@ namespace ${env['packagename']}.Implementations
/// <summary>
/// $operation['description']
/// </summary>
public override async Task<IActionResult> ${operation['func']}( #slurp
#if $operation['paramsInputTypes']
#set $sep = ""
#for $paramsInputType in $operation['paramsInputTypes']
$sep [FromRoute (Name = "$paramsInputType['name']")] #slurp
#if $paramsInputType['required']
[Required] #slurp
#end if
$paramsInputType['type'] $paramsInputType['name'] #slurp
#set $sep = ","
#end for
#elif $operation['bodyInputType']
public override async Task<IActionResult> ${operation['func']}(#slurp
#if $operation['bodyInputType']
[FromBody]$operation['bodyInputType']['csName'] $operation['bodyInputType']['apiName'] #slurp
#end if
#if $operation['paramInputTypes']
#set sep = ''
#for $inputType in $operation['paramInputTypes']
$sep#slurp
#if $inputType['in'] == 'query'
[FromQuery #slurp
#elif $inputType['in'] == 'path'
[FromPath #slurp
#else
#raise Exception('Invalid in for paramInput')
#end if
(Name = "$inputType['name']")]#slurp
#if $inputType['required']
[Required()]#slurp
#end if
$inputType['type'] $inputType['name']#slurp
#set sep = ', '
#end for
#end if
) {
List<$operation['resultType']['csName']> res = await _dbService.JustDoSomething<$operation['resultType']['csName']>("Hello ${operation['func']}");
#if $operation['paramInputTypes']
${operation['func']}InputType paramInput = new ${operation['func']}InputType();
#for $inputType in $operation['paramInputTypes']
paramInput.$inputType['csName'] = $inputType['name'];
#end for
#end if
List<$operation['resultType']['csName']> res = await _dbService.ReadBySelect<#slurp
#if $operation['bodyInputType']
$operation['bodyInputType']['csName'], #slurp
#elif $operation['paramInputTypes']
${operation['func']}InputType, #slurp
#else
Object, #slurp
#end if
$operation['resultType']['csName']>("#slurp
#if not $operation['statement']
SELECT #slurp
#set $sep = ""
#for $property in $types[$operation['resultType']['apiName']]['properties']
$sep$property['sqlName'] #slurp
#set $sep = ","
#end for
FROM $types[$operation['resultType']['apiName']]['sqlName']#slurp
#else
$operation['statement']#slurp
#end if
", #slurp
#if $operation['bodyInputType']
$operation['bodyInputType']['apiName']#slurp
#elif $operation['paramInputTypes']
paramInput#slurp
#else
null#slurp
#end if
);
// Statement:
#if not $operation['statement']
@ -94,3 +164,4 @@ $paramsInputType['type'] $paramsInputType['name'] #slurp
}
}
\#pragma warning restore 1591