with and without parameters works
This commit is contained in:
parent
66d222e0bf
commit
10c3cab432
44
DbService.cs
44
DbService.cs
@ -1,3 +1,5 @@
|
|||||||
|
#pragma warning disable 1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
@ -7,39 +9,47 @@ using de.hottis.genericdatabaseapiservice.Models;
|
|||||||
|
|
||||||
namespace de.hottis.genericdatabaseapiservice.Services {
|
namespace de.hottis.genericdatabaseapiservice.Services {
|
||||||
public interface IDbService {
|
public interface IDbService {
|
||||||
Task<List<T>> JustDoSomething<T>(string msg);
|
Task<List<TOUT>> ReadBySelect<TIN, TOUT>(string selectStatement, TIN input);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DbService : IDbService {
|
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")) {
|
using (var conn = new MySqlConnection("Server=172.16.10.18;User ID=apiservicetestdb;Password=geheim123;Database=apiservicetestdb")) {
|
||||||
await conn.OpenAsync();
|
await conn.OpenAsync();
|
||||||
|
|
||||||
using (var cmd = conn.CreateCommand()) {
|
using (var cmd = conn.CreateCommand()) {
|
||||||
// cmd.CommandText = "INSERT INTO test1 (txt, nr) VALUES (@txt, @nr)";
|
cmd.CommandText = selectStatement;
|
||||||
// cmd.Parameters.AddWithValue("txt", "txt1");
|
if (input != null){
|
||||||
// cmd.Parameters.AddWithValue("nr", 12);
|
foreach (var propertyInfo in typeof(TIN).GetProperties()) {
|
||||||
// await cmd.ExecuteNonQueryAsync();
|
Console.WriteLine("Input Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
|
||||||
cmd.CommandText = "SELECT id, txt, nr FROM test1";
|
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()) {
|
using (var reader = await cmd.ExecuteReaderAsync()) {
|
||||||
while (await reader.ReadAsync()) {
|
while (await reader.ReadAsync()) {
|
||||||
var item = Activator.CreateInstance<T>();
|
var item = Activator.CreateInstance<TOUT>();
|
||||||
foreach (var propertyInfo in typeof(T).GetProperties()) {
|
foreach (var propertyInfo in typeof(TOUT).GetProperties()) {
|
||||||
Console.WriteLine("Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
|
Console.WriteLine("Output Property name: {0} {1} ", propertyInfo.Name, propertyInfo.PropertyType);
|
||||||
var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), true);
|
var attributes = propertyInfo.GetCustomAttributes(typeof(DataMemberAttribute), true);
|
||||||
var dma = (DataMemberAttribute)attributes[0];
|
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)) {
|
if (propertyInfo.PropertyType == typeof(System.String)) {
|
||||||
propertyInfo.SetValue(item, reader.GetString(dma.Name));
|
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)) {
|
} else if (propertyInfo.PropertyType == typeof(System.Int32)) {
|
||||||
propertyInfo.SetValue(item, reader.GetInt32(dma.Name));
|
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);
|
itemList.Add(item);
|
||||||
@ -51,3 +61,5 @@ namespace de.hottis.genericdatabaseapiservice.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning restore 1591
|
||||||
|
@ -95,12 +95,14 @@ for path in apiDefinition['paths'].values():
|
|||||||
if 'requestBody' in operation:
|
if 'requestBody' in operation:
|
||||||
bodyInputTypeName = OpenApiExtractRefType(operation['requestBody']['content']['application/json']['schema']['$ref'])
|
bodyInputTypeName = OpenApiExtractRefType(operation['requestBody']['content']['application/json']['schema']['$ref'])
|
||||||
bodyInputType = { 'apiName': bodyInputTypeName, 'csName': CsOperationNameConverter(bodyInputTypeName) }
|
bodyInputType = { 'apiName': bodyInputTypeName, 'csName': CsOperationNameConverter(bodyInputTypeName) }
|
||||||
paramsInputTypes =[]
|
|
||||||
|
paramInputTypes = []
|
||||||
if 'parameters' in operation:
|
if 'parameters' in operation:
|
||||||
for paramsInputType in operation['parameters']:
|
for paramsInputType in operation['parameters']:
|
||||||
paramsInputType['type'] = CsTypeConverter(paramsInputType['schema']['type'])
|
paramsInputType['type'] = CsTypeConverter(paramsInputType['schema']['type'])
|
||||||
del paramsInputType['schema']
|
del paramsInputType['schema']
|
||||||
paramsInputTypes.append(paramsInputType)
|
paramsInputType['csName'] = CsOperationNameConverter(paramsInputType['name'])
|
||||||
|
paramInputTypes.append(paramsInputType)
|
||||||
|
|
||||||
|
|
||||||
operations.append({
|
operations.append({
|
||||||
@ -113,7 +115,7 @@ for path in apiDefinition['paths'].values():
|
|||||||
'byIdSelector': operation['operationId'].endswith('byid'),
|
'byIdSelector': operation['operationId'].endswith('byid'),
|
||||||
'statement': statement,
|
'statement': statement,
|
||||||
'bodyInputType': bodyInputType,
|
'bodyInputType': bodyInputType,
|
||||||
'paramsInputTypes': paramsInputTypes
|
'paramInputTypes': paramInputTypes
|
||||||
})
|
})
|
||||||
#print(f"{operations=}")
|
#print(f"{operations=}")
|
||||||
apiDefinition["operations"] = operations
|
apiDefinition["operations"] = operations
|
||||||
|
@ -4,14 +4,19 @@
|
|||||||
REMOVE="0"
|
REMOVE="0"
|
||||||
BUILD="0"
|
BUILD="0"
|
||||||
EXECUTE="0"
|
EXECUTE="0"
|
||||||
while getopts rxbh flag
|
STAGE1="0"
|
||||||
|
STAGE2="0"
|
||||||
|
while getopts rxbh12 flag
|
||||||
do
|
do
|
||||||
case "${flag}" in
|
case "${flag}" in
|
||||||
h)
|
h)
|
||||||
|
echo "1 ... generator stage 1 (implementation generator)";
|
||||||
|
echo "2 ... generator stage 2 (openapi generator)";
|
||||||
echo "r ... remove output directory";
|
echo "r ... remove output directory";
|
||||||
echo "b ... build after generating";
|
echo "b ... build after generating";
|
||||||
echo "x ... execute after building";
|
echo "x ... execute after building";
|
||||||
echo "h ... show help";
|
echo "h ... show help";
|
||||||
|
|
||||||
;;
|
;;
|
||||||
b)
|
b)
|
||||||
BUILD="1"
|
BUILD="1"
|
||||||
@ -22,6 +27,12 @@ do
|
|||||||
x)
|
x)
|
||||||
EXECUTE="1"
|
EXECUTE="1"
|
||||||
;;
|
;;
|
||||||
|
1)
|
||||||
|
STAGE1="1"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
STAGE2="1"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -41,31 +52,38 @@ fi
|
|||||||
# PACKAGE_NAME will be loaded here
|
# PACKAGE_NAME will be loaded here
|
||||||
. ENV
|
. ENV
|
||||||
|
|
||||||
echo "generate server code and endpoint stubs from openapi.yaml"
|
if [ "$STAGE1" = "1" ]; then
|
||||||
docker run -it --rm -v $PWD:/work -u $UID openapitools/openapi-generator-cli:v5.3.0 \
|
echo "generate endpoint code from openapi.yaml"
|
||||||
generate -i /work/openapi.yaml -g aspnetcore -o /work/output \
|
python3.10 generate.py
|
||||||
--package-name $PACKAGE_NAME \
|
fi
|
||||||
--additional-properties="packageVersion=0.0.1,aspnetCoreVersion=5.0,operationIsAsync=false,operationResultTask=true,\
|
|
||||||
generateBody=false,classModifier=abstract,operationModifier=abstract"
|
|
||||||
|
|
||||||
echo "patch DbService registering into generated startup code"
|
if [ "$STAGE2" = "1" ]; then
|
||||||
sed -i output/src/$PACKAGE_NAME/Startup.cs \
|
echo "generate server code and endpoint stubs from openapi.yaml"
|
||||||
-e 's#\(using '$PACKAGE_NAME'.OpenApi;\)#\1\n\n// added by post-processor\nusing '$PACKAGE_NAME'.Services;\n#' \
|
docker run -it --rm -v $PWD:/work -u $UID openapitools/openapi-generator-cli:v5.3.0 \
|
||||||
-e 's#^\([[:space:]]*\)\(// Add framework services.\)#\1// added by post-processor\n\1services.AddTransient<IDbService, DbService>();\n\n\1\2#'
|
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"
|
echo "patch DbService registering into generated startup code"
|
||||||
mkdir output/src/$PACKAGE_NAME/Implementations
|
sed -i output/src/$PACKAGE_NAME/Startup.cs \
|
||||||
mkdir output/src/$PACKAGE_NAME/Services
|
-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"
|
echo "create directories for manually developed code"
|
||||||
cp DbService.cs output/src/$PACKAGE_NAME/Services
|
mkdir output/src/$PACKAGE_NAME/Implementations
|
||||||
|
mkdir output/src/$PACKAGE_NAME/Services
|
||||||
|
|
||||||
echo "generate endpoint code from openapi.yaml"
|
echo "copy database service into source code try"
|
||||||
python3.10 generate.py
|
cp DbService.cs output/src/$PACKAGE_NAME/Services
|
||||||
|
|
||||||
echo "copy endpoint code into source code tree"
|
|
||||||
cp regular.cs output/src/$PACKAGE_NAME/Implementations
|
|
||||||
|
|
||||||
|
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
|
if [ "$BUILD" = "1" ]; then
|
||||||
echo "build service"
|
echo "build service"
|
||||||
|
42
openapi.yaml
42
openapi.yaml
@ -34,26 +34,6 @@ paths:
|
|||||||
# responses:
|
# responses:
|
||||||
# 201:
|
# 201:
|
||||||
# description: Your items has been inserted
|
# 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:
|
/pdb/v2/test1/specificSelectName:
|
||||||
get:
|
get:
|
||||||
tags: [ "Regular" ]
|
tags: [ "Regular" ]
|
||||||
@ -63,7 +43,7 @@ paths:
|
|||||||
STATEMENTBEGIN
|
STATEMENTBEGIN
|
||||||
select txt
|
select txt
|
||||||
from test1
|
from test1
|
||||||
where nr = ?
|
where nr = @nr
|
||||||
STATEMENTEND
|
STATEMENTEND
|
||||||
INPUTMAPPINGBEGIN
|
INPUTMAPPINGBEGIN
|
||||||
nr = Nummer
|
nr = Nummer
|
||||||
@ -76,12 +56,12 @@ paths:
|
|||||||
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo
|
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
|
dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem
|
||||||
ipsum dolor sit amet.
|
ipsum dolor sit amet.
|
||||||
requestBody:
|
parameters:
|
||||||
description: specificSelectNameType
|
- name: nr
|
||||||
content:
|
in: query
|
||||||
application/json:
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/specificSelectNameType"
|
type: integer
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Here are your test1 items
|
description: Here are your test1 items
|
||||||
@ -108,14 +88,6 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
nr:
|
nr:
|
||||||
type: integer
|
type: integer
|
||||||
specificSelectNameType:
|
|
||||||
description: Specific type to defintion select condition
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- nr
|
|
||||||
properties:
|
|
||||||
nr:
|
|
||||||
type: integer
|
|
||||||
specificResultType:
|
specificResultType:
|
||||||
description: Specific result type to defintion select clause
|
description: Specific result type to defintion select clause
|
||||||
type: object
|
type: object
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
$GENERATED_CS_COMMENT
|
$GENERATED_CS_COMMENT
|
||||||
|
|
||||||
|
\#pragma warning disable 1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Swashbuckle.AspNetCore.Annotations;
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -16,6 +19,29 @@ using ${env['packagename']}.Services;
|
|||||||
|
|
||||||
namespace ${env['packagename']}.Implementations
|
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>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RegularApiImplementation : RegularApiController
|
public class RegularApiImplementation : RegularApiController
|
||||||
@ -31,22 +57,66 @@ namespace ${env['packagename']}.Implementations
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// $operation['description']
|
/// $operation['description']
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override async Task<IActionResult> ${operation['func']}( #slurp
|
public override async Task<IActionResult> ${operation['func']}(#slurp
|
||||||
#if $operation['paramsInputTypes']
|
#if $operation['bodyInputType']
|
||||||
#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']
|
|
||||||
[FromBody]$operation['bodyInputType']['csName'] $operation['bodyInputType']['apiName'] #slurp
|
[FromBody]$operation['bodyInputType']['csName'] $operation['bodyInputType']['apiName'] #slurp
|
||||||
#end if
|
#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:
|
// Statement:
|
||||||
#if not $operation['statement']
|
#if not $operation['statement']
|
||||||
@ -94,3 +164,4 @@ $paramsInputType['type'] $paramsInputType['name'] #slurp
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
\#pragma warning restore 1591
|
||||||
|
Loading…
x
Reference in New Issue
Block a user