diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..8fa45b1 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,24 @@ + + + + + + SmartCode + 2019 SmartCode, Inc. + $(AssemblyName) + Ahoo Wang;ncc + ahoowang@qq.com + latest + https://github.com/Smart-Kit/SmartCode + git + $(MSBuildThisFileDirectory) + https://raw.githubusercontent.com/Smart-Kit/SmartCode/master/doc/Logo.png + https://github.com/Smart-Kit/SmartCode + True + Apache-2.0 + SmartCode SmartSql + + SmartCode = IDataSource -> IBuildTask -> IOutput => Build Everything!!! + + + \ No newline at end of file diff --git a/README-EN.md b/README-EN.md index d8317d6..99ceae7 100644 --- a/README-EN.md +++ b/README-EN.md @@ -10,6 +10,12 @@ ![SmartCode](./doc/SmartCode-EN.png) +## Nuget Packages + +| Package | NuGet Stable | Downloads | +| ------- | -------- | ------- | +| [SmartCode.CLI](https://www.nuget.org/packages/SmartCode.CLI/) | [![SmartCode.CLI](https://img.shields.io/nuget/v/SmartCode.CLI.svg)](https://www.nuget.org/packages/SmartCode.CLI/) | [![SmartCode.CLI](https://img.shields.io/nuget/dt/SmartCode.CLI.svg)](https://www.nuget.org/packages/SmartCode.CLI/) | + ## SmartCode.Generator (Code generator) ### Demo @@ -21,7 +27,7 @@ 1. Install from .NET Core Global Tool ``` shell - dotnet tool install --global SmartCode.CLI + dotnet tool install --global SmartCode.CLI ``` 2. edit build configuration file (default: SmartCode.yml) @@ -40,179 +46,211 @@ Module: SmartSql.Starter Author: Ahoo Wang DataSource: Name: DbTable - Paramters: - DbName: SmartSqlDB + Parameters: + DbName: SmartSqlTestDB DbProvider: SqlServer - ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True + ConnectionString: Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True Language: CSharp -TemplateEngine: Razor +TemplateEngine: + Name: Razor + Root: CSharp Output: Type: File - Path: 'E://SmartSql-Starter' + Path: 'E:\SmartSql-Starter' +Parameters: + SmartSqlVersion: '4.0.46' + SmartSqlSchemaVersion: '4.0.42' + BuildDir: 'E:\SmartSql-Starter\build' + DockerImage: 'smartsql.starter' + +NamingConverter: + Table: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'T_' + Delimiter: '_' + Converter: + Type: Pascal + Parameters: { } + View: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'V_' + Delimiter: '_' + Converter: + Type: Pascal + Column: + Tokenizer: + Type: Default + Parameters: + Delimiter: '_' + Converter: + Type: Pascal # 构建任务 Build: - ClearDir: - Type: Clear - Paramters: - Dirs: '.' +# ClearDir: +# Type: Clear +# Parameters: +# Dirs: '.' + + MakeBuildDir: + Type: Process + Parameters: + FileName: powershell + Args: mkdir '{{Project.Parameters.BuildDir}}' + Copy: + Type: Process + Parameters: + FileName: powershell + Args: cp '{{Project.ConfigPath}}' '{{Project.Parameters.BuildDir}}' Scaffolding: Type: MultiTemplate Output: Path: '.' - Paramters: + Parameters: Templates: [{Key: 'Sln.cshtml',Output: {Name: '{{Project.Module}}',Extension: '.sln'}}, - {Key: "Proj-Entity.cshtml",Output: {Path: '{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, - {Key: "Proj-Repository.cshtml",Output: {Path: '{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, - {Key: "Proj-Service.cshtml",Output: {Path: '{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, - {Key: "Proj-API.cshtml",Output: {Path: '{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, - {Key: "API/LaunchSettings.cshtml",Output: {Path: '{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, - {Key: "API/AppSettings.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, - {Key: "API/AppSettings-Development.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, - {Key: "API/Program.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, - {Key: "API/Startup.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, - {Key: "API/APIException.cshtml",Output: {Path: '{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, - {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, - {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, - {Key: "API/QueryRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, - {Key: "API/QueryByPageRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "API/QueryResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, - {Key: "API/QueryByPageResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "SqlMapConfig.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'SmartSqlMapConfig',Extension: '.xml'}} - ] + {Key: 'Sln-Directory.Build.cshtml',Output: {Name: 'Directory.Build',Extension: '.props'}}, + {Key: 'Sln-Version.cshtml',Output: {Path: 'build',Name: 'version',Extension: '.props'}}, + {Key: 'Sln-Dockerfile.cshtml',Output: {Name: 'Dockerfile',Extension: ''}}, + {Key: 'Sln-DockerIgnore.cshtml',Output: {Name: '.dockerignore',Extension: ''}}, + {Key: 'Sln-GitIgnore.cshtml',Output: {Name: '.gitignore',Extension: ''}}, + {Key: "Proj-Entity.cshtml",Output: {Path: 'src/{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, + {Key: "Proj-Repository.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, + {Key: "Proj-Service.cshtml",Output: {Path: 'src/{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, + {Key: "Proj-API.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, + {Key: "API/LaunchSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, + {Key: "API/AppSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, + {Key: "API/AppSettings-Development.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, + {Key: "API/Program.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, + {Key: "API/Startup.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, + {Key: "API/APIException.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, + {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, + {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, + {Key: "API/QueryRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, + {Key: "API/QueryByPageRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "API/QueryResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, + {Key: "API/QueryByPageResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig',Extension: '.xml'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig.Development',Extension: '.xml'}}] Entity: Type: Table Module: Entity - Template: Entity.cshtml + TemplateEngine: + Path: Entity.cshtml Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: '.cs' - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - Paramters: { } - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - Delimiter: '_' - Converter: - Type: Pascal Repository: Type: Table Module: Repository - Template: Repository.cshtml + TemplateEngine: + Path: Repository.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: 'I{{Items.CurrentTable.ConvertedName}}Repository' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal Service: Type: Table Module: Service - Template: Service.cshtml + TemplateEngine: + Path: Service.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}Service' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal APIController: Type: Table Module: API - Template: API/APIController.cshtml + TemplateEngine: + Path: API/APIController.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}/Controllers' + Path: 'src/{{Project.Module}}.{{Build.Module}}/Controllers' Name: '{{Items.CurrentTable.ConvertedName}}Controller' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal SqlMap: Type: Table - Template: SqlMap.cshtml + TemplateEngine: + Path: SqlMap.cshtml Output: - Path: '{{Project.Module}}.API/Maps' + Path: 'src/{{Project.Module}}.Repository/Maps' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: .xml IgnoreNoPKTable: true IgnoreView: true - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal + +# Please install dotnet-format first! +# dotnet tool install -g dotnet-format + CodeFormat: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet-format + + ReStore: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet restore + +# BuildDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker build -t {{Project.Parameters.DockerImage}}:v1.0.0 . + +# RunDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker run --name {{Project.Parameters.DockerImage}} --rm -d -p 8008:80 {{Project.Parameters.DockerImage}}:v1.0.0 . + +# Publish: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: dotnet publish -c Release -o '{{Project.Output.Path}}\publish' + +# Run: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}\publish' +# CreateNoWindow: false +# RedirectStandardOutput: false +# RedirectStandardError: false +# WaitForExit: false +# WriteLines: ['dotnet {{Project.Module}}.API.dll'] + +# RunChrome: +# Type: Process +# Parameters: +# FileName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +# CreateNoWindow: false +# Args: http://localhost:8008/swagger ``` ### Build file parameter overview @@ -227,11 +265,11 @@ Build: | Output | Output | | Build | Task Build | -#### DataSource Data Source, Name: Db +#### DataSource Data Source, Name: DbTable -> Property Name: Db, using the DbSource plugin as a data source +> Property Name: DbTable, using the DbTableSource plugin as a data source -DbSource.Paramters accepts the following three parameters: +DbTableSource.Parameters accepts the following three parameters: | Parameter Name | Description | | :--------- | --------:| @@ -253,7 +291,7 @@ DbSource.Paramters accepts the following three parameters: | IncludeTables | Include table name s | | IgnoreTables | Ignore table name s | | NamingConverter | Named Converter | -| Paramters | Custom Build Parameters | +| Parameters | Custom Build Parameters | #### NamingConverter Name Conversion @@ -268,9 +306,9 @@ DbSource.Paramters accepts the following three parameters: | Attribute | Description | | :--------- | --------:| | Type | Default | -| Paramters.IgnorePrefix | Ignore prefix characters | -| Paramters.Delimiter | Separator | -| Paramters.UppercaseSplit | Using uppercase separation, default: true | +| Parameters.IgnorePrefix | Ignore prefix characters | +| Parameters.Delimiter | Separator | +| Parameters.UppercaseSplit | Using uppercase separation, default: true | ### How to contribute a template @@ -289,13 +327,13 @@ DbSource.Paramters accepts the following three parameters: Author: Ahoo Wang DataSource: Name: Extract - Paramters: + Parameters: DbProvider: SqlServer ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True Query: SELECT [Id],[UserName],[Pwd],[Status],[LastLoginTime],[CreationTime],[Deleted] FROM [T_User] Where Id>@LastMaxId And CreationTime>@LastQueryTime PKColumn: Id -Paramters: +Parameters: ETLCode: SmartCode.ETL.Test ETLRepository: PG @@ -303,12 +341,12 @@ Build: Transform: Type: Transform - Paramters: + Parameters: Script: Load2PostgreSql.cshtml Load2PostgreSql: Type: Load - Paramters: + Parameters: DbProvider: PostgreSql ConnectionString: Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartsql_db; Table: t_user diff --git a/README.md b/README.md index 2b57cad..01b8440 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ ![SmartCode](./doc/SmartCode.png) +## Nuget Packages + +| Package | NuGet Stable | Downloads | +| ------- | -------- | ------- | +| [SmartCode.CLI](https://www.nuget.org/packages/SmartCode.CLI/) | [![SmartCode.CLI](https://img.shields.io/nuget/v/SmartCode.CLI.svg)](https://www.nuget.org/packages/SmartCode.CLI/) | [![SmartCode.CLI](https://img.shields.io/nuget/dt/SmartCode.CLI.svg)](https://www.nuget.org/packages/SmartCode.CLI/) | + ## SmartCode.Generator (代码生成器) ### Demo @@ -18,7 +24,7 @@ ### Getting Started -1. Install from .NET Core Global Tool +1. Install from .NET Core Global Tool ``` shell dotnet tool install --global SmartCode.CLI @@ -40,179 +46,211 @@ Module: SmartSql.Starter Author: Ahoo Wang DataSource: Name: DbTable - Paramters: - DbName: SmartSqlDB + Parameters: + DbName: SmartSqlTestDB DbProvider: SqlServer - ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True + ConnectionString: Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True Language: CSharp -TemplateEngine: Razor +TemplateEngine: + Name: Razor + Root: CSharp Output: Type: File - Path: 'E://SmartSql-Starter' + Path: 'E:\SmartSql-Starter' +Parameters: + SmartSqlVersion: '4.0.46' + SmartSqlSchemaVersion: '4.0.42' + BuildDir: 'E:\SmartSql-Starter\build' + DockerImage: 'smartsql.starter' + +NamingConverter: + Table: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'T_' + Delimiter: '_' + Converter: + Type: Pascal + Parameters: { } + View: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'V_' + Delimiter: '_' + Converter: + Type: Pascal + Column: + Tokenizer: + Type: Default + Parameters: + Delimiter: '_' + Converter: + Type: Pascal # 构建任务 Build: - ClearDir: - Type: Clear - Paramters: - Dirs: '.' +# ClearDir: +# Type: Clear +# Parameters: +# Dirs: '.' + + MakeBuildDir: + Type: Process + Parameters: + FileName: powershell + Args: mkdir '{{Project.Parameters.BuildDir}}' + Copy: + Type: Process + Parameters: + FileName: powershell + Args: cp '{{Project.ConfigPath}}' '{{Project.Parameters.BuildDir}}' Scaffolding: Type: MultiTemplate Output: Path: '.' - Paramters: + Parameters: Templates: [{Key: 'Sln.cshtml',Output: {Name: '{{Project.Module}}',Extension: '.sln'}}, - {Key: "Proj-Entity.cshtml",Output: {Path: '{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, - {Key: "Proj-Repository.cshtml",Output: {Path: '{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, - {Key: "Proj-Service.cshtml",Output: {Path: '{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, - {Key: "Proj-API.cshtml",Output: {Path: '{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, - {Key: "API/LaunchSettings.cshtml",Output: {Path: '{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, - {Key: "API/AppSettings.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, - {Key: "API/AppSettings-Development.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, - {Key: "API/Program.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, - {Key: "API/Startup.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, - {Key: "API/APIException.cshtml",Output: {Path: '{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, - {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, - {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, - {Key: "API/QueryRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, - {Key: "API/QueryByPageRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "API/QueryResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, - {Key: "API/QueryByPageResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "SqlMapConfig.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'SmartSqlMapConfig',Extension: '.xml'}} - ] + {Key: 'Sln-Directory.Build.cshtml',Output: {Name: 'Directory.Build',Extension: '.props'}}, + {Key: 'Sln-Version.cshtml',Output: {Path: 'build',Name: 'version',Extension: '.props'}}, + {Key: 'Sln-Dockerfile.cshtml',Output: {Name: 'Dockerfile',Extension: ''}}, + {Key: 'Sln-DockerIgnore.cshtml',Output: {Name: '.dockerignore',Extension: ''}}, + {Key: 'Sln-GitIgnore.cshtml',Output: {Name: '.gitignore',Extension: ''}}, + {Key: "Proj-Entity.cshtml",Output: {Path: 'src/{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, + {Key: "Proj-Repository.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, + {Key: "Proj-Service.cshtml",Output: {Path: 'src/{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, + {Key: "Proj-API.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, + {Key: "API/LaunchSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, + {Key: "API/AppSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, + {Key: "API/AppSettings-Development.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, + {Key: "API/Program.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, + {Key: "API/Startup.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, + {Key: "API/APIException.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, + {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, + {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, + {Key: "API/QueryRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, + {Key: "API/QueryByPageRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "API/QueryResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, + {Key: "API/QueryByPageResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig',Extension: '.xml'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig.Development',Extension: '.xml'}}] Entity: Type: Table Module: Entity - Template: Entity.cshtml + TemplateEngine: + Path: Entity.cshtml Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: '.cs' - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - Paramters: { } - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - Delimiter: '_' - Converter: - Type: Pascal Repository: Type: Table Module: Repository - Template: Repository.cshtml + TemplateEngine: + Path: Repository.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: 'I{{Items.CurrentTable.ConvertedName}}Repository' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal Service: Type: Table Module: Service - Template: Service.cshtml + TemplateEngine: + Path: Service.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}Service' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal APIController: Type: Table Module: API - Template: API/APIController.cshtml + TemplateEngine: + Path: API/APIController.cshtml IgnoreNoPKTable: true IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}/Controllers' + Path: 'src/{{Project.Module}}.{{Build.Module}}/Controllers' Name: '{{Items.CurrentTable.ConvertedName}}Controller' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal SqlMap: Type: Table - Template: SqlMap.cshtml + TemplateEngine: + Path: SqlMap.cshtml Output: - Path: '{{Project.Module}}.API/Maps' + Path: 'src/{{Project.Module}}.Repository/Maps' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: .xml IgnoreNoPKTable: true IgnoreView: true - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal + +# Please install dotnet-format first! +# dotnet tool install -g dotnet-format + CodeFormat: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet-format + + ReStore: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet restore + +# BuildDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker build -t {{Project.Parameters.DockerImage}}:v1.0.0 . + +# RunDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker run --name {{Project.Parameters.DockerImage}} --rm -d -p 8008:80 {{Project.Parameters.DockerImage}}:v1.0.0 . + +# Publish: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: dotnet publish -c Release -o '{{Project.Output.Path}}\publish' + +# Run: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}\publish' +# CreateNoWindow: false +# RedirectStandardOutput: false +# RedirectStandardError: false +# WaitForExit: false +# WriteLines: ['dotnet {{Project.Module}}.API.dll'] + +# RunChrome: +# Type: Process +# Parameters: +# FileName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +# CreateNoWindow: false +# Args: http://localhost:8008/swagger ``` ### 构建文件参数概览 @@ -227,11 +265,11 @@ Build: | Output | 输出 | | Build | 任务构建s | -#### DataSource 数据源,Name:Db +#### DataSource 数据源,Name:DbTable -> 属性 Name:Db,使用DbSource插件作为数据源 +> 属性 Name:DbTable,使用 DbTableSource 插件作为数据源 -DbSource.Paramters 接受以下三个参数: +DbTableSource.Parameters 接受以下三个参数: | 参数名 | 说明 | | :--------- | --------:| @@ -263,7 +301,7 @@ DbSource.Paramters 接受以下三个参数: | IncludeTables | 包括表名s | | IgnoreTables | 忽略表名s | | NamingConverter | 命名转换器 | -| Paramters | 自定义构建参数 | +| Parameters | 自定义构建参数 | #### NamingConverter 命名转换 @@ -278,15 +316,15 @@ DbSource.Paramters 接受以下三个参数: | 属性 | 说明 | | :--------- | --------:| | Type | Default | -| Paramters.IgnorePrefix | 忽略前缀字符 | -| Paramters.Delimiter | 分隔符 | -| Paramters.UppercaseSplit | 使用大写分隔,默认:true | +| Parameters.IgnorePrefix | 忽略前缀字符 | +| Parameters.Delimiter | 分隔符 | +| Parameters.UppercaseSplit | 使用大写分隔,默认:true | ### 如何贡献模板 >为了让更多人参与到SmartCode模板建设中来,故有以下模板规范: -1. 模板作者在 src/SmartCode.Generator/RazorTemplates 中新建目录,并以作者英文名为目录名称 +1. 模板作者在 src/SmartCode.Generator/RazorTemplates/Contributions 中新建目录,并以作者英文名为目录名称 2. 把模板放置到作者目录 3. 作者目录下必须包括 README.md 文件,以说明模板的用途场景以及使用方式 4. 提交PR @@ -299,13 +337,13 @@ DbSource.Paramters 接受以下三个参数: Author: Ahoo Wang DataSource: Name: Extract - Paramters: + Parameters: DbProvider: SqlServer ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True Query: SELECT [Id],[UserName],[Pwd],[Status],[LastLoginTime],[CreationTime],[Deleted] FROM [T_User] Where Id>@LastMaxId And CreationTime>@LastQueryTime PKColumn: Id -Paramters: +Parameters: ETLCode: SmartCode.ETL.Test ETLRepository: PG @@ -313,12 +351,12 @@ Build: Transform: Type: Transform - Paramters: + Parameters: Script: Load2PostgreSql.cshtml Load2PostgreSql: Type: Load - Paramters: + Parameters: DbProvider: PostgreSql ConnectionString: Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartsql_db; Table: t_user diff --git a/SmartCode.sln b/SmartCode.sln index c5ffd19..cacd50e 100644 --- a/SmartCode.sln +++ b/SmartCode.sln @@ -27,6 +27,35 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmartCode.ETL.PostgreSql", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmartCode.ETL.SQLite", "src\SmartCode.ETL.SQLite\SmartCode.ETL.SQLite.csproj", "{BB00F470-7D25-4F82-A410-1DB8BD458A5E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmartCode.ETL.LoadToES", "src\SmartCode.ETL.LoadToES\SmartCode.ETL.LoadToES.csproj", "{DADD6996-91C4-496D-AE97-D8EA5E33716A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{B0F696A9-339D-4348-9032-F8DFC775ABD4}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + build\version.props = build\version.props + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{55E0A4D0-F749-4C33-837C-30F881AA293F}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + LICENSE = LICENSE + README-EN.md = README-EN.md + README.md = README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{B3766EC2-4AD1-4610-B141-5C8D267BF70A}" + ProjectSection(SolutionItems) = preProject + doc\common-problem.md = doc\common-problem.md + doc\SmartCode-ETL-ES.yml = doc\SmartCode-ETL-ES.yml + doc\SmartCode-ETL.yml = doc\SmartCode-ETL.yml + doc\SmartCode-Gen-ETL.yml = doc\SmartCode-Gen-ETL.yml + doc\SmartCode-Spring-Boot.yml = doc\SmartCode-Spring-Boot.yml + doc\SmartCode.ETL-EN.md = doc\SmartCode.ETL-EN.md + doc\SmartCode.ETL.md = doc\SmartCode.ETL.md + doc\SmartCode.json = doc\SmartCode.json + doc\SmartCode.yml = doc\SmartCode.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +102,10 @@ Global {BB00F470-7D25-4F82-A410-1DB8BD458A5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {BB00F470-7D25-4F82-A410-1DB8BD458A5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {BB00F470-7D25-4F82-A410-1DB8BD458A5E}.Release|Any CPU.Build.0 = Release|Any CPU + {DADD6996-91C4-496D-AE97-D8EA5E33716A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DADD6996-91C4-496D-AE97-D8EA5E33716A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DADD6996-91C4-496D-AE97-D8EA5E33716A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DADD6996-91C4-496D-AE97-D8EA5E33716A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -82,6 +115,8 @@ Global {95071030-0C10-4771-B093-4F2626A39F9F} = {EE2194B6-5B23-42C0-AF6A-EC86331E3E08} {60B49703-2352-477B-8F18-98CC229EEFDA} = {EE2194B6-5B23-42C0-AF6A-EC86331E3E08} {BB00F470-7D25-4F82-A410-1DB8BD458A5E} = {EE2194B6-5B23-42C0-AF6A-EC86331E3E08} + {DADD6996-91C4-496D-AE97-D8EA5E33716A} = {EE2194B6-5B23-42C0-AF6A-EC86331E3E08} + {B3766EC2-4AD1-4610-B141-5C8D267BF70A} = {55E0A4D0-F749-4C33-837C-30F881AA293F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9A45CDB0-E532-4F55-84C6-B82C98BE5F38} diff --git a/build/version.props b/build/version.props new file mode 100644 index 0000000..8013612 --- /dev/null +++ b/build/version.props @@ -0,0 +1,8 @@ + + + 2 + 4 + 0-preview.1 + $(VersionMajor).$(VersionMinor).$(VersionPatch) + + diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 0000000..c299d64 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,45 @@ +# MEMBER CODE OF CONDUCT + +The .NET Core Community (NCC) was created to doster an open, innovative, inclusive and welcoming community around open source .NET/.NET Core. To clarify expected behaviour in our communities we have adopted the [Contributor Covenant](contributor-covenant.org). This code of conduct has been adopted by [many other open source communities](contributor-covenant.org/adopters) and we feel it expresses our values well. + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [dotnet-community@outlook.com](dotnet-community@outlook.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership. + +### Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/code-of-conduct.zh-CN.md b/code-of-conduct.zh-CN.md new file mode 100644 index 0000000..2cdfc4a --- /dev/null +++ b/code-of-conduct.zh-CN.md @@ -0,0 +1,51 @@ +# 组织成员行为准则 + +.NET Core Community (NCC) 旨在建立一个围绕开源 .NET/.NET Core 的开放、创新、包容和热情的社区。为向大家表明我们社区的预期行动,我们编写了贡献者公约。许多其他开源社区已采用此行为准则,我们认为它很好地表达了我们的价值观。 + +### 我们的承诺 + +为建设开放友好的环境,我们贡献者和维护者承诺:不论年龄、体型、身体健全与否、民族、性征、性别认同与表征、经验水平、教育程度、社会地位、国籍、相貌、种族、信仰、性取向,我们项目和社区的参与者皆免于骚扰。 + +### 我们的准则 + +有助于创造积极环境的行为包括但不限于: + +- 措辞友好且包容 +- 尊重不同的观点和经验 +- 耐心接受有益批评 +- 关注对社区最有利的事情 +- 与社区其他成员友善相处 + +参与者不应采取的行为包括但不限于: + +- 发布与性有关的言论或图像、不受欢迎地献殷勤 +- 捣乱/煽动/造谣行为、侮辱/贬损的评论、人身及政治攻击 +- 公开或私下骚扰 +- 未经明确授权便发布他人的资料,如住址、电子邮箱等 +- 其他有理由认定为违反职业操守的不当行为 + +### 我们的义务 + +项目维护者有义务诠释何谓“妥当行为”,并妥善公正地纠正已发生的不当行为。 + +项目维护者有权利和义务去删除、编辑、拒绝违背本行为标准的评论(comments)、提交(commits)、代码、wiki 编辑、问题(issues)等贡献;项目维护者可暂时或永久地封禁任何他们认为行为不当、威胁、冒犯、有害的参与者。 + +### 适用范围 + +本行为标准适用于本项目。当有人代表本项目或本社区时,本标准亦适用于此人所处的公共平台。 + +代表本项目或本社区的情形包括但不限于:使用项目的官方电子邮件、通过官方媒体账号发布消息、作为指定代表参与在线或线下活动等。 + +代表本项目的行为可由项目维护者进一步定义及解释。 + +### 贯彻落实 + +可以致信 [dotnet-community@outlook.com](dotnet-community@outlook.com),向项目团队举报滥用、骚扰及不当行为。 + +维护团队将审议并调查全部投诉,妥善地予以必要的回应。项目团队有义务保密举报者信息。具体执行方针或将另行发布。 + +未切实遵守或执行本行为标准的项目维护人员,经项目负责人或其他成员决议,可能被暂时或永久地剥夺参与本项目的资格。 + +### 来源 + +本行为标准改编自参与者公约,版本 1.4 可在此查阅:https://www.contributor-covenant.org/zh-cn/version/1/4/code-of-conduct.html diff --git a/doc/SmartCode-ETL-ES.yml b/doc/SmartCode-ETL-ES.yml new file mode 100644 index 0000000..30f26d6 --- /dev/null +++ b/doc/SmartCode-ETL-ES.yml @@ -0,0 +1,31 @@ +Author: Ahoo Wang +DataSource: + Name: Extract + Parameters: + DbProvider: PostgreSql + ConnectionString: 'Server=localhost;Port=5432;User Id=report;Password=SmartCode; Database=report;' + Query: select * from es_sync_product where max_motify_time>@LastMaxModifyTime + PKColumn: id + AutoIncrement: true + ModifyTime: max_motify_time + +Parameters: + ETLCode: SmartCode.ETL.LoadToES + ETLRepository: SQLite + +Build: + + Transform: + Type: Transform + Parameters: + Script: + + LoadToES: + Type: LoadToES + Parameters: + Host: http://es.smartsql.net/ + Index: smartsql + Type: product + BaseAuth: + UserName: smartsql + Password: https://github.com/Ahoo-Wang/SmartCode \ No newline at end of file diff --git a/doc/SmartCode-ETL.yml b/doc/SmartCode-ETL.yml index d9ac2ce..2ce3671 100644 --- a/doc/SmartCode-ETL.yml +++ b/doc/SmartCode-ETL.yml @@ -1,38 +1,37 @@ Author: Ahoo Wang +Mode: ETL + DataSource: Name: Extract - Paramters: + Parameters: DbProvider: SqlServer - ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True - Query: SELECT [Id],[UserName],[Pwd],[Status],[LastLoginTime],[CreationTime],[Deleted] FROM [T_User] Where Id>@LastMaxId And CreationTime>@LastQueryTime + ConnectionString: Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True + Query: "SELECT * FROM [T_ModifyTime] Where ModifyTime>@LastMaxModifyTime" + Order By Id Desc Offset @Offset Rows Fetch Next @BulkSize Rows Only;" + Total: Select Count(*) From T_ModifyTime Where ModifyTime>@LastMaxModifyTime + BulkSize: 1000 PKColumn: Id AutoIncrement: true - ModifyTime: CreationTime + ModifyTime: ModifyTime -Paramters: +Parameters: ETLCode: SmartCode.ETL.Test ETLRepository: SQLite - + Build: Transform: Type: Transform - Paramters: - Script: + Parameters: + Script: - Load2PostgreSql: + Load2PostgreSql: Type: Load - Paramters: - DbProvider: PostgreSql - ConnectionString: Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartsql_db; - Table: t_user - ColumnMapping: [{Column: Id,Mapping: id} - ,{Column: UserName,Mapping: user_name} - ,{Column: Pwd,Mapping: pwd} - ,{Column: Status,Mapping: status} - ,{Column: LastLoginTime,Mapping: lastlogintime} - ,{Column: CreationTime,Mapping: creationtime} - ,{Column: Deleted,Mapping: deleted}] - PreCommand: + Parameters: + DbProvider: SqlServer + ConnectionString: Data Source=.;Initial Catalog=DestinationDB;Integrated Security=True + Table: T_ModifyTime + ColumnMapping: [{Column: Id,Mapping: Id},{Column: ModifyTime,Mapping: ModifyTime}] + PreCommand: PostCommand: \ No newline at end of file diff --git a/doc/SmartCode-Gen-ETL.yml b/doc/SmartCode-Gen-ETL.yml index 4cd8fa7..d6cbe45 100644 --- a/doc/SmartCode-Gen-ETL.yml +++ b/doc/SmartCode-Gen-ETL.yml @@ -3,14 +3,16 @@ Module: SqlServer2PG Author: Ahoo Wang DataSource: Name: DbTable - Paramters: + Parameters: DbName: SqlServerDB DbProvider: SqlServer ConnectionString: Data Source=localhost;database=SqlServerDB;uid=SmartSql;pwd=SmartSql Language: PostgreSql -TemplateEngine: Razor -Paramters: - ExtractMode: QueryTime +TemplateEngine: + Name: Razor + Root: . +Parameters: + ExtractMode: LastMaxModifyTime ModifyTime: ModifyTime ExtractConnectionString: Data Source=localhost;database=SqlServerDB;uid=SmartSql;pwd=SmartSql LoadDbProvider: PostgreSql @@ -24,13 +26,14 @@ Build: ClearDir: Type: Clear - Paramters: + Parameters: Dirs: '.' # 生成迁移SQL DbToPGSql: Type: Single Module: SmartCode - Template: Sql/DbToPGSql.cshtml + TemplateEngine: + Path: Sql/DbToPGSql.cshtml IgnoreNoPKTable: true Output: Path: '.' @@ -40,13 +43,13 @@ Build: Table: Tokenizer: Type: Default - Paramters: + Parameters: IgnorePrefix: 'T_' Delimiter: '_' UppercaseSplit: true Converter: Type: Delimiter - Paramters: + Parameters: Delimiter: '_' Mode: AllLower Prefix: smartcode_ @@ -54,19 +57,20 @@ Build: Column: Tokenizer: Type: Default - Paramters: + Parameters: Delimiter: '_' UppercaseSplit: true Converter: Type: Delimiter - Paramters: + Parameters: Delimiter: '_' Mode: AllLower # 生成 SmartCode.ETL 数据迁移构建配置 ToPGBuild: Type: Table Module: SmartCode - Template: ETL/ToPGBuild.cshtml + TemplateEngine: + Path: ETL/ToPGBuild.cshtml IgnoreNoPKTable: true Output: Path: '.' @@ -76,24 +80,24 @@ Build: Table: Tokenizer: Type: Default - Paramters: + Parameters: IgnorePrefix: 'T_' Delimiter: '_' UppercaseSplit: true Converter: Type: Delimiter - Paramters: + Parameters: Delimiter: '_' Mode: AllLower Prefix: smartcode_ Column: Tokenizer: Type: Default - Paramters: + Parameters: Delimiter: '_' UppercaseSplit: true Converter: Type: Delimiter - Paramters: + Parameters: Delimiter: '_' Mode: AllLower \ No newline at end of file diff --git a/doc/SmartCode-Spring-Boot.yml b/doc/SmartCode-Spring-Boot.yml index c170347..73c2b52 100644 --- a/doc/SmartCode-Spring-Boot.yml +++ b/doc/SmartCode-Spring-Boot.yml @@ -1,59 +1,171 @@ -Module: smartcode.starter +Module: net.smartsql.demo Author: Ahoo Wang DataSource: Name: DbTable - Paramters: - DbName: SmartSqlDB - DbProvider: SqlServer - ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True + Parameters: + DbName: smartsql_db + DbProvider: MySql + ConnectionString: Data Source=serverAddress;database=smartsql_db;uid=root;pwd=smartsql.net;Charset=utf8;SslMode=none Language: Java -TemplateEngine: - Name: Razor - Root: Java -Output: +TemplateEngine: + Name: Razor + Root: Java +Output: Type: File - Path: 'E://SmartSql-Java' + Path: 'D://SmartSql-Java' +Parameters: + BuildDir: 'D:\SmartSql-Java\build' + ApplicationName: Demo +NamingConverter: + Table: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 't_' + Delimiter: '_' + Converter: + Type: Pascal + Parameters: { } + View: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'v_' + Delimiter: '_' + Converter: + Type: Pascal + Column: + Tokenizer: + Type: Default + Parameters: + Delimiter: '_' + Converter: + Type: Camel + +TableFilter: + IgnoreNoPKTable: true + IgnoreView: true # 构建任务 Build: - ClearDir: - Type: Clear - Paramters: - Dirs: '.' +# ClearDir: +# Type: Clear +# Parameters: +# Dirs: '.' + + MakeBuildDir: + Type: Process + Parameters: + FileName: powershell + Args: mkdir '{{Project.Parameters.BuildDir}}' + Copy: + Type: Process + Parameters: + FileName: powershell + Args: cp '{{Project.ConfigPath}}' '{{Project.Parameters.BuildDir}}' + Scaffolding: + Type: MultiTemplate + Output: + Path: '.' + Parameters: + Templates: [ + {Key: 'Pom-Parent.cshtml',Output: {Name: 'pom',Extension: '.xml'}}, + {Key: 'Pom-Api.cshtml',Output: {Path: "api",Name: 'pom',Extension: '.xml'}}, + {Key: 'Pom-Server.cshtml',Output: {Path: "server",Name: 'pom',Extension: '.xml'}}, + {Key: 'Resources/Application-YAML.cshtml',Output: {Path: "server/src/main/resources",Name: 'application',Extension: '.yml'}}, + {Key: 'Application.cshtml',Output: + { + Path: "server/src/main/java/{{Project.Module}}/server/", + DotSplit: true, + Name: '{{Project.Parameters.ApplicationName}}Application', + Extension: '.java' + } + }, + {Key: 'Test/Application-Test.cshtml',Output: + { + Path: "server/src/test/java/{{Project.Module}}/server/", + DotSplit: true, + Name: '{{Project.Parameters.ApplicationName}}ApplicationTests', + Extension: '.java' + } + }, + {Key: 'AppConfig.cshtml',Output: + { + Path: "server/src/main/java/{{Project.Module}}/server/config", + DotSplit: true, + Name: 'AppConfig', + Extension: '.java' + } + } + ] Entity: Type: Table - Module: entity - TemplateEngine: + Module: server.entity + TemplateEngine: Path: Entity.cshtml - Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Output: + Path: 'server/src/main/java/{{Project.Module}}.{{Build.Module}}' + DotSplit: true Name: '{{Items.CurrentTable.ConvertedName}}' Extension: '.java' - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - Paramters: { } - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - Delimiter: '_' - Converter: - Type: Camel \ No newline at end of file + Parameters: + AbstractEntity: + Name: AbstractEntity + Package: net.smartsql.entity + Properties: + - id + - createTime + - modifiedTime + - deleted + + SqlMap: + Type: Table + Module: server.repository + TemplateEngine: + Path: SqlMap.cshtml + Output: + Path: 'server/src/main/resources/mappers/' + DotSplit: true + Name: '{{Items.CurrentTable.ConvertedName}}Mapper' + Extension: '.xml' + Parameters: + LogicalDelete: deleted + + Repository: + Type: Table + Module: server.repository + TemplateEngine: + Path: Repository.cshtml + Output: + Path: 'server/src/main/java/{{Project.Module}}.{{Build.Module}}' + DotSplit: true + Name: '{{Items.CurrentTable.ConvertedName}}Repository' + Extension: '.java' + Parameters: + GenericRepository: + Package: net.smartsql.repository + + Service: + Type: Table + Module: server.service + TemplateEngine: + Path: Service.cshtml + Output: + Path: 'server/src/main/java/{{Project.Module}}.{{Build.Module}}' + DotSplit: true + Name: '{{Items.CurrentTable.ConvertedName}}Service' + Extension: '.java' + + Controller: + Type: Table + Module: server.controller + TemplateEngine: + Path: Controller.cshtml + Output: + Path: 'server/src/main/java/{{Project.Module}}.{{Build.Module}}' + DotSplit: true + Name: '{{Items.CurrentTable.ConvertedName}}Controller' + Extension: '.java' \ No newline at end of file diff --git a/doc/SmartCode-TypeScript.yml b/doc/SmartCode-TypeScript.yml new file mode 100644 index 0000000..3a3e3d8 --- /dev/null +++ b/doc/SmartCode-TypeScript.yml @@ -0,0 +1,66 @@ +Author: Beginor +Module: NetCoreApp +DataSource: + Name: DbTable + Parameters: + DbName: net_core_app + DbProvider: PostgreSql + ConnectionString: server=127.0.0.1;database=net_core_app;user id=postgres;password=NO_PASSWORD; + DbSchema: public +Language: TypeScript +TemplateEngine: + Name: Razor + Root: TypeScript +Output: + Type: File + Mode: Full # Incre 增量创建,如果存在则忽略; Full 全量创建,如果存在则重新创建 + Path: /tmp/test +NamingConverter: + Table: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'T_' + Delimiter: '_' + Converter: + Type: Pascal + Parameters: { } + View: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'V_' + Delimiter: '_' + Converter: + Type: Pascal + Column: + Tokenizer: + Type: Default + Parameters: + Delimiter: '_' + Converter: + Type: Camel +TableFilter: + IgnoreTables: + # - app_roles + # - app_users + - aspnet_role_claims + - aspnet_roles + - aspnet_user_claims + - aspnet_user_logins + - aspnet_user_roles + - aspnet_user_tokens + # - aspnet_users + IgnoreNoPKTable: true + IgnoreView: true + +Build: + Entities: + Type: Table + Module: Data + TemplateEngine: + Path: Model.cshtml + Output: + Path: '{{Items.CurrentTable.Name}}/services' + Name: '{{Items.CurrentTable.Name}}' + Extension: '.ts' diff --git a/doc/SmartCode.ETL-EN.md b/doc/SmartCode.ETL-EN.md index f139588..587751a 100644 --- a/doc/SmartCode.ETL-EN.md +++ b/doc/SmartCode.ETL-EN.md @@ -117,7 +117,7 @@ I believe that many students who have already landed the microservices architect { "Type": "SmartCode.ETL.IETLRepository,SmartCode.ETL", "ImplType": "SmartCode.ETL.PostgreSql.PGETLRepository,SmartCode.ETL.PostgreSql", - "Paramters": { + "Parameters": { "ConnectionString": "Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartcode_etl;" } } @@ -133,24 +133,24 @@ I believe that many students who have already landed the microservices architect Author: Ahoo Wang DataSource: Name: Extract - Paramters: + Parameters: DbProvider: SqlServer ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True Query: SELECT [Id],[UserName],[Status],[LastLoginTime],[CreationTime],[ModifyTime],[Deleted] FROM [T_User] With(NoLock) Where ModifyTime>@LastMaxModifyTime PKColumn: Id AutoIncrement: true ModifyTime: ModifyTime -Paramters: +Parameters: ETLCode: SmartCode.ETL.Test ETLRepository: PG Build: Transform: Type: Transform - Paramters: + Parameters: Script: Load2PostgreSql: Type: Load - Paramters: + Parameters: DbProvider: PostgreSql ConnectionString: Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartsql_db; Table: t_user__temp @@ -168,7 +168,7 @@ Build: ,{Column: Deleted,Mapping: deleted}] ``` -### Root Paramters +### Root Parameters | Parameter Name | Description | | :------------ | -----------------------------: | @@ -179,7 +179,7 @@ Build: > Attribute Name:Extract, using the ExtractDataSource plugin as a data source -#### ExtractDataSource.Paramters +#### ExtractDataSource.Parameters | Parameter Name | Description | | :--------------- | -------------------------------- | @@ -194,7 +194,7 @@ AutoIncrement | Whether to auto-increment the primary key, true automatically ca > Attribute Type:Load, using the LoadBuildTask plugin as a build task -#### Build.Load.Paramters +#### Build.Load.Parameters | Parameter Name | Description | | :--------------- | -------------------------------- | @@ -247,7 +247,7 @@ The following is the data extraction performance, the number of extraction is 14 "QueryCommand": { "Taken": 41267, "Command": "Select * From T_ProductSearchLog With(NoLock) Where Id>@LastMaxId", - "Paramters": { + "Parameters": { "LastMaxId": -1, "LastQueryTime": "1970-01-01T08:00:00" } diff --git a/doc/SmartCode.ETL.md b/doc/SmartCode.ETL.md index 04b3e6d..22475c5 100644 --- a/doc/SmartCode.ETL.md +++ b/doc/SmartCode.ETL.md @@ -117,7 +117,7 @@ { "Type": "SmartCode.ETL.IETLRepository,SmartCode.ETL", "ImplType": "SmartCode.ETL.PostgreSql.PGETLRepository,SmartCode.ETL.PostgreSql", - "Paramters": { + "Parameters": { "ConnectionString": "Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartcode_etl;" } } @@ -133,24 +133,24 @@ Author: Ahoo Wang DataSource: Name: Extract - Paramters: + Parameters: DbProvider: SqlServer ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True Query: SELECT [Id],[UserName],[Status],[LastLoginTime],[CreationTime],[ModifyTime],[Deleted] FROM [T_User] With(NoLock) Where ModifyTime>@LastMaxModifyTime PKColumn: Id AutoIncrement: true ModifyTime: ModifyTime -Paramters: +Parameters: ETLCode: SmartCode.ETL.Test ETLRepository: PG Build: Transform: Type: Transform - Paramters: + Parameters: Script: Load2PostgreSql: Type: Load - Paramters: + Parameters: DbProvider: PostgreSql ConnectionString: Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartsql_db; Table: t_user__temp @@ -168,7 +168,7 @@ Build: ,{Column: Deleted,Mapping: deleted}] ``` -### 根 Paramters +### 根 Parameters | 参数名 | 说明 | | :------------ | -----------------------------: | @@ -179,7 +179,7 @@ Build: > 属性 Name:Extract,使用 ExtractDataSource 插件作为数据源 -#### ExtractDataSource.Paramters +#### ExtractDataSource.Parameters | 参数名 | 说明 | | :--------------- | ------------------------------------------------------------------------------------------------------: | @@ -194,7 +194,7 @@ Build: > 属性 Type:Load,使用 LoadBuildTask 插件作为构建任务 -#### Build.Load.Paramters +#### Build.Load.Parameters | 参数名 | 说明 | | :--------------- | --------------------------------------------------------------: | @@ -247,7 +247,7 @@ LastMaxModifyTime 即上一次抽取的数据最大ModifyTime值(第一次抽取 "QueryCommand": { "Taken": 41267, "Command": "Select * From T_ProductSearchLog With(NoLock) Where Id>@LastMaxId", - "Paramters": { + "Parameters": { "LastMaxId": -1, "LastQueryTime": "1970-01-01T08:00:00", "LastMaxModifyTime": "1970-01-01T08:00:00" diff --git a/doc/SmartCode.json b/doc/SmartCode.json index 217b9bb..b4d00a6 100644 --- a/doc/SmartCode.json +++ b/doc/SmartCode.json @@ -1,420 +1,800 @@ { - "Module": "SmartSql.Starter", - "Author": "Ahoo Wang", - "DataSource": { - "Name": "Db", - "Paramters": { - "DbName": "SmartSqlStarterDB", - "DbProvider": "SqlServer", - "ConnectionString": "Data Source=.;Initial Catalog=SmartSqlStarterDB;Integrated Security=True" + "ConfigPath": null, + "Module": "SmartSql.Starter", + "Author": "Ahoo Wang", + "DataSource": { + "Name": "DbTable", + "Parameters": { + "DbName": "SmartSqlTestDB", + "DbProvider": "SqlServer", + "ConnectionString": "Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True" + } + }, + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp" + }, + "Language": "CSharp", + "Output": { + "Type": "File", + "Path": "E:\\SmartSql-Starter" + }, + "Parameters": { + "SmartSqlVersion": "4.0.86", + "SmartSqlSchemaVersion": "4.0.82", + "BuildDir": "E:\\SmartSql-Starter\\build", + "DockerImage": "smartsql.starter" + }, + "BuildTasks": { + "MakeBuildDir": { + "Type": "Process", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp" + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } } + }, + "Parameters": { + "FileName": "powershell", + "Args": "mkdir '{{Project.Parameters.BuildDir}}'" + } }, - "TemplateEngine": "Razor", - "Language": "CSharp", - "Output": { - "Type": "File", - "Path": "E://SmartSql-Starter", - "Name": null, - "Extension": null + "Copy": { + "Type": "Process", + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + }, + "Parameters": { + "FileName": "powershell", + "Args": "cp '{{Project.ConfigPath}}' '{{Project.Parameters.BuildDir}}'" + } }, - "Paramters": null, - "BuildTasks": { - "ClearDir": { - "Type": "Clear", - "Module": null, - "TemplateEngine": "Razor", - "Template": null, - "Output": null, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": { - "Dirs": "." + "Scaffolding": { + "Type": "MultiTemplate", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp" + }, + "Output": { + "Type": "File", + "Path": "." + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } }, - "Solution": { - "Type": "Project", - "Module": null, - "TemplateEngine": "Razor", - "Template": "Sln.cshtml", - "Output": { - "Type": "File", - "Path": ".", - "Name": "{{Project.Module}}", - "Extension": ".sln" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": null + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } }, - "SmartSqlConfig": { - "Type": "Project", - "Module": null, - "TemplateEngine": "Razor", - "Template": "SqlMapConfig.cshtml", + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + }, + "Parameters": { + "Templates": [ + { + "Key": "Sln.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.API", - "Name": "SmartSqlMapConfig", - "Extension": ".xml" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": null - }, - "Entity_Project": { - "Type": "Project", - "Module": null, - "TemplateEngine": "Razor", - "Template": "Proj.cshtml", + "Name": "{{Project.Module}}", + "Extension": ".sln" + } + }, + { + "Key": "Sln-Directory.Build.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.Entity", - "Name": "{{Project.Module}}.Entity", - "Extension": ".csproj" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": null - }, - "Entity": { - "Type": "Table", - "Module": "Entity", - "TemplateEngine": "Razor", - "Template": "Entity.cshtml", + "Name": "Directory.Build", + "Extension": ".props" + } + }, + { + "Key": "Sln-Version.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.{{Build.Module}}", - "Name": null, - "Extension": ".cs" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "T_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "V_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Pascal", - "Paramters": null - } - }, - "Column": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Pascal", - "Paramters": null - } - } - }, - "Paramters": null - }, - "Repository_Project": { - "Type": "Project", - "Module": null, - "TemplateEngine": "Razor", - "Template": "Proj-Repository.cshtml", + "Path": "build", + "Name": "version", + "Extension": ".props" + } + }, + { + "Key": "Sln-Dockerfile.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.Repository", - "Name": "{{Project.Module}}.Repository", - "Extension": ".csproj" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "View": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": null - }, - "Repository": { - "Type": "Table", - "Module": "Repository", - "TemplateEngine": "Razor", - "Template": "Repository.cshtml", + "Name": "Dockerfile", + "Extension": "" + } + }, + { + "Key": "Sln-DockerIgnore.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.{{Build.Module}}", - "Name": "I{{OutputName}}Repository", - "Extension": ".cs" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "T_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": null - } - }, - "View": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "V_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": null - } - }, - "Column": { - "Tokenizer": { - "Type": "Defalut", - "Paramters": {} - }, - "Converter": { - "Type": "Defalut", - "Paramters": {} - } - } - }, - "Paramters": null - }, - "SqlMap": { - "Type": "Table", - "Module": null, - "TemplateEngine": "Razor", - "Template": "SqlMap-SqlServer.cshtml", + "Name": ".dockerignore", + "Extension": "" + } + }, + { + "Key": "Sln-GitIgnore.cshtml", + "Output": { + "Name": ".gitignore", + "Extension": "" + } + }, + { + "Key": "Proj-Entity.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.Entity", + "Name": "{{Project.Module}}.Entity", + "Extension": ".csproj" + } + }, + { + "Key": "Proj-Repository.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.Repository", + "Name": "{{Project.Module}}.Repository", + "Extension": ".csproj" + } + }, + { + "Key": "Proj-Service.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.Service", + "Name": "{{Project.Module}}.Service", + "Extension": ".csproj" + } + }, + { + "Key": "Proj-API.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API", + "Name": "{{Project.Module}}.API", + "Extension": ".csproj" + } + }, + { + "Key": "API/LaunchSettings.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Properties", + "Name": "launchSettings", + "Extension": ".json" + } + }, + { + "Key": "API/AppSettings.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API", + "Name": "appsettings", + "Extension": ".json" + } + }, + { + "Key": "API/AppSettings-Development.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API", + "Name": "appsettings.Development", + "Extension": ".json" + } + }, + { + "Key": "API/Program.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API", + "Name": "Program", + "Extension": ".cs" + } + }, + { + "Key": "API/Startup.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API", + "Name": "Startup", + "Extension": ".cs" + } + }, + { + "Key": "API/APIException.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Exceptions", + "Name": "APIException", + "Extension": ".cs" + } + }, + { + "Key": "API/GlobalExceptionFilter.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Filters", + "Name": "GlobalExceptionFilter", + "Extension": ".cs" + } + }, + { + "Key": "API/GlobalValidateModelFilter.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Filters", + "Name": "GlobalValidateModelFilter", + "Extension": ".cs" + } + }, + { + "Key": "API/QueryRequest.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "QueryRequest", + "Extension": ".cs" + } + }, + { + "Key": "API/QueryByPageRequest.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "QueryByPageRequest", + "Extension": ".cs" + } + }, + { + "Key": "API/ResponseMessage.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "ResponseMessage", + "Extension": ".cs" + } + }, + { + "Key": "API/QueryResponse.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "QueryResponse", + "Extension": ".cs" + } + }, + { + "Key": "API/QueryByPageResponse.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "QueryByPageResponse", + "Extension": ".cs" + } + }, + { + "Key": "API/ResponseMessage.cshtml", "Output": { - "Type": "File", - "Path": "{{Project.Module}}.API/Maps", - "Name": null, - "Extension": ".xml" - }, - "IncludeTables": null, - "IgnoreTables": null, - "NamingConverter": { - "Table": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "T_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": null - } - }, - "View": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "V_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": null - } - }, - "Column": { - "Tokenizer": { - "Type": "Default", - "Paramters": { - "IgnorePrefix": "T_", - "Delimiter": "_" - } - }, - "Converter": { - "Type": "Default", - "Paramters": null - } - } - }, - "Paramters": null + "Path": "src/{{Project.Module}}.API/Messages", + "Name": "ResponseMessage", + "Extension": ".cs" + } + }, + { + "Key": "SqlMapConfig.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.Repository", + "Name": "SmartSqlMapConfig", + "Extension": ".xml" + } + }, + { + "Key": "SqlMapConfig.cshtml", + "Output": { + "Path": "src/{{Project.Module}}.Repository", + "Name": "SmartSqlMapConfig.Development", + "Extension": ".xml" + } + } + ] + } + }, + "Entity": { + "Type": "Table", + "Module": "Entity", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp", + "Path": "Entity.cshtml" + }, + "Output": { + "Type": "File", + "Path": "src/{{Project.Module}}.{{Build.Module}}", + "Mode": 1, + "Name": "{{Items.CurrentTable.ConvertedName}}", + "Extension": ".cs" + }, + "IgnoreNoPKTable": false, + "IgnoreView": false, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + } + }, + "Repository": { + "Type": "Table", + "Module": "Repository", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp", + "Path": "Repository.cshtml" + }, + "Output": { + "Type": "File", + "Path": "src/{{Project.Module}}.{{Build.Module}}", + "Mode": 1, + "Name": "I{{Items.CurrentTable.ConvertedName}}Repository", + "Extension": ".cs" + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + } + }, + "Service": { + "Type": "Table", + "Module": "Service", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp", + "Path": "Service.cshtml" + }, + "Output": { + "Type": "File", + "Path": "src/{{Project.Module}}.{{Build.Module}}", + "Name": "{{Items.CurrentTable.ConvertedName}}Service", + "Extension": ".cs" + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + } + }, + "APIController": { + "Type": "Table", + "Module": "API", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp", + "Path": "API/APIController.cshtml" + }, + "Output": { + "Type": "File", + "Path": "src/{{Project.Module}}.{{Build.Module}}/Controllers", + "Name": "{{Items.CurrentTable.ConvertedName}}Controller", + "Extension": ".cs" + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + } + }, + "SqlMap": { + "Type": "Table", + "TemplateEngine": { + "Name": "Razor", + "Root": "CSharp", + "Path": "SqlMap.cshtml" + }, + "Output": { + "Type": "File", + "Path": "src/{{Project.Module}}.Repository/Maps", + "Name": "{{Items.CurrentTable.ConvertedName}}", + "Extension": ".xml" + }, + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } } + } }, - "OutputPath": "E://SmartSql-Starter" + "CodeFormat": { + "Type": "Process", + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + }, + "Parameters": { + "FileName": "powershell", + "WorkingDirectory": "{{Project.Output.Path}}", + "Args": "dotnet-format" + } + }, + "ReStore": { + "Type": "Process", + "IgnoreNoPKTable": true, + "IgnoreView": true, + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": {} + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + } + }, + "Parameters": { + "FileName": "powershell", + "WorkingDirectory": "{{Project.Output.Path}}", + "Args": "dotnet restore" + } + } + }, + "OutputPath": "E:\\SmartSql-Starter", + "NamingConverter": { + "Table": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "T_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "View": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "IgnorePrefix": "V_", + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal" + } + }, + "Column": { + "Tokenizer": { + "Type": "Default", + "Parameters": { + "Delimiter": "_" + } + }, + "Converter": { + "Type": "Pascal", + "Parameters": null + } + } + }, + "TableFilter": { + "IgnoreNoPKTable": true, + "IgnoreView": true + } } \ No newline at end of file diff --git a/doc/SmartCode.yml b/doc/SmartCode.yml index 67861ab..6cd9397 100644 --- a/doc/SmartCode.yml +++ b/doc/SmartCode.yml @@ -2,183 +2,206 @@ Module: SmartSql.Starter Author: Ahoo Wang DataSource: Name: DbTable - Paramters: - DbName: SmartSqlDB + Parameters: + DbName: SmartSqlTestDB DbProvider: SqlServer - ConnectionString: Data Source=.;Initial Catalog=SmartSqlDB;Integrated Security=True + ConnectionString: Data Source=.;Initial Catalog=SmartSqlTestDB;Integrated Security=True Language: CSharp TemplateEngine: Name: Razor Root: CSharp Output: Type: File - Path: 'E://SmartSql-Starter' + Path: 'D:\SmartSql-Starter' +Parameters: + SmartSqlVersion: '4.1.42' + SmartSqlSchemaVersion: '4.1.30' + BuildDir: 'D:\SmartSql-Starter\build' + DockerImage: 'smartsql.starter' + +NamingConverter: + Table: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'T_' + Delimiter: '_' + Converter: + Type: Pascal + Parameters: { } + View: + Tokenizer: + Type: Default + Parameters: + IgnorePrefix: 'V_' + Delimiter: '_' + Converter: + Type: Pascal + Column: + Tokenizer: + Type: Default + Parameters: + Delimiter: '_' + Converter: + Type: Pascal + +TableFilter: + IgnoreNoPKTable: true + IgnoreView: true # 构建任务 Build: - ClearDir: - Type: Clear - Paramters: - Dirs: '.' +# ClearDir: +# Type: Clear +# Parameters: +# Dirs: '.' + + MakeBuildDir: + Type: Process + Parameters: + FileName: powershell + Args: mkdir '{{Project.Parameters.BuildDir}}' + Copy: + Type: Process + Parameters: + FileName: powershell + Args: cp '{{Project.ConfigPath}}' '{{Project.Parameters.BuildDir}}' Scaffolding: Type: MultiTemplate - Output: + Output: Path: '.' - Paramters: + Parameters: Templates: [{Key: 'Sln.cshtml',Output: {Name: '{{Project.Module}}',Extension: '.sln'}}, - {Key: "Proj-Entity.cshtml",Output: {Path: '{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, - {Key: "Proj-Repository.cshtml",Output: {Path: '{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, - {Key: "Proj-Service.cshtml",Output: {Path: '{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, - {Key: "Proj-API.cshtml",Output: {Path: '{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, - {Key: "API/LaunchSettings.cshtml",Output: {Path: '{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, - {Key: "API/AppSettings.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, - {Key: "API/AppSettings-Development.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, - {Key: "API/Program.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, - {Key: "API/Startup.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, - {Key: "API/APIException.cshtml",Output: {Path: '{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, - {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, - {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: '{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, - {Key: "API/QueryRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, - {Key: "API/QueryByPageRequest.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "API/QueryResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, - {Key: "API/QueryByPageResponse.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, - {Key: "API/ResponseMessage.cshtml",Output: {Path: '{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, - {Key: "SqlMapConfig.cshtml",Output: {Path: '{{Project.Module}}.API',Name: 'SmartSqlMapConfig',Extension: '.xml'}} - ] + {Key: 'Sln-Directory.Build.cshtml',Output: {Name: 'Directory.Build',Extension: '.props'}}, + {Key: 'Sln-Version.cshtml',Output: {Path: 'build',Name: 'version',Extension: '.props'}}, + {Key: 'Sln-Dockerfile.cshtml',Output: {Name: 'Dockerfile',Extension: ''}}, + {Key: 'Sln-DockerIgnore.cshtml',Output: {Name: '.dockerignore',Extension: ''}}, + {Key: 'Sln-GitIgnore.cshtml',Output: {Name: '.gitignore',Extension: ''}}, + {Key: "Proj-Entity.cshtml",Output: {Path: 'src/{{Project.Module}}.Entity',Name: '{{Project.Module}}.Entity',Extension: '.csproj'}}, + {Key: "Proj-Repository.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: '{{Project.Module}}.Repository',Extension: '.csproj'}}, + {Key: "Proj-Service.cshtml",Output: {Path: 'src/{{Project.Module}}.Service',Name: '{{Project.Module}}.Service',Extension: '.csproj'}}, + {Key: "Proj-API.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: '{{Project.Module}}.API',Extension: '.csproj'}}, + {Key: "API/LaunchSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Properties',Name: 'launchSettings',Extension: '.json'}}, + {Key: "API/AppSettings.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings',Extension: '.json'}}, + {Key: "API/AppSettings-Development.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'appsettings.Development',Extension: '.json'}}, + {Key: "API/Program.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Program',Extension: '.cs'}}, + {Key: "API/Startup.cshtml",Output: {Path: 'src/{{Project.Module}}.API',Name: 'Startup',Extension: '.cs'}}, + {Key: "API/APIException.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Exceptions',Name: 'APIException',Extension: '.cs'}}, + {Key: "API/GlobalExceptionFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalExceptionFilter',Extension: '.cs'}}, + {Key: "API/GlobalValidateModelFilter.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Filters',Name: 'GlobalValidateModelFilter',Extension: '.cs'}}, + {Key: "API/QueryRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryRequest',Extension: '.cs'}}, + {Key: "API/QueryByPageRequest.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageRequest',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "API/QueryResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryResponse',Extension: '.cs'}}, + {Key: "API/QueryByPageResponse.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'QueryByPageResponse',Extension: '.cs'}}, + {Key: "API/ResponseMessage.cshtml",Output: {Path: 'src/{{Project.Module}}.API/Messages',Name: 'ResponseMessage',Extension: '.cs'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig',Extension: '.xml'}}, + {Key: "SqlMapConfig.cshtml",Output: {Path: 'src/{{Project.Module}}.Repository',Name: 'SmartSqlMapConfig.Development',Extension: '.xml'}}] Entity: Type: Table Module: Entity TemplateEngine: Path: Entity.cshtml + IgnoreNoPKTable: false + IgnoreView: false Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: '.cs' - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - Paramters: { } - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - Delimiter: '_' - Converter: - Type: Pascal Repository: Type: Table Module: Repository TemplateEngine: Path: Repository.cshtml - IgnoreNoPKTable: true - IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: 'I{{Items.CurrentTable.ConvertedName}}Repository' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal Service: Type: Table Module: Service TemplateEngine: Path: Service.cshtml - IgnoreNoPKTable: true - IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}' + Path: 'src/{{Project.Module}}.{{Build.Module}}' Name: '{{Items.CurrentTable.ConvertedName}}Service' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal APIController: Type: Table Module: API TemplateEngine: Path: API/APIController.cshtml - IgnoreNoPKTable: true - IgnoreView: true Output: - Path: '{{Project.Module}}.{{Build.Module}}/Controllers' + Path: 'src/{{Project.Module}}.{{Build.Module}}/Controllers' Name: '{{Items.CurrentTable.ConvertedName}}Controller' Extension: .cs - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal SqlMap: Type: Table TemplateEngine: Path: SqlMap.cshtml Output: - Path: '{{Project.Module}}.API/Maps' + Path: 'src/{{Project.Module}}.Repository/Maps' Name: '{{Items.CurrentTable.ConvertedName}}' Extension: .xml - IgnoreNoPKTable: true - IgnoreView: true - NamingConverter: - Table: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal - View: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'V_' - Delimiter: '_' - Converter: - Type: Pascal - Column: - Tokenizer: - Type: Default - Paramters: - IgnorePrefix: 'T_' - Delimiter: '_' - Converter: - Type: Pascal \ No newline at end of file + +# Please install dotnet-format first! +# dotnet tool install -g dotnet-format + CodeFormat: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet-format + + ReStore: + Type: Process + Parameters: + FileName: powershell + WorkingDirectory: '{{Project.Output.Path}}' + Args: dotnet restore + +# BuildDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker build -t {{Project.Parameters.DockerImage}}:v1.0.0 . + +# RunDocker: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: docker run --name {{Project.Parameters.DockerImage}} --rm -d -p 8008:80 {{Project.Parameters.DockerImage}}:v1.0.0 . + +# Publish: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}' +# Args: dotnet publish -c Release -o '{{Project.Output.Path}}\publish' + +# Run: +# Type: Process +# Parameters: +# FileName: powershell +# WorkingDirectory: '{{Project.Output.Path}}\publish' +# CreateNoWindow: false +# RedirectStandardOutput: false +# RedirectStandardError: false +# WaitForExit: false +# WriteLines: ['dotnet {{Project.Module}}.API.dll'] + +# RunChrome: +# Type: Process +# Parameters: +# FileName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe +# CreateNoWindow: false +# Args: http://localhost:8008/swagger \ No newline at end of file diff --git a/doc/smartcode-etl.db b/doc/smartcode-etl.db index 745c1f7..87d7ac0 100644 Binary files a/doc/smartcode-etl.db and b/doc/smartcode-etl.db differ diff --git a/src/SmartCode.App/BuildTasks/AbstractBuildTask.cs b/src/SmartCode.App/BuildTasks/AbstractBuildTask.cs index 14c43d4..32415f6 100644 --- a/src/SmartCode.App/BuildTasks/AbstractBuildTask.cs +++ b/src/SmartCode.App/BuildTasks/AbstractBuildTask.cs @@ -22,7 +22,7 @@ public AbstractBuildTask(string name, ILogger logger) public abstract Task Build(BuildContext context); - public virtual void Initialize(IDictionary paramters) + public virtual void Initialize(IDictionary parameters) { Initialized = true; } diff --git a/src/SmartCode.App/BuildTasks/ClearBuildTask.cs b/src/SmartCode.App/BuildTasks/ClearBuildTask.cs index f8c9aa6..87a7d9f 100644 --- a/src/SmartCode.App/BuildTasks/ClearBuildTask.cs +++ b/src/SmartCode.App/BuildTasks/ClearBuildTask.cs @@ -20,9 +20,9 @@ public ClearBuildTask(ILogger logger) public Task Build(BuildContext context) { - var paramters = context.Build.Paramters; - if (paramters == null) { return Task.CompletedTask; ; } - if (paramters.Value("Dirs", out string clearDirs)) + var parameters = context.Build.Parameters; + if (parameters == null) { return Task.CompletedTask; ; } + if (parameters.Value("Dirs", out string clearDirs)) { var _clearDirs = clearDirs.Split(','); foreach (var dir in _clearDirs) @@ -36,7 +36,7 @@ public Task Build(BuildContext context) _logger.LogInformation($"ClearBuildTask Delete directory:{fullDir} End!"); } } - if (paramters.Value("Files", out string clearFiles)) + if (parameters.Value("Files", out string clearFiles)) { var _clearFiles = clearFiles.Split(','); foreach (var file in _clearFiles) @@ -54,7 +54,7 @@ public Task Build(BuildContext context) } private readonly ILogger _logger; - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode.App/BuildTasks/MultiTemplateBuildTask.cs b/src/SmartCode.App/BuildTasks/MultiTemplateBuildTask.cs index 436b567..d12229f 100644 --- a/src/SmartCode.App/BuildTasks/MultiTemplateBuildTask.cs +++ b/src/SmartCode.App/BuildTasks/MultiTemplateBuildTask.cs @@ -4,7 +4,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Text; using System.Threading.Tasks; namespace SmartCode.App.BuildTasks @@ -30,59 +29,81 @@ public MultiTemplateBuildTask(IPluginManager pluginManager _pluginManager = pluginManager; _logger = logger; } + public async Task Build(BuildContext context) { - if (context.Build.Paramters.Value(TEMPLATES_KEY, out IEnumerable templates)) + if (context.Build.Parameters.Value(TEMPLATES_KEY, out IEnumerable templates)) { foreach (var templateKVs in templates) { - var _templateKVs = (Dictionary)templateKVs; + var _templateKVs = (Dictionary) templateKVs; if (!_templateKVs.Value(TEMPLATE_KEY, out string templateKey)) { throw new SmartCodeException($"Build:{context.BuildKey},Can not find TemplateKey!"); } + context.Build.TemplateEngine.Path = templateKey; - context.Result = await _pluginManager.Resolve(context.Build.TemplateEngine.Name).Render(context); + context.Result = await _pluginManager.Resolve(context.Build.TemplateEngine.Name) + .Render(context); if (!_templateKVs.Value(TEMPLATE_OUTPUT_KEY, out Dictionary outputKVs)) { throw new SmartCodeException($"Build:{context.BuildKey},Can not find Output!"); } + if (context.Output == null) { throw new SmartCodeException($"Build:{context.BuildKey},Output can not be null!"); } + + Output output = new Output + { + Path = context.Output.Path, + Mode = context.Output.Mode, + DotSplit = context.Output.DotSplit, + Name = context.Output.Name, + Extension = context.Output.Extension + }; if (outputKVs.Value(nameof(Output.Path), out string outputPath)) { - context.Output.Path = outputPath; + output.Path = outputPath; } + if (outputKVs.Value(nameof(Output.Mode), out CreateMode outputMode)) { - context.Output.Mode = outputMode; + output.Mode = outputMode; } - if (String.IsNullOrEmpty(context.Output.Path)) + + if (outputKVs.Value(nameof(Output.DotSplit), out string dotSplit)) { - throw new SmartCodeException($"Build:{context.BuildKey},Template:{templateKey},can not find Output.Path!"); + output.DotSplit = Convert.ToBoolean(dotSplit); } + + if (String.IsNullOrEmpty(output.Path)) + { + throw new SmartCodeException( + $"Build:{context.BuildKey},Template:{templateKey},can not find Output.Path!"); + } + if (!outputKVs.Value(nameof(Output.Name), out string outputName)) { - throw new SmartCodeException($"Build:{context.BuildKey},Template:{templateKey},can not find Output.Name!"); + throw new SmartCodeException( + $"Build:{context.BuildKey},Template:{templateKey},can not find Output.Name!"); } - context.Output.Name = outputName; - if (!outputKVs.Value(nameof(Output.Extension), out string extension)) + output.Name = outputName; + + if (outputKVs.Value(nameof(Output.Extension), out string extension)) { - throw new SmartCodeException($"Build:{context.BuildKey},Template:{templateKey},can not find Output.Extension!"); + output.Extension = extension; } - context.Output.Extension = extension; - await _pluginManager.Resolve(context.Output.Type).Output(context); + await _pluginManager.Resolve(context.Output.Type).Output(context, output); } } } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - } } -} +} \ No newline at end of file diff --git a/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs b/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs index ff8cf96..1544dcf 100644 --- a/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs +++ b/src/SmartCode.App/BuildTasks/ProcessBuildTask.cs @@ -1,9 +1,12 @@ using Microsoft.Extensions.Logging; using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading.Tasks; +using HandlebarsDotNet; +using SmartCode.Utilities; namespace SmartCode.App.BuildTasks { @@ -11,11 +14,11 @@ public class ProcessBuildTask : IBuildTask { const string CREATE_NO_WINDOW = "CreateNoWindow"; const string WORKING_DIRECTORY = "WorkingDirectory"; + const string WRITE_LINES = "WriteLines"; const string FILE_NAME = "FileName"; const string ARGS = "Args"; const string TIMEOUT = "Timeout"; private readonly ILogger _logger; - const int DEFAULT_TIME_OUT = 30 * 1000; const bool DEFAULT_CREATE_NO_WINDOW = true; public bool Initialized => true; @@ -27,59 +30,95 @@ public ProcessBuildTask(ILogger logger) public Task Build(BuildContext context) { - if (!context.Build.Paramters.Value(FILE_NAME, out string fileName)) + if (!context.Build.Parameters.Value(FILE_NAME, out string fileName)) { - throw new SmartCodeException($"Build:{context.BuildKey},Can not find Paramter:{FILE_NAME}!"); + throw new SmartCodeException($"Build:{context.BuildKey},Can not find Parameter:{FILE_NAME}!"); } - if (!context.Build.Paramters.Value(ARGS, out string args)) + var startInfo = new ProcessStartInfo(fileName) { - throw new SmartCodeException($"Build:{context.BuildKey},Can not find Paramter:{ARGS}!"); + UseShellExecute = false, + RedirectStandardInput = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = DEFAULT_CREATE_NO_WINDOW + }; + if (context.Build.Parameters.Value(nameof(ProcessStartInfo.RedirectStandardInput), out bool redirectStandardInput)) + { + startInfo.RedirectStandardInput = redirectStandardInput; + } + if (context.Build.Parameters.Value(nameof(ProcessStartInfo.RedirectStandardOutput), out bool redirectStandardOutput)) + { + startInfo.RedirectStandardOutput = redirectStandardOutput; + } + if (context.Build.Parameters.Value(nameof(ProcessStartInfo.RedirectStandardError), out bool redirectStandardError)) + { + startInfo.RedirectStandardError = redirectStandardError; } - var process = new Process(); - var startInfo = process.StartInfo; - startInfo.CreateNoWindow = DEFAULT_CREATE_NO_WINDOW; - startInfo.FileName = fileName; - startInfo.Arguments = args; - if (context.Build.Paramters.Value(WORKING_DIRECTORY, out string workingDic)) + if (context.Build.Parameters.Value(ARGS, out string args)) { - startInfo.WorkingDirectory = workingDic; + startInfo.Arguments = Handlebars.Compile(args)(context); } - if (context.Build.Paramters.Value(CREATE_NO_WINDOW, out bool createNoWin)) + if (context.Build.Parameters.Value(WORKING_DIRECTORY, out string workingDic)) + { + startInfo.WorkingDirectory = Handlebars.Compile(workingDic)(context); + } + if (context.Build.Parameters.Value(CREATE_NO_WINDOW, out bool createNoWin)) { startInfo.CreateNoWindow = createNoWin; } _logger.LogDebug($"--------Process.FileName:{startInfo.FileName},Args:{startInfo.Arguments} Start--------"); - process.ErrorDataReceived += Process_ErrorDataReceived; - process.OutputDataReceived += Process_OutputDataReceived; - try + using (var process = Process.Start(startInfo)) { - process.Start(); - var timeOut = DEFAULT_TIME_OUT; - if (context.Build.Paramters.Value(TIMEOUT, out int _timeout)) + if (startInfo.RedirectStandardOutput) { - timeOut = _timeout; + process.OutputDataReceived += Process_OutputDataReceived; + process.BeginOutputReadLine(); } - process.WaitForExit(timeOut); - _logger.LogDebug($"--------Process.FileName:{startInfo.FileName},Args:{startInfo.Arguments} End--------"); - } - finally - { - process.Dispose(); + if (startInfo.RedirectStandardError) + { + process.ErrorDataReceived += Process_ErrorDataReceived; + process.BeginErrorReadLine(); + } + if (context.Build.Parameters.Value(WRITE_LINES, out IEnumerable lines)) + { + foreach (var line in lines) + { + var lineCommand = Handlebars.Compile(line.ToString())(context); + _logger.LogDebug($"StandardInput.WriteLine: [{lineCommand}]."); + process.StandardInput.WriteLine(lineCommand); + } + } + + if (!(context.Build.Parameters.Value(nameof(Process.WaitForExit), out bool waitForExit) + && !waitForExit)) + { + if (context.Build.Parameters.Value(TIMEOUT, out int _timeout)) + { + process.WaitForExit(_timeout); + } + else + { + process.WaitForExit(); + } + } + _logger.LogDebug($"--------Process.FileName:{startInfo.FileName},Args:{startInfo.Arguments},Taken:{process.TotalProcessorTime.TotalMilliseconds} End--------"); } return Task.CompletedTask; } - private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) + private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) { - _logger.LogDebug(e.Data); + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine(e.Data); } - private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) + private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) { - _logger.LogDebug(e.Data); + if (!string.IsNullOrEmpty(e.Data)) + Console.WriteLine(e.Data); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode.App/Outputs/FileOutput.cs b/src/SmartCode.App/Outputs/FileOutput.cs index 957ae1a..602a4f0 100644 --- a/src/SmartCode.App/Outputs/FileOutput.cs +++ b/src/SmartCode.App/Outputs/FileOutput.cs @@ -5,6 +5,9 @@ using System.Text; using System.Threading.Tasks; using HandlebarsDotNet; +using SmartCode.Configuration; +using SmartCode.Utilities; +using System.Text.RegularExpressions; namespace SmartCode.App.Outputs { @@ -21,28 +24,43 @@ public FileOutput(ILogger logger) public string Name { get; private set; } = "File"; - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters == null) { return; } - if (paramters.Value("Name", out string name)) + if (parameters == null) + { + return; + } + + if (parameters.Value(nameof(Name), out string name)) { Name = name; } + Initialized = true; } - public async Task Output(BuildContext context) + public async Task Output(BuildContext context, Output output = null) { - var output = context.Output; + if (output == null) + { + output = context.Output; + } + _logger.LogInformation($"------ Mode:{output.Mode},Build:{context.BuildKey} Start! ------"); - + var outputPath = Handlebars.Compile(output.Path)(context); outputPath = Path.Combine(context.Project.OutputPath, outputPath); + if (output.DotSplit == true) + { + outputPath = outputPath.Replace('.', '/'); + } + if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); _logger.LogWarning($"------ Directory:{outputPath} is not Exists,Created! ------"); } + var fileName = Handlebars.Compile(output.Name)(context) + output.Extension; var filePath = Path.Combine(outputPath, fileName); var fileExists = File.Exists(filePath); @@ -50,9 +68,11 @@ public async Task Output(BuildContext context) { switch (output.Mode) { + case Configuration.CreateMode.None: case Configuration.CreateMode.Incre: { - _logger.LogWarning($"------ Mode:{output.Mode},Build:{context.BuildKey},FilePath:{filePath} Exists ignore output End! ------"); + _logger.LogWarning( + $"------ Mode:{output.Mode},Build:{context.BuildKey},FilePath:{filePath} Exists ignore output End! ------"); return; } case Configuration.CreateMode.Full: @@ -63,13 +83,16 @@ public async Task Output(BuildContext context) } } } - using (StreamWriter streamWriter = new StreamWriter(filePath)) + + //采购VS默认的UTF-8 WITH BOM 编码 + using (StreamWriter streamWriter = new StreamWriter(filePath, false, new UTF8Encoding(true))) { - await streamWriter.WriteAsync(context.Result); + //强制行尾为 \r\n + var result = Regex.Replace(context.Result.Trim(), @"[\r\n]+", "\r\n", RegexOptions.Multiline); + await streamWriter.WriteAsync(result); } + _logger.LogInformation($"------ Mode:{output.Mode},Build:{context.BuildKey} -> {filePath} End! ------"); } - - } -} +} \ No newline at end of file diff --git a/src/SmartCode.App/PluginManager.cs b/src/SmartCode.App/PluginManager.cs index f211e45..498911f 100644 --- a/src/SmartCode.App/PluginManager.cs +++ b/src/SmartCode.App/PluginManager.cs @@ -56,19 +56,23 @@ private IEnumerable ResolvePlugins() where TPlugin : IPlugin var plugins = _serviceProvider.GetServices(); foreach (var plugin in plugins) { - if (!plugin.Initialized) + lock (this) { - var pluginType = plugin.GetType(); - var names = pluginType.AssemblyQualifiedName.Split(','); - var typeName = names[0].Trim(); - var assName = names[1].Trim(); - var pluginConfig = _smartCodeOptions - .Plugins - .FirstOrDefault(m => m.ImplAssemblyName == assName && m.ImplTypeName == typeName); - plugin.Initialize(pluginConfig.Paramters); + if (!plugin.Initialized) + { + var pluginType = plugin.GetType(); + var names = pluginType.AssemblyQualifiedName.Split(','); + var typeName = names[0].Trim(); + var assName = names[1].Trim(); + var pluginConfig = _smartCodeOptions + .Plugins + .FirstOrDefault(m => m.ImplAssemblyName == assName && m.ImplTypeName == typeName); + plugin.Initialize(pluginConfig.Parameters); + } } } return plugins; + } } } diff --git a/src/SmartCode.App/ProjectBuilder.cs b/src/SmartCode.App/ProjectBuilder.cs deleted file mode 100644 index 02c07e9..0000000 --- a/src/SmartCode.App/ProjectBuilder.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Microsoft.Extensions.Logging; -using SmartCode.Configuration; -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using System.Linq; - -namespace SmartCode.App -{ - public class ProjectBuilder : IProjectBuilder - { - private readonly Project _project; - private readonly IPluginManager _pluginManager; - private readonly ILogger _logger; - - public ProjectBuilder( - Project project - , IPluginManager pluginManager - , ILogger logger) - { - _project = project; - _pluginManager = pluginManager; - _logger = logger; - } - public event OnProjectBuildStartupHandler OnStartup; - public event OnProjectBuildSucceedHandler OnSucceed; - public event OnProjectBuildFailedHandler OnFailed; - - - public async Task Build() - { - BuildContext buildContext = null; - try - { - var dataSource = _pluginManager.Resolve(_project.DataSource.Name); - await OnStartup?.Invoke(this, new OnProjectBuildStartupEventArgs { Project = _project }); - await dataSource.InitData(); - foreach (var buildKV in _project.BuildTasks) - { - _logger.LogInformation($"-------- BuildTask:{buildKV.Key} Start! ---------"); - var output = buildKV.Value.Output; - buildContext = new BuildContext - { - PluginManager = _pluginManager, - Project = _project, - DataSource = dataSource, - BuildKey = buildKV.Key, - Build = buildKV.Value, - Output = output == null ? null : new Output - { - Type = output.Type, - Path = output.Path, - Name = output.Name, - Mode = output.Mode, - Extension = output.Extension - } - }; - await _pluginManager.Resolve(buildKV.Value.Type).Build(buildContext); - _logger.LogInformation($"-------- BuildTask:{buildKV.Key} End! ---------"); - } - await OnSucceed?.Invoke(this, new OnProjectBuildSucceedEventArgs - { - Project = _project - }); - } - catch (Exception ex) - { - await OnFailed?.Invoke(this, new OnProjectBuildFailedEventArgs - { - Project = _project, - Context = buildContext, - ErrorException = ex - }); - throw ex; - } - } - - } -} diff --git a/src/SmartCode.App/SmartCode.App.csproj b/src/SmartCode.App/SmartCode.App.csproj index 95cae97..20c43c8 100644 --- a/src/SmartCode.App/SmartCode.App.csproj +++ b/src/SmartCode.App/SmartCode.App.csproj @@ -2,14 +2,14 @@ netstandard2.0 - 7.1 - 1.2.0 - - + + + + diff --git a/src/SmartCode.App/SmartCodeApp.cs b/src/SmartCode.App/SmartCodeApp.cs index c3a2e46..46c037a 100644 --- a/src/SmartCode.App/SmartCodeApp.cs +++ b/src/SmartCode.App/SmartCodeApp.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.Threading.Tasks; @@ -7,19 +8,22 @@ using SmartCode.Configuration.ConfigBuilders; using System.Reflection; using HandlebarsDotNet; +using SmartCode.ETL; +using SmartCode.Generator; namespace SmartCode.App { public class SmartCodeApp { public SmartCodeOptions SmartCodeOptions { get; } - public String AppDirectory { get { return AppDomain.CurrentDomain.BaseDirectory; } } + public String AppDirectory => AppDomain.CurrentDomain.BaseDirectory; public IConfigBuilder ConfigBuilder { get; private set; } - public IServiceCollection Services { get { return SmartCodeOptions.Services; } } + public IServiceCollection Services => SmartCodeOptions.Services; public IServiceProvider ServiceProvider { get; private set; } public Project Project { get; private set; } - public string ConfigPath { get { return SmartCodeOptions.ConfigPath; } } + public string ConfigPath => SmartCodeOptions.ConfigPath; public ILogger Logger { get; private set; } + public SmartCodeApp(SmartCodeOptions smartCodeOptions) { SmartCodeOptions = smartCodeOptions; @@ -33,20 +37,23 @@ private void BuildProject() switch (pathExtension) { case ".JSON": - { - ConfigBuilder = new JsonBuilder(ConfigPath); - break; - } + { + ConfigBuilder = new JsonBuilder(ConfigPath); + break; + } + case ".YML": - { - ConfigBuilder = new YamlBuilder(ConfigPath); - break; - } + { + ConfigBuilder = new YamlBuilder(ConfigPath); + break; + } + default: - { - throw new SmartCodeException($"ConfigPath:{ConfigPath},未知扩展名:{pathExtension}"); - } + { + throw new SmartCodeException($"ConfigPath:{ConfigPath},未知扩展名:{pathExtension}"); + } } + Project = ConfigBuilder.Build(); Project.ConfigPath = ConfigPath; } @@ -57,7 +64,21 @@ private void RegisterServices() Services.AddSingleton(Project); RegisterPlugins(); Services.AddSingleton(); - Services.AddSingleton(); + if (Project.Mode == Project.ProjectMode.ETL) + { + Services.AddSingleton(); + } + else + { + if (Project.DataSource.Parameters.ContainsKey("Query")) + { + Services.AddSingleton(); + } + else + { + Services.AddSingleton(); + } + } ServiceProvider = Services.BuildServiceProvider(); Logger = ServiceProvider.GetRequiredService>(); } @@ -71,15 +92,19 @@ private void RegisterPlugins() { throw new SmartCodeException($"Plugin.Type:{plugin.TypeName} can not find!"); } + var implType = Assembly.Load(plugin.ImplAssemblyName).GetType(plugin.ImplTypeName); if (implType == null) { throw new SmartCodeException($"Plugin.ImplType:{plugin.ImplTypeName} can not find!"); } + if (!pluginType.IsAssignableFrom(implType)) { - throw new SmartCodeException($"Plugin.ImplType:{implType.FullName} can not Impl Plugin.Type:{pluginType.FullName}!"); + throw new SmartCodeException( + $"Plugin.ImplType:{implType.FullName} can not Impl Plugin.Type:{pluginType.FullName}!"); } + Services.AddSingleton(pluginType, implType); } } @@ -90,23 +115,27 @@ public async Task Run() { Handlebars.Configuration.TextEncoder = NullTextEncoder.Instance; var projectBuilder = ServiceProvider.GetRequiredService(); + Stopwatch stopwatch = Stopwatch.StartNew(); Logger.LogInformation($"------- Build ConfigPath:{ConfigPath} Start! --------"); await projectBuilder.Build(); - Logger.LogInformation($"-------- Build ConfigPath:{ConfigPath},Output:{Project.Output?.Path} End! --------"); + Logger.LogInformation( + $"-------- Build ConfigPath:[{ConfigPath}],Output:[{Project.Output?.Path}],Taken:[{stopwatch.ElapsedMilliseconds}ms] End! --------"); } catch (SmartCodeException scEx) { Logger.LogError(new EventId(scEx.HResult), scEx, scEx.Message); + throw; } } public class NullTextEncoder : ITextEncoder { public static NullTextEncoder Instance = new NullTextEncoder(); + public string Encode(string value) { return value; } } } -} +} \ No newline at end of file diff --git a/src/SmartCode.App/SmartCodeOptions.cs b/src/SmartCode.App/SmartCodeOptions.cs index 92291f9..d4e410d 100644 --- a/src/SmartCode.App/SmartCodeOptions.cs +++ b/src/SmartCode.App/SmartCodeOptions.cs @@ -9,7 +9,6 @@ public class SmartCodeOptions { public string Name { get; } = "SmartCode"; public string Author { get; } = "Ahoo Wang"; - public string Version { get; set; } = "1.0.0"; public string Github { get; } = "https://github.com/Ahoo-Wang/SmartCode"; public String ConfigPath { get; set; } public IServiceCollection Services { get; set; } = new ServiceCollection(); diff --git a/src/SmartCode.CLI/DefaultSmartCodeAppBuilder.cs b/src/SmartCode.CLI/DefaultSmartCodeAppBuilder.cs index e74925c..5634a0e 100644 --- a/src/SmartCode.CLI/DefaultSmartCodeAppBuilder.cs +++ b/src/SmartCode.CLI/DefaultSmartCodeAppBuilder.cs @@ -12,7 +12,7 @@ public class DefaultSmartCodeAppBuilder { const string APP_SETTINGS_PATH = "appsettings.json"; const string SMARTCODE_KEY = "SmartCode"; - public String AppDirectory { get { return AppDomain.CurrentDomain.BaseDirectory; } } + public String AppDirectory => AppDomain.CurrentDomain.BaseDirectory; public SmartCodeApp Build(string configPath) { diff --git a/src/SmartCode.CLI/Program.cs b/src/SmartCode.CLI/Program.cs index 59c0667..e54f256 100644 --- a/src/SmartCode.CLI/Program.cs +++ b/src/SmartCode.CLI/Program.cs @@ -1,60 +1,22 @@ using System; +using System.Diagnostics; using System.Threading.Tasks; using SmartCode.Utilities; using SmartCode.App; using System.Text; using System.Threading; using System.IO; +using McMaster.Extensions.CommandLineUtils; namespace SmartCode.CLI { class Program { - /// - /// 默认配置文件路径 - /// - static string DEFAULT_CONFIG_PATH = AppPath.Relative("SmartCode.yml"); - static async Task Main(string[] args) { - var configPath = String.Empty; - if (args.Length > 0) - { - configPath = args[0]; - } - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine("------------ SmartCode Build Start! --------------"); - - if (String.IsNullOrEmpty(configPath)) - { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine("Pleace Please enter the path to build configuration file:"); - configPath = Console.ReadLine(); - if (String.IsNullOrEmpty(configPath)) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine("------- Not Find ConfigPath Arg! -------"); - Console.ForegroundColor = ConsoleColor.Magenta; - Console.WriteLine($"------- Use default config :{DEFAULT_CONFIG_PATH}! -------"); - configPath = DEFAULT_CONFIG_PATH; - } - } - try - { - SmartCodeApp app = new DefaultSmartCodeAppBuilder().Build(configPath); - await app.Run(); - Thread.Sleep(200);//Wait for Logger - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine($"------------ SmartCode Build End! Output:[{app.Project.Output?.Path}] --------------"); - } - catch (Exception ex) - { - throw ex; - } - finally - { - Console.ResetColor(); - } + ThreadPool.SetMinThreads(1000, 1000); + ThreadPool.SetMaxThreads(1000, 1000); + await CommandLineApplication.ExecuteAsync(args); } } } diff --git a/src/SmartCode.CLI/SmartCode.CLI.csproj b/src/SmartCode.CLI/SmartCode.CLI.csproj index 32dd61d..5727544 100644 --- a/src/SmartCode.CLI/SmartCode.CLI.csproj +++ b/src/SmartCode.CLI/SmartCode.CLI.csproj @@ -2,38 +2,27 @@ Exe - netcoreapp2.1 + netcoreapp2.2 true - latest true SmartCode ./nupkg SmartCode.CLI - - SmartCode = IDataSource -> IBuildTask -> IOutput => Build Everything!!! - Ahoo Wang - Ahoo Wang - https://raw.githubusercontent.com/Ahoo-Wang/SmartCode/master/LICENSE - https://github.com/Ahoo-Wang/SmartCode - https://github.com/Ahoo-Wang/SmartCode - Github - SmartCode SmartSql - true - 1.20.0 - https://raw.githubusercontent.com/Ahoo-Wang/SmartCode/master/doc/Logo.png - - - - + + + + + + @@ -47,6 +36,7 @@ PreserveNewest + Always @@ -65,5 +55,6 @@ + diff --git a/src/SmartCode.CLI/SmartCodeCommand.cs b/src/SmartCode.CLI/SmartCodeCommand.cs new file mode 100644 index 0000000..c158d8a --- /dev/null +++ b/src/SmartCode.CLI/SmartCodeCommand.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using McMaster.Extensions.CommandLineUtils; +using SmartCode.App; +using SmartCode.Utilities; + +namespace SmartCode.CLI +{ + [Subcommand(typeof(MarketCommand))] + [VersionOptionFromMember("-v|--version", MemberName = nameof(GetVersion))] + public class SmartCodeCommand + { + /// + /// 默认配置文件路径 + /// + static string DEFAULT_CONFIG_PATH = AppPath.Relative("SmartCode.yml"); + + [Argument(0, Description = "Config Path")] + [FileExists] + public String ConfigPath { get; set; } + + [Option("-ci|--culture-info", Description = "CultureInfo")] + public String CultureInfo { get; set; } + + private async Task OnExecute() + { + if (!String.IsNullOrEmpty(CultureInfo)) + { + System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(CultureInfo); + System.Threading.Thread.CurrentThread.CurrentCulture = culture; + } + + if (String.IsNullOrEmpty(ConfigPath)) + { + var useDefaultConfig = + Prompt.GetYesNo( + $"If you do not enter ConfigPath, you will use the default configuration:{DEFAULT_CONFIG_PATH}", + true); + ConfigPath = useDefaultConfig + ? DEFAULT_CONFIG_PATH + : Prompt.GetString("Please enter the path to build configuration file:"); + } + + SmartCodeApp app = new DefaultSmartCodeAppBuilder().Build(ConfigPath); + await app.Run(); + } + + private static string GetVersion() + => typeof(SmartCodeCommand).Assembly.GetCustomAttribute() + .InformationalVersion; + + [Command(name: "pull", Description = "Pull Git Template.")] + public class MarketCommand + { + private readonly IConsole _console; + + public MarketCommand(IConsole console) + { + _console = console; + } + + [Option(Description = "Source Path")] public String Source { get; set; } + [Option(Description = "Target Path")] public String Target { get; set; } + + private string ParseGitArgs() + { + var toPath = Path.Combine(AppContext.BaseDirectory, "RazorTemplates", Target); + return $"clone --progress -v \"{Source}\" \"{toPath}\""; + } + + private void OnExecute(IConsole console) + { + var startInfo = new ProcessStartInfo("git") + { + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true, + ErrorDialog = true, + Arguments = ParseGitArgs() + }; + + using (var process = Process.Start(startInfo)) + { + process.OutputDataReceived += Process_OutputDataReceived; + ; + process.ErrorDataReceived += Process_ErrorDataReceived; + ; + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + } + } + + private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e) + { + if (!string.IsNullOrEmpty(e.Data)) + _console.WriteLine(e.Data); + } + + private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) + { + if (!string.IsNullOrEmpty(e.Data)) + _console.WriteLine(e.Data); + } + } + } +} \ No newline at end of file diff --git a/src/SmartCode.CLI/appsettings.json b/src/SmartCode.CLI/appsettings.json index b08e088..9fe42b6 100644 --- a/src/SmartCode.CLI/appsettings.json +++ b/src/SmartCode.CLI/appsettings.json @@ -8,7 +8,6 @@ } }, "SmartCode": { - "Version": "v1.18.2", "Plugins": [ { "Type": "SmartCode.IDataSource,SmartCode", @@ -63,8 +62,12 @@ "ImplType": "SmartCode.Generator.DbTypeConverter.DefaultDbTypeConverter,SmartCode.Generator" }, { - "Type": "SmartCode.IDataSource,SmartCode", - "ImplType": "SmartCode.ETL.ExtractDataSource,SmartCode.ETL" + "Type": "SmartCode.ETL.IExtractData,SmartCode.ETL", + "ImplType": "SmartCode.ETL.ExtractData,SmartCode.ETL" + }, + { + "Type": "SmartCode.ETL.IExtractData,SmartCode.ETL", + "ImplType": "SmartCode.ETL.ExtractDictionaryData,SmartCode.ETL" }, { "Type": "SmartCode.IBuildTask,SmartCode", @@ -78,6 +81,10 @@ "Type": "SmartCode.IBuildTask,SmartCode", "ImplType": "SmartCode.ETL.BuildTasks.LoadBuildTask,SmartCode.ETL" }, + { + "Type": "SmartCode.IBuildTask,SmartCode", + "ImplType": "SmartCode.ETL.LoadToES.LoadToESBuildTask,SmartCode.ETL.LoadToES" + }, { "Type": "SmartCode.ETL.IETLTaskRepository,SmartCode.ETL", "ImplType": "SmartCode.ETL.NoneETLTaskRepository,SmartCode.ETL" @@ -85,14 +92,14 @@ { "Type": "SmartCode.ETL.IETLTaskRepository,SmartCode.ETL", "ImplType": "SmartCode.ETL.PostgreSql.PGETLTaskRepository,SmartCode.ETL.PostgreSql", - "Paramters": { + "Parameters": { "ConnectionString": "Server=localhost;Port=5432;User Id=postgres;Password=SmartSql; Database=smartcode_etl;" } }, { "Type": "SmartCode.ETL.IETLTaskRepository,SmartCode.ETL", "ImplType": "SmartCode.ETL.SQLite.SQLiteETLTaskRepository,SmartCode.ETL.SQLite", - "Paramters": { + "Parameters": { //"ConnectionString": "Data Source=YOUR_DB_DIR\smartcode-etl.db;Version=3;" } } diff --git a/src/SmartCode.Db/DbProviders.cs b/src/SmartCode.Db/DbProviders.cs deleted file mode 100644 index 488f193..0000000 --- a/src/SmartCode.Db/DbProviders.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace SmartCode.Db -{ - public class DbProviders - { - static DbProviders() - { - InitDbProviders(); - } - private static readonly IDictionary _dbProviders = new Dictionary(); - private static void InitDbProviders() - { - _dbProviders.Add("MySql", new SmartSql.Configuration.DbProvider - { - Name = "MySql", - ParameterPrefix = "?", - Type = "MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data" - }); - _dbProviders.Add("MariaDB", new SmartSql.Configuration.DbProvider - { - Name = "MariaDB", - ParameterPrefix = "?", - Type = "MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data" - }); - _dbProviders.Add("PostgreSql", new SmartSql.Configuration.DbProvider - { - Name = "PostgreSql", - ParameterPrefix = "@", - Type = "Npgsql.NpgsqlFactory,Npgsql" - }); - _dbProviders.Add("SqlServer", new SmartSql.Configuration.DbProvider - { - Name = "SqlServer", - ParameterPrefix = "@", - Type = "System.Data.SqlClient.SqlClientFactory,System.Data.SqlClient" - }); - _dbProviders.Add("Oracle", new SmartSql.Configuration.DbProvider - { - Name = "Oracle", - ParameterPrefix = ":", - Type = "Oracle.ManagedDataAccess.Client.OracleClientFactory,Oracle.ManagedDataAccess" - }); - _dbProviders.Add("SQLite", new SmartSql.Configuration.DbProvider - { - Name = "SQLite", - ParameterPrefix = "$", - Type = "System.Data.SQLite.SQLiteFactory,System.Data.SQLite" - }); - } - public static SmartSql.Configuration.DbProvider GetDbProvider(string providerName) - { - if (!_dbProviders.TryGetValue(providerName, out SmartSql.Configuration.DbProvider dbProvider)) - { - var supportDbProviders = String.Join(",", _dbProviders.Select(m => m.Key)); - throw new SmartCodeException($"Can not find DbProvider:{providerName},SmartCode support DbProviders:{supportDbProviders}!"); - } - return dbProvider; - } - } -} diff --git a/src/SmartCode.Db/DbRepository.cs b/src/SmartCode.Db/DbRepository.cs index 0ef3b6b..8bd989c 100644 --- a/src/SmartCode.Db/DbRepository.cs +++ b/src/SmartCode.Db/DbRepository.cs @@ -2,28 +2,26 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; -using SmartCode.Configuration; using SmartSql; -using SmartSql.Abstractions; using SmartSql.Options; namespace SmartCode.Db { public class DbRepository : IDbRepository { - private readonly DataSource _dataSource; + private readonly Configuration.DataSource _dataSource; private readonly ILoggerFactory _loggerFactory; private readonly ILogger _logger; - public ISmartSqlMapper SqlMapper { get; private set; } + public ISqlMapper SqlMapper { get; private set; } public string DbProviderName { get; private set; } - public DbProvider DbProvider { get { return (DbProvider)Enum.Parse(typeof(DbProvider), DbProviderName); } } + public DbProvider DbProvider => (DbProvider)Enum.Parse(typeof(DbProvider), DbProviderName); public string DbName { get; private set; } public string DbSchema { get; protected set; } public string ConnectionString { get; private set; } public String SqlMapPath { get; private set; } = "Maps"; public DbRepository( - DataSource dataSource + Configuration.DataSource dataSource , ILoggerFactory loggerFactory) { _dataSource = dataSource; @@ -35,17 +33,17 @@ DataSource dataSource private void InitDataSource() { var dataSource = _dataSource; - dataSource.Paramters.EnsureValue("DbProvider", out string dbProvider); + dataSource.Parameters.EnsureValue("DbProvider", out string dbProvider); DbProviderName = dbProvider; - dataSource.Paramters.EnsureValue("DbName", out string dbName); + dataSource.Parameters.EnsureValue("DbName", out string dbName); DbName = dbName; - dataSource.Paramters.EnsureValue("ConnectionString", out string connectionString); + dataSource.Parameters.EnsureValue("ConnectionString", out string connectionString); ConnectionString = connectionString; - if (dataSource.Paramters.Value("DbSchema", out string dbSchema)) + if (dataSource.Parameters.Value("DbSchema", out string dbSchema)) { DbSchema = dbSchema; } - if (dataSource.Paramters.Value("SqlMapPath", out string mapPath)) + if (dataSource.Parameters.Value("SqlMapPath", out string mapPath)) { SqlMapPath = mapPath; } @@ -55,7 +53,7 @@ private void InitSqlMapper() { SqlMapper = SmartSqlMapperFactory.Create(new SmartSqlMapperFactory.CreateSmartSqlMapperOptions { - DataSource = new SmartSql.Configuration.WriteDataSource + DataSource = new DataSource { Name = DbName, ConnectionString = ConnectionString diff --git a/src/SmartCode.Db/DbSource.cs b/src/SmartCode.Db/DbSource.cs index ab6f296..84720e4 100644 --- a/src/SmartCode.Db/DbSource.cs +++ b/src/SmartCode.Db/DbSource.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using SmartSql.Configuration; +using SmartSql.DataSource; namespace SmartCode.Db { @@ -24,21 +26,20 @@ Project project public virtual string Name { get; private set; } = "Db"; public DbRepository DbRepository { get; protected set; } - public SmartSql.SmartSqlOptions SmartSqlOptions { get { return DbRepository.SqlMapper.SmartSqlOptions; } } - public SmartSql.SmartSqlContext SmartSqlContext { get { return SmartSqlOptions.SmartSqlContext; } } - public SmartSql.Configuration.Database Database { get { return SmartSqlContext.Database; } } - public SmartSql.Configuration.DbProvider DbProvider { get { return Database.DbProvider; } } - public SmartSql.Configuration.WriteDataSource WriteDataSource { get { return Database.WriteDataSource; } } + public SmartSqlConfig SmartSqlConfig => DbRepository.SqlMapper.SmartSqlConfig; + public Database Database => SmartSqlConfig.Database; + public SmartSql.DataSource.DbProvider DbProvider => Database.DbProvider; + public WriteDataSource WriteDataSource => Database.Write; public Project Project { get; } public ILoggerFactory LoggerFactory { get; } public IPluginManager PluginManager { get; } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters != null) + if (parameters != null) { - if (paramters.Value("Name", out string name)) + if (parameters.Value("Name", out string name)) { Name = name; } diff --git a/src/SmartCode.Db/Maps/Database-Oracle.xml b/src/SmartCode.Db/Maps/Database-Oracle.xml deleted file mode 100644 index cccf293..0000000 --- a/src/SmartCode.Db/Maps/Database-Oracle.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - SELECT - T.TABLE_NAME AS "Name", - 'T' AS TypeName, - NVL(C.COMMENTS,T.TABLE_NAME) AS "Description" - FROM USER_TABLES T - LEFT JOIN USER_TAB_COMMENTS C ON T.TABLE_NAME = C.TABLE_NAME - UNION ALL - SELECT - T.VIEW_NAME AS "Name", - 'V' AS "TypeName", - NVL(C.COMMENTS,T.VIEW_NAME) AS "Description" - FROM USER_VIEWS T - LEFT JOIN USER_TAB_COMMENTS C ON T.VIEW_NAME = C.TABLE_NAME - - - SELECT - C.COLUMN_ID AS "Id", - C.TABLE_NAME AS "TableId", - C.COLUMN_NAME AS "Name", - C.DATA_TYPE AS "DbType", - C.DATA_LENGTH AS "DataLength", - NVL(CC.COMMENTS,C.COLUMN_NAME) AS "Description", - (CASE C.NULLABLE WHEN 'N' THEN 1 ELSE 0 END) AS "IsNullable", - 0 AS "AutoIncrement", - (CASE P.COLUMN_NAME WHEN 'P' THEN 1 ELSE 0 END) AS "IsPrimaryKey" - FROM USER_TAB_COLUMNS C - LEFT JOIN USER_COL_COMMENTS CC ON C.TABLE_NAME = CC.TABLE_NAME AND C.COLUMN_NAME = CC.COLUMN_NAME - LEFT JOIN ( - SELECT CU.COLUMN_NAME FROM USER_CONS_COLUMNS CU - LEFT JOIN USER_CONSTRAINTS AU ON CU.CONSTRAINT_NAME = AU.CONSTRAINT_NAME - WHERE CU.TABLE_NAME = :TableName AND AU.CONSTRAINT_TYPE='P' - )P ON C.COLUMN_NAME = P.COLUMN_NAME - WHERE C.TABLE_NAME = :TableName ORDER BY C.COLUMN_ID - - - diff --git a/src/SmartCode.Db/SmartCode.Db.csproj b/src/SmartCode.Db/SmartCode.Db.csproj index c10a09b..22f33f7 100644 --- a/src/SmartCode.Db/SmartCode.Db.csproj +++ b/src/SmartCode.Db/SmartCode.Db.csproj @@ -2,20 +2,17 @@ netstandard2.0 - 1.8.0 - - - - - - - - - - + + + + + + + + diff --git a/src/SmartCode.Db/SmartSqlMapperFactory.cs b/src/SmartCode.Db/SmartSqlMapperFactory.cs index c5caacd..5934d7b 100644 --- a/src/SmartCode.Db/SmartSqlMapperFactory.cs +++ b/src/SmartCode.Db/SmartSqlMapperFactory.cs @@ -1,77 +1,77 @@ using Microsoft.Extensions.Logging; using SmartSql; -using SmartSql.Abstractions; using SmartSql.Options; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; +using SmartSql.ConfigBuilder; namespace SmartCode.Db { public class SmartSqlMapperFactory { - public static ISmartSqlMapper Create(CreateSmartSqlMapperOptions options) + public static ISqlMapper Create(CreateSmartSqlMapperOptions options) { - var smartSqlDbProvider = DbProviders.GetDbProvider(options.ProviderName); SmartSqlConfigOptions smartSqlConfigOptions = new SmartSqlConfigOptions { Settings = new SmartSql.Configuration.Settings { ParameterPrefix = "$", IgnoreParameterCase = true, - IsWatchConfigFile = false, IsCacheEnabled = false, }, Database = new Database { - DbProvider = smartSqlDbProvider, + DbProvider = new SmartSql.DataSource.DbProvider { Name = options.ProviderName }, Write = options.DataSource, - Read = new List() + Reads = new List() }, - SmartSqlMaps = new List(), - TypeHandlers = new List { - new SmartSql.Configuration.TypeHandler - { - Name="Json", Type="SmartSql.TypeHandler.JsonTypeHandler,SmartSql.TypeHandler" - }, - new SmartSql.Configuration.TypeHandler + SmartSqlMaps = new List(), + TypeHandlers = new List + { + new TypeHandler { - Name="PGJson", Type="SmartSql.TypeHandler.PostgreSql.JsonTypeHandler,SmartSql.TypeHandler.PostgreSql" + Name = "Json", Type = "SmartSql.TypeHandler.JsonTypeHandler,SmartSql.TypeHandler" }, - new SmartSql.Configuration.TypeHandler + new TypeHandler { - Name="PGJsonb", Type="SmartSql.TypeHandler.PostgreSql.JsonbTypeHandler,SmartSql.TypeHandler.PostgreSql" + Name = "PGJson", + Type = "SmartSql.TypeHandler.PostgreSql.JsonTypeHandler,SmartSql.TypeHandler.PostgreSql" }, - new SmartSql.Configuration.TypeHandler + new TypeHandler { - Name="OracleBoolean", Type="SmartSql.TypeHandler.Oracle.BooleanTypeHandler,SmartSql.TypeHandler.Oracle" + Name = "PGJsonb", + Type = "SmartSql.TypeHandler.PostgreSql.JsonTypeHandler,SmartSql.TypeHandler.PostgreSql", + Properties=new Dictionary + { + { "DataTypeName","jsonb"} + } } } }; if (!String.IsNullOrEmpty(options.SqlMapPath)) { - smartSqlConfigOptions.SmartSqlMaps.Add(new SmartSql.Configuration.SmartSqlMapSource + smartSqlConfigOptions.SmartSqlMaps.Add(new SqlMapSource { Path = options.SqlMapPath, - Type = SmartSql.Configuration.SmartSqlMapSource.ResourceType.Directory + Type = ResourceType.Directory }); } - var _configLoader = new OptionConfigLoader(smartSqlConfigOptions, options.LoggerFactory); - var smartsqlOptions = new SmartSqlOptions - { - Alias = options.Alias, - ConfigPath = options.Alias, - ConfigLoader = _configLoader, - LoggerFactory = options.LoggerFactory - }; - return MapperContainer.Instance.GetSqlMapper(smartsqlOptions); + + var optionConfigBuilder = new OptionConfigBuilder(smartSqlConfigOptions, options.LoggerFactory); + return new SmartSqlBuilder() + .UseLoggerFactory(options.LoggerFactory) + .UseConfigBuilder(optionConfigBuilder) + .UseAlias(options.Alias) + .Build().SqlMapper; } public class CreateSmartSqlMapperOptions { public string Alias { get; set; } = "SmartSql"; public string ProviderName { get; set; } - public SmartSql.Configuration.WriteDataSource DataSource { get; set; } + public DataSource DataSource { get; set; } public ILoggerFactory LoggerFactory { get; set; } public string SqlMapPath { get; set; } } diff --git a/src/SmartCode.ETL.LoadToES/ESOptions.cs b/src/SmartCode.ETL.LoadToES/ESOptions.cs new file mode 100644 index 0000000..50be3ad --- /dev/null +++ b/src/SmartCode.ETL.LoadToES/ESOptions.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SmartCode.ETL.LoadToES +{ + public class ESOptions + { + public String Host { get; set; } + public String Index { get; set; } + public String TypeName { get; set; } + public String Cert { get; set; } + public String UserName { get; set; } + public String Password { get; set; } + } + +} diff --git a/src/SmartCode.ETL.LoadToES/LoadToESBuildTask.cs b/src/SmartCode.ETL.LoadToES/LoadToESBuildTask.cs new file mode 100644 index 0000000..8133ba4 --- /dev/null +++ b/src/SmartCode.ETL.LoadToES/LoadToESBuildTask.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Nest; +using Elasticsearch.Net; +using System.Linq; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; +using System.Diagnostics; +using System.Collections; +using System.Data; + +namespace SmartCode.ETL.LoadToES +{ + public class LoadToESBuildTask : IBuildTask + { + private const string COLUMN_MAPPING = "ColumnMapping"; + private const string ID_MAPPING = "Id"; + private const string HOST = "Host"; + private const string INDEX_NAME = "Index"; + private const string TYPE_NAME = "Type"; + private const string BASE_AUTH = "BaseAuth"; + private const string CERT_PATH = "Cert"; + private readonly Project _project; + private readonly IPluginManager _pluginManager; + private readonly ILogger _logger; + + public bool Initialized => true; + + public string Name => "LoadToES"; + public LoadToESBuildTask(Project project + , IPluginManager pluginManager + , ILogger logger) + { + _project = project; + _pluginManager = pluginManager; + _logger = logger; + } + public async Task Build(BuildContext context) + { + ESOptions esOptions = InitOptions(context); + var etlRepository = _pluginManager.Resolve(_project.GetETLRepository()); + var dataSource = context.GetExtractData(); + var loadEntity = new Entity.ETLLoad + { + Size = 0, + Parameters = new Dictionary + { + { "Task","LoadToES"}, + { "Index",esOptions.Index}, + { "Type",esOptions.TypeName} + } + }; + if (dataSource.TransformData.Count == 0) + { + await etlRepository.Load(_project.GetETKTaskId(), loadEntity); + return; + } + Stopwatch stopwatch = Stopwatch.StartNew(); + #region InitColumnMapping + + var colMapping = new Dictionary(); + if (context.Build.Parameters.Value(COLUMN_MAPPING, out IEnumerable colMapps)) + { + foreach (IDictionary colMappingKV in colMapps) + { + colMappingKV.EnsureValue("Column", out string colName); + colMappingKV.EnsureValue("Mapping", out string mapping); + colMapping.Add(colName, mapping); + } + } + dataSource.TransformData = dataSource.TransformData.Select((dic) => + { + IDictionary newItem = new Dictionary(); + foreach (KeyValuePair item in dic) + { + var itemKey = item.Key; + if (colMapps != null) + { + if (colMapping.TryGetValue(itemKey, out string mapping)) + { + itemKey = mapping; + } + } + newItem.Add(itemKey,item.Value); + } + return newItem; + }).ToList(); + + #endregion + #region BatchInsert + var esClient = GetElasticClient(esOptions); + var indexExResp = await esClient.IndexExistsAsync(esOptions.Index); + if (!indexExResp.Exists) + { + var createIndexResp = await esClient.CreateIndexAsync(esOptions.Index); + } + var esSyncResp = await esClient.BulkAsync((bulkRequest) => + { + var bulkReqDesc = bulkRequest + .Index(esOptions.Index) + .Type(esOptions.TypeName); + if (context.Build.Parameters.Value(ID_MAPPING, out string es_id)) + { + return bulkReqDesc.IndexMany(dataSource.TransformData, (bulkIdxDesc, item) => + { + var idVal = item[es_id].ToString(); + return bulkIdxDesc.Id(idVal); + } + ); + } + return bulkReqDesc.IndexMany(dataSource.TransformData); + } + ); + if (esSyncResp.Errors || !esSyncResp.IsValid) + { + _logger.LogError($"ES.ERRORS:{esSyncResp.DebugInformation}"); + throw new SmartCodeException($"ES.ERRORS:{esSyncResp.DebugInformation}"); + } + stopwatch.Stop(); + loadEntity.Size = dataSource.TransformData.Count; + loadEntity.Taken = stopwatch.ElapsedMilliseconds; + #endregion + await etlRepository.Load(_project.GetETKTaskId(), loadEntity); + } + + private static ESOptions InitOptions(BuildContext context) + { + context.Build.Parameters.EnsureValue(HOST, out string host); + context.Build.Parameters.EnsureValue(INDEX_NAME, out string index_name); + context.Build.Parameters.EnsureValue(TYPE_NAME, out string type_name); + context.Build.Parameters.Value(BASE_AUTH, out IDictionary baseAuth); + baseAuth.Value("UserName", out string user_name); + baseAuth.Value("Password", out string password); + context.Build.Parameters.Value(CERT_PATH, out string cert); + + return new ESOptions + { + Host = host, + Index = index_name, + TypeName = type_name, + Cert = cert, + UserName = user_name, + Password = password + }; + } + + private IElasticClient GetElasticClient(ESOptions esOptions) + { + Uri node = new Uri(esOptions.Host); + ConnectionSettings settings = new ConnectionSettings(node); + settings.DefaultIndex(esOptions.Index); + settings.DefaultTypeName(esOptions.TypeName); + #region Auth + if (!String.IsNullOrEmpty(esOptions.UserName)) + { + settings.BasicAuthentication(esOptions.UserName, esOptions.Password); + } + if (!String.IsNullOrEmpty(esOptions.Cert)) + { + settings.ClientCertificate(esOptions.Cert); + } + #endregion + return new ElasticClient(settings); + } + + public void Initialize(IDictionary parameters) + { + + } + } +} diff --git a/src/SmartCode.ETL.LoadToES/SmartCode.ETL.LoadToES.csproj b/src/SmartCode.ETL.LoadToES/SmartCode.ETL.LoadToES.csproj new file mode 100644 index 0000000..db96e9a --- /dev/null +++ b/src/SmartCode.ETL.LoadToES/SmartCode.ETL.LoadToES.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/src/SmartCode.ETL.PostgreSql/PGETLTaskRepository.cs b/src/SmartCode.ETL.PostgreSql/PGETLTaskRepository.cs index 1cf2916..4f20172 100644 --- a/src/SmartCode.ETL.PostgreSql/PGETLTaskRepository.cs +++ b/src/SmartCode.ETL.PostgreSql/PGETLTaskRepository.cs @@ -4,7 +4,8 @@ using SmartCode.ETL.Entity; using SmartCode.Db; using Microsoft.Extensions.Logging; -using SmartSql.Abstractions; +using SmartSql; +using SmartSql.Options; namespace SmartCode.ETL.PostgreSql { @@ -16,7 +17,7 @@ public class PGETLTaskRepository : IETLTaskRepository public bool Initialized { get; private set; } public string Name => "PG"; public string Scope => "EtlTask"; - public ISmartSqlMapper SqlMapper { get; set; } + public ISqlMapper SqlMapper { get; set; } public PGETLTaskRepository(ILoggerFactory loggerFactory) { _loggerFactory = loggerFactory; @@ -24,13 +25,14 @@ public PGETLTaskRepository(ILoggerFactory loggerFactory) public void Initialize(IDictionary paramters) { paramters.EnsureValue(CONNECTION_STRING, out string connectionString); + SqlMapper = SmartSqlMapperFactory.Create(new SmartSqlMapperFactory.CreateSmartSqlMapperOptions { Alias = "PGETLRepository", LoggerFactory = _loggerFactory, ProviderName = "PostgreSql", SqlMapPath = DEFAULT_SQLMAP_PATH, - DataSource = new SmartSql.Configuration.WriteDataSource + DataSource = new DataSource { ConnectionString = connectionString, Name = "PGETL" @@ -53,7 +55,7 @@ public Task Extract(long etlTaskId, ETLExtract extract) }); } - public Task Fail(long etlTaskId, string errMsg) + public Task Fail(long etlTaskId, Exception errorException) { return SqlMapper.ExecuteAsync(new RequestContext { @@ -65,7 +67,8 @@ public Task Fail(long etlTaskId, string errMsg) Status = ETLTaskStatus.Failed, ExtendData = new Dictionary { - { "error_msg",errMsg} + { "error_msg",errorException.Message}, + { "stack_trace",errorException.StackTrace} } } }); diff --git a/src/SmartCode.ETL.PostgreSql/SmartCode.ETL.PostgreSql.csproj b/src/SmartCode.ETL.PostgreSql/SmartCode.ETL.PostgreSql.csproj index 4a48e19..2e746e5 100644 --- a/src/SmartCode.ETL.PostgreSql/SmartCode.ETL.PostgreSql.csproj +++ b/src/SmartCode.ETL.PostgreSql/SmartCode.ETL.PostgreSql.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 diff --git a/src/SmartCode.ETL.SQLite/SQLiteETLTaskRepository.cs b/src/SmartCode.ETL.SQLite/SQLiteETLTaskRepository.cs index 442526e..00e74c4 100644 --- a/src/SmartCode.ETL.SQLite/SQLiteETLTaskRepository.cs +++ b/src/SmartCode.ETL.SQLite/SQLiteETLTaskRepository.cs @@ -2,10 +2,11 @@ using SmartCode.Db; using SmartCode.ETL.Entity; using SmartCode.Utilities; -using SmartSql.Abstractions; using System; using System.Collections.Generic; using System.Threading.Tasks; +using SmartSql; +using SmartSql.Options; namespace SmartCode.ETL.SQLite { @@ -18,7 +19,7 @@ public class SQLiteETLTaskRepository : IETLTaskRepository public bool Initialized { get; private set; } public string Name => "SQLite"; public string Scope => "EtlTask"; - public ISmartSqlMapper SqlMapper { get; set; } + public ISqlMapper SqlMapper { get; set; } public SQLiteETLTaskRepository(ILoggerFactory loggerFactory) { _loggerFactory = loggerFactory; @@ -37,7 +38,7 @@ public void Initialize(IDictionary paramters) LoggerFactory = _loggerFactory, ProviderName = "SQLite", SqlMapPath = DEFAULT_SQLMAP_PATH, - DataSource = new SmartSql.Configuration.WriteDataSource + DataSource = new DataSource { ConnectionString = connectionString, Name = "SQLiteETL" @@ -60,7 +61,7 @@ public Task Extract(long etlTaskId, ETLExtract extract) }); } - public Task Fail(long etlTaskId, string errMsg) + public Task Fail(long etlTaskId, Exception errorException) { return SqlMapper.ExecuteAsync(new RequestContext { @@ -72,7 +73,8 @@ public Task Fail(long etlTaskId, string errMsg) Status = ETLTaskStatus.Failed, ExtendData = new Dictionary { - { "error_msg",errMsg} + { "error_msg",errorException.Message}, + { "stack_trace",errorException.StackTrace} } } }); diff --git a/src/SmartCode.ETL.SQLite/SmartCode.ETL.SQLite.csproj b/src/SmartCode.ETL.SQLite/SmartCode.ETL.SQLite.csproj index a570080..43d8d41 100644 --- a/src/SmartCode.ETL.SQLite/SmartCode.ETL.SQLite.csproj +++ b/src/SmartCode.ETL.SQLite/SmartCode.ETL.SQLite.csproj @@ -1,11 +1,11 @@ - + netstandard2.0 - + diff --git a/src/SmartCode.ETL/AbstractExtractData.cs b/src/SmartCode.ETL/AbstractExtractData.cs new file mode 100644 index 0000000..e0e8db6 --- /dev/null +++ b/src/SmartCode.ETL/AbstractExtractData.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; +using SmartCode.ETL.Entity; +using SmartSql; + +namespace SmartCode.ETL +{ + public abstract class AbstractExtractData : IExtractData + { + private readonly Project _project; + private readonly ILoggerFactory _loggerFactory; + private readonly ILogger _logger; + private readonly IPluginManager _pluginManager; + public abstract string Name { get; } + protected ISqlMapper SqlMapper { get; private set; } + + public bool Initialized { get; private set; } + + private IETLTaskRepository _etlRepository; + + protected AbstractExtractData(Project project + , ILoggerFactory loggerFactory + , ILogger logger + , IPluginManager pluginManager) + { + _project = project; + _loggerFactory = loggerFactory; + _logger = logger; + _pluginManager = pluginManager; + _etlRepository = _pluginManager.Resolve(_project.GetETLRepository()); + } + + private async Task Extract() + { + var queryParams = new Dictionary + { + {"LastMaxId", LastExtract.MaxId}, + {"LastQueryTime", LastExtract.QueryTime}, + {"LastMaxModifyTime", LastExtract.MaxModifyTime}, + {nameof(Offset), Offset}, + {nameof(BulkSize), BulkSize}, + }; + + var extractEntity = new ETLExtract + { + QueryTime = DateTime.Now, + PKColumn = PKColumn, + QueryCommand = new ETLDbCommand + { + Command = QueryCmd, + Parameters = queryParams + }, + Count = -1, + MaxId = -1 + }; + Stopwatch stopwatch = Stopwatch.StartNew(); + await LoadData(new RequestContext {RealSql = QueryCmd, Request = queryParams}); + stopwatch.Stop(); + extractEntity.Count = GetCount(); + extractEntity.QueryCommand.Taken = stopwatch.ElapsedMilliseconds; + _logger.LogWarning($"InitData,Data.Size:{extractEntity.Count},Taken:{extractEntity.QueryCommand.Taken}ms!"); + + if (!String.IsNullOrEmpty(PKColumn) + && (PkIsNumeric || AutoIncrement) + && extractEntity.Count > 0) + { + extractEntity.MaxId = GetMaxId(PKColumn); + } + else + { + extractEntity.MaxId = LastExtract.MaxId; + } + + if (!String.IsNullOrEmpty(ModifyTime) + && extractEntity.Count > 0) + { + extractEntity.MaxModifyTime = GetMaxModifyTime(ModifyTime); + } + else + { + extractEntity.MaxModifyTime = LastExtract.MaxModifyTime; + } + + await _etlRepository.Extract(_project.GetETKTaskId(), extractEntity); + } + + protected abstract Task LoadData(RequestContext requestContext); + public abstract int GetCount(); + public abstract long GetMaxId(string pkColumn); + public abstract DateTime GetMaxModifyTime(string modifyTime); + + public void Initialize(IDictionary parameters) + { + Initialized = true; + } + + public int Total { get; private set; } + public int BulkSize { get; private set; } + public int Offset { get; private set; } + + public String PKColumn { get; private set; } + public String ModifyTime { get; private set; } + public String QueryCmd { get; private set; } + public String TotalCmd { get; private set; } + public bool PkIsNumeric { get; private set; } + public bool AutoIncrement { get; private set; } + protected ETLExtract LastExtract { get; private set; } + + public async Task Run() + { + InitParameters(); + + LastExtract = await _etlRepository.GetLastExtract(_project.GetETLCode()); + _project.SetETLLastExtract(LastExtract); + + var queryParams = new Dictionary + { + {"LastMaxId", LastExtract.MaxId}, + {"LastQueryTime", LastExtract.QueryTime}, + {"LastMaxModifyTime", LastExtract.MaxModifyTime} + }; + + Total = await SqlMapper.ExecuteScalarAsync(new RequestContext + { + RealSql = TotalCmd, + Request = queryParams + }); + + if (Total == 0) + { + _logger.LogInformation("can not find any record."); + return; + } + + if (BulkSize == 0) + { + BulkSize = Total; + } + + BuildContext buildContext = null; + while (Offset < Total) + { + _logger.LogInformation($"--------Total:[{Total}] , Offset:[{Offset}] ---------"); + try + { + var etlTaskId = await _etlRepository.Startup(_project.ConfigPath, _project.GetETLCode()); + _project.SetETKTaskId(etlTaskId); + await Extract(); + if (String.IsNullOrEmpty(TotalCmd)) + { + Total = GetCount(); + BulkSize = Total; + } + + foreach (var buildKV in _project.BuildTasks) + { + _logger.LogInformation($"-------- BuildTask:{buildKV.Key} Start! ---------"); + var output = buildKV.Value.Output; + buildContext = new BuildContext + { + PluginManager = _pluginManager, + Project = _project, + BuildKey = buildKV.Key, + Build = buildKV.Value, + Output = output?.Copy() + }; + buildContext.SetExtractData(this); + await _pluginManager.Resolve(buildKV.Value.Type).Build(buildContext); + _logger.LogInformation($"-------- BuildTask:{buildKV.Key} End! ---------"); + } + + await _etlRepository.Success(_project.GetETKTaskId()); + Offset += BulkSize; + } + catch (Exception e) + { + await _etlRepository.Fail(_project.GetETKTaskId(), e); + throw; + } + } + } + + private void InitParameters() + { + var dataSource = _project.DataSource; + dataSource.Parameters.EnsureValue("DbProvider", out string dbProvider); + dataSource.Parameters.EnsureValue("ConnectionString", out String connString); + dataSource.Parameters.Value("PKColumn", out string pkColumn); + PKColumn = pkColumn; + dataSource.Parameters.Value("ModifyTime", out string modifyTime); + ModifyTime = modifyTime; + dataSource.Parameters.Value("PkIsNumeric", out bool pkIsNumeric); + PkIsNumeric = pkIsNumeric; + dataSource.Parameters.Value("AutoIncrement", out bool autoIncrement); + AutoIncrement = autoIncrement; + dataSource.Parameters.EnsureValue("Query", out string queryCmd); + QueryCmd = queryCmd; + + #region CreateSqlMapper + + SqlMapper = new SmartSqlBuilder() + .UseAlias(Name) + .UseLoggerFactory(_loggerFactory) + .UseDataSource(dbProvider, connString) + .Build().SqlMapper; + + #endregion + + TotalCmd = dataSource.Parameters.Value("Total", out String totalCmd) + ? totalCmd + : $"Select Count(*) From ({QueryCmd.TrimEnd(';')}) as t;"; + + _project.DataSource.Parameters.Value("BulkSize", out int bulkSize); + BulkSize = bulkSize; + } + } +} \ No newline at end of file diff --git a/src/SmartCode.ETL/BatchInsertFactory.cs b/src/SmartCode.ETL/BatchInsertFactory.cs index d9e364f..3a6e4cb 100644 --- a/src/SmartCode.ETL/BatchInsertFactory.cs +++ b/src/SmartCode.ETL/BatchInsertFactory.cs @@ -1,36 +1,40 @@ -using SmartSql.Batch; -using SmartSql.Configuration; -using System; +using SmartSql.Bulk; using System.Collections.Generic; -using System.Text; -using SmartSql.Abstractions; +using SmartSql; namespace SmartCode.ETL { public class BatchInsertFactory { - public static IBatchInsert Create(ISmartSqlMapper smartSqlMapper, Db.DbProvider dbProvider) + public static IBulkInsert Create(ISqlMapper sqlMapper, Db.DbProvider dbProvider, BuildContext buildContext) { switch (dbProvider) { case Db.DbProvider.MySql: case Db.DbProvider.MariaDB: + { + var bulkInset = new SmartSql.Bulk.MySql.BulkInsert(sqlMapper.SessionStore.LocalSession); + if (buildContext.Build.Parameters.Value("SecureFilePriv", + out string secureFilePriv)) { - return new SmartSql.Batch.MySql.BatchInsert(smartSqlMapper); + bulkInset.SecureFilePriv = secureFilePriv; } + + return bulkInset; + } case Db.DbProvider.PostgreSql: - { - return new SmartSql.Batch.PostgreSql.BatchInsert(smartSqlMapper); - } + { + return new SmartSql.Bulk.PostgreSql.BulkInsert(sqlMapper.SessionStore.LocalSession); + } case Db.DbProvider.SqlServer: - { - return new SmartSql.Batch.SqlServer.BatchInsert(smartSqlMapper); - } + { + return new SmartSql.Bulk.SqlServer.BulkInsert(sqlMapper.SessionStore.LocalSession); + } default: - { - throw new SmartCodeException($"can not support DbProvider:{dbProvider}!"); - } + { + throw new SmartCodeException($"can not support DbProvider:{dbProvider}!"); + } } } } -} +} \ No newline at end of file diff --git a/src/SmartCode.ETL/BuildContextExtensions.cs b/src/SmartCode.ETL/BuildContextExtensions.cs index 3b9a26a..c287138 100644 --- a/src/SmartCode.ETL/BuildContextExtensions.cs +++ b/src/SmartCode.ETL/BuildContextExtensions.cs @@ -2,20 +2,19 @@ using System.Collections.Generic; using System.Text; using SmartSql; -using SmartSql.Batch; namespace SmartCode.ETL { public static class BuildContextExtensions { - //public const String ETL_DB_TABLE = "ETLDbTable"; - //public static DbTable GetETLDbTable(this BuildContext context) - //{ - // return context.GetItem(ETL_DB_TABLE); - //} - //public static void SetETLDbTable(this BuildContext context, DbTable dbTable) - //{ - // context.SetItem(ETL_DB_TABLE, dbTable); - //} + public const String ETL_EXTRACT_DATA = "ETL_ExtractData"; + public static TExtractData GetExtractData(this BuildContext context)where TExtractData : IExtractData + { + return context.GetItem(ETL_EXTRACT_DATA); + } + public static void SetExtractData(this BuildContext context, IExtractData extractData) + { + context.SetItem(ETL_EXTRACT_DATA, extractData); + } } } diff --git a/src/SmartCode.ETL/BuildTasks/LoadBuildTask.cs b/src/SmartCode.ETL/BuildTasks/LoadBuildTask.cs index 182ece6..6659eb3 100644 --- a/src/SmartCode.ETL/BuildTasks/LoadBuildTask.cs +++ b/src/SmartCode.ETL/BuildTasks/LoadBuildTask.cs @@ -1,14 +1,14 @@ using Microsoft.Extensions.Logging; using SmartCode.Configuration; using SmartCode.Db; -using SmartSql.Abstractions; -using SmartSql.Batch; +using SmartSql.Bulk; using System; using System.Collections; using System.Collections.Generic; +using System.Data; using System.Diagnostics; -using System.Text; using System.Threading.Tasks; +using SmartSql; using static SmartCode.Db.SmartSqlMapperFactory; namespace SmartCode.ETL.BuildTasks @@ -20,19 +20,20 @@ public class LoadBuildTask : IBuildTask private const string COLUMN_MAPPING = "ColumnMapping"; private const string PRE_COMMAND = "PreCommand"; private const string POST_COMMAND = "PostCommand"; - private readonly ILoggerFactory _loggerFacotry; + private readonly ILoggerFactory _loggerFactory; private readonly Project _project; private readonly IPluginManager _pluginManager; private readonly ILogger _logger; public bool Initialized => true; public string Name => "Load"; - public LoadBuildTask(ILoggerFactory loggerFacotry + + public LoadBuildTask(ILoggerFactory loggerFactory , Project project , IPluginManager pluginManager , ILogger logger) { - _loggerFacotry = loggerFacotry; + _loggerFactory = loggerFactory; _project = project; _pluginManager = pluginManager; _logger = logger; @@ -40,10 +41,10 @@ public LoadBuildTask(ILoggerFactory loggerFacotry public async Task Build(BuildContext context) { - context.Build.Paramters.EnsureValue(TABLE_NAME, out string tableName); - context.Build.Paramters.EnsureValue(DB_PROVIDER, out DbProvider dbProvider); + context.Build.Parameters.EnsureValue(TABLE_NAME, out string tableName); + context.Build.Parameters.EnsureValue(DB_PROVIDER, out DbProvider dbProvider); var etlRepository = _pluginManager.Resolve(_project.GetETLRepository()); - var dataSource = context.GetDataSource(); + var dataSource = context.GetExtractData(); if (dataSource.TransformData.Rows.Count == 0) { await etlRepository.Load(_project.GetETKTaskId(), new Entity.ETLLoad @@ -53,16 +54,18 @@ public async Task Build(BuildContext context) }); return; } + var batchTable = dataSource.TransformData; - batchTable.Name = tableName; + batchTable.TableName = tableName; + var sqlMapper = GetSqlMapper(context); - context.Build.Paramters.Value(PRE_COMMAND, out string preCmd); + context.Build.Parameters.Value(PRE_COMMAND, out string preCmd); var lastExtract = _project.GetETLLastExtract(); var queryParams = new Dictionary { - { "LastMaxId",lastExtract.MaxId}, - { "LastQueryTime",lastExtract.QueryTime}, - { "LastMaxModifyTime",lastExtract.MaxModifyTime}, + {"LastMaxId", lastExtract.MaxId}, + {"LastQueryTime", lastExtract.QueryTime}, + {"LastMaxModifyTime", lastExtract.MaxModifyTime}, }; Stopwatch stopwatch = Stopwatch.StartNew(); var loadEntity = new Entity.ETLLoad @@ -71,8 +74,10 @@ public async Task Build(BuildContext context) }; try { - sqlMapper.BeginSession(); + sqlMapper.SessionStore.Open(); + #region PreCmd + if (!String.IsNullOrEmpty(preCmd)) { stopwatch.Restart(); @@ -85,24 +90,31 @@ await sqlMapper.ExecuteAsync(new RequestContext loadEntity.PreCommand = new Entity.ETLDbCommand { Command = preCmd, - Paramters = queryParams, + Parameters = queryParams, Taken = stopwatch.ElapsedMilliseconds }; } + #endregion + #region BatchInsert - var batchInsert = BatchInsertFactory.Create(sqlMapper, dbProvider); - InitColumnMapping(batchInsert, context); + + var batchInsert = BatchInsertFactory.Create(sqlMapper, dbProvider, context); + InitColumnMapping(batchTable, context); batchInsert.Table = batchTable; stopwatch.Restart(); await batchInsert.InsertAsync(); stopwatch.Stop(); loadEntity.Size = batchTable.Rows.Count; loadEntity.Taken = stopwatch.ElapsedMilliseconds; - _logger.LogWarning($"Build:{context.BuildKey},BatchInsert.Size:{loadEntity.Size},Taken:{loadEntity.Taken}ms!"); + _logger.LogWarning( + $"Build:{context.BuildKey},BatchInsert.Size:{loadEntity.Size},Taken:{loadEntity.Taken}ms!"); + #endregion + #region PostCmd - if (context.Build.Paramters.Value(POST_COMMAND, out string postCmd) && !String.IsNullOrEmpty(postCmd)) + + if (context.Build.Parameters.Value(POST_COMMAND, out string postCmd) && !String.IsNullOrEmpty(postCmd)) { stopwatch.Restart(); await sqlMapper.ExecuteAsync(new RequestContext @@ -114,64 +126,54 @@ await sqlMapper.ExecuteAsync(new RequestContext loadEntity.PostCommand = new Entity.ETLDbCommand { Command = postCmd, - Paramters = queryParams, + Parameters = queryParams, Taken = stopwatch.ElapsedMilliseconds }; } + #endregion + await etlRepository.Load(_project.GetETKTaskId(), loadEntity); } finally { - sqlMapper.EndSession(); + sqlMapper.SessionStore.Dispose(); } } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - } - private void InitColumnMapping(IBatchInsert batchInsert, BuildContext context) + private void InitColumnMapping(DataTable bulkTable, BuildContext context) { - if (context.Build.Paramters.Value(COLUMN_MAPPING, out IEnumerable colMapps)) + if (context.Build.Parameters.Value(COLUMN_MAPPING, out IEnumerable colMapps)) { foreach (IDictionary colMappingKV in colMapps) { colMappingKV.EnsureValue("Column", out string colName); colMappingKV.EnsureValue("Mapping", out string mapping); - colMappingKV.Value("DataTypeName", out string dataTypeName); - var colMapping = new ColumnMapping + var sourceColumn = bulkTable.Columns[colName]; + sourceColumn.ColumnName = mapping; + if (colMappingKV.Value("DataTypeName", out string dataTypeName)) { - Column = colName, - Mapping = mapping, - DataTypeName = dataTypeName - }; - batchInsert.AddColumnMapping(colMapping); + sourceColumn.ExtendedProperties.Add("DataTypeName", dataTypeName); + } } } } - private ISmartSqlMapper GetSqlMapper(BuildContext context) - { - var smartSqlOptions = InitCreateSmartSqlMapperOptions(context); - return SmartSqlMapperFactory.Create(smartSqlOptions); - } - private CreateSmartSqlMapperOptions InitCreateSmartSqlMapperOptions(BuildContext context) + + private ISqlMapper GetSqlMapper(BuildContext context) { - context.Build.Paramters.EnsureValue(DB_PROVIDER, out string dbProvider); - context.Build.Paramters.EnsureValue("ConnectionString", out string connString); - var alias_name = $"{Name}_{context.BuildKey}"; - return new CreateSmartSqlMapperOptions - { - Alias = alias_name, - LoggerFactory = _loggerFacotry, - ProviderName = dbProvider, - DataSource = new SmartSql.Configuration.WriteDataSource - { - Name = Name, - ConnectionString = connString - } - }; + context.Build.Parameters.EnsureValue(DB_PROVIDER, out string dbProvider); + context.Build.Parameters.EnsureValue("ConnectionString", out string connString); + var alias_name = $"{Name}_{context.BuildKey}_{Guid.NewGuid():N}"; + + return new SmartSqlBuilder() + .UseDataSource(dbProvider, connString) + .UseLoggerFactory(_loggerFactory) + .UseAlias(alias_name) + .Build().SqlMapper; } } -} +} \ No newline at end of file diff --git a/src/SmartCode.ETL/BuildTasks/TransformBuildTask.cs b/src/SmartCode.ETL/BuildTasks/TransformBuildTask.cs index cb41a09..518d54d 100644 --- a/src/SmartCode.ETL/BuildTasks/TransformBuildTask.cs +++ b/src/SmartCode.ETL/BuildTasks/TransformBuildTask.cs @@ -28,8 +28,8 @@ public async Task Build(BuildContext context) { var etlRepository = _pluginManager.Resolve(_project.GetETLRepository()); Stopwatch stopwatch = Stopwatch.StartNew(); - var dataSource = context.GetDataSource(); - if (dataSource.TransformData.Rows.Count > 0) + var dataSource = context.GetExtractData(); + if (dataSource.GetCount()> 0) { await _pluginManager.Resolve(DEFAULT_SCRIPT_ENGINE).Transform(context); } @@ -40,7 +40,7 @@ public async Task Build(BuildContext context) }); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode.ETL/ETLProjectBuilder.cs b/src/SmartCode.ETL/ETLProjectBuilder.cs new file mode 100644 index 0000000..91de66e --- /dev/null +++ b/src/SmartCode.ETL/ETLProjectBuilder.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; + +namespace SmartCode.ETL +{ + public class ETLProjectBuilder : IProjectBuilder + { + private readonly Project _project; + private readonly IPluginManager _pluginManager; + private readonly ILogger _logger; + + + public ETLProjectBuilder( + Project project + , IPluginManager pluginManager + , ILogger logger) + { + _project = project; + _pluginManager = pluginManager; + _logger = logger; + } + + public Task Build() + { + var extractData = _pluginManager.Resolve(_project.DataSource.Name); + return extractData.Run(); + } + } +} \ No newline at end of file diff --git a/src/SmartCode.ETL/Entity/ETLDbCommand.cs b/src/SmartCode.ETL/Entity/ETLDbCommand.cs index f2cfd06..b3e7ae3 100644 --- a/src/SmartCode.ETL/Entity/ETLDbCommand.cs +++ b/src/SmartCode.ETL/Entity/ETLDbCommand.cs @@ -7,7 +7,7 @@ namespace SmartCode.ETL.Entity public class ETLDbCommand { public string Command { get; set; } - public IDictionary Paramters { get; set; } + public IDictionary Parameters { get; set; } public long Taken { get; set; } } } diff --git a/src/SmartCode.ETL/Entity/ETLExtract.cs b/src/SmartCode.ETL/Entity/ETLExtract.cs index 7c700ce..1e58504 100644 --- a/src/SmartCode.ETL/Entity/ETLExtract.cs +++ b/src/SmartCode.ETL/Entity/ETLExtract.cs @@ -13,13 +13,14 @@ public class ETLExtract MaxId = -1, QueryTime = MinDateTime, MaxModifyTime = MinDateTime, - QuerySize = -1 + Count = -1 }; public string PKColumn { get; set; } + public int Count { get; set; } public long MaxId { get; set; } public DateTime MaxModifyTime { get; set; } public DateTime QueryTime { get; set; } public ETLDbCommand QueryCommand { get; set; } - public int QuerySize { get; set; } + } } diff --git a/src/SmartCode.ETL/Entity/ETLLoad.cs b/src/SmartCode.ETL/Entity/ETLLoad.cs index 27c86b8..41ee63e 100644 --- a/src/SmartCode.ETL/Entity/ETLLoad.cs +++ b/src/SmartCode.ETL/Entity/ETLLoad.cs @@ -11,5 +11,6 @@ public class ETLLoad public int Size { get; set; } public long Taken { get; set; } public string Table { get; set; } + public IDictionary Parameters { get; set; } } } diff --git a/src/SmartCode.ETL/Entity/Monitor.cs b/src/SmartCode.ETL/Entity/Monitor.cs index d3ec5e3..f7b674b 100644 --- a/src/SmartCode.ETL/Entity/Monitor.cs +++ b/src/SmartCode.ETL/Entity/Monitor.cs @@ -6,7 +6,7 @@ namespace SmartCode.ETL.Entity { public class Monitor { - public string BuidKey { get; set; } + public string BuildKey { get; set; } public string MachineName { get; } diff --git a/src/SmartCode.ETL/ExtractData.cs b/src/SmartCode.ETL/ExtractData.cs new file mode 100644 index 0000000..6dec48f --- /dev/null +++ b/src/SmartCode.ETL/ExtractData.cs @@ -0,0 +1,43 @@ +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; +using SmartSql; + +namespace SmartCode.ETL +{ + public class ExtractData : AbstractExtractData + { + public ExtractData(Project project, ILoggerFactory loggerFactory, ILogger logger, + IPluginManager pluginManager) : base(project, loggerFactory, logger, pluginManager) + { + } + + public override string Name => "Extract"; + public DataSet DataSet { get; set; } + public DataTable TransformData { get; set; } + + protected override async Task LoadData(RequestContext requestContext) + { + DataSet = await SqlMapper.GetDataSetAsync(requestContext); + TransformData = DataSet.Tables[0]; + } + + public override long GetMaxId(string pkColumn) + { + return TransformData.Rows.Cast().AsParallel().Max(dr => Convert.ToInt64(dr[pkColumn])); + } + + public override DateTime GetMaxModifyTime(string modifyTime) + { + return TransformData.Rows.Cast().AsParallel().Max(dr => Convert.ToDateTime(dr[modifyTime])); + } + + public override int GetCount() + { + return TransformData.Rows.Count; + } + } +} \ No newline at end of file diff --git a/src/SmartCode.ETL/ExtractDataSource.cs b/src/SmartCode.ETL/ExtractDataSource.cs deleted file mode 100644 index 21ef8d3..0000000 --- a/src/SmartCode.ETL/ExtractDataSource.cs +++ /dev/null @@ -1,154 +0,0 @@ -using Microsoft.Extensions.Logging; -using SmartCode.Configuration; -using SmartSql.Abstractions; -using SmartSql.Batch; -using System.Collections.Generic; -using System.Threading.Tasks; -using static SmartCode.Db.SmartSqlMapperFactory; -using System.Data; -using System.Diagnostics; -using SmartSql; -using System.Linq; -using System; -using SmartCode.ETL.Entity; - -namespace SmartCode.ETL -{ - public class ExtractDataSource : IDataSource - { - private readonly Project _project; - private readonly ILoggerFactory _loggerFactory; - private readonly ILogger _logger; - private readonly IProjectBuilder _projectBuilder; - private readonly IPluginManager _pluginManager; - - public bool Initialized { get; private set; } - public string Name => "Extract"; - public DbSet DbSet { get; set; } - public DbTable TransformData { get; set; } - IETLTaskRepository _etlRepository; - public ExtractDataSource(Project project - , ILoggerFactory loggerFactory - , ILogger logger - , IProjectBuilder projectBuilder - , IPluginManager pluginManager) - { - _project = project; - _loggerFactory = loggerFactory; - _logger = logger; - _projectBuilder = projectBuilder; - _pluginManager = pluginManager; - _etlRepository = _pluginManager.Resolve(_project.GetETLRepository()); - - } - private void InitProjectBuilderEvent() - { - _projectBuilder.OnStartup += _projectBuilder_OnStartup; - _projectBuilder.OnFailed += _projectBuilder_OnFailed; - _projectBuilder.OnSucceed += _projectBuilder_OnSucceed; - } - - private async Task _projectBuilder_OnSucceed(object sender, OnProjectBuildSucceedEventArgs eventArgs) - { - await _etlRepository.Success(_project.GetETKTaskId()); - } - - private async Task _projectBuilder_OnStartup(object sender, OnProjectBuildStartupEventArgs eventArgs) - { - var etlTaskId = await _etlRepository.Startup(_project.ConfigPath, _project.GetETLCode()); - _project.SetETKTaskId(etlTaskId); - } - - private async Task _projectBuilder_OnFailed(object sender, OnProjectBuildFailedEventArgs eventArgs) - { - await _etlRepository.Fail(_project.GetETKTaskId(), eventArgs.ErrorException.Message); - } - - public async Task InitData() - { - var dataSource = _project.DataSource; - dataSource.Paramters.EnsureValue("DbProvider", out string dbProvider); - dataSource.Paramters.EnsureValue("ConnectionString", out string connString); - dataSource.Paramters.Value("PKColumn", out string pkColumn); - dataSource.Paramters.Value("ModifyTime", out string modifyTime); - dataSource.Paramters.EnsureValue("Query", out string queryCmd); - #region CreateSqlMapper - var smartSqlOptions = new CreateSmartSqlMapperOptions - { - LoggerFactory = _loggerFactory, - ProviderName = dbProvider, - Alias = Name, - DataSource = new SmartSql.Configuration.WriteDataSource - { - Name = Name, - ConnectionString = connString - } - }; - var sqlMapper = Create(smartSqlOptions); - #endregion - var lastExtract = await _etlRepository.GetLastExtract(_project.GetETLCode()); - _project.SetETLLastExtract(lastExtract); - var queryParams = new Dictionary - { - { "LastMaxId",lastExtract.MaxId}, - { "LastQueryTime",lastExtract.QueryTime}, - { "LastMaxModifyTime",lastExtract.MaxModifyTime}, - }; - var extractEntity = new ETLExtract - { - QueryTime = DateTime.Now, - PKColumn = pkColumn, - QueryCommand = new ETLDbCommand - { - Command = queryCmd, - Paramters = queryParams - }, - QuerySize = -1, - MaxId = -1 - }; - Stopwatch stopwatch = Stopwatch.StartNew(); - DbSet = await sqlMapper.GetDbSetAsync(new RequestContext { RealSql = queryCmd, Request = queryParams }); - TransformData = DbSet.Tables.First(); - stopwatch.Stop(); - extractEntity.QuerySize = TransformData.Rows.Count; - extractEntity.QueryCommand.Taken = stopwatch.ElapsedMilliseconds; - _logger.LogWarning($"InitData,Data.Size:{extractEntity.QuerySize},Taken:{extractEntity.QueryCommand.Taken}ms!"); - - dataSource.Paramters.Value("PkIsNumeric", out bool pkIsNumeric); - dataSource.Paramters.Value("AutoIncrement", out bool autoIncrement); - - if (!String.IsNullOrEmpty(pkColumn) - && (pkIsNumeric || autoIncrement) - && extractEntity.QuerySize > 0) - { - var maxId = TransformData.Rows.Max(m => m.Cells[pkColumn].Value); - extractEntity.MaxId = Convert.ToInt64(maxId); - } - else - { - extractEntity.MaxId = lastExtract.MaxId; - } - - if (!String.IsNullOrEmpty(modifyTime) - && extractEntity.QuerySize > 0) - { - var maxModifyTime = TransformData.Rows.Max(m => m.Cells[modifyTime].Value); - extractEntity.MaxModifyTime = Convert.ToDateTime(maxModifyTime); - } - else - { - extractEntity.MaxModifyTime = lastExtract.MaxModifyTime; - } - - - await _etlRepository.Extract(_project.GetETKTaskId(), extractEntity); - } - - - public void Initialize(IDictionary paramters) - { - InitProjectBuilderEvent(); - Initialized = true; - } - } -} diff --git a/src/SmartCode.ETL/ExtractDictionaryData.cs b/src/SmartCode.ETL/ExtractDictionaryData.cs new file mode 100644 index 0000000..4e40d3a --- /dev/null +++ b/src/SmartCode.ETL/ExtractDictionaryData.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; +using SmartSql; + +namespace SmartCode.ETL +{ + public class ExtractDictionaryData : AbstractExtractData + { + public ExtractDictionaryData(Project project, ILoggerFactory loggerFactory, + ILogger logger, + IPluginManager pluginManager) : base(project, loggerFactory, logger, pluginManager) + { + } + + public IList> TransformData { get; set; } + + public override string Name => "ExtractDictionary"; + + protected override async Task LoadData(RequestContext requestContext) + { + TransformData = await SqlMapper.QueryAsync>(requestContext); + } + + public override int GetCount() + { + return TransformData.Count; + } + + public override long GetMaxId(string pkColumn) + { + return TransformData.AsParallel().Max(dr => Convert.ToInt64(dr[pkColumn])); + } + + public override DateTime GetMaxModifyTime(string modifyTime) + { + return TransformData.AsParallel().Max(dr => Convert.ToDateTime(dr[modifyTime])); + } + } +} \ No newline at end of file diff --git a/src/SmartCode.ETL/IETLTaskRepository.cs b/src/SmartCode.ETL/IETLTaskRepository.cs index 9540dfe..6d86732 100644 --- a/src/SmartCode.ETL/IETLTaskRepository.cs +++ b/src/SmartCode.ETL/IETLTaskRepository.cs @@ -14,7 +14,7 @@ public interface IETLTaskRepository : IPlugin Task Load(long etlTaskId, ETLLoad load); Task GetLastTask(string code); Task GetLastExtract(string code); - Task Fail(long etlTaskId, string errMsg); + Task Fail(long etlTaskId, Exception errorException); Task Success(long etlTaskId); } } diff --git a/src/SmartCode.ETL/IExtractData.cs b/src/SmartCode.ETL/IExtractData.cs new file mode 100644 index 0000000..9e357fd --- /dev/null +++ b/src/SmartCode.ETL/IExtractData.cs @@ -0,0 +1,12 @@ +using System.Threading.Tasks; + +namespace SmartCode.ETL +{ + public interface IExtractData : IPlugin + { + int Total { get; } + int BulkSize { get; } + int Offset { get; } + Task Run(); + } +} \ No newline at end of file diff --git a/src/SmartCode.ETL/NoneETLTaskRepository.cs b/src/SmartCode.ETL/NoneETLTaskRepository.cs index 311600f..04e34af 100644 --- a/src/SmartCode.ETL/NoneETLTaskRepository.cs +++ b/src/SmartCode.ETL/NoneETLTaskRepository.cs @@ -16,7 +16,7 @@ public Task Extract(long etlTaskId, ETLExtract extract) { return Task.CompletedTask; } - public Task Fail(long etlTaskId, string errMsg) + public Task Fail(long etlTaskId, Exception errorException) { return Task.CompletedTask; } @@ -31,7 +31,7 @@ public Task GetLastTask(string code) return Task.FromResult(new ETLTask()); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode.ETL/ProjectExtensions.cs b/src/SmartCode.ETL/ProjectExtensions.cs index 9ccc7fa..46bd95e 100644 --- a/src/SmartCode.ETL/ProjectExtensions.cs +++ b/src/SmartCode.ETL/ProjectExtensions.cs @@ -4,7 +4,6 @@ using SmartCode.Configuration; using SmartCode.ETL.Entity; using SmartSql; -using SmartSql.Batch; namespace SmartCode.ETL { @@ -13,18 +12,18 @@ public static class ProjectExtensions public const String ETL_TASK_ID = "ETLTaskId"; public static void SetETKTaskId(this Project project, long etlTaskId) { - if (project.Paramters.ContainsKey(ETL_TASK_ID)) + if (project.Parameters.ContainsKey(ETL_TASK_ID)) { - project.Paramters[ETL_TASK_ID] = etlTaskId; + project.Parameters[ETL_TASK_ID] = etlTaskId; } else { - project.Paramters.Add(ETL_TASK_ID, etlTaskId); + project.Parameters.Add(ETL_TASK_ID, etlTaskId); } } public static long GetETKTaskId(this Project project) { - project.Paramters.EnsureValue(ETL_TASK_ID, out long etlTaskId); + project.Parameters.EnsureValue(ETL_TASK_ID, out long etlTaskId); return etlTaskId; } @@ -32,24 +31,24 @@ public static long GetETKTaskId(this Project project) public static string GetETLRepository(this Project project) { - project.Paramters.Value(ETL_REPOSITORY, out string repository); + project.Parameters.Value(ETL_REPOSITORY, out string repository); return repository; } public const String ETL_LAST_EXTRACT = "ETLLastExtract"; public static void SetETLLastExtract(this Project project, ETLExtract extract) { - if (project.Paramters.ContainsKey(ETL_LAST_EXTRACT)) + if (project.Parameters.ContainsKey(ETL_LAST_EXTRACT)) { - project.Paramters[ETL_LAST_EXTRACT] = extract; + project.Parameters[ETL_LAST_EXTRACT] = extract; } else { - project.Paramters.Add(ETL_LAST_EXTRACT, extract); + project.Parameters.Add(ETL_LAST_EXTRACT, extract); } } public static ETLExtract GetETLLastExtract(this Project project) { - project.Paramters.Value(ETL_LAST_EXTRACT, out ETLExtract lastExtract); + project.Parameters.Value(ETL_LAST_EXTRACT, out ETLExtract lastExtract); return lastExtract; } @@ -57,7 +56,7 @@ public static ETLExtract GetETLLastExtract(this Project project) public static string GetETLCode(this Project project) { - if (project.Paramters.Value(ETL_CODE, out string etlCode)) + if (project.Parameters.Value(ETL_CODE, out string etlCode)) { return etlCode; } diff --git a/src/SmartCode.ETL/SmartCode.ETL.csproj b/src/SmartCode.ETL/SmartCode.ETL.csproj index c9af451..8da3559 100644 --- a/src/SmartCode.ETL/SmartCode.ETL.csproj +++ b/src/SmartCode.ETL/SmartCode.ETL.csproj @@ -2,14 +2,12 @@ netstandard2.0 - 7.1 - - - - + + + diff --git a/src/SmartCode.ETL/TransformEngine/RazorTransformEngine.cs b/src/SmartCode.ETL/TransformEngine/RazorTransformEngine.cs index 0106d90..30cad9c 100644 --- a/src/SmartCode.ETL/TransformEngine/RazorTransformEngine.cs +++ b/src/SmartCode.ETL/TransformEngine/RazorTransformEngine.cs @@ -5,15 +5,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.ObjectPool; -using SmartCode.Configuration; -using SmartCode.TemplateEngine; using SmartCode.TemplateEngine.Impl; using SmartCode.Utilities; using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; -using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; @@ -24,7 +21,7 @@ public class RazorTransformEngine : ITransformEngine private const String SCRIPT = "Script"; public async Task Transform(BuildContext context) { - if (context.Build.Paramters.Value(SCRIPT, out string script) && !String.IsNullOrEmpty(script)) + if (context.Build.Parameters.Value(SCRIPT, out string script) && !String.IsNullOrEmpty(script)) { using (var serviceScope = _scopeFactory.CreateScope()) { @@ -38,16 +35,16 @@ public async Task Transform(BuildContext context) public string Name { get; private set; } = "Razor"; private string _root = AppPath.Relative("TransformScripts"); private IServiceScopeFactory _scopeFactory; - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { Initialized = true; - if (paramters != null) + if (parameters != null) { - if (paramters.Value("Name", out string name)) + if (parameters.Value( "Name", out string name)) { Name = name; } - if (paramters.Value("Root", out string root)) + if (parameters.Value( "Root", out string root)) { _root = root; } diff --git a/src/SmartCode.ETL/TransformScripts/Load2PostgreSql.cshtml b/src/SmartCode.ETL/TransformScripts/Load2PostgreSql.cshtml index 8e017fa..41ecb7d 100644 --- a/src/SmartCode.ETL/TransformScripts/Load2PostgreSql.cshtml +++ b/src/SmartCode.ETL/TransformScripts/Load2PostgreSql.cshtml @@ -2,5 +2,5 @@ @using SmartCode.ETL; @model BuildContext @{ - var dataSource = Model.GetDataSource(); + var dataSource = Model.GetExtractData(); } diff --git a/src/SmartCode.Generator/BuildTasks/AbstractDbBuildTask.cs b/src/SmartCode.Generator/BuildTasks/AbstractDbBuildTask.cs index 73cc999..e4c2d5f 100644 --- a/src/SmartCode.Generator/BuildTasks/AbstractDbBuildTask.cs +++ b/src/SmartCode.Generator/BuildTasks/AbstractDbBuildTask.cs @@ -25,37 +25,43 @@ public AbstractDbBuildTask(string name, ILogger logger) public abstract Task Build(BuildContext context); - public virtual void Initialize(IDictionary paramters) + public virtual void Initialize(IDictionary parameters) { this.Initialized = true; } - protected IEnumerable FilterTable(IEnumerable
tables, string buildKey, Build build) + protected IList
FilterTable(IEnumerable
tables, string buildKey, Build build) { _logger.LogInformation($"FilterTable Build:{buildKey} Start!"); IEnumerable
buildTables = CopyTables(tables); - if (build.IgnoreNoPKTable) + if (build.IgnoreNoPKTable.HasValue && build.IgnoreNoPKTable.Value) { _logger.LogInformation($"FilterTable Build:{buildKey} IgnoreNoPKTable!"); buildTables = buildTables.Where(m => m.PKColumn != null); } - if (build.IgnoreView) + + if (build.IgnoreView.HasValue && build.IgnoreView.Value) { _logger.LogInformation($"FilterTable Build:{buildKey} IgnoreView!"); buildTables = buildTables.Where(m => m.Type != Table.TableType.View); } + if (build.IgnoreTables != null) { - _logger.LogInformation($"FilterTable Build:{buildKey} IgnoreTables: [{String.Join(",", build.IgnoreTables)}]!"); + _logger.LogInformation( + $"FilterTable Build:{buildKey} IgnoreTables: [{String.Join(",", build.IgnoreTables)}]!"); buildTables = buildTables.Where(m => !build.IgnoreTables.Contains(m.Name)); } + if (build.IncludeTables != null) { - _logger.LogInformation($"FilterTable Build:{buildKey} IncludeTables: [{String.Join(",", build.IncludeTables)}]!"); + _logger.LogInformation( + $"FilterTable Build:{buildKey} IncludeTables: [{String.Join(",", build.IncludeTables)}]!"); buildTables = buildTables.Where(m => build.IncludeTables.Contains(m.Name)); } + _logger.LogInformation($"FilterTable Build:{buildKey} End!"); - return buildTables; + return buildTables.ToList(); } protected IList
CopyTables(IEnumerable
tables) @@ -83,4 +89,4 @@ protected IList
CopyTables(IEnumerable
tables) }).ToList(); } } -} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/BuildTasks/SingleBuildTask.cs b/src/SmartCode.Generator/BuildTasks/SingleBuildTask.cs index 9e096ba..d2e14ae 100644 --- a/src/SmartCode.Generator/BuildTasks/SingleBuildTask.cs +++ b/src/SmartCode.Generator/BuildTasks/SingleBuildTask.cs @@ -18,9 +18,10 @@ public SingleBuildTask(IPluginManager pluginManager _pluginManager = pluginManager; _logger = logger; } - public async override Task Build(BuildContext context) + public override async Task Build(BuildContext context) { - var filterTables = FilterTable(context.GetDataSource().Tables, context.BuildKey, context.Build); + + var filterTables = FilterTable(context.GetDataSource().Tables, context.BuildKey, context.Build); context.SetCurrentAllTable(filterTables); foreach (var table in filterTables) { diff --git a/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs b/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs index 969dca0..42dc537 100644 --- a/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs +++ b/src/SmartCode.Generator/BuildTasks/TableBuildTask.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace SmartCode.Generator.BuildTasks @@ -25,22 +26,24 @@ public TableBuildTask(IPluginManager pluginManager public override async Task Build(BuildContext context) { - var filterTables = FilterTable(context.GetDataSource().Tables, context.BuildKey, context.Build); + var filterTables = FilterTable(context.GetDataSource().Tables, context.BuildKey, + context.Build); context.SetCurrentAllTable(filterTables); foreach (var table in filterTables) { _logger.LogInformation($"BuildTable:{table.Name} Start!"); context.SetCurrentTable(table); _pluginManager.Resolve().Convert(context); - context.Result = await _pluginManager.Resolve(context.Build.TemplateEngine.Name).Render(context); + context.Result = await _pluginManager.Resolve(context.Build.TemplateEngine.Name) + .Render(context); await _pluginManager.Resolve(context.Build.Output.Type).Output(context); _logger.LogInformation($"BuildTable:{table.Name} End!"); } } - public override void Initialize(IDictionary paramters) + public override void Initialize(IDictionary parameters) { - base.Initialize(paramters); + base.Initialize(parameters); } } -} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/DbTableRepository.cs b/src/SmartCode.Generator/DbTableRepository.cs index fcb3a55..3c6ce72 100644 --- a/src/SmartCode.Generator/DbTableRepository.cs +++ b/src/SmartCode.Generator/DbTableRepository.cs @@ -5,7 +5,7 @@ using Microsoft.Extensions.Logging; using SmartCode.Configuration; using SmartCode.Generator.Entity; -using SmartSql.Abstractions; +using SmartSql; namespace SmartCode.Db { @@ -32,13 +32,13 @@ DataSource dataSource } } } - public async Task> QueryTable() + public async Task> QueryTable() { _logger.LogInformation($"----Db:{DbName} Provider:{DbProviderName}, QueryTable Start! ----"); - IEnumerable
tables; + IList
tables; try { - SqlMapper.BeginSession(); + SqlMapper.SessionStore.Open(); tables = await SqlMapper.QueryAsync
(new RequestContext { Scope = Scope, @@ -57,7 +57,7 @@ public async Task> QueryTable() } finally { - SqlMapper.EndSession(); + SqlMapper.SessionStore.Dispose(); } _logger.LogInformation($"----Db:{DbName} Provider:{DbProviderName},Tables:{tables.Count()} QueryTable End! ----"); return tables; diff --git a/src/SmartCode.Generator/DbTableSource.cs b/src/SmartCode.Generator/DbTableSource.cs index 86063d7..dda3d24 100644 --- a/src/SmartCode.Generator/DbTableSource.cs +++ b/src/SmartCode.Generator/DbTableSource.cs @@ -9,18 +9,18 @@ namespace SmartCode.Generator { - public class DbTableSource : DbSource + public class DbTableSource : DbSource, ITableSource { public DbTableSource( - Project project - , ILoggerFactory loggerFactory - , IPluginManager pluginManager - ) : base(project, loggerFactory, pluginManager) + Project project + , ILoggerFactory loggerFactory + , IPluginManager pluginManager + ) : base(project, loggerFactory, pluginManager) { } public override string Name => "DbTable"; - public IEnumerable
Tables { get; private set; } + public IList
Tables { get; private set; } public override async Task InitData() { @@ -32,7 +32,8 @@ public override async Task InitData() { foreach (var col in table.Columns) { - if ((DbRepository.DbProvider == Db.DbProvider.MySql || DbRepository.DbProvider == Db.DbProvider.MariaDB) + if ((DbRepository.DbProvider == Db.DbProvider.MySql || + DbRepository.DbProvider == Db.DbProvider.MariaDB) && col.DbType == "char" && col.DataLength == 36 && Project.Language == "CSharp") @@ -41,10 +42,11 @@ public override async Task InitData() } else { - col.LanguageType = dbTypeConvert.LanguageType(DbRepository.DbProvider, Project.Language, col.DbType); + col.LanguageType = + dbTypeConvert.LanguageType(DbRepository.DbProvider, Project.Language, col.DbType); } } } } } -} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/DbTypeConverter/DbTypeMap.xml b/src/SmartCode.Generator/DbTypeConverter/DbTypeMap.xml index 799f3f2..c18f729 100644 --- a/src/SmartCode.Generator/DbTypeConverter/DbTypeMap.xml +++ b/src/SmartCode.Generator/DbTypeConverter/DbTypeMap.xml @@ -1,489 +1,898 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/SmartCode.Generator/DbTypeConverter/DefaultDbTypeConverter.cs b/src/SmartCode.Generator/DbTypeConverter/DefaultDbTypeConverter.cs index dd2fd99..f8a47b7 100644 --- a/src/SmartCode.Generator/DbTypeConverter/DefaultDbTypeConverter.cs +++ b/src/SmartCode.Generator/DbTypeConverter/DefaultDbTypeConverter.cs @@ -1,10 +1,7 @@ -using System; -using System.Linq; +using System.Linq; using System.Collections.Generic; -using System.Text; using SmartCode.Utilities; using Microsoft.Extensions.Logging; -using System.IO; using SmartCode.Db; namespace SmartCode.Generator.DbTypeConverter @@ -30,6 +27,7 @@ private void LoadMap() DbTypeMap = XmlConvert.Deserialize(_xmlPath); _logger.LogDebug($"DbTypeConverter Load DbTypeMap:{_xmlPath} End!"); } + public string LanguageType(DbProvider dbProvider, string lang, string dbType) { var databaseMap = DbTypeMap.Databases.FirstOrDefault(m => m.DbProvider == dbProvider && m.Language == lang); @@ -37,12 +35,14 @@ public string LanguageType(DbProvider dbProvider, string lang, string dbType) { _logger.LogError($"Can not find DatabaseMap:DbProvider:{dbProvider},Language:{lang}!"); } + var dbTypeMap = databaseMap?.DbTypes?.FirstOrDefault(m => m.Name == dbType); if (dbTypeMap == null) { _logger.LogError($"Can not find DatabaseMap:DbProvider:{dbProvider},Language:{lang},DbType:{dbType}!"); } + return dbTypeMap?.To; } @@ -53,20 +53,23 @@ public string DbType(DbProvider dbProvider, string lang, string languageType) { _logger.LogError($"Can not find DatabaseMap:DbProvider:{dbProvider},Language:{lang}!"); } + var dbTypeMap = databaseMap?.DbTypes?.FirstOrDefault(m => m.To == languageType); if (dbTypeMap == null) { - _logger.LogError($"Can not find DatabaseMap:DbProvider:{dbProvider},Language:{lang},LanguageType:{languageType}!"); + _logger.LogError( + $"Can not find DatabaseMap:DbProvider:{dbProvider},Language:{lang},LanguageType:{languageType}!"); } + return dbTypeMap?.To; } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters != null) + if (parameters != null) { - if (paramters.Value("XmlPath", out string xmlPath)) + if (parameters.Value("XmlPath", out string xmlPath)) { _xmlPath = xmlPath; } @@ -76,4 +79,4 @@ public void Initialize(IDictionary paramters) Initialized = true; } } -} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/Entity/ColumnExtensions.cs b/src/SmartCode.Generator/Entity/ColumnExtensions.cs new file mode 100644 index 0000000..f61832c --- /dev/null +++ b/src/SmartCode.Generator/Entity/ColumnExtensions.cs @@ -0,0 +1,22 @@ +using System; +using System.Text; + +namespace SmartCode.Generator.Entity +{ + public static class ColumnExtensions + { + /// + /// 获取列的摘要说明,如果 Description 不为空, 则返回 Description; + /// 否则返回 Name + DbType + /// + public static string GetSummary(this Column column) + { + if (!string.IsNullOrEmpty(column.Description)) + { + return column.Description; + } + + return column.Name + ", " + column.DbType; + } + } +} \ No newline at end of file diff --git a/src/SmartCode.Generator/Entity/TableExtensions.cs b/src/SmartCode.Generator/Entity/TableExtensions.cs new file mode 100644 index 0000000..b1d81bd --- /dev/null +++ b/src/SmartCode.Generator/Entity/TableExtensions.cs @@ -0,0 +1,16 @@ +namespace SmartCode.Generator.Entity { + + public static class TableExtensions { + + /// + /// 获取表的摘要说明,如果 Description 不为空, 则返回 Description; + /// 否则返回 Type + Name + /// + public static string GetSummary(this Table table) { + if (!string.IsNullOrEmpty(table.Description)) { + return table.Description; + } + return table.Type + ", " + table.Name; + } + } +} diff --git a/src/SmartCode.Generator/Extensions/SummaryExtensions.cs b/src/SmartCode.Generator/Extensions/SummaryExtensions.cs new file mode 100644 index 0000000..2929ed2 --- /dev/null +++ b/src/SmartCode.Generator/Extensions/SummaryExtensions.cs @@ -0,0 +1,82 @@ +using System; +using System.Text; +using SmartCode.Generator.Entity; + +namespace SmartCode.Generator.Extensions +{ + public static class SummaryExtensions + { + public static string GetCSharpSummary(this Column column) + { + var summary = column.GetSummary(); + return GetCSharpSummary(summary); + } + + public static string GetCSharpSummary(this Table table) + { + var summary = table.GetSummary(); + return GetCSharpSummary(summary); + } + + public static string GetJavaSummary(this Column column) + { + var summary = column.GetSummary(); + return GetJavaSummary(summary); + } + + public static string GetJavaSummary(this Table table) + { + var summary = table.GetSummary(); + return GetJavaSummary(summary); + } + + public static string GetJavaSummary(this string summary) + { + StringBuilder csharpSummary = new StringBuilder(); + csharpSummary.AppendLine("/**"); + if (summary.Contains(Environment.NewLine)) + { + foreach (var summaryLine in summary.Split(Environment.NewLine.ToCharArray())) + { + if (String.IsNullOrEmpty(summaryLine)) + { + continue; + } + csharpSummary.AppendLine($"* {summaryLine}"); + } + } + else + { + csharpSummary.AppendLine($"* {summary}"); + } + + csharpSummary.Append("*/"); + return csharpSummary.ToString(); + } + + public static string GetCSharpSummary(this string summary) + { + StringBuilder csharpSummary = new StringBuilder(); + csharpSummary.AppendLine("///"); + if (summary.Contains(Environment.NewLine)) + { + foreach (var summaryLine in summary.Split(Environment.NewLine.ToCharArray())) + { + if (String.IsNullOrEmpty(summaryLine)) + { + continue; + } + + csharpSummary.AppendLine($"/// {summaryLine}"); + } + } + else + { + csharpSummary.AppendLine($"/// {summary}"); + } + + csharpSummary.Append("///"); + return csharpSummary.ToString(); + } + } +} \ No newline at end of file diff --git a/src/SmartCode.Generator/GeneratorProjectBuilder.cs b/src/SmartCode.Generator/GeneratorProjectBuilder.cs new file mode 100644 index 0000000..d43ac21 --- /dev/null +++ b/src/SmartCode.Generator/GeneratorProjectBuilder.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using SmartCode.Configuration; + +namespace SmartCode.Generator +{ + public class GeneratorProjectBuilder : IProjectBuilder + { + private readonly Project _project; + private readonly IPluginManager _pluginManager; + private readonly ILogger _logger; + + public GeneratorProjectBuilder( + Project project + , IPluginManager pluginManager + , ILogger logger) + { + _project = project; + _pluginManager = pluginManager; + _logger = logger; + } + + CountdownEvent countdown = new CountdownEvent(1); + + + public async Task Build() + { + var dataSource = _pluginManager.Resolve(_project.DataSource.Name); + await dataSource.InitData(); + + if (_project.AllowParallel) + { + await this.ParallelBuild(dataSource); + } + else + { + await this.SerialBuild(dataSource); + } + } + + public async Task SerialBuild(IDataSource dataSource) + { + foreach (var buildKV in _project.BuildTasks) + { + _logger.LogInformation($"-------- BuildTask:{buildKV.Key} Start! ---------"); + var context = new BuildContext + { + PluginManager = _pluginManager, + Project = _project, + DataSource = dataSource, + BuildKey = buildKV.Key, + Build = buildKV.Value, + Output = buildKV.Value.Output?.Copy(), + }; + + //ִ + await _pluginManager.Resolve(context.Build.Type).Build(context); + + _logger.LogInformation($"-------- BuildTask:{buildKV.Key} End! ---------"); + } + } + + private Task ParallelBuild(IDataSource dataSource) + { + + IList allContexts = _project.BuildTasks.Select(d => new BuildContext + { + PluginManager = _pluginManager, + Project = _project, + DataSource = dataSource, + BuildKey = d.Key, + Build = d.Value, + Output = d.Value.Output?.Copy(), + }).ToArray(); + foreach (var context in allContexts) + { + if (context.Build.DependOn != null && context.Build.DependOn.Count() > 0) + { + context.DependOn = allContexts.Where(d => context.Build.DependOn.Contains(d.BuildKey)).ToArray(); + } + } + countdown.Reset(); + countdown.AddCount(allContexts.Count); + foreach (var context in allContexts) + { + context.CountDown.Reset(); + if (context.DependOn != null && context.DependOn.Count > 0) + { + context.CountDown.AddCount(context.DependOn.Count); + } + + ThreadPool.QueueUserWorkItem((obj) => _ = this.BuildTask(obj), (context, allContexts)); + } + + foreach (var context in allContexts) + { + context.CountDown.Signal(); + } + + countdown.Signal(); + countdown.Wait(); + + return Task.CompletedTask; + } + + private async Task BuildTask(object obj) + { + var p = ((BuildContext context, IList allContexts))obj; + + if (p.context.DependOn != null && p.context.DependOn.Count > 0) + { + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} Wait [{string.Join(",", p.context.DependOn?.Select(d => d.BuildKey)?.ToArray())}]---------"); + } + //ȴ + p.context.CountDown.Wait(); + + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} Start! ---------"); + //ִ + await _pluginManager.Resolve(p.context.Build.Type).Build(p.context); + + foreach (var c in p.allContexts) + { + if (c.DependOn == null || c.DependOn.Count == 0) + { + continue; + } + if (c.DependOn.Contains(p.context)) + { + c.CountDown.Signal(); + } + } + + countdown.Signal(); + _logger.LogInformation($"-------- BuildTask:{p.context.BuildKey} End! ---------"); + } + } +} \ No newline at end of file diff --git a/src/SmartCode.Generator/ITableSource.cs b/src/SmartCode.Generator/ITableSource.cs new file mode 100644 index 0000000..99c5e49 --- /dev/null +++ b/src/SmartCode.Generator/ITableSource.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using SmartCode.Generator.Entity; + +namespace SmartCode.Generator +{ + public interface ITableSource : IDataSource + { + IList
Tables { get; } + } +} \ No newline at end of file diff --git a/src/SmartCode.Generator/Maps/Database-MySql.xml b/src/SmartCode.Generator/Maps/Database-MySql.xml index 2e6db05..896b802 100644 --- a/src/SmartCode.Generator/Maps/Database-MySql.xml +++ b/src/SmartCode.Generator/Maps/Database-MySql.xml @@ -4,7 +4,8 @@ SELECT T.TABLE_NAME Name, - ( CASE WHEN T.TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END ) AS TypeName + ( CASE WHEN T.TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END ) AS TypeName, + T.TABLE_COMMENT AS `Description` FROM Information_Schema.TABLES AS T WHERE @@ -24,7 +25,8 @@ Col.Column_Comment AS `Description` FROM Information_Schema.COLUMNS AS Col - Where Table_Schema=?DbName and Table_Name=?TableName; + Where Table_Schema=?DbName and Table_Name=?TableName + Order By Col.ORDINAL_POSITION asc; diff --git a/src/SmartCode.Generator/Maps/Database-Oracle.xml b/src/SmartCode.Generator/Maps/Database-Oracle.xml index 52ec303..ced7146 100644 --- a/src/SmartCode.Generator/Maps/Database-Oracle.xml +++ b/src/SmartCode.Generator/Maps/Database-Oracle.xml @@ -1,12 +1,5 @@  - - - - - - - SELECT @@ -23,7 +16,7 @@ FROM USER_VIEWS T LEFT JOIN USER_TAB_COMMENTS C ON T.VIEW_NAME = C.TABLE_NAME - + SELECT C.COLUMN_ID AS "Id", C.TABLE_NAME AS "TableId", @@ -31,7 +24,7 @@ C.DATA_TYPE AS "DbType", C.DATA_LENGTH AS "DataLength", NVL(CC.COMMENTS,C.COLUMN_NAME) AS "Description", - to_number(CASE C.NULLABLE WHEN 'N' THEN '1' ELSE '0' END) AS "IsNullable", + to_number(CASE C.NULLABLE WHEN 'Y' THEN '1' ELSE '0' END) AS "IsNullable", to_number('0') AS "AutoIncrement", to_number(CASE WHEN P.COLUMN_NAME = C.COLUMN_NAME THEN '1' ELSE '0' END) AS "IsPrimaryKey" FROM USER_TAB_COLUMNS C diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/API/APIController.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/API/APIController.cshtml index d5ae81b..8732f1a 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/API/APIController.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/API/APIController.cshtml @@ -1,4 +1,5 @@ @using SmartCode +@using SmartCode.Generator.Extensions @model BuildContext @{ Layout = "../_CSharpLayout.cshtml"; @@ -25,6 +26,7 @@ using @(project.Module).API.Messages; namespace @(project.Module).API.Controllers { + @table.GetCSharpSummary() [ApiController] [Route("[controller]/[action]")] public class @(table.ConvertedName)Controller : Controller @@ -44,15 +46,15 @@ namespace @(project.Module).API.Controllers Body = @(serviceName).Insert(@entityCamelName) }; } - [HttpPost] - public ResponseMessageWrap@("") DeleteById([FromBody]@pkType id) + [HttpDelete] + public ResponseMessageWrap@("") DeleteById(@pkType id) { return new ResponseMessageWrap@("") { Body = @(serviceName).DeleteById(id) }; } - [HttpPost] + [HttpPut] public ResponseMessageWrap@("") Update([FromBody]@entityName @entityCamelName) { return new ResponseMessageWrap@("") @@ -61,8 +63,8 @@ namespace @(project.Module).API.Controllers }; } - [HttpPost] - public ResponseMessageWrap@($"<{entityName}>") GetById([FromBody]@pkType id) + [HttpGet] + public ResponseMessageWrap@($"<{entityName}>") GetById(@pkType id) { var @entityCamelName = @(repositoryName).GetById(id); return new ResponseMessageWrap@($"<{entityName}>") diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/API/LaunchSettings.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/API/LaunchSettings.cshtml index 8420b39..68aa728 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/API/LaunchSettings.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/API/LaunchSettings.cshtml @@ -13,7 +13,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:8088/" + "applicationUrl": "http://localhost:8088" } } } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/API/Startup.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/API/Startup.cshtml index f51ba11..5ed503a 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/API/Startup.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/API/Startup.cshtml @@ -43,7 +43,8 @@ namespace @(project.Module).API } private void RegisterRepository(IServiceCollection services) { - services.AddSmartSqlRepositoryFromAssembly((options) => + services.AddSmartSql() + .AddRepositoryFromAssembly(options => { options.AssemblyString = "@(project.Module).Repository"; }); @@ -65,7 +66,7 @@ namespace @(project.Module).API { Title = SERVICE_NAME, Version = "v1", - Description = "https://github.com/Ahoo-Wang/SmartCode" + Description = "https://github.com/Smart-Kit/SmartCode" }); c.CustomSchemaIds((type) => type.FullName); var filePath = Path.Combine(AppContext.BaseDirectory, $"{SERVICE_NAME}.xml"); diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Copyright.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Copyright.cshtml index 259b9a3..3e2f8ac 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Copyright.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Copyright.cshtml @@ -1,5 +1,4 @@ @using SmartCode -@using SmartCode.CLI @model BuildContext @{ var project = Model.Project; diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Entity.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Entity.cshtml index df8f80d..30fe4d9 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Entity.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Entity.cshtml @@ -1,5 +1,5 @@ @using SmartCode -@using SmartCode.Db +@using SmartCode.Generator.Extensions @model BuildContext @{ Layout = "_CSharpLayout.cshtml"; @@ -32,21 +32,17 @@ public string ConvertLangType(SmartCode.Generator.Entity.Column column) using System; namespace @(project.Module).@buildTask.Module { -@Html.PadLeft(4)@("///") -@Html.PadLeft(4)@($"///{table.Description ?? table.ConvertedName}") -@Html.PadLeft(4)@("///") + + @table.GetCSharpSummary() public class @table.ConvertedName { @foreach (var column in table.Columns) { - @Html.PadLeft(8)@("///") - @Html.PadLeft(8)@Html.NewLine() - @Html.PadLeft(8)@($"///{column.Description ?? column.ConvertedName}") - @Html.PadLeft(8)@Html.NewLine() - @Html.PadLeft(8)@("///") - @Html.PadLeft(8)@Html.NewLine() - @Html.PadLeft(8)public @(ConvertLangType(column)) @column.ConvertedName { get; set; } - @Html.PadLeft(8)@Html.NewLine() + + @column.GetCSharpSummary() + @Html.NewLine() + public virtual @(ConvertLangType(column)) @column.ConvertedName { get; set; } + @Html.NewLine() } } } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-API.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-API.cshtml index 0a3abdb..8a8f3c8 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-API.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-API.cshtml @@ -1,52 +1,30 @@ @using SmartCode -@using SmartCode.Db; @model BuildContext @{ var project = Model.Project; - var dbSource = Model.GetDataSource(); - var dbFactory = dbSource.Database.DbProvider.Factory; - var dbProviderAssNames = dbFactory.GetType().Assembly.FullName.Split(','); - var dbProviderName = dbProviderAssNames[0]; - var dbProviderVersion = dbProviderAssNames[1].Split('=')[1]; + var smartsqlVersion = "4.0.42"; + if (project.Parameters.Value("SmartSqlVersion", out string version)) + { + smartsqlVersion = version; + } } - netcoreapp2.1 + netcoreapp2.2 - @if (dbSource.DbRepository.DbProvider != DbProvider.SqlServer) - { - - } - @if (dbSource.DbRepository.DbProvider == DbProvider.PostgreSql) - { - - } - else - { - - } - - - + + - - - - Always - - - Always - - + diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-Repository.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-Repository.cshtml index fae13c9..8835c59 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-Repository.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Proj-Repository.cshtml @@ -1,8 +1,23 @@ @using SmartCode +@using SmartCode.Db @model BuildContext @{ - var project = Model.Project; + var dbSource = Model.GetDataSource(); + var dbFactory = dbSource.Database.DbProvider.Factory; + var dbProviderAssNames = dbFactory.GetType().Assembly.FullName.Split(','); + var dbProviderName = dbProviderAssNames[0]; + var dbProviderVersion = dbProviderAssNames[1].Split('=')[1]; + var smartSqlVersion = "4.0.42"; + if (project.Parameters.Value("SmartSqlVersion", out string version)) + { + smartSqlVersion = version; + } + var smartSqlSchemaVersion = "4.0.42"; + if (project.Parameters.Value("SmartSqlSchemaVersion", out string schemaVersion)) + { + smartSqlSchemaVersion = schemaVersion; + } } @@ -10,10 +25,35 @@ netstandard2.0 - + @if (dbSource.DbRepository.DbProvider != DbProvider.SqlServer) + { + + } + @if (dbSource.DbRepository.DbProvider == DbProvider.PostgreSql) + { + + } + else + { + + } + + + + + + Always + + + Always + + + Always + + diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Repository.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Repository.cshtml index 2b29186..05a5d26 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Repository.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Repository.cshtml @@ -1,40 +1,83 @@ @using SmartCode @using SmartCode.Db; +@using SmartCode.Generator.Extensions @model BuildContext @{ Layout = "_CSharpLayout.cshtml"; var project = Model.Project; var buildTask = Model.Build; var table = Model.GetCurrentTable(); - var primaryKeyType = table.PKColumn?.LanguageType ?? "int"; + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Repository Template can not find PKColumn,Table:{table.Name}."); + } + var primaryKeyType = pkCol.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; var dbSource = Model.GetDataSource(); + + var pkNameEqId = pkCol.ConvertedName == "Id"; + var genericParameterKey = $"{table.ConvertedName},{primaryKeyType}"; } using System; using System.Collections.Generic; using System.Data; using System.Text; -using SmartSql.Abstractions; +using System.Threading.Tasks; using SmartSql.DyRepository; +using SmartSql.DyRepository.Annotations; using @(project.Module).Entity; namespace @(project.Module).@buildTask.Module { - public interface I@(table.ConvertedName)Repository : IRepository<@(table.ConvertedName), @(primaryKeyType)> +@table.GetCSharpSummary() +public interface I@(table.ConvertedName)Repository : IRepository<@genericParameterKey> + ,IRepositoryAsync<@genericParameterKey> { - @if (dbSource.DbRepository.DbProvider == DbProvider.PostgreSql -&& autoIncrement) + @if (dbSource.DbRepository.DbProvider == DbProvider.PostgreSql && autoIncrement) { [Statement(Execute = ExecuteBehavior.QuerySingle)] @Html.NewLine() @Html.PadLeft(8) new @primaryKeyType Insert(@table.ConvertedName entity); @Html.NewLine() + + [Statement(Execute = ExecuteBehavior.QuerySingle)] + @Html.NewLine() + @Html.PadLeft(8) new Task<@primaryKeyType> InsertAsync(@table.ConvertedName entity); + @Html.NewLine() } else if (autoIncrement && primaryKeyType != "int") { @Html.PadLeft(8) new @primaryKeyType Insert(@table.ConvertedName entity); @Html.NewLine() + + @Html.PadLeft(8) new Task<@primaryKeyType> InsertAsync(@table.ConvertedName entity); + @Html.NewLine() + } + + @if (!pkNameEqId) + { + [Statement(Id = "GetEntity")] + @Html.NewLine() + @Html.PadLeft(8) new @table.ConvertedName GetById([Param("@pkCol.ConvertedName")]@primaryKeyType id); + @Html.NewLine() + + [Statement(Id = "GetEntity")] + @Html.NewLine() + @Html.PadLeft(8) new Task<@table.ConvertedName> GetByIdAsync([Param("@pkCol.ConvertedName")]@primaryKeyType id); + @Html.NewLine() + + [Statement(Id = "Delete")] + @Html.NewLine() + @Html.PadLeft(8) new int DeleteById([Param("@pkCol.ConvertedName")]@primaryKeyType id); + @Html.NewLine() + + [Statement(Id = "Delete")] + @Html.NewLine() + @Html.PadLeft(8) new Task<@("int")> DeleteByIdAsync([Param("@pkCol.ConvertedName")]@primaryKeyType id); + @Html.NewLine() + } } } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Service.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Service.cshtml index d3cc150..8046b04 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Service.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Service.cshtml @@ -1,11 +1,16 @@ @using SmartCode +@using SmartCode.Generator.Extensions @model BuildContext @{ Layout = "_CSharpLayout.cshtml"; var project = Model.Project; var table = Model.GetCurrentTable(); - - var pkType = table.PKColumn.LanguageType; + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Service Template can not find PKColumn,Table:{table.Name}."); + } + var pkType = pkCol.LanguageType; var insertRetType = table.AutoIncrement ? pkType : "int"; var entityName = table.ConvertedName; var entityCamelName = NamingUtil.CamelCase(table.ConvertedName); @@ -21,6 +26,7 @@ using @(project.Module).Repository; namespace @(project.Module).Service { + @table.GetCSharpSummary() public class @serviceName { public I@(repositoryName) @repositoryName { get; } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Directory.Build.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Directory.Build.cshtml new file mode 100644 index 0000000..8b57d59 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Directory.Build.cshtml @@ -0,0 +1,18 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; +} + + + + + @project.Module + 2019 @project.Module, Inc. + $(AssemblyName) + @project.Author + + + + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-DockerIgnore.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-DockerIgnore.cshtml new file mode 100644 index 0000000..037b231 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-DockerIgnore.cshtml @@ -0,0 +1,9 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; +} + +.vs +.git +doc/** \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Dockerfile.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Dockerfile.cshtml new file mode 100644 index 0000000..99a9660 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Dockerfile.cshtml @@ -0,0 +1,21 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; + var apiProjectName = $"{project.Module}.API"; +} + +FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS publish +WORKDIR /src +COPY /src . +RUN dotnet publish "@(apiProjectName)/@(apiProjectName).csproj" -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "@(apiProjectName).dll"] \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-GitIgnore.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-GitIgnore.cshtml new file mode 100644 index 0000000..4446dca --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-GitIgnore.cshtml @@ -0,0 +1,9 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; +} + +.vs +bin +obj diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Version.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Version.cshtml new file mode 100644 index 0000000..7e366f2 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln-Version.cshtml @@ -0,0 +1,14 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; +} + + + + 1 + 0 + 0 + $(VersionMajor).$(VersionMinor).$(VersionPatch) + + diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln.cshtml index 376afea..6444783 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/Sln.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/Sln.cshtml @@ -1,51 +1,65 @@ -@using SmartCode +@using System.IO +@using SmartCode @model BuildContext @{ var project = Model.Project; + var configFileName = System.IO.Path.GetFileName(project.ConfigPath); } Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27428.2037 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Entity", "@(project.Module).Entity\@(project.Module).Entity.csproj", "{88A185DB-0242-4843-9284-334850FF611C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Entity", "src\@(project.Module).Entity\@(project.Module).Entity.csproj", "{88A185DB-0242-4843-9284-334850FF611C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Repository", "@(project.Module).Repository\@(project.Module).Repository.csproj", "{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Repository", "src\@(project.Module).Repository\@(project.Module).Repository.csproj", "{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Service", "@(project.Module).Service\@(project.Module).Service.csproj", "{D274EF03-E956-40EF-B874-58A5FBE83A00}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).Service", "src\@(project.Module).Service\@(project.Module).Service.csproj", "{D274EF03-E956-40EF-B874-58A5FBE83A00}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).API", "@(project.Module).API\@(project.Module).API.csproj", "{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "@(project.Module).API", "src\@(project.Module).API\@(project.Module).API.csproj", "{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "API", "API", "{20C12BB6-7202-46F4-9A92-3528FFC2B91B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{68E40CDE-0E75-4372-96C4-1507D50993CD}" +ProjectSection(SolutionItems) = preProject +Directory.Build.props = Directory.Build.props +build\version.props = build\version.props +build\@configFileName = build\@configFileName +EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{1666CC75-624D-4AE9-84D7-7F9F338658C5}" +ProjectSection(SolutionItems) = preProject +.dockerignore = .dockerignore +Dockerfile = Dockerfile +EndProjectSection +EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {88A185DB-0242-4843-9284-334850FF611C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {88A185DB-0242-4843-9284-334850FF611C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {88A185DB-0242-4843-9284-334850FF611C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {88A185DB-0242-4843-9284-334850FF611C}.Release|Any CPU.Build.0 = Release|Any CPU - {6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Release|Any CPU.Build.0 = Release|Any CPU - {D274EF03-E956-40EF-B874-58A5FBE83A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D274EF03-E956-40EF-B874-58A5FBE83A00}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D274EF03-E956-40EF-B874-58A5FBE83A00}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D274EF03-E956-40EF-B874-58A5FBE83A00}.Release|Any CPU.Build.0 = Release|Any CPU - {CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E} = {20C12BB6-7202-46F4-9A92-3528FFC2B91B} - EndGlobalSection -EndGlobal - +GlobalSection(SolutionConfigurationPlatforms) = preSolution +Debug|Any CPU = Debug|Any CPU +Release|Any CPU = Release|Any CPU +EndGlobalSection +GlobalSection(ProjectConfigurationPlatforms) = postSolution +{88A185DB-0242-4843-9284-334850FF611C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{88A185DB-0242-4843-9284-334850FF611C}.Debug|Any CPU.Build.0 = Debug|Any CPU +{88A185DB-0242-4843-9284-334850FF611C}.Release|Any CPU.ActiveCfg = Release|Any CPU +{88A185DB-0242-4843-9284-334850FF611C}.Release|Any CPU.Build.0 = Release|Any CPU +{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Debug|Any CPU.Build.0 = Debug|Any CPU +{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Release|Any CPU.ActiveCfg = Release|Any CPU +{6A7E8C9E-6A9F-49FD-AD48-F297E515EB10}.Release|Any CPU.Build.0 = Release|Any CPU +{D274EF03-E956-40EF-B874-58A5FBE83A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{D274EF03-E956-40EF-B874-58A5FBE83A00}.Debug|Any CPU.Build.0 = Debug|Any CPU +{D274EF03-E956-40EF-B874-58A5FBE83A00}.Release|Any CPU.ActiveCfg = Release|Any CPU +{D274EF03-E956-40EF-B874-58A5FBE83A00}.Release|Any CPU.Build.0 = Release|Any CPU +{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU +{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Debug|Any CPU.Build.0 = Debug|Any CPU +{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Release|Any CPU.ActiveCfg = Release|Any CPU +{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E}.Release|Any CPU.Build.0 = Release|Any CPU +EndGlobalSection +GlobalSection(SolutionProperties) = preSolution +HideSolutionNode = FALSE +EndGlobalSection +GlobalSection(NestedProjects) = preSolution +{CEA52B07-9E7F-4A4D-AF6D-4C43E7255D0E} = {20C12BB6-7202-46F4-9A92-3528FFC2B91B} +EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml index 9f7fd22..345b7ad 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml @@ -14,11 +14,16 @@ - Select T.* From @table.Name As T - - - T.@pkCol.Name= @($"{prefix}{pkCol.ConvertedName}") - + Select + + From @table.Name As T + + @foreach (var col in table.Columns) + { + + T.@col.Name= @($"{prefix}{col.ConvertedName}") + + } Limit 1 \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-IsExist.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-IsExist.cshtml index 5eb3307..8b288d1 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-IsExist.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-IsExist.cshtml @@ -2,10 +2,7 @@ @using SmartCode.Db @model BuildContext @{ - var project = Model.Project; - var dbSource = Model.GetDataSource(); var table = Model.GetCurrentTable(); - var pkCol = table.PKColumn; } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Query.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Query.cshtml index 57b3239..d0e59e7 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Query.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Query.cshtml @@ -11,7 +11,7 @@ throw new SmartCodeException($"{table.Name} can not find PKColumn!"); } var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; @@ -19,12 +19,14 @@ - SELECT T.* From @table.Name T + SELECT + + From @table.Name T T.@pkCol.Name Desc - @(prefix)Taken + @(dbPrefix)Taken \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml index 3c09b82..680b0a7 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml @@ -12,23 +12,22 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; } -@section QueryByPage - { - - - Select T.* From @table.Name As T - - - - T.@pkCol.Name Desc - - - Limit @("@PageSize") Offset @("@Offset") - -} \ No newline at end of file + + + Select + + From @table.Name As T + + + + T.@pkCol.Name Desc + + + Limit @(dbPrefix)PageSize Offset @(dbPrefix)Offset + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Update.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Update.cshtml index e1383fa..025f542 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Update.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/CURD/SqlMap-Update.cshtml @@ -11,7 +11,7 @@ throw new SmartCodeException($"{table.Name} can not find PKColumn!"); } var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; } @@ -23,10 +23,10 @@ if (!col.IsPrimaryKey) { - @col.Name = @($"{prefix}{col.ConvertedName}") + @col.Name = @($"{dbPrefix}{col.ConvertedName}") } } - Where @pkCol.Name=@prefix@pkCol.ConvertedName + Where @pkCol.Name=@dbPrefix@pkCol.ConvertedName \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Columns.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Columns.cshtml index 4b533bd..e0eda88 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Columns.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Columns.cshtml @@ -11,6 +11,6 @@ @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) { var col = table.Columns.ElementAt(colIndex); - @col.Name@(colIndex == table.Columns.Count() - 1 ? "" : ",") + @($"T.{col.Name}")@(colIndex == table.Columns.Count() - 1 ? "" : ",") } \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-MySql.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-MySql.cshtml index 75a0597..697dfbe 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-MySql.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-MySql.cshtml @@ -14,7 +14,7 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; @@ -23,14 +23,16 @@ { - Select T.* From @table.Name As T + Select + + From @table.Name As T T.@pkCol.Name Desc - Limit ?Offset,?PageSize + Limit @(dbPrefix)Offset,@(dbPrefix)PageSize } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Oracle.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Oracle.cshtml index 737242d..e0ce1d2 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Oracle.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-Oracle.cshtml @@ -14,7 +14,7 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; @@ -27,7 +27,7 @@ Select TT.* From (Select ROW_NUMBER() Over(Order By T.@pkCol.Name Desc) Row_Index,T.* From @table.Name T ) TT - Where TT.Row_Index Between ((@@PageIndex-1)*@@PageSize+1) And (@@PageIndex*@@PageSize) + Where TT.Row_Index Between ((@(dbPrefix)PageIndex-1)*@(dbPrefix)PageSize+1) And (@(dbPrefix)PageIndex*@(dbPrefix)PageSize) } @section GetEntity @@ -35,11 +35,14 @@ Select T.* From @table.Name T - + ROWNUM = 1 - - T.@pkCol.Name=@prefix@pkCol.ConvertedName + @foreach (var col in table.Columns) + { + + T.@col.Name= @($"{dbPrefix}{col.ConvertedName}") + } } @@ -48,16 +51,21 @@ { - SELECT - - (@(prefix)Taken) + select * from ( + + SELECT + T.* From @table.Name T + + + + T.@pkCol.Name Desc + + + ) + + - T.* From @table.Name T - - - - T.@pkCol.Name Desc - - } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-PostgreSql.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-PostgreSql.cshtml index c0549d6..7ee9f49 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-PostgreSql.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-PostgreSql.cshtml @@ -15,7 +15,7 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; @@ -25,14 +25,16 @@ { - Select T.* From @table.Name As T + Select + + From @table.Name As T T.@pkCol.Name Desc - Limit @("@PageSize") Offset @("@Offset") + Limit @(dbPrefix)PageSize Offset @(dbPrefix)Offset } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SQLite.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SQLite.cshtml index 67cb7df..b8abc2d 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SQLite.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SQLite.cshtml @@ -14,7 +14,7 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; @@ -23,13 +23,15 @@ { - Select T.* From @table.Name As T + Select + + From @table.Name As T T.@pkCol.Name Desc - Limit @("@PageSize") Offset @("@Offset") + Limit @(dbPrefix)PageSize Offset @(dbPrefix)Offset } \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SqlServer.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SqlServer.cshtml index 3905ece..cf0da07 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SqlServer.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/SqlMap-SqlServer.cshtml @@ -7,7 +7,7 @@ var project = Model.Project; var dbSource = Model.GetDataSource(); var versionNo = 2008; - var sqlServerVersion = dbSource.DbRepository.SqlMapper.ExecuteScalar(new SmartSql.Abstractions.RequestContext + var sqlServerVersion = dbSource.DbRepository.SqlMapper.ExecuteScalar(new SmartSql.RequestContext { RealSql = "Select @@Version;" }); @@ -23,22 +23,25 @@ } var primaryKeyType = pkCol?.LanguageType ?? "int"; var autoIncrement = table.AutoIncrement; - var prefix = dbSource.DbProvider.ParameterPrefix; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); var resultMapName = $"{table.ConvertedName}ResultMap"; var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; } @section QueryByPage - { +{ - @if (versionNo > 2012) + @if (versionNo >= 2012) { - Select T.* From @table.Name T With(NoLock) + Select + + From @table.Name T With(NoLock) + Order By T.@pkCol.Name Desc - Offset ((@@PageIndex-1)*@@PageSize) Rows Fetch Next @@PageSize Rows Only; + Offset ((@(dbPrefix)PageIndex-1)*@(dbPrefix)PageSize) Rows Fetch Next @(dbPrefix)PageSize Rows Only; } else @@ -46,39 +49,46 @@ Select TT.* From (Select ROW_NUMBER() Over(Order By T.@pkCol.Name Desc) Row_Index,T.* From @table.Name T With(NoLock) - ) TT - Where TT.Row_Index Between ((@@PageIndex-1)*@@PageSize+1) And (@@PageIndex*@@PageSize); + ) TT + Where TT.Row_Index Between ((@(dbPrefix)PageIndex-1)*@(dbPrefix)PageSize+1) And (@(dbPrefix)PageIndex*@(dbPrefix)PageSize); } } + @section GetEntity - { +{ - Select Top 1 T.* From @table.Name T With(NoLock) - - - T.@pkCol.Name=@prefix@pkCol.ConvertedName - + Select Top 1 + + From @table.Name T With(NoLock) + + @foreach (var col in table.Columns) + { + + T.@col.Name= @($"{dbPrefix}{col.ConvertedName}") + + } } @section Query - { +{ SELECT - (@(prefix)Taken) + (@(dbPrefix)Taken) - T.* From @table.Name T - + + From @table.Name T + T.@pkCol.Name Desc -} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/_SqlMapLayout.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/_SqlMapLayout.cshtml index 50bc26b..b3257bf 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/_SqlMapLayout.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMap-Partials/_SqlMapLayout.cshtml @@ -4,6 +4,7 @@ @{ var project = Model.Project; var dbSource = Model.GetDataSource(); + var dbPrefix = dbSource.DbProvider.ParameterPrefix; var buildTask = Model.Build; var table = Model.GetCurrentTable(); var pkCol = table.PKColumn; @@ -16,8 +17,15 @@ @{ await Html.RenderPartialAsync("SqlMap-ResultMaps.cshtml", Model); } + @{ await Html.RenderPartialAsync("SqlMap-Columns.cshtml", Model); } + @foreach (var col in table.Columns) + { + + T.@col.Name = @dbPrefix@col.ConvertedName + + } diff --git a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMapConfig.cshtml b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMapConfig.cshtml index 5251dfd..07cac71 100644 --- a/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMapConfig.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/CSharp/SqlMapConfig.cshtml @@ -7,31 +7,67 @@ var dbProvider = dbSource.DbProvider; var writeDataSource = dbSource.WriteDataSource; } - + + - - - - - - - - + + + + + @if (dbSource.DbRepository.DbProvider == DbProvider.PostgreSql) { - - + + } else { - - + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/ETL/ToMysqlTable.cshtml b/src/SmartCode.Generator/RazorTemplates/ETL/ToMysqlTable.cshtml new file mode 100644 index 0000000..4f6606d --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/ETL/ToMysqlTable.cshtml @@ -0,0 +1,118 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var buildTask = Model.Build; + project.Parameters.Value("ExtractMode", out string extractMode);//Last: Full,LastMaxModifyTime,LastQueryTime,LastMaxId + bool extractModeUseTime = extractMode == "LastMaxModifyTime" || extractMode == "LastQueryTime"; + project.Parameters.Value("ExtractConnectionString", out string extractConnectionString); + extractConnectionString = extractConnectionString ?? dbSource.Database.Write.ConnectionString; + project.Parameters.Value("LoadDbProvider", out string loadDbProvider); + project.Parameters.Value("LoadConnectionString", out string loadConnectionString); + project.Parameters.Value("SecureFilePriv", out string secureFilePriv); + project.Parameters.Value("DateTimeFormat", out string dateTimeFormat); + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); + var table = Model.GetCurrentTable(); + var loadTable = extractModeUseTime ? $"{table.ConvertedName}__temp" : table.ConvertedName; + var PKColumn = Model.GetCurrentTable().PKColumn; +} + +@functions{ + string GetExtractWhere() + { + string sql = String.Empty; + Model.Project.Parameters.Value("ExtractMode", out string extractMode); + switch (extractMode) + { + case "Full": { return ""; } + case "LastMaxModifyTime": + { + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); + sql = $"{modifyTime}>@LastMaxModifyTime"; + break; + } + case "LastQueryTime": + { + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); + sql = $"{modifyTime}>@LastQueryTime"; + break; + } + case "LastMaxId": + default: + { + sql = $"{Model.GetCurrentTable().PKColumn.Name}>@LastMaxId"; + break; + } + } + return $"Where {sql}"; + } +} + +Author: Rocher Kong +DataSource: + Name: Extract + Parameters: + DbProvider: @dbSource.DbRepository.DbProviderName + ConnectionString: @extractConnectionString + Query: 'Select * From @table.Name @GetExtractWhere() Order By @PKColumn.Name Asc Offset @@Offset Rows Fetch Next @@BulkSize Rows Only;' + Total: 'Select Count(*) From @table.Name With(NoLock) @GetExtractWhere()' + BulkSize: 1000 + PKColumn: @PKColumn.Name + AutoIncrement: @(PKColumn.AutoIncrement ? "true" : "false") + @if (!String.IsNullOrEmpty(modifyTime)) + { + @Html.PadLeft(4)ModifyTime: @modifyTime + } + + +Parameters: + ETLCode: @(project.Module).@table.Name + ETLRepository: MySql + +Build: + Transform: + Type: Transform + Parameters: + Script: + + Load: + Type: Load + Parameters: + DbProvider: @loadDbProvider + SecureFilePriv: @secureFilePriv + DateTimeFormat: @dateTimeFormat + ConnectionString: @loadConnectionString + Table: @loadTable + @switch (extractMode) + { + case "LastMaxModifyTime": + case "LastQueryTime": + { + + PreCommand: create TEMPORARY table @(loadTable) select * from @table.ConvertedName where 1=0; + PostCommand: "delete from @table.ConvertedName where EXISTS(select * from @(loadTable) as temp where temp.@(PKColumn.ConvertedName)=@table.@(PKColumn.ConvertedName)); + insert into @table.ConvertedName select * from @loadTable;" + + break; + } + case "Full": + { + + PreCommand: TRUNCATE TABLE @(loadTable); + + break; + } + } + + ColumnMapping: [ + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + {Column: @col.Name,Mapping: @col.ConvertedName} + if (colIndex < table.Columns.Count() - 1) + {@(",")} + @Html.NewLine() +} + ] diff --git a/src/SmartCode.Generator/RazorTemplates/ETL/ToPGBuild.cshtml b/src/SmartCode.Generator/RazorTemplates/ETL/ToPGBuild.cshtml index 463e68e..9cbf35f 100644 --- a/src/SmartCode.Generator/RazorTemplates/ETL/ToPGBuild.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/ETL/ToPGBuild.cshtml @@ -5,13 +5,13 @@ var project = Model.Project; var dbSource = Model.GetDataSource(); var buildTask = Model.Build; - project.Paramters.Value("ExtractMode", out string extractMode);//Last: Full,LastMaxModifyTime,LastQueryTime,LastMaxId + project.Parameters.Value("ExtractMode", out string extractMode);//Last: Full,LastMaxModifyTime,LastQueryTime,LastMaxId bool extractModeUseTime = extractMode == "LastMaxModifyTime" || extractMode == "LastQueryTime"; - project.Paramters.Value("ExtractConnectionString", out string extractConnectionString); - extractConnectionString = extractConnectionString ?? dbSource.Database.WriteDataSource.ConnectionString; - project.Paramters.Value("LoadDbProvider", out string loadDbProvider); - project.Paramters.Value("LoadConnectionString", out string loadConnectionString); - Model.Project.Paramters.Value("ModifyTime", out string modifyTime); + project.Parameters.Value("ExtractConnectionString", out string extractConnectionString); + extractConnectionString = extractConnectionString ?? dbSource.Database.Write.ConnectionString; + project.Parameters.Value("LoadDbProvider", out string loadDbProvider); + project.Parameters.Value("LoadConnectionString", out string loadConnectionString); + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); var table = Model.GetCurrentTable(); var loadTable = extractModeUseTime ? $"{table.ConvertedName}__temp" : table.ConvertedName; var PKColumn = Model.GetCurrentTable().PKColumn; @@ -21,19 +21,19 @@ string GetExtractWhere() { string sql = String.Empty; - Model.Project.Paramters.Value("ExtractMode", out string extractMode); + Model.Project.Parameters.Value("ExtractMode", out string extractMode); switch (extractMode) { case "Full": { return ""; } case "LastMaxModifyTime": { - Model.Project.Paramters.Value("ModifyTime", out string modifyTime); + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); sql = $"{modifyTime}>@LastMaxModifyTime"; break; } case "LastQueryTime": { - Model.Project.Paramters.Value("ModifyTime", out string modifyTime); + Model.Project.Parameters.Value("ModifyTime", out string modifyTime); sql = $"{modifyTime}>@LastQueryTime"; break; } @@ -51,9 +51,9 @@ Author: Ahoo Wang DataSource: Name: Extract - Paramters: + Parameters: DbProvider: @dbSource.DbRepository.DbProviderName - ConnectionString: "@extractConnectionString" + ConnectionString: @extractConnectionString Query: 'Select * From @table.Name @GetExtractWhere()' PKColumn: @PKColumn.Name AutoIncrement: @(PKColumn.AutoIncrement ? "true" : "false") @@ -63,21 +63,21 @@ DataSource: } -Paramters: +Parameters: ETLCode: @(project.Module).@table.Name ETLRepository: PG Build: Transform: Type: Transform - Paramters: + Parameters: Script: Load: Type: Load - Paramters: + Parameters: DbProvider: @loadDbProvider - ConnectionString: "@loadConnectionString" + ConnectionString: @loadConnectionString Table: @loadTable @switch (extractMode) { @@ -109,4 +109,4 @@ Build: {@(",")} @Html.NewLine() } - ] \ No newline at end of file + ] diff --git a/src/SmartCode.Generator/RazorTemplates/Java/AbstractEntity.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/AbstractEntity.cshtml new file mode 100644 index 0000000..58d289e --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/AbstractEntity.cshtml @@ -0,0 +1,53 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; +} + + +package @(project.Module).entity; + +import java.io.Serializable; +import java.util.Date; + +public abstract class AbstractEntity@("") implements Serializable { + private TKey id; + private Date createTime = new Date(); + private Date modifiedTime = new Date(); + private boolean deleted; + + @@Override + public TKey getId() { + return id; + } + + @@Override + public void setId(TKey id) { + this.id = id; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getModifiedTime() { + return modifiedTime; + } + + public void setModifiedTime(Date modifiedTime) { + this.modifiedTime = modifiedTime; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public boolean isDeleted() { + return deleted; + } +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/AppConfig.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/AppConfig.cshtml new file mode 100644 index 0000000..6fa690f --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/AppConfig.cshtml @@ -0,0 +1,19 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + var buildTask = Model.Build; +} + + +package @(project.Module).server.config; + +import org.springframework.context.annotation.Configuration; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@@Configuration +@@EnableSwagger2 +public class AppConfig { + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Application.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Application.cshtml new file mode 100644 index 0000000..3a8a599 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Application.cshtml @@ -0,0 +1,29 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + + var appName = "Demo"; + + if (project.Parameters.TryGetValue("ApplicationName", out var _appName)) + { + appName = _appName.ToString(); + } + var appClassName = $"{appName}Application"; +} + +package @(project.Module).server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@@SpringBootApplication +public class @appClassName { + +public static void main(String[] args) { + SpringApplication.run(@(appClassName).class, args); +} + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Controller.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Controller.cshtml new file mode 100644 index 0000000..79f54a0 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Controller.cshtml @@ -0,0 +1,43 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Service Template can not find PKColumn,Table:{table.Name}."); + } + var pkType = pkCol.LanguageType; + var insertRetType = table.AutoIncrement ? pkType : "int"; + var entityName = table.ConvertedName; + var entityCamelName = NamingUtil.CamelCase(table.ConvertedName); + var serviceName = $"{table.ConvertedName}Service"; + var serviceCamelName = NamingUtil.CamelCase(serviceName); + var controllerName = $"{table.ConvertedName}Controller"; + if (!project.BuildTasks.TryGetValue("Service", out var serviceBuild)) + { + throw new ArgumentException("can not find Project -> BuildTasks -> Service ."); + } +} + +package @(project.Module).@buildTask.Module; + +import lombok.var; + +import org.springframework.beans.factory.annotation.Autowired; +import javax.validation.Valid; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import @(project.Module).@(serviceBuild.Module).@serviceName; + +@Html.NewLine() +@@RestController +@@RequestMapping("@entityCamelName") +public class @controllerName { +@@Autowired +@serviceName @serviceCamelName; + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Copyright.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Copyright.cshtml index e31ac8a..f43b08a 100644 --- a/src/SmartCode.Generator/RazorTemplates/Java/Copyright.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/Java/Copyright.cshtml @@ -4,8 +4,8 @@ var project = Model.Project; } /******************************* -* Create By @project.Author -* Date @DateTime.Now.ToString("yyyy-MM-dd HH:mm") +* @@author @project.Author +* @@date @DateTime.Now.ToString("yyyy-MM-dd HH:mm") * Code Generate By SmartCode * Code Generate Github : https://github.com/Ahoo-Wang/SmartCode *******************************/ \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Entity.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Entity.cshtml index 94a2fa9..93945c0 100644 --- a/src/SmartCode.Generator/RazorTemplates/Java/Entity.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/Java/Entity.cshtml @@ -1,64 +1,96 @@ @using SmartCode -@using SmartCode.Db +@using SmartCode.Generator.Extensions @model BuildContext @{ Layout = "_JavaLayout.cshtml"; var project = Model.Project; var buildTask = Model.Build; var table = Model.GetCurrentTable(); -} -@functions { -public string ConvertLangType(SmartCode.Generator.Entity.Column column) -{ - if (String.IsNullOrEmpty(column.LanguageType)) + bool useAbstractEntity = false; + String abstractEntityName = ""; + String abstractEntityPackage = ""; + ISet abstractEntityProperties = new HashSet(); + if (buildTask.Parameters.TryGetValue("AbstractEntity", out var abstractEntity)) { - return "NAType"; - } - if (!column.IsNullable) - { - return column.LanguageType; + useAbstractEntity = true; + var abstractEntityParams = (Dictionary) abstractEntity; + if (!abstractEntityParams.TryGetValue("Name", out Object _abstractEntityName)) + { + throw new ArgumentException("AbstractEntity.Name can not be null."); + } + abstractEntityName = _abstractEntityName.ToString(); + if (!abstractEntityParams.TryGetValue("Package", out var _abstractEntityPackage)) + { + throw new ArgumentException("AbstractEntity.Package can not be null."); + } + abstractEntityPackage = _abstractEntityPackage.ToString(); + if (!abstractEntityParams.TryGetValue("Properties", out var _abstractEntityProperties)) + { + throw new ArgumentException("AbstractEntity.Properties can not be null."); + } + ((List) _abstractEntityProperties).ForEach(p => + { + abstractEntityProperties.Add(p.ToString()); + }); } +} - if (column.LanguageType.Contains("[]") || column.LanguageType.ToLower() == "string") +@functions { + + public string ConvertLangType(SmartCode.Generator.Entity.Column column) { - return column.LanguageType; + if (String.IsNullOrEmpty(column.LanguageType)) + { + return "NAType"; + } + if (!column.IsNullable) + { + return column.LanguageType; + } + + if (column.LanguageType.Contains("[]") || column.LanguageType.ToLower() == "string") + { + return column.LanguageType; + } + return $"{column.LanguageType}"; } - return $"{column.LanguageType}?"; -} } package @(project.Module).@buildTask.Module; -import java.security.Timestamp; - /** - * @(table.Description ?? table.ConvertedName) - */ - public class @table.ConvertedName - { - @foreach (var column in table.Columns) - { - - /** - * @column.Description - */ - private @(ConvertLangType(column)) @column.ConvertedName; - - } - - @foreach (var column in table.Columns) - { - - public @ConvertLangType(column) get@(NamingUtil.PascalCase(column.ConvertedName))(){ - return @column.ConvertedName ; - } +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.util.UUID; +import java.util.Date; +@if (useAbstractEntity) +{ + import @($"{abstractEntityPackage}.{abstractEntityName}"); +} - public void set@(NamingUtil.PascalCase(column.ConvertedName))(@(ConvertLangType(column)) @column.ConvertedName){ - this.@column.ConvertedName = @column.ConvertedName; - } - +import lombok.Data; +import lombok.ToString; +@table.GetJavaSummary() +@@Data +@@ToString +public class @table.ConvertedName +@if (useAbstractEntity) +{ + extends @abstractEntityName +} +{ +@foreach (var column in table.Columns) +{ + if (useAbstractEntity && abstractEntityProperties.Contains(column.ConvertedName)) + { + continue; } - } + + @column.GetJavaSummary() + private @(ConvertLangType(column)) @column.ConvertedName; + +} +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/GenericRepository.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/GenericRepository.cshtml new file mode 100644 index 0000000..609f174 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/GenericRepository.cshtml @@ -0,0 +1,20 @@ +@using SmartCode +@using SmartCode.Db; +@using SmartCode.Generator.Extensions +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Repository Template can not find PKColumn,Table:{table.Name}."); + } + var primaryKeyType = pkCol.LanguageType ?? "int"; + var autoIncrement = table.AutoIncrement; + var dbSource = Model.GetDataSource(); + +} + diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Pom-Api.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Api.cshtml new file mode 100644 index 0000000..9f08672 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Api.cshtml @@ -0,0 +1,19 @@ +@using SmartCode +@model BuildContext + +@{ + Layout = null; + var project = Model.Project; +} + + + + + 4.0.0 + @project.Module + api + 0.0.1-SNAPSHOT + api + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Pom-Parent.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Parent.cshtml new file mode 100644 index 0000000..f924ae6 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Parent.cshtml @@ -0,0 +1,29 @@ +@using SmartCode +@model BuildContext + +@{ + Layout = null; + var project = Model.Project; +} + + + + + 4.0.0 + @project.Module + parent + 0.0.1-SNAPSHOT + pom + parent + SmartCode project for Spring Boot + + + 1.8 + + + api + server + + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Pom-Server.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Server.cshtml new file mode 100644 index 0000000..4d30c45 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Pom-Server.cshtml @@ -0,0 +1,122 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext + +@{ + Layout = null; + var project = Model.Project; + var dbSource = Model.GetDataSource(); +} + + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.9.RELEASE + + + @project.Module + server + 0.0.1-SNAPSHOT + server + Api project for Spring Boot + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.1.1 + + @switch (dbSource.DbProvider.Name) + { + case SmartSql.DataSource.DbProvider.MYSQL: + { + + mysql + mysql-connector-java + runtime + + break; + } + case SmartSql.DataSource.DbProvider.POSTGRESQL: + { + + org.postgresql + postgresql + runtime + + break; + } + } + + org.projectlombok + lombok + true + + + io.springfox + springfox-swagger2 + 2.9.2 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + + + generate-docs + prepare-package + + process-asciidoc + + + html + book + + + + + + org.springframework.restdocs + spring-restdocs-asciidoctor + ${spring-restdocs.version} + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Repository.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Repository.cshtml new file mode 100644 index 0000000..b937e8e --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Repository.cshtml @@ -0,0 +1,60 @@ +@using SmartCode +@using SmartCode.Db; +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Repository Template can not find PKColumn,Table:{table.Name}."); + } + var primaryKeyType = pkCol.LanguageType ?? "int"; + switch (primaryKeyType) + { + case "long": + { + primaryKeyType = "Long"; + break; + } + case "int": + { + primaryKeyType = "Integer"; + break; + } + } + var dbSource = Model.GetDataSource(); + + String genericRepositoryPackageName = ""; + if (buildTask.Parameters.TryGetValue("GenericRepository", out var _genericRepositoryParams)) + { + var genericRepositoryParams = (Dictionary) _genericRepositoryParams; + if (!genericRepositoryParams.TryGetValue("Package", out var _genericRepositoryPackage)) + { + throw new ArgumentException("GenericRepository.Package can not be null."); + } + genericRepositoryPackageName = _genericRepositoryPackage.ToString(); + } + + if (!project.BuildTasks.TryGetValue("Entity", out var entityBuild)) + { + throw new ArgumentException("can not find Project -> BuildTasks -> [Entity] ."); + } + var genericParameterKey = $"{table.ConvertedName},{primaryKeyType}"; +} + +package @(project.Module).@buildTask.Module; + +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; +import @(genericRepositoryPackageName).GenericRepository; +import @(project.Module).@(entityBuild.Module).@table.ConvertedName; + +@Html.NewLine() +@@Repository +@@Mapper +public interface @(table.ConvertedName)Repository extends GenericRepository<@genericParameterKey> { + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Resources/Application-YAML.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Resources/Application-YAML.cshtml new file mode 100644 index 0000000..731e955 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Resources/Application-YAML.cshtml @@ -0,0 +1,72 @@ +@using System.Text +@using MySql.Data.MySqlClient +@using Npgsql +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var buildTask = Model.Build; + var appName = "Demo"; + if (project.Parameters.TryGetValue("ApplicationName", out var _appName)) + { + appName = _appName.ToString(); + } + var appClassName = $"{appName}Application"; + var dbSource = Model.GetDataSource(); + if (!project.BuildTasks.TryGetValue("Entity", out var entityBuild)) + { + throw new ArgumentException("can not find Project -> BuildTasks -> [Entity] ."); + } + + var driveName = "mysql"; + var host = "localhost"; + uint port = 3306; + var userName = "root"; + var pwd = "root"; + var database = "smartsql_db"; + var appendUrl = new StringBuilder(); + + switch (dbSource.DbProvider.Name) + { + case SmartSql.DataSource.DbProvider.MYSQL: + { + driveName = "mysql"; + var builder= new MySqlConnectionStringBuilder(dbSource.WriteDataSource.ConnectionString); + host = builder.Server; + database= builder.Database; + userName= builder.UserID; + pwd = builder.Password; + port = builder.Port; + appendUrl.Append("?"); + appendUrl.Append("serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8"); + break; + } + case SmartSql.DataSource.DbProvider.POSTGRESQL: + { + driveName = "postgresql"; + var builder= new NpgsqlConnectionStringBuilder(dbSource.WriteDataSource.ConnectionString); + host = builder.Host; + database= builder.Database; + userName= builder.Username; + pwd = builder.Password; + port = (uint)builder.Port; + break; + } + } +} + +spring: + application: + name: @appName-service + + datasource: + url: jdbc:@(driveName)://@host:@port/@database@appendUrl.ToString() + username: @userName + password: @pwd + +mybatis: + mapper-locations: classpath:/mappers/*.xml + type-aliases-package: @(project.Module).@(entityBuild.Module) + configuration: + map-underscore-to-camel-case: true \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Service.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Service.cshtml new file mode 100644 index 0000000..876562a --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Service.cshtml @@ -0,0 +1,46 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "_JavaLayout.cshtml"; + var project = Model.Project; + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"Service Template can not find PKColumn,Table:{table.Name}."); + } + var pkType = pkCol.LanguageType; + var insertRetType = table.AutoIncrement ? pkType : "int"; + var entityName = table.ConvertedName; + var entityCamelName = NamingUtil.CamelCase(table.ConvertedName); + var serviceName = $"{table.ConvertedName}Service"; + var repositoryName = $"{table.ConvertedName}Repository"; + var repositoryCamelName = NamingUtil.CamelCase(repositoryName); + if (!project.BuildTasks.TryGetValue("Repository", out var repositoryBuild)) + { + throw new ArgumentException("can not find Project -> BuildTasks -> [Repository] ."); + } +} + + + +package @(project.Module).@buildTask.Module; + +import lombok.var; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import javax.validation.Valid; +import java.util.Date; +import java.util.stream.Collectors; +import @(project.Module).@(repositoryBuild.Module).@repositoryName; + + +@Html.NewLine() +@@Service +public class @serviceName { +@@Autowired +@repositoryName @repositoryCamelName; + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Delete.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Delete.cshtml new file mode 100644 index 0000000..8d98c88 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Delete.cshtml @@ -0,0 +1,29 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var buildTask = Model.Build; + buildTask.Parameters.TryGetValue("LogicalDelete", out var logicalDeleteKey); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; +} + +@if (logicalDeleteKey != null) +{ + + + update @table.Name + set @logicalDeleteKey =1 + where @pkCol.Name=#{id} + +} +else +{ + + + delete from @table.Name + where @pkCol.Name=#{id} + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetById.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetById.cshtml new file mode 100644 index 0000000..c6fc4e4 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetById.cshtml @@ -0,0 +1,17 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml new file mode 100644 index 0000000..e0d96d7 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetEntity.cshtml @@ -0,0 +1,16 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetTotal.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetTotal.cshtml new file mode 100644 index 0000000..103f780 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-GetTotal.cshtml @@ -0,0 +1,14 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; +} + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Insert.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Insert.cshtml new file mode 100644 index 0000000..3519a47 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Insert.cshtml @@ -0,0 +1,43 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + var autoIncrement = table.AutoIncrement; + var useGK = autoIncrement ? $"useGeneratedKeys=\"true\" keyProperty=\"{pkCol.ConvertedName}\"" : ""; +} + + + insert into @table.Name + ( + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + @if (!col.AutoIncrement) + { + @Html.PadLeft(6)@col.Name@(colIndex == table.Columns.Count() - 1 ? "" : ",") + @Html.NewLine() + } + } + ) + values + ( + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + @if (!col.AutoIncrement) + { + @Html.PadLeft(6)#{@col.ConvertedName} + @(colIndex == table.Columns.Count() - 1 ? "" : ",") + @Html.NewLine() + } + } + ) + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Query.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Query.cshtml new file mode 100644 index 0000000..e96e090 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Query.cshtml @@ -0,0 +1,22 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml new file mode 100644 index 0000000..604459c --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-QueryByPage.cshtml @@ -0,0 +1,20 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Update.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Update.cshtml new file mode 100644 index 0000000..16d5682 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/CURD/SqlMap-Update.cshtml @@ -0,0 +1,31 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } +} + + + update @table.Name + + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + @if (col.IsPrimaryKey) + { + continue; + } + @Html.PadLeft(6)@col.Name = #{@col.ConvertedName} + @(colIndex == table.Columns.Count() - 1 ? "" : ",") + @Html.NewLine() + } + + where @pkCol.Name=#{@pkCol.Name} + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-Columns.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-Columns.cshtml new file mode 100644 index 0000000..05b88ae --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-Columns.cshtml @@ -0,0 +1,17 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); +} + + + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + @($"{col.Name}")@(colIndex == table.Columns.Count() - 1 ? "" : ",") + } + @Html.NewLine() + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-MySql.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-MySql.cshtml new file mode 100644 index 0000000..5f53444 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-MySql.cshtml @@ -0,0 +1,26 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + Layout = "_SqlMapLayout.cshtml"; + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + +@section QueryByPage +{ + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-PostgreSql.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-PostgreSql.cshtml new file mode 100644 index 0000000..5f53444 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-PostgreSql.cshtml @@ -0,0 +1,26 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + Layout = "_SqlMapLayout.cshtml"; + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + + var resultMapName = $"{table.ConvertedName}ResultMap"; +} + +@section QueryByPage +{ + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-ResultMaps.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-ResultMaps.cshtml new file mode 100644 index 0000000..0b9b20f --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-ResultMaps.cshtml @@ -0,0 +1,59 @@ +@using SmartCode +@using SmartCode.Db +@using SmartCode.Generator +@using SmartCode.Generator.Entity +@model BuildContext + +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + + var resultMapName = $"{table.ConvertedName}ResultMap"; + + var buildTask = Model.Build; + + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + + if (!project.BuildTasks.TryGetValue("Entity", out var entityBuild)) + { + throw new ArgumentException("can not find Project -> BuildTasks -> [Entity] ."); + } + + var entityName = $"{project.Module}.{entityBuild.Module}.{table.ConvertedName}"; + IDbTypeConverter dbTypeConverter = Model.PluginManager.Resolve(); +} + +@functions +{ + + String GetJdbcType(IDbTypeConverter dbTypeConverter, DbSource dbSource, Column column) + { + var dbType = column.DbType; + var dbProvider = dbSource.DbRepository.DbProvider; + var jdbcType = dbTypeConverter.LanguageType(dbProvider, "Jdbc", dbType); + if (dbType.Equals("tinyint", StringComparison.OrdinalIgnoreCase) + && column.DataLength <= 4) + { + jdbcType = "BOOLEAN"; + } + return String.IsNullOrEmpty(jdbcType) ? "" : $" jdbcType=\"{jdbcType}\""; + } +} + + + + + @foreach (var col in table.Columns) + { + if (col.IsPrimaryKey) + { + continue; + } + + } + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-SqlServer.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-SqlServer.cshtml new file mode 100644 index 0000000..edf1342 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-SqlServer.cshtml @@ -0,0 +1,80 @@ +@using SmartCode +@using SmartCode.Db +@using System.Text.RegularExpressions +@model BuildContext +@{ + Layout = "_SqlMapLayout.cshtml"; + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var versionNo = 2008; + var sqlServerVersion = dbSource.DbRepository.SqlMapper.ExecuteScalar(new SmartSql.RequestContext + { + RealSql = "Select @@Version;" + }); + var versionRegex = new Regex(@"^Microsoft SQL Server (\d*)", RegexOptions.Singleline); + var versionNoStr = versionRegex.Match(sqlServerVersion).Groups[1].Value; + int.TryParse(versionNoStr, out versionNo); + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + var primaryKeyType = pkCol?.LanguageType ?? "int"; + var autoIncrement = table.AutoIncrement; + var dbPrefix = dbSource.DbProvider.ParameterPrefix; + var notEqCols = table.Columns.Where(m => m.ConvertedName != m.Name); + var resultMapName = $"{table.ConvertedName}ResultMap"; + var queryStatementResultMap = table.HasColNameNotEqConvertedName ? $"ResultMap=\"{resultMapName}\"" : ""; +} + +@section QueryByPage +{ + + +} + +@section GetEntity +{ + + +} + +@section Query +{ + + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-WhereQueryParams.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-WhereQueryParams.cshtml new file mode 100644 index 0000000..43d54e1 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/SqlMap-WhereQueryParams.cshtml @@ -0,0 +1,28 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var table = Model.GetCurrentTable(); + Model.Build.Parameters.TryGetValue("LogicalDelete", out var logicalDeleteKey); +} + + + + @if (logicalDeleteKey != null) + { + @logicalDeleteKey=0 + } + @foreach (var col in table.Columns) + { + if (logicalDeleteKey != null && logicalDeleteKey.ToString().Equals(col.Name)) + { + continue; + } + + and @col.Name = #{@col.ConvertedName} + + } + + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/_SqlMapLayout.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/_SqlMapLayout.cshtml new file mode 100644 index 0000000..a69ea30 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap-Partials/_SqlMapLayout.cshtml @@ -0,0 +1,95 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); + var dbPrefix = dbSource.DbProvider.ParameterPrefix; + var buildTask = Model.Build; + var table = Model.GetCurrentTable(); + var pkCol = table.PKColumn; + if (pkCol == null) + { + throw new SmartCodeException($"{table.Name} can not find PKColumn!"); + } + + var repositoryName = $"{project.Module}.{buildTask.Module}.{table.ConvertedName}Repository"; +} + + + @{ await Html.RenderPartialAsync("SqlMap-ResultMaps.cshtml", Model); } + @{ await Html.RenderPartialAsync("SqlMap-Columns.cshtml", Model); } + @{ await Html.RenderPartialAsync("SqlMap-WhereQueryParams.cshtml", Model); } + + @if (IsSectionDefined("Insert")) + { + await RenderSectionAsync("Insert", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-Insert.cshtml", Model); + } + + @if (IsSectionDefined("Delete")) + { + await RenderSectionAsync("Delete", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-Delete.cshtml", Model); + } + + @if (IsSectionDefined("Update")) + { + await RenderSectionAsync("Update", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-Update.cshtml", Model); + } + + @if (IsSectionDefined("Query")) + { + await RenderSectionAsync("Query", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-Query.cshtml", Model); + } + + @if (IsSectionDefined("QueryByPage")) + { + await RenderSectionAsync("QueryByPage", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-QueryByPage.cshtml", Model); + } + + @if (IsSectionDefined("GetTotal")) + { + await RenderSectionAsync("GetTotal", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-GetTotal.cshtml", Model); + } + + @if (IsSectionDefined("GetEntity")) + { + await RenderSectionAsync("GetEntity", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-GetEntity.cshtml", Model); + } + + @if (IsSectionDefined("GetById")) + { + await RenderSectionAsync("GetById", required: false); + } + else + { + await Html.RenderPartialAsync("./CURD/SqlMap-GetById.cshtml", Model); + } + \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Java/SqlMap.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap.cshtml new file mode 100644 index 0000000..bd9468e --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/SqlMap.cshtml @@ -0,0 +1,12 @@ +@using SmartCode +@using SmartCode.Db +@model BuildContext +@{ + var project = Model.Project; + var dbSource = Model.GetDataSource(); +} + + +@{ await Html.RenderPartialAsync($"./SqlMap-Partials/SqlMap-{dbSource.DbProvider.Name}.cshtml", Model); } diff --git a/src/SmartCode.Generator/RazorTemplates/Java/Test/Application-Test.cshtml b/src/SmartCode.Generator/RazorTemplates/Java/Test/Application-Test.cshtml new file mode 100644 index 0000000..b524926 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Java/Test/Application-Test.cshtml @@ -0,0 +1,31 @@ +@using SmartCode +@model BuildContext +@{ + Layout = "../_JavaLayout.cshtml"; + var project = Model.Project; + + var appName = "Demo"; + + if (project.Parameters.TryGetValue("ApplicationName", out var _appName)) + { + appName = _appName.ToString(); + } + var appClassTestsName = $"{appName}ApplicationTests"; +} + +package @(project.Module).server; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@@RunWith(SpringRunner.class) +@@SpringBootTest +public class @appClassTestsName { + +@@Test +public void contextLoads() { +} + +} \ No newline at end of file diff --git a/src/SmartCode.Generator/RazorTemplates/Sql/DbToMySql.cshtml b/src/SmartCode.Generator/RazorTemplates/Sql/DbToMySql.cshtml new file mode 100644 index 0000000..7de3a8f --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/Sql/DbToMySql.cshtml @@ -0,0 +1,45 @@ +@using SmartCode +@model BuildContext +@{ + var all_table = Model.GetCurrentAllTable(); +} +@functions { + String GetPGSqlType(SmartCode.Generator.Entity.Column col) + { + var sqlDbType = col.LanguageType; + if (string.IsNullOrEmpty(sqlDbType)) { + return "NAType"; + } + if (sqlDbType.StartsWith("varchar")) + { + if (col.DataLength == -1) { + return "text"; + } + return $"varchar({col.DataLength})"; + } + return sqlDbType; + } +} + +@foreach (var table in all_table) +{ + + /*==============================================================*/ + /* Table: @table.ConvertedName */ + /*==============================================================*/ + create table @table.ConvertedName ( + + @for (var colIndex = 0; colIndex < table.Columns.Count(); colIndex++) + { + var col = table.Columns.ElementAt(colIndex); + @col.ConvertedName @Html.PadLeft(4) @GetPGSqlType(col) @Html.PadLeft(4) @(col.IsNullable ? "null" : "not null") @(col.IsPrimaryKey?" primary key":"") @(col.AutoIncrement?" AUTO_INCREMENT":"") @if (!String.IsNullOrEmpty(col.Description)) + { + comment '@col.Description' + } if (colIndex < table.Columns.Count() - 1) + {@(",")} + @Html.NewLine() + } + ); + + + } diff --git a/src/SmartCode.Generator/RazorTemplates/Sql/DbToPGSql.cshtml b/src/SmartCode.Generator/RazorTemplates/Sql/DbToPGSql.cshtml index 85450cd..8e21140 100644 --- a/src/SmartCode.Generator/RazorTemplates/Sql/DbToPGSql.cshtml +++ b/src/SmartCode.Generator/RazorTemplates/Sql/DbToPGSql.cshtml @@ -7,6 +7,9 @@ String GetPGSqlType(SmartCode.Generator.Entity.Column col) { var sqlDbType = col.LanguageType; + if (string.IsNullOrEmpty(sqlDbType)) { + return "NAType"; + } if (sqlDbType.StartsWith("varchar")) { if (col.DataLength == -1) { @@ -51,4 +54,4 @@ @Html.NewLine() } - } \ No newline at end of file + } diff --git a/src/SmartCode.Generator/RazorTemplates/TypeScript/Copyright.cshtml b/src/SmartCode.Generator/RazorTemplates/TypeScript/Copyright.cshtml new file mode 100644 index 0000000..bc98341 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/TypeScript/Copyright.cshtml @@ -0,0 +1,9 @@ +@using SmartCode +@model BuildContext +@{ + var project = Model.Project; +} +// Create By @project.Author +// Date @DateTime.Now.ToString("yyyy-MM-dd HH:mm") +// Code Generated By SmartCode +// Code Generater Github : https://github.com/dotnetcore/SmartCode diff --git a/src/SmartCode.Generator/RazorTemplates/TypeScript/Model.cshtml b/src/SmartCode.Generator/RazorTemplates/TypeScript/Model.cshtml new file mode 100644 index 0000000..8977d25 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/TypeScript/Model.cshtml @@ -0,0 +1,20 @@ +@using System; +@using SmartCode +@using SmartCode.Db +@using SmartCode.Generator.Entity; +@model BuildContext +@{ + Layout = "_Layout.cshtml"; + var project = Model.Project; + var task = Model.Build; + var table = Model.GetCurrentTable(); +} +@functions { } + +/** interface for @table.GetSummary() */ +export interface @(table.ConvertedName) { + @foreach (var col in table.Columns) { + @($"{Html.PadLeft(4)}/** {col.GetSummary()} */{Html.NewLine()}") + @($"{Html.PadLeft(4)}{col.ConvertedName}: {col.LanguageType};{Html.NewLine()}") + } +} diff --git a/src/SmartCode.Generator/RazorTemplates/TypeScript/_Layout.cshtml b/src/SmartCode.Generator/RazorTemplates/TypeScript/_Layout.cshtml new file mode 100644 index 0000000..6b5ed08 --- /dev/null +++ b/src/SmartCode.Generator/RazorTemplates/TypeScript/_Layout.cshtml @@ -0,0 +1,4 @@ +@using SmartCode +@model BuildContext +@{ Html.RenderPartial("Copyright.cshtml", Model); } +@RenderBody() diff --git a/src/SmartCode.TemplateEngine/Impl/HandlebarsTemplateEngine.cs b/src/SmartCode.TemplateEngine/Impl/HandlebarsTemplateEngine.cs index 3115d33..e460772 100644 --- a/src/SmartCode.TemplateEngine/Impl/HandlebarsTemplateEngine.cs +++ b/src/SmartCode.TemplateEngine/Impl/HandlebarsTemplateEngine.cs @@ -56,14 +56,14 @@ public Task Render(BuildContext context) return Task.FromResult(context.Result); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters == null) { return; } - if (paramters.Value("Name", out string name)) + if (parameters == null) { return; } + if (parameters.Value("Name", out string name)) { Name = name; } - if (paramters.Value("Root", out string root)) + if (parameters.Value("Root", out string root)) { _root = root; } diff --git a/src/SmartCode.TemplateEngine/Impl/OfficialRazorTemplateEngine.cs b/src/SmartCode.TemplateEngine/Impl/OfficialRazorTemplateEngine.cs index 64fefd8..65803a3 100644 --- a/src/SmartCode.TemplateEngine/Impl/OfficialRazorTemplateEngine.cs +++ b/src/SmartCode.TemplateEngine/Impl/OfficialRazorTemplateEngine.cs @@ -1,6 +1,8 @@ //******************************* // Thx https://github.com/aspnet/Entropy/tree/master/samples/Mvc.RenderViewToString //******************************* + +using System; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.AspNetCore.Mvc.Razor; @@ -11,41 +13,64 @@ using SmartCode.Utilities; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Reflection; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Microsoft.Extensions.FileProviders.Physical; namespace SmartCode.TemplateEngine.Impl { public class OfficialRazorTemplateEngine : ITemplateEngine { + private const string TEMP = ".temp"; public bool Initialized { get; private set; } public string Name { get; private set; } = "Razor"; private string _root = AppPath.Relative("RazorTemplates"); + private string _temp; private IServiceScopeFactory _scopeFactory; - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { Initialized = true; - if (paramters != null) + if (parameters != null) { - if (paramters.Value("Name", out string name)) + if (parameters.Value("Name", out string name)) { Name = name; } - if (paramters.Value("Root", out string root)) + if (parameters.Value("Root", out string root)) { _root = root; } } + _temp = Path.Combine(_root, TEMP); + if (!Directory.Exists(_temp)) + { + Directory.CreateDirectory(_temp); + } InitializeServices(); } - public Task Render(BuildContext context) + public async Task Render(BuildContext context) { using (var serviceScope = _scopeFactory.CreateScope()) { var helper = serviceScope.ServiceProvider.GetRequiredService(); - return helper.RenderViewToStringAsync(context.Build.TemplateEngine.FullPath, context); + var viewPath = context.Build.TemplateEngine.FullPath; + if (Path.IsPathRooted(viewPath)) + { + var tempFileName = $"{Path.GetFileNameWithoutExtension(viewPath)}-{Guid.NewGuid():N}{Path.GetExtension(viewPath)}"; + var destFileName = Path.Combine(_temp, tempFileName); + File.Copy(context.Build.TemplateEngine.FullPath, destFileName); + viewPath = Path.Combine(TEMP, tempFileName); + var result = await helper.RenderViewToStringAsync(viewPath, context); + File.Delete(destFileName); + return result; + } + else + { + return await helper.RenderViewToStringAsync(viewPath, context); + } } } @@ -58,7 +83,7 @@ private void InitializeServices() private IServiceCollection ConfigureDefaultServices() { var services = new ServiceCollection(); - IFileProvider fileProvider = new PhysicalFileProvider(_root); + IFileProvider fileProvider = new PhysicalFileProvider(_root, ExclusionFilters.None); services.AddSingleton(new HostingEnvironment { ApplicationName = Assembly.GetEntryAssembly().GetName().Name, diff --git a/src/SmartCode.TemplateEngine/SmartCode.TemplateEngine.csproj b/src/SmartCode.TemplateEngine/SmartCode.TemplateEngine.csproj index ac32f8a..5d4671a 100644 --- a/src/SmartCode.TemplateEngine/SmartCode.TemplateEngine.csproj +++ b/src/SmartCode.TemplateEngine/SmartCode.TemplateEngine.csproj @@ -2,12 +2,11 @@ netstandard2.0 - 1.5.0 - - - + + + diff --git a/src/SmartCode.Tests/DbTypeConverter_Test.cs b/src/SmartCode.Tests/DbTypeConverter_Test.cs index f146e9b..81463ad 100644 --- a/src/SmartCode.Tests/DbTypeConverter_Test.cs +++ b/src/SmartCode.Tests/DbTypeConverter_Test.cs @@ -6,6 +6,8 @@ using System.Text; using Xunit; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + namespace SmartCode.Tests { public class DbTypeConverter_Test @@ -13,12 +15,11 @@ public class DbTypeConverter_Test [Fact] public void Convert() { - var logger = SmartSql.Logging.NoneLoggerFactory.Instance.CreateLogger(); var xmlPath = @"E:\Ahoo\SmartCode\src\SmartCode\DbTypeConverter\DbTypeMap.xml"; var patamters = new Dictionary { { "XmlPath",xmlPath} }; - IDbTypeConverter convert = new DefaultDbTypeConverter(logger); + IDbTypeConverter convert = new DefaultDbTypeConverter(NullLogger.Instance); convert.Initialize(patamters); var langType = convert.LanguageType(DbProvider.SqlServer, "CSharp", "int"); Assert.Equal("Int16", langType); diff --git a/src/SmartCode.Tests/SmartCode.Tests.csproj b/src/SmartCode.Tests/SmartCode.Tests.csproj index d24f7b0..54c0bb6 100644 --- a/src/SmartCode.Tests/SmartCode.Tests.csproj +++ b/src/SmartCode.Tests/SmartCode.Tests.csproj @@ -1,15 +1,18 @@  - netcoreapp2.1 + netcoreapp2.2 false - - - + + + + all + runtime; build; native; contentfiles; analyzers + diff --git a/src/SmartCode/AbstractPlugin.cs b/src/SmartCode/AbstractPlugin.cs index 817b0ba..e0c99c4 100644 --- a/src/SmartCode/AbstractPlugin.cs +++ b/src/SmartCode/AbstractPlugin.cs @@ -22,14 +22,11 @@ public abstract class AbstractPlugin : IPlugin public ILoggerFactory LoggerFactory { get; protected set; } public Project Project { get; protected set; } public IPluginManager PluginManager { get; protected set; } - public virtual void Initialize(IDictionary paramters) + public virtual void Initialize(IDictionary parameters) { - if (paramters != null) + if (parameters != null) { - if (paramters.Value(NAME_KEY, out string name)) - { - Name = name; - } + } this.Initialized = true; } diff --git a/src/SmartCode/BuildContext.cs b/src/SmartCode/BuildContext.cs index e6c560f..9746c0d 100644 --- a/src/SmartCode/BuildContext.cs +++ b/src/SmartCode/BuildContext.cs @@ -1,12 +1,15 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading; +using System.Threading.Tasks; using SmartCode.Configuration; namespace SmartCode { public class BuildContext { + public Project Project { get; set; } public IDataSource DataSource { get; set; } public IPluginManager PluginManager { get; set; } @@ -16,7 +19,7 @@ public class BuildContext public String Result { get; set; } public Output Output { get; set; } #endregion - public object this[string key] { get { return Items[key]; } set { Items[key] = value; } } + public object this[string key] { get => Items[key]; set => Items[key] = value; } public IDictionary Items { get; set; } = new Dictionary(); public TItem GetItem(string key) { @@ -26,5 +29,9 @@ public void SetItem(string key, object item) { Items[key] = item; } + + public IList DependOn { get; set; } + //public Task BuildTask { get; set; } + public CountdownEvent CountDown { get; } = new CountdownEvent(1); } } diff --git a/src/SmartCode/BuildContextExtensions.cs b/src/SmartCode/BuildContextExtensions.cs index 8c4872d..f1904c4 100644 --- a/src/SmartCode/BuildContextExtensions.cs +++ b/src/SmartCode/BuildContextExtensions.cs @@ -10,6 +10,5 @@ public static TDataSource GetDataSource(this BuildContext context) { return (TDataSource)context.DataSource; } - } } diff --git a/src/SmartCode/Configuration/Build.cs b/src/SmartCode/Configuration/Build.cs index 03f06b1..f00f859 100644 --- a/src/SmartCode/Configuration/Build.cs +++ b/src/SmartCode/Configuration/Build.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; namespace SmartCode.Configuration @@ -12,16 +13,20 @@ public class Build /// public String Type { get; set; } public String Module { get; set; } - public TemplateEngine TemplateEngine { get; set; } + public TemplateEngine TemplateEngine { get; set; } public Output Output { get; set; } public IEnumerable IncludeTables { get; set; } public IEnumerable IgnoreTables { get; set; } - public bool IgnoreNoPKTable { get; set; } - public bool IgnoreView { get; set; } + public bool? IgnoreNoPKTable { get; set; } + public bool? IgnoreView { get; set; } public NamingConverter NamingConverter { get; set; } /// + /// 依赖于 + /// + public IEnumerable DependOn { get; set; } + /// /// 自定义构建参数 /// - public IDictionary Paramters { get; set; } + public IDictionary Parameters { get; set; } } } diff --git a/src/SmartCode/Configuration/ConfigBuilders/ConfigBuilder.cs b/src/SmartCode/Configuration/ConfigBuilders/ConfigBuilder.cs index d8bd859..9b33bf1 100644 --- a/src/SmartCode/Configuration/ConfigBuilders/ConfigBuilder.cs +++ b/src/SmartCode/Configuration/ConfigBuilders/ConfigBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using System.Threading.Tasks; @@ -7,10 +8,29 @@ namespace SmartCode.Configuration.ConfigBuilders { public abstract class ConfigBuilder : IConfigBuilder { - protected Project Project { get; set; } - public abstract Project Build(); + public string ConfigPath { get; } + public Project Project { get; set; } - protected void InitDefault() + protected ConfigBuilder(string configPath) + { + ConfigPath = configPath; + } + + public Project Build() + { + using (StreamReader configStream = new StreamReader(ConfigPath)) + { + var jsonConfigStr = configStream.ReadToEnd(); + Project = Deserialize(jsonConfigStr); + } + + InitDefault(); + return Project; + } + + protected abstract Project Deserialize(string content); + + private void InitDefault() { if (Project.Output != null) { @@ -18,12 +38,18 @@ protected void InitDefault() { Project.Output.Type = "File"; } + if (Project.Output?.Mode == CreateMode.None) { Project.Output.Mode = CreateMode.Incre; } } + if (Project.NamingConverter == null) + { + Project.NamingConverter = NamingConverter.Default; + } + foreach (var buildTask in Project.BuildTasks.Values) { if (buildTask.Output != null) @@ -32,11 +58,18 @@ protected void InitDefault() { buildTask.Output.Type = Project.Output.Type; } + if (buildTask.Output.Mode == CreateMode.None) { buildTask.Output.Mode = Project.Output.Mode; } + + if (!buildTask.Output.DotSplit.HasValue) + { + buildTask.Output.DotSplit = Project.Output.DotSplit; + } } + if (buildTask.TemplateEngine == null) { buildTask.TemplateEngine = Project.TemplateEngine; @@ -47,10 +80,12 @@ protected void InitDefault() { buildTask.TemplateEngine.Name = Project.TemplateEngine.Name; } + if (String.IsNullOrEmpty(buildTask.TemplateEngine.Root)) { buildTask.TemplateEngine.Root = Project.TemplateEngine.Root; } + if (String.IsNullOrEmpty(buildTask.TemplateEngine.Path)) { buildTask.TemplateEngine.Path = Project.TemplateEngine.Path; @@ -59,24 +94,54 @@ protected void InitDefault() if (buildTask.NamingConverter == null) { - buildTask.NamingConverter = NamingConverter.Defalut; + buildTask.NamingConverter = Project.NamingConverter; } else { if (buildTask.NamingConverter.Table == null) { - buildTask.NamingConverter.Table = TokenizerMapConverter.Default; + buildTask.NamingConverter.Table = Project.NamingConverter.Table; } + if (buildTask.NamingConverter.View == null) { - buildTask.NamingConverter.View = TokenizerMapConverter.Default; + buildTask.NamingConverter.View = Project.NamingConverter.View; } + if (buildTask.NamingConverter.Column == null) { - buildTask.NamingConverter.Column = TokenizerMapConverter.Default; + buildTask.NamingConverter.Column = Project.NamingConverter.Column; + } + } + + if (Project.TableFilter != null) + { + if (buildTask.IgnoreTables == null) + { + buildTask.IgnoreTables = Project.TableFilter.IgnoreTables; + } + + if (buildTask.IncludeTables == null) + { + buildTask.IncludeTables = Project.TableFilter.IncludeTables; + } + + if (!buildTask.IgnoreView.HasValue) + { + buildTask.IgnoreView = Project.TableFilter.IgnoreView; + } + + if (!buildTask.IgnoreNoPKTable.HasValue) + { + buildTask.IgnoreNoPKTable = Project.TableFilter.IgnoreNoPKTable; } } + + if (buildTask.Parameters == null) + { + buildTask.Parameters = new Dictionary(); + } } } } -} +} \ No newline at end of file diff --git a/src/SmartCode/Configuration/ConfigBuilders/JsonBuilder.cs b/src/SmartCode/Configuration/ConfigBuilders/JsonBuilder.cs index b585a1d..ea0fa7e 100644 --- a/src/SmartCode/Configuration/ConfigBuilders/JsonBuilder.cs +++ b/src/SmartCode/Configuration/ConfigBuilders/JsonBuilder.cs @@ -4,25 +4,18 @@ using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; + namespace SmartCode.Configuration.ConfigBuilders { public class JsonBuilder : ConfigBuilder { - private readonly string _configPath; - - public JsonBuilder(string configPath) + public JsonBuilder(string configPath) : base(configPath) { - _configPath = configPath; } - public override Project Build() + + protected override Project Deserialize(string content) { - using (StreamReader configStream = new StreamReader(_configPath)) - { - var jsonConfigStr = configStream.ReadToEnd(); - Project = JsonConvert.DeserializeObject(jsonConfigStr); - } - InitDefault(); - return Project; + return JsonConvert.DeserializeObject(content); } } -} +} \ No newline at end of file diff --git a/src/SmartCode/Configuration/ConfigBuilders/YamlBuilder.cs b/src/SmartCode/Configuration/ConfigBuilders/YamlBuilder.cs index c001779..50e0e98 100644 --- a/src/SmartCode/Configuration/ConfigBuilders/YamlBuilder.cs +++ b/src/SmartCode/Configuration/ConfigBuilders/YamlBuilder.cs @@ -10,23 +10,15 @@ namespace SmartCode.Configuration.ConfigBuilders { public class YamlBuilder : ConfigBuilder { - private readonly string _configPath; private readonly IDeserializer _deserializer; - public YamlBuilder(string configPath) + public YamlBuilder(string configPath):base(configPath) { - _configPath = configPath; _deserializer = new DeserializerBuilder().Build(); } - public override Project Build() + protected override Project Deserialize(string content) { - using (StreamReader configStream = new StreamReader(_configPath)) - { - var yamlConfigStr = configStream.ReadToEnd(); - Project = _deserializer.Deserialize(yamlConfigStr); - } - InitDefault(); - return Project; + return _deserializer.Deserialize(content); } } } diff --git a/src/SmartCode/Configuration/DataSource.cs b/src/SmartCode/Configuration/DataSource.cs index c27b75a..e703478 100644 --- a/src/SmartCode/Configuration/DataSource.cs +++ b/src/SmartCode/Configuration/DataSource.cs @@ -8,6 +8,6 @@ namespace SmartCode.Configuration public class DataSource { public String Name { get; set; } - public IDictionary Paramters { get; set; } + public IDictionary Parameters { get; set; } } } diff --git a/src/SmartCode/Configuration/NamingConverter.cs b/src/SmartCode/Configuration/NamingConverter.cs index 7fc232e..62e0615 100644 --- a/src/SmartCode/Configuration/NamingConverter.cs +++ b/src/SmartCode/Configuration/NamingConverter.cs @@ -6,7 +6,7 @@ namespace SmartCode.Configuration { public class NamingConverter { - public static NamingConverter Defalut = new NamingConverter + public static NamingConverter Default = new NamingConverter { Table = TokenizerMapConverter.Default, Column = TokenizerMapConverter.Default, @@ -35,11 +35,11 @@ public class Tokenizer { public static Tokenizer Default = new Tokenizer { - Type = "Defalut", - Paramters = new Dictionary() + Type = "Default", + Parameters = new Dictionary() }; public String Type { get; set; } - public IDictionary Paramters { get; set; } + public IDictionary Parameters { get; set; } } /// /// 词转换器 @@ -48,10 +48,10 @@ public class WordsConverter { public static WordsConverter Default = new WordsConverter { - Type = "Defalut", - Paramters = new Dictionary() + Type = "Default", + Parameters = new Dictionary() }; public String Type { get; set; } - public IDictionary Paramters { get; set; } + public IDictionary Parameters { get; set; } } } diff --git a/src/SmartCode/Configuration/Output.cs b/src/SmartCode/Configuration/Output.cs index 66e9869..0be7a9d 100644 --- a/src/SmartCode/Configuration/Output.cs +++ b/src/SmartCode/Configuration/Output.cs @@ -10,36 +10,61 @@ public class Output /// 输出插件类型 /// public String Type { get; set; } + /// /// 输出目录 /// public String Path { get; set; } + /// /// 文件创建模式 /// public CreateMode Mode { get; set; } = CreateMode.None; + /// /// 文件名 /// public String Name { get; set; } + + /// + /// '.' 拆分成 '/' + /// + public bool? DotSplit { get; set; } + /// /// 文件扩展名 /// public String Extension { get; set; } + + public Output Copy() + { + return new Output + { + Type = Type, + Path = Path, + DotSplit = DotSplit, + Name = Name, + Mode = Mode, + Extension = Extension + }; + } } + /// /// 文件创建模式 /// public enum CreateMode { None, + /// /// 增量创建,如果存在则忽略 /// Incre, + /// /// 全量创建,如果存在则重新创建 /// Full } -} +} \ No newline at end of file diff --git a/src/SmartCode/Configuration/Project.cs b/src/SmartCode/Configuration/Project.cs index 52ce66d..92deb0b 100644 --- a/src/SmartCode/Configuration/Project.cs +++ b/src/SmartCode/Configuration/Project.cs @@ -11,13 +11,23 @@ public class Project public String ConfigPath { get; set; } public String Module { get; set; } public String Author { get; set; } + public bool AllowParallel { get; set; } = false; + public ProjectMode? Mode { get; set; } public DataSource DataSource { get; set; } public TemplateEngine TemplateEngine { get; set; } = TemplateEngine.Default; public String Language { get; set; } = "CSharp"; public Output Output { get; set; } - public IDictionary Paramters { get; set; } = new Dictionary(); - [YamlMember(Alias = "Build")] - public IDictionary BuildTasks { get; set; } - public String OutputPath { get { return Output.Path; } } + public IDictionary Parameters { get; set; } = new Dictionary(); + [YamlMember(Alias = "Build")] public IDictionary BuildTasks { get; set; } + public String OutputPath => Output.Path; + public NamingConverter NamingConverter { get; set; } + public TableFilter TableFilter { get; set; } + + + public enum ProjectMode + { + GENERATOR, + ETL + } } -} +} \ No newline at end of file diff --git a/src/SmartCode/Configuration/TableFilter.cs b/src/SmartCode/Configuration/TableFilter.cs new file mode 100644 index 0000000..ca79f5a --- /dev/null +++ b/src/SmartCode/Configuration/TableFilter.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace SmartCode.Configuration +{ + public class TableFilter + { + public IEnumerable IncludeTables { get; set; } + public IEnumerable IgnoreTables { get; set; } + public bool? IgnoreNoPKTable { get; set; } + public bool? IgnoreView { get; set; } + } +} \ No newline at end of file diff --git a/src/SmartCode/Configuration/TemplateEngine.cs b/src/SmartCode/Configuration/TemplateEngine.cs index faf8ebf..0e4300e 100644 --- a/src/SmartCode/Configuration/TemplateEngine.cs +++ b/src/SmartCode/Configuration/TemplateEngine.cs @@ -13,6 +13,7 @@ public class TemplateEngine public String Name { get; set; } public String Root { get; set; } public String Path { get; set; } - public String FullPath { get { return System.IO.Path.Combine(Root, Path); } } + [Newtonsoft.Json.JsonIgnore] + public String FullPath => System.IO.Path.Combine(Root, Path); } } diff --git a/src/SmartCode/IInitialize.cs b/src/SmartCode/IInitialize.cs index d354103..8689d55 100644 --- a/src/SmartCode/IInitialize.cs +++ b/src/SmartCode/IInitialize.cs @@ -6,6 +6,6 @@ namespace SmartCode { public interface IInitialize { - void Initialize(IDictionary paramters); + void Initialize(IDictionary parameters); } } diff --git a/src/SmartCode/IOutput.cs b/src/SmartCode/IOutput.cs index c4331ac..cc21bd4 100644 --- a/src/SmartCode/IOutput.cs +++ b/src/SmartCode/IOutput.cs @@ -2,11 +2,12 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; +using SmartCode.Configuration; namespace SmartCode { public interface IOutput : IPlugin { - Task Output(BuildContext context); + Task Output(BuildContext context, Output output = null); } } diff --git a/src/SmartCode/IProjectBuilder.cs b/src/SmartCode/IProjectBuilder.cs index b1799e7..f420116 100644 --- a/src/SmartCode/IProjectBuilder.cs +++ b/src/SmartCode/IProjectBuilder.cs @@ -4,30 +4,8 @@ namespace SmartCode { - public class OnProjectBuildStartupEventArgs : EventArgs - { - public Project Project { get; set; } - } - public delegate Task OnProjectBuildStartupHandler(object sender, OnProjectBuildStartupEventArgs eventArgs); - public class OnProjectBuildSucceedEventArgs : EventArgs - { - public Project Project { get; set; } - } - public delegate Task OnProjectBuildSucceedHandler(object sender, OnProjectBuildSucceedEventArgs eventArgs); - - public class OnProjectBuildFailedEventArgs : EventArgs - { - public Project Project { get; set; } - public BuildContext Context { get; set; } - public Exception ErrorException { get; set; } - } - public delegate Task OnProjectBuildFailedHandler(object sender, OnProjectBuildFailedEventArgs eventArgs); - public interface IProjectBuilder { - event OnProjectBuildStartupHandler OnStartup; - event OnProjectBuildSucceedHandler OnSucceed; - event OnProjectBuildFailedHandler OnFailed; Task Build(); } } diff --git a/src/SmartCode/NoneDataSource.cs b/src/SmartCode/NoneDataSource.cs index 1440e24..79b37c6 100644 --- a/src/SmartCode/NoneDataSource.cs +++ b/src/SmartCode/NoneDataSource.cs @@ -16,7 +16,7 @@ public Task InitData() return Task.CompletedTask; } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode/PluginConfig.cs b/src/SmartCode/PluginConfig.cs index 3e7953e..3a684a8 100644 --- a/src/SmartCode/PluginConfig.cs +++ b/src/SmartCode/PluginConfig.cs @@ -8,12 +8,12 @@ public class PluginConfig { public String Name { get; set; } public String Type { get; set; } - public String TypeName { get { return Type.Split(',')[0].Trim(); } } - public String AssemblyName { get { return Type.Split(',')[1].Trim(); } } + public String TypeName => Type.Split(',')[0].Trim(); + public String AssemblyName => Type.Split(',')[1].Trim(); public String ImplType { get; set; } - public String ImplTypeName { get { return ImplType.Split(',')[0].Trim(); } } - public String ImplAssemblyName { get { return ImplType.Split(',')[1].Trim(); } } - public IDictionary Paramters { get; set; } + public String ImplTypeName => ImplType.Split(',')[0].Trim(); + public String ImplAssemblyName => ImplType.Split(',')[1].Trim(); + public IDictionary Parameters { get; set; } } } diff --git a/src/SmartCode/SmartCode.csproj b/src/SmartCode/SmartCode.csproj index bf63679..b083a2d 100644 --- a/src/SmartCode/SmartCode.csproj +++ b/src/SmartCode/SmartCode.csproj @@ -3,26 +3,14 @@ netstandard2.0 true - latest SmartCode - - SmartCode = IDataSource -> IBuildTask -> IOutput => Build Everything!!! - - Ahoo Wang - Ahoo Wang - https://raw.githubusercontent.com/Ahoo-Wang/SmartCode/master/LICENSE - https://github.com/Ahoo-Wang/SmartCode - Github - SmartCode - true - https://github.com/Ahoo-Wang/SmartCode - 1.2.0 - - - + + + + diff --git a/src/SmartCode/TokenizerFactory.cs b/src/SmartCode/TokenizerFactory.cs index 8055324..b3d9495 100644 --- a/src/SmartCode/TokenizerFactory.cs +++ b/src/SmartCode/TokenizerFactory.cs @@ -8,11 +8,24 @@ namespace SmartCode { public class TokenizerFactory { - public static ITokenizer Create(Tokenizer tokenizer) + public static ITokenizer Create(Tokenizer tokenizerConfig) { - DefaultTokenizer defaultTokenizer = new DefaultTokenizer(); - defaultTokenizer.Initialize(tokenizer.Paramters); - return defaultTokenizer; + ITokenizer tokenizer; + switch (tokenizerConfig.Type) + { + case "None": + { + tokenizer = new NoneTokenizer(); + break; + } + default: + { + tokenizer = new DefaultTokenizer(); + break; + } + } + tokenizer.Initialize(tokenizerConfig.Parameters); + return tokenizer; } } } diff --git a/src/SmartCode/Utilities/IDictionaryExtensions.cs b/src/SmartCode/Utilities/IDictionaryExtensions.cs deleted file mode 100644 index e64e18d..0000000 --- a/src/SmartCode/Utilities/IDictionaryExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -using SmartCode; -using System; -using System.Collections.Generic; -using System.Text; - -namespace System.Collections.Generic -{ - public static class IDictionaryExtensions - { - public static bool Value(this IDictionary dic, TKey key, out TTypedValue value) - { - value = default; - if (dic == null) { return false; } - if (!dic.TryGetValue(key, out TValue val)) - { - return false; - } - - object objVal = val; - var valType = typeof(TValue); - var typedValType = typeof(TTypedValue); - if (typedValType.IsEnum && objVal is string) - { - value = (TTypedValue)Enum.Parse(typedValType, objVal.ToString()); - } - else if (typeof(IConvertible).IsAssignableFrom(typedValType)) - { - value = (TTypedValue)Convert.ChangeType(objVal, typedValType); - } - else - { - value = (TTypedValue)objVal; - } - return true; - } - public static void EnsureValue(this IDictionary dic, TKey key, out TTypedValue value) - { - if (!dic.Value(key, out value)) - { - throw new SmartCodeException($"Can not find Paramter:{key}!"); - } - } - } -} diff --git a/src/SmartCode/Utilities/NamingUtil.cs b/src/SmartCode/Utilities/NamingUtil.cs index b445750..5768165 100644 --- a/src/SmartCode/Utilities/NamingUtil.cs +++ b/src/SmartCode/Utilities/NamingUtil.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; namespace SmartCode { @@ -16,5 +17,57 @@ public static String PascalCase(string phrase) string firstChar = phrase.Substring(0, 1).ToUpper(); return firstChar + phrase.Substring(1); } + + /// 讲单词转换为单数的形式 + public static string ToSingular(string phrase) + { + Regex plural1 = new Regex("(?[^aeiou])ies$"); + Regex plural2 = new Regex("(?[aeiou]y)s$"); + Regex plural3 = new Regex("(?[sxzh])es$"); + Regex plural4 = new Regex("(?[^sxzhyu])s$"); + if (plural1.IsMatch(phrase)) + { + return plural1.Replace(phrase, "${keep}y"); + } + else if (plural2.IsMatch(phrase)) + { + return plural2.Replace(phrase, "${keep}"); + } + else if (plural3.IsMatch(phrase)) + { + return plural3.Replace(phrase, "${keep}"); + } + else if (plural4.IsMatch(phrase)) + { + return plural4.Replace(phrase, "${keep}"); + } + return phrase; + } + + /// 讲单词转换为复数的形式 + public static string ToPlural(string phrase) + { + Regex plural1 = new Regex("(?[^aeiou])y$"); + Regex plural2 = new Regex("(?[aeiou]y)$"); + Regex plural3 = new Regex("(?[sxzh])$"); + Regex plural4 = new Regex("(?[^sxzhy])$"); + if (plural1.IsMatch(phrase)) + { + return plural1.Replace(phrase, "${keep}ies"); + } + else if (plural2.IsMatch(phrase)) + { + return plural2.Replace(phrase, "${keep}s"); + } + else if (plural3.IsMatch(phrase)) + { + return plural3.Replace(phrase, "${keep}es"); + } + else if (plural4.IsMatch(phrase)) + { + return plural4.Replace(phrase, "${keep}s"); + } + return phrase; + } } } diff --git a/src/SmartCode/WordsConverter/CamelCaseConverter.cs b/src/SmartCode/WordsConverter/CamelCaseConverter.cs index a949c06..2450ff8 100644 --- a/src/SmartCode/WordsConverter/CamelCaseConverter.cs +++ b/src/SmartCode/WordsConverter/CamelCaseConverter.cs @@ -17,7 +17,11 @@ public String Convert(IEnumerable words) foreach (var word in words) { string firstChar = word.Substring(0, 1).ToUpper(); - if (isFirstWord) { firstChar = firstChar.ToLower(); } + if (isFirstWord) + { + firstChar = firstChar.ToLower(); + isFirstWord = false; + } stringBuilder.Append(firstChar); string leftChar = word.Substring(1).ToLower(); stringBuilder.Append(leftChar); @@ -25,7 +29,7 @@ public String Convert(IEnumerable words) return stringBuilder.ToString(); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { Initialized = true; } diff --git a/src/SmartCode/WordsConverter/DefaultTokenizer.cs b/src/SmartCode/WordsConverter/DefaultTokenizer.cs index d50d8bb..f8510c1 100644 --- a/src/SmartCode/WordsConverter/DefaultTokenizer.cs +++ b/src/SmartCode/WordsConverter/DefaultTokenizer.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using SmartCode.Utilities; namespace SmartCode.WordsConverter { @@ -61,19 +62,19 @@ public IEnumerable Segment(string phrase) return new string[] { phrase }; } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters != null) + if (parameters != null) { - if (paramters.Value(IGNORE_PREFIX_KEY, out string ignorePre)) + if (parameters.Value(IGNORE_PREFIX_KEY, out string ignorePre)) { IgnorePrefix = ignorePre; } - if (paramters.Value(DELIMITER_KEY, out string delimiter)) + if (parameters.Value(DELIMITER_KEY, out string delimiter)) { Delimiter = delimiter; } - if (paramters.Value(UPPERCASESPLIT_KEY, out bool upperSplit)) + if (parameters.Value(UPPERCASESPLIT_KEY, out bool upperSplit)) { UppercaseSplit = upperSplit; } diff --git a/src/SmartCode/WordsConverter/DelimiterConverter.cs b/src/SmartCode/WordsConverter/DelimiterConverter.cs index 23bfdbf..72f0234 100644 --- a/src/SmartCode/WordsConverter/DelimiterConverter.cs +++ b/src/SmartCode/WordsConverter/DelimiterConverter.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using SmartCode.Utilities; namespace SmartCode.WordsConverter { @@ -54,19 +55,19 @@ public string Convert(IEnumerable words) return _prefix + phrase; } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { - if (paramters != null) + if (parameters != null) { - if (!paramters.Value(DELIMITER, out _delimiter)) + if (!parameters.Value(DELIMITER, out _delimiter)) { _delimiter = "_"; } - if (!paramters.Value(CONVERT_MODE, out _convertMode)) + if (!parameters.Value(CONVERT_MODE, out _convertMode)) { _convertMode = ConvertMode.None; } - if (!paramters.Value(PREFIX, out _prefix)) + if (!parameters.Value(PREFIX, out _prefix)) { _prefix = string.Empty; } diff --git a/src/SmartCode/WordsConverter/NoneConverter.cs b/src/SmartCode/WordsConverter/NoneConverter.cs index 462b529..80844c3 100644 --- a/src/SmartCode/WordsConverter/NoneConverter.cs +++ b/src/SmartCode/WordsConverter/NoneConverter.cs @@ -15,7 +15,7 @@ public string Convert(IEnumerable words) return String.Join("", words); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode/WordsConverter/NoneTokenizer.cs b/src/SmartCode/WordsConverter/NoneTokenizer.cs new file mode 100644 index 0000000..6f63b74 --- /dev/null +++ b/src/SmartCode/WordsConverter/NoneTokenizer.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SmartCode.WordsConverter +{ + public class NoneTokenizer : ITokenizer + { + public void Initialize(IDictionary parameters) + { + + } + + public bool Initialized => true; + public string Name => "None"; + public IEnumerable Segment(string phrase) + { + return new[] { phrase }; + } + } +} diff --git a/src/SmartCode/WordsConverter/PascalCaseConverter.cs b/src/SmartCode/WordsConverter/PascalCaseConverter.cs index 794f8ad..02547b8 100644 --- a/src/SmartCode/WordsConverter/PascalCaseConverter.cs +++ b/src/SmartCode/WordsConverter/PascalCaseConverter.cs @@ -23,7 +23,7 @@ public String Convert(IEnumerable words) return stringBuilder.ToString(); } - public void Initialize(IDictionary paramters) + public void Initialize(IDictionary parameters) { } diff --git a/src/SmartCode/WordsConverter/PascalCaseSingularConverter.cs b/src/SmartCode/WordsConverter/PascalCaseSingularConverter.cs new file mode 100644 index 0000000..4001179 --- /dev/null +++ b/src/SmartCode/WordsConverter/PascalCaseSingularConverter.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace SmartCode.WordsConverter { + + /// + /// 在原来的 PascalCaseConverter 的基础之上, 增加了强制转成单数的转换, 应对某些数据 + /// 库表名称为复数单词的情况, 确认生成的类名是单数形式。(仅仅用正则表达式进行判断, 可能 + /// 会有误伤)。 + /// + public class PascalCaseSingularConverter : IWordsConverter { + + private PascalCaseConverter converter = new PascalCaseConverter(); + + public bool Initialized => converter.Initialized; + + public string Name => "PascalSingular"; + + public string Convert(IEnumerable words) { + var pascalWords = converter.Convert(words); + return NamingUtil.ToSingular(pascalWords); + } + + public void Initialize(IDictionary parameters) { + converter.Initialize(parameters); + } + + } + +} diff --git a/src/SmartCode/WordsConverter/StrikeThroughConverter.cs b/src/SmartCode/WordsConverter/StrikeThroughConverter.cs new file mode 100644 index 0000000..127f7aa --- /dev/null +++ b/src/SmartCode/WordsConverter/StrikeThroughConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using System.Text; + +namespace SmartCode.WordsConverter { + + /// 前端常用的小写中划线命名转换器 + public class StrikeThroughConverter : IWordsConverter { + + public bool Initialized { get; private set; } + + public string Name => "StrikeThrough"; + + public string Convert(IEnumerable words) { + return string.Join("-", words).ToLowerInvariant(); + } + + public void Initialize(IDictionary parameters) { + Initialized = true; + } + } + +} diff --git a/src/SmartCode/WordsConverterFactory.cs b/src/SmartCode/WordsConverterFactory.cs index b99177b..72346c3 100644 --- a/src/SmartCode/WordsConverterFactory.cs +++ b/src/SmartCode/WordsConverterFactory.cs @@ -25,12 +25,20 @@ public static IWordsConverter Create(Configuration.WordsConverter wordsConverter { converter = new DelimiterConverter(); break; } + case "PascalSingular": + { + converter = new PascalCaseSingularConverter(); break; + } + case "StrikeThrough": + { + converter = new StrikeThroughConverter(); break; + } default: { return new NoneConverter(); } } - converter.Initialize(wordsConverter.Paramters); + converter.Initialize(wordsConverter.Parameters); return converter; } }