From 450d77e5b26cada011b67329c733a517cd5713af Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Tue, 17 Sep 2024 18:02:24 +0800 Subject: [PATCH 1/7] Add init command --- e2e/mds/templates/java_type.partial.hbs | 19 ++-- pkg/cmd/init/init.go | 130 ++++++++++++++++++++++++ pkg/cmd/root.go | 2 + 3 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 pkg/cmd/init/init.go diff --git a/e2e/mds/templates/java_type.partial.hbs b/e2e/mds/templates/java_type.partial.hbs index f1c0192..64ad758 100644 --- a/e2e/mds/templates/java_type.partial.hbs +++ b/e2e/mds/templates/java_type.partial.hbs @@ -1,8 +1,15 @@ -{{~#if (match 'varchar.*|text' columnType)}}String -{{~else if (match 'bigint|int64' columnType)}}Long -{{~else if (match '.*int.*' columnType)}}Integer -{{~else if (match 'timestamp' columnType)}}java.util.Date -{{~else if (match 'enum.*' columnType)}}String -{{~else if (match 'decimal.*' columnType)}}java.math.BigDecimal +{{~#if (match 'varchar\(\d+\)|char|tinytext|text|mediumtext|longtext' columnType)}}String +{{~else if (match 'bigint' columnType)}}Long +{{~else if (match 'int|integer|mediumint' columnType)}}Integer +{{~else if (match 'smallint' columnType)}}Short +{{~else if (match 'tinyint' columnType)}}Byte +{{~else if (match 'bit|bool|boolean' columnType)}}Boolean +{{~else if (match 'decimal' columnType)}}java.math.BigDecimal +{{~else if (match 'float' columnType)}}Double +{{~else if (match 'datetime' columnType)}}java.time.LocalDateTime +{{~else if (match 'date' columnType)}}java.time.LocalDate +{{~else if (match 'time' columnType)}}java.time.LocalTime +{{~else if (match 'timestamp' columnType)}}java.sql.Timestamp +{{~else if (match 'varbinary' columnType)}}byte[] {{~else}}String {{~/if}} \ No newline at end of file diff --git a/pkg/cmd/init/init.go b/pkg/cmd/init/init.go new file mode 100644 index 0000000..e3dca3c --- /dev/null +++ b/pkg/cmd/init/init.go @@ -0,0 +1,130 @@ +package init + +import ( + "github.com/DanielLiu1123/gencoder/pkg/model" + "github.com/spf13/cobra" + "log" + "os" +) + +type initOptions struct { +} + +func NewCmdInit(globalOptions *model.GlobalOptions) *cobra.Command { + + opt := &initOptions{} + + c := &cobra.Command{ + Use: "init", + Short: "Init basic configuration for gencoder", + PreRun: func(cmd *cobra.Command, args []string) { + }, + Run: func(cmd *cobra.Command, args []string) { + run(cmd, args, opt, globalOptions) + }, + } + + return c +} + +func run(_ *cobra.Command, _ []string, _ *initOptions, _ *model.GlobalOptions) { + + // init gencoder.yaml + gencoderYaml := `templatesDir: templates +databases: + - name: mysql + dsn: 'mysql://root:root@localhost:3306/testdb' + tables: + - name: 'user' + properties: + package: mysqlpackage + ignoreColumns: + - deleted_at + - name: postgres + dsn: 'postgres://root:root@localhost:5432/testdb?sslmode=disable' + properties: + package: defaultpackage + tables: + - name: 'user' + properties: + package: postgrespackage + ignoreColumns: + - deleted_at` + + if _, err := os.Stat("gencoder.yaml"); err != nil { + err := os.WriteFile("gencoder.yaml", []byte(gencoderYaml), 0644) + if err != nil { + log.Fatal(err) + } + } + + // init templates dir + if _, err := os.Stat("templates"); err != nil { + err = os.Mkdir("templates", 0755) + if err != nil { + log.Fatal(err) + } + } + + // init templates + entityJava := `/** + * @gencoder.generated: src/main/java/{{replaceAll properties.package '\.' '/'}}/{{pascalCase table.name}}.java + */ + +package {{properties.package}}; + +/** + * @gencoder.block.start: table + *

table: {{table.name}} + *

comment: {{table.comment}} + *

indexes: + {{#each table.indexes}} + *

{{name}}: ({{#each columns}}{{name}}{{#unless @last}}, {{/unless}}{{/each}}) + {{/each}} + */ +public record {{pascalCase table.name}} ( + {{#each table.columns}} + /** + * {{comment}} + */ + {{> 'java_type.partial.hbs' columnType=type}} {{camelCase name}}{{#unless @last}},{{/unless}} + {{/each}} + // @gencoder.block.end: table +) {} +` + + if _, err := os.Stat("templates/entity.java.hbs"); err != nil { + err = os.WriteFile("templates/entity.java.hbs", []byte(entityJava), 0644) + if err != nil { + log.Fatal(err) + } + } + + javaTypePartial := `{{~#if (match 'varchar\(\d+\)|char|tinytext|text|mediumtext|longtext' columnType)}}String +{{~else if (match 'bigint' columnType)}}Long +{{~else if (match 'int|integer|mediumint' columnType)}}Integer +{{~else if (match 'smallint' columnType)}}Short +{{~else if (match 'tinyint' columnType)}}Byte +{{~else if (match 'bit|bool|boolean' columnType)}}Boolean +{{~else if (match 'decimal' columnType)}}java.math.BigDecimal +{{~else if (match 'float' columnType)}}Double +{{~else if (match 'datetime' columnType)}}java.time.LocalDateTime +{{~else if (match 'date' columnType)}}java.time.LocalDate +{{~else if (match 'time' columnType)}}java.time.LocalTime +{{~else if (match 'timestamp' columnType)}}java.time.LocalDateTime +{{~else if (match 'varbinary' columnType)}}byte[] +{{~else if (match 'enum.*' columnType)}}String +{{~else}}Object +{{~/if}}` + + if _, err := os.Stat("templates/java_type.partial.hbs"); err != nil { + err = os.WriteFile("templates/java_type.partial.hbs", []byte(javaTypePartial), 0644) + if err != nil { + log.Fatal(err) + } + } + + log.Println("Init success! Please modify the gencoder.yaml and templates to fit your project needs.") + log.Println() + log.Println("Thank you for using gencoder!") +} diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index cc072bb..4b216d6 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/DanielLiu1123/gencoder/pkg/cmd/generate" + initCmd "github.com/DanielLiu1123/gencoder/pkg/cmd/init" "github.com/DanielLiu1123/gencoder/pkg/cmd/introspect" "github.com/DanielLiu1123/gencoder/pkg/model" "github.com/spf13/cobra" @@ -27,6 +28,7 @@ func NewCmdRoot(buildInfo *model.BuildInfo) *cobra.Command { c.AddCommand(generate.NewCmdGenerate(opt)) c.AddCommand(introspect.NewCmdIntrospect(opt)) + c.AddCommand(initCmd.NewCmdInit(opt)) return c } From 86188d71abcd0c642731c18cb0ff1898ba971da3 Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Tue, 17 Sep 2024 18:03:34 +0800 Subject: [PATCH 2/7] update java_type.partial.hbs --- e2e/mds/templates/java_type.partial.hbs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/e2e/mds/templates/java_type.partial.hbs b/e2e/mds/templates/java_type.partial.hbs index 64ad758..dfddb7b 100644 --- a/e2e/mds/templates/java_type.partial.hbs +++ b/e2e/mds/templates/java_type.partial.hbs @@ -9,7 +9,8 @@ {{~else if (match 'datetime' columnType)}}java.time.LocalDateTime {{~else if (match 'date' columnType)}}java.time.LocalDate {{~else if (match 'time' columnType)}}java.time.LocalTime -{{~else if (match 'timestamp' columnType)}}java.sql.Timestamp +{{~else if (match 'timestamp' columnType)}}java.time.LocalDateTime {{~else if (match 'varbinary' columnType)}}byte[] -{{~else}}String +{{~else if (match 'enum.*' columnType)}}String +{{~else}}Object {{~/if}} \ No newline at end of file From aba23437591dffc06bfae8f3cd279c2ef231ff1d Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Tue, 17 Sep 2024 18:08:21 +0800 Subject: [PATCH 3/7] update ci --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea91b80..7298196 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ permissions: contents: write jobs: - build: + release: runs-on: ubuntu-latest timeout-minutes: 10 steps: From 8b47bed1e125029f0e56e7b67938b81e4bb41895 Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Wed, 18 Sep 2024 14:06:50 +0800 Subject: [PATCH 4/7] Add mapper.java.hbs --- e2e/mds/templates/mapper.java.hbs | 159 ++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 e2e/mds/templates/mapper.java.hbs diff --git a/e2e/mds/templates/mapper.java.hbs b/e2e/mds/templates/mapper.java.hbs new file mode 100644 index 0000000..1070f9f --- /dev/null +++ b/e2e/mds/templates/mapper.java.hbs @@ -0,0 +1,159 @@ +/** + * @gencoder.generated: src/main/java/{{replaceAll properties.mapperPkg '\.' '/'}}/{{pascalCase table.name}}Mapper.java + */ +package {{properties.mapperPkg}}; + +import static {{properties.mapperPkg}}.{{pascalCase table.name}}DynamicSqlSupport.*; +import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; + +import {{properties.entityPkg}}.{{pascalCase table.name}}; +import jakarta.annotation.Generated; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.SelectKey; +import org.apache.ibatis.annotations.SelectProvider; +import org.apache.ibatis.type.JdbcType; +import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.delete.DeleteDSLCompleter; +import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; +import org.mybatis.dynamic.sql.select.CountDSLCompleter; +import org.mybatis.dynamic.sql.select.SelectDSLCompleter; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.update.UpdateDSL; +import org.mybatis.dynamic.sql.update.UpdateDSLCompleter; +import org.mybatis.dynamic.sql.update.UpdateModel; +import org.mybatis.dynamic.sql.util.SqlProviderAdapter; +import org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper; +import org.mybatis.dynamic.sql.util.mybatis3.CommonDeleteMapper; +import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper; +import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils; + +public class {{pascalCase table.name}}Mapper extends CommonCountMapper, CommonDeleteMapper, CommonUpdateMapper { + + // @gencoder.block.start: mapper + + BasicColumn[] selectList = BasicColumn.columnList({{#each table.columns}}{{camelCase name}}{{#unless @last}}, {{/unless}}{{/each}}); + + @InsertProvider(type=SqlProviderAdapter.class, method="insert") + @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="row.id", before=false, resultType=Integer.class) + int insert(InsertStatementProvider<{{pascalCase table.name}}> insertStatement); + + @SelectProvider(type=SqlProviderAdapter.class, method="select") + @Results(id="{{pascalCase table.name}}Result", value = { + {{#each table.columns}} + @Result(column="{{name}}", property="{{camelCase name}}"/**, jdbcType={{jdbcType}}*/{{#if isPrimaryKey}}, id=true{{/if}}){{#unless @last}},{{/unless}} + {{/each}} + }) + List<{{pascalCase table.name}}> selectMany(SelectStatementProvider selectStatement); + + @SelectProvider(type=SqlProviderAdapter.class, method="select") + @ResultMap("{{pascalCase table.name}}Result") + Optional<{{pascalCase table.name}}> selectOne(SelectStatementProvider selectStatement); + + default long count(CountDSLCompleter completer) { + return MyBatis3Utils.countFrom(this::count, {{camelCase table.name}}, completer); + } + + default int delete(DeleteDSLCompleter completer) { + return MyBatis3Utils.deleteFrom(this::delete, {{camelCase table.name}}, completer); + } + + default int deleteByPrimaryKey(Integer id_) { + return delete(c -> + c.where(id, isEqualTo(id_)) + ); + } + + default int insert({{pascalCase table.name}} row) { + return MyBatis3Utils.insert(this::insert, row, {{camelCase table.name}}, c -> c + {{#each table.columns}} + {{#if (ne name 'id')}} + .map({{camelCase name}}).toProperty("{{camelCase name}}") + {{/if}} + {{/each}} + ); + } + + default int insertSelective({{pascalCase table.name}} row) { + return MyBatis3Utils.insert(this::insert, row, user, c -> c + {{#each table.columns}} + {{#if (ne name 'id')}} + .map({{camelCase name}}).toPropertyWhenPresent("{{camelCase name}}") + {{/if}} + {{/each}} + ); + } + + default Optional<{{pascalCase table.name}}> selectOne(SelectDSLCompleter completer) { + return MyBatis3Utils.selectOne(this::selectOne, selectList, {{camelCase table.name}}, completer); + } + + default List<{{pascalCase table.name}}> select(SelectDSLCompleter completer) { + return MyBatis3Utils.selectList(this::selectMany, selectList, {{camelCase table.name}}, completer); + } + + default List<{{pascalCase table.name}}> selectDistinct(SelectDSLCompleter completer) { + return MyBatis3Utils.selectDistinct(this::selectMany, selectList, {{camelCase table.name}}, completer); + } + + default Optional<{{pascalCase table.name}}> selectByPrimaryKey(Integer id_) { + return selectOne(c -> + c.where(id, isEqualTo(id_)) + ); + } + + default int update(UpdateDSLCompleter completer) { + return MyBatis3Utils.update(this::update, {{camelCase table.name}}, completer); + } + + static UpdateDSL updateAllColumns({{pascalCase table.name}} row, UpdateDSL dsl) { + return dsl + {{#each table.columns}} + {{#if (ne name 'id')}} + .set({{camelCase name}}).equalTo(row::get{{upperFirst (camelCase name)}}){{#if @last}};{{/if}} + {{/if}} + {{/each}} + } + + static UpdateDSL updateSelectiveColumns({{pascalCase table.name}} row, UpdateDSL dsl) { + return dsl + {{#each table.columns}} + {{#if (ne name 'id')}} + .set({{camelCase name}}).equalToWhenPresent(row::get{{upperFirst (camelCase name)}}){{#if @last}};{{/if}} + {{/if}} + {{/each}} + } + + default int updateByPrimaryKey({{pascalCase table.name}} row) { + return update(c -> c + {{#each table.columns}} + {{#if (ne name 'id')}} + .set({{camelCase name}}).equalTo(row::get{{upperFirst (camelCase name)}}) + {{/if}} + {{/each}} + .where(id, isEqualTo(row::getId)) + ); + } + + default int updateByPrimaryKeySelective({{pascalCase table.name}} row) { + return update(c -> c + {{#each table.columns}} + {{#if (ne name 'id')}} + .set({{camelCase name}}).equalToWhenPresent(row::get{{upperFirst (camelCase name)}}) + {{/if}} + {{/each}} + .where(id, isEqualTo(row::getId)) + ); + } + + List> generalSelect(SelectStatementProvider selectStatement); + + // @gencoder.block.end: mapper + +} From 24deba2627e327ab3650b3c78d208ba3a513447f Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Thu, 19 Sep 2024 13:22:34 +0800 Subject: [PATCH 5/7] update init cmd --- pkg/cmd/init/init.go | 25 +++++----- pkg/jsruntime/gen/helper.gen.go | 83 ++++++++++++++++++++++++++------- pkg/jsruntime/helper.js | 83 ++++++++++++++++++++++++++------- 3 files changed, 147 insertions(+), 44 deletions(-) diff --git a/pkg/cmd/init/init.go b/pkg/cmd/init/init.go index e3dca3c..7c00de7 100644 --- a/pkg/cmd/init/init.go +++ b/pkg/cmd/init/init.go @@ -37,20 +37,12 @@ databases: tables: - name: 'user' properties: - package: mysqlpackage + package: 'com.example' ignoreColumns: - deleted_at - - name: postgres - dsn: 'postgres://root:root@localhost:5432/testdb?sslmode=disable' - properties: - package: defaultpackage - tables: - - name: 'user' - properties: - package: postgrespackage - ignoreColumns: - - deleted_at` +` + // init gencoder.yaml if _, err := os.Stat("gencoder.yaml"); err != nil { err := os.WriteFile("gencoder.yaml", []byte(gencoderYaml), 0644) if err != nil { @@ -89,8 +81,17 @@ public record {{pascalCase table.name}} ( */ {{> 'java_type.partial.hbs' columnType=type}} {{camelCase name}}{{#unless @last}},{{/unless}} {{/each}} + + // NOTE: you can't make changes in the block, it will be overwritten by generating again + // @gencoder.block.end: table -) {} +) { + + // TIP: you can make changes outside the block, it will not be overwritten by generating again + public void hello() { + System.out.println("Hello, World!"); + } +} ` if _, err := os.Stat("templates/entity.java.hbs"); err != nil { diff --git a/pkg/jsruntime/gen/helper.gen.go b/pkg/jsruntime/gen/helper.gen.go index e2691b8..9a193a4 100644 --- a/pkg/jsruntime/gen/helper.gen.go +++ b/pkg/jsruntime/gen/helper.gen.go @@ -2,63 +2,114 @@ package gen -const HelperJS = `// Add custom Handlebars helpers here +const HelperJS = ` +function isUndefinedOrNull(value) { + return value === undefined || value === null; +} -Handlebars.registerHelper('replaceAll', function(target, old, newV) { +function hasUndefinedOrNull(value) { + return Array.isArray(value) + ? value.some(e => isUndefinedOrNull(e)) + : isUndefinedOrNull(value); +} + +// Add custom Handlebars helpers below + +Handlebars.registerHelper('replaceAll', function (target, old, newV) { + if (hasUndefinedOrNull([target, old, newV])) { + return target; + } return target.replace(new RegExp(old, 'g'), newV); }); -Handlebars.registerHelper('match', function(pattern, target) { +Handlebars.registerHelper('match', function (pattern, target) { + if (hasUndefinedOrNull([pattern, target])) { + return false; + } return new RegExp(pattern).test(target); }); -Handlebars.registerHelper('ne', function(left, right) { +Handlebars.registerHelper('eq', function (left, right) { + return left === right; +}); + +Handlebars.registerHelper('ne', function (left, right) { return left !== right; }); -Handlebars.registerHelper('snakeCase', function(s) { +Handlebars.registerHelper('snakeCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase(); }); -Handlebars.registerHelper('camelCase', function(s) { - return s.replace(/([-_][a-z])/ig, function($1) { +Handlebars.registerHelper('camelCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } + return s.replace(/([-_][a-z])/ig, function ($1) { return $1.toUpperCase() .replace('-', '') .replace('_', ''); }); }); -Handlebars.registerHelper('pascalCase', function(s) { - return s.replace(/(\w)(\w*)/g, function($0, $1, $2) { +Handlebars.registerHelper('pascalCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } + return s.replace(/(\w)(\w*)/g, function ($0, $1, $2) { return $1.toUpperCase() + $2.toLowerCase(); }); }); -Handlebars.registerHelper('upperFirst', function(s) { +Handlebars.registerHelper('upperFirst', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.charAt(0).toUpperCase() + s.slice(1); }); -Handlebars.registerHelper('lowerFirst', function(s) { +Handlebars.registerHelper('lowerFirst', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.charAt(0).toLowerCase() + s.slice(1); }); -Handlebars.registerHelper('uppercase', function(s) { +Handlebars.registerHelper('uppercase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.toUpperCase(); }); -Handlebars.registerHelper('lowercase', function(s) { +Handlebars.registerHelper('lowercase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.toLowerCase(); }); -Handlebars.registerHelper('trim', function(s) { +Handlebars.registerHelper('trim', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.trim(); }); -Handlebars.registerHelper('removePrefix', function(s, prefix) { +Handlebars.registerHelper('removePrefix', function (s, prefix) { + if (hasUndefinedOrNull([s, prefix])) { + return s; + } return s.startsWith(prefix) ? s.slice(prefix.length) : s; }); -Handlebars.registerHelper('removeSuffix', function(s, suffix) { +Handlebars.registerHelper('removeSuffix', function (s, suffix) { + if (hasUndefinedOrNull([s, suffix])) { + return s; + } return s.endsWith(suffix) ? s.slice(0, -suffix.length) : s; }); ` diff --git a/pkg/jsruntime/helper.js b/pkg/jsruntime/helper.js index ff8bff4..ad8590a 100644 --- a/pkg/jsruntime/helper.js +++ b/pkg/jsruntime/helper.js @@ -1,59 +1,110 @@ -// Add custom Handlebars helpers here -Handlebars.registerHelper('replaceAll', function(target, old, newV) { +function isUndefinedOrNull(value) { + return value === undefined || value === null; +} + +function hasUndefinedOrNull(value) { + return Array.isArray(value) + ? value.some(e => isUndefinedOrNull(e)) + : isUndefinedOrNull(value); +} + +// Add custom Handlebars helpers below + +Handlebars.registerHelper('replaceAll', function (target, old, newV) { + if (hasUndefinedOrNull([target, old, newV])) { + return target; + } return target.replace(new RegExp(old, 'g'), newV); }); -Handlebars.registerHelper('match', function(pattern, target) { +Handlebars.registerHelper('match', function (pattern, target) { + if (hasUndefinedOrNull([pattern, target])) { + return false; + } return new RegExp(pattern).test(target); }); -Handlebars.registerHelper('ne', function(left, right) { +Handlebars.registerHelper('eq', function (left, right) { + return left === right; +}); + +Handlebars.registerHelper('ne', function (left, right) { return left !== right; }); -Handlebars.registerHelper('snakeCase', function(s) { +Handlebars.registerHelper('snakeCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase(); }); -Handlebars.registerHelper('camelCase', function(s) { - return s.replace(/([-_][a-z])/ig, function($1) { +Handlebars.registerHelper('camelCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } + return s.replace(/([-_][a-z])/ig, function ($1) { return $1.toUpperCase() .replace('-', '') .replace('_', ''); }); }); -Handlebars.registerHelper('pascalCase', function(s) { - return s.replace(/(\w)(\w*)/g, function($0, $1, $2) { +Handlebars.registerHelper('pascalCase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } + return s.replace(/(\w)(\w*)/g, function ($0, $1, $2) { return $1.toUpperCase() + $2.toLowerCase(); }); }); -Handlebars.registerHelper('upperFirst', function(s) { +Handlebars.registerHelper('upperFirst', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.charAt(0).toUpperCase() + s.slice(1); }); -Handlebars.registerHelper('lowerFirst', function(s) { +Handlebars.registerHelper('lowerFirst', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.charAt(0).toLowerCase() + s.slice(1); }); -Handlebars.registerHelper('uppercase', function(s) { +Handlebars.registerHelper('uppercase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.toUpperCase(); }); -Handlebars.registerHelper('lowercase', function(s) { +Handlebars.registerHelper('lowercase', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.toLowerCase(); }); -Handlebars.registerHelper('trim', function(s) { +Handlebars.registerHelper('trim', function (s) { + if (hasUndefinedOrNull(s)) { + return s; + } return s.trim(); }); -Handlebars.registerHelper('removePrefix', function(s, prefix) { +Handlebars.registerHelper('removePrefix', function (s, prefix) { + if (hasUndefinedOrNull([s, prefix])) { + return s; + } return s.startsWith(prefix) ? s.slice(prefix.length) : s; }); -Handlebars.registerHelper('removeSuffix', function(s, suffix) { +Handlebars.registerHelper('removeSuffix', function (s, suffix) { + if (hasUndefinedOrNull([s, suffix])) { + return s; + } return s.endsWith(suffix) ? s.slice(0, -suffix.length) : s; }); From 723477dc6ab1a325a140ab8de41278d5a3c5cbe8 Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Thu, 19 Sep 2024 13:48:20 +0800 Subject: [PATCH 6/7] update mds example --- e2e/mds/gencoder.yaml | 12 ++++++------ e2e/mds/templates/dynamic_support.java.hbs | 4 +++- e2e/mds/templates/entity.java.hbs | 4 ++-- e2e/mds/templates/mapper.java.hbs | 11 ++++++----- e2e/mds/templates/partials/id_name.partial.hbs | 5 +++++ e2e/mds/templates/partials/id_type.partial.hbs | 5 +++++ .../templates/{ => partials}/java_type.partial.hbs | 0 .../templates/{ => partials}/jdbc_type.partial.hbs | 0 8 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 e2e/mds/templates/partials/id_name.partial.hbs create mode 100644 e2e/mds/templates/partials/id_type.partial.hbs rename e2e/mds/templates/{ => partials}/java_type.partial.hbs (100%) rename e2e/mds/templates/{ => partials}/jdbc_type.partial.hbs (100%) diff --git a/e2e/mds/gencoder.yaml b/e2e/mds/gencoder.yaml index d9d4a8b..4e6165d 100644 --- a/e2e/mds/gencoder.yaml +++ b/e2e/mds/gencoder.yaml @@ -7,21 +7,21 @@ databases: dsn: 'mysql://root:root@localhost:3306/testdb' schema: testdb properties: - package: defaultpackage + entityPkg: com.example.entity + mapperPkg: com.example.mapper + dynamicSQLPkg: com.example.mapper tables: - name: 'user' - properties: - package: mysqlpackage ignoreColumns: - deleted_at - name: postgres dsn: 'postgres://root:root@localhost:5432/testdb?sslmode=disable' schema: public properties: - package: defaultpackage + entityPkg: com.example.pg.entity + mapperPkg: com.example.pg.mapper + dynamicSQLPkg: com.example.pg.mapper tables: - name: 'user' - properties: - package: postgrespackage ignoreColumns: - deleted_at diff --git a/e2e/mds/templates/dynamic_support.java.hbs b/e2e/mds/templates/dynamic_support.java.hbs index 6f011c5..8790f48 100644 --- a/e2e/mds/templates/dynamic_support.java.hbs +++ b/e2e/mds/templates/dynamic_support.java.hbs @@ -1,7 +1,9 @@ /** - * @gencoder.generated: src/main/java/{{replaceAll properties.package '\.' '/'}}/{{pascalCase table.name}}DynamicSqlSupport.java + * @gencoder.generated: src/main/java/{{replaceAll properties.dynamicSQLPkg '\.' '/'}}/{{pascalCase table.name}}DynamicSqlSupport.java */ +package {{properties.dynamicSQLPkg}}; + import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.AliasableSqlTable; diff --git a/e2e/mds/templates/entity.java.hbs b/e2e/mds/templates/entity.java.hbs index 8283bfc..ed33246 100644 --- a/e2e/mds/templates/entity.java.hbs +++ b/e2e/mds/templates/entity.java.hbs @@ -1,8 +1,8 @@ /** - * @gencoder.generated: src/main/java/{{replaceAll properties.package '\.' '/'}}/{{pascalCase table.name}}.java + * @gencoder.generated: src/main/java/{{replaceAll properties.entityPkg '\.' '/'}}/{{pascalCase table.name}}.java */ -package {{properties.package}}; +package {{properties.entityPkg}}; /** * @gencoder.block.start: table diff --git a/e2e/mds/templates/mapper.java.hbs b/e2e/mds/templates/mapper.java.hbs index 1070f9f..1919011 100644 --- a/e2e/mds/templates/mapper.java.hbs +++ b/e2e/mds/templates/mapper.java.hbs @@ -1,9 +1,10 @@ /** * @gencoder.generated: src/main/java/{{replaceAll properties.mapperPkg '\.' '/'}}/{{pascalCase table.name}}Mapper.java */ + package {{properties.mapperPkg}}; -import static {{properties.mapperPkg}}.{{pascalCase table.name}}DynamicSqlSupport.*; +import static {{properties.dynamicSQLPkg}}.{{pascalCase table.name}}DynamicSqlSupport.*; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; import {{properties.entityPkg}}.{{pascalCase table.name}}; @@ -41,7 +42,7 @@ public class {{pascalCase table.name}}Mapper extends CommonCountMapper, CommonDe BasicColumn[] selectList = BasicColumn.columnList({{#each table.columns}}{{camelCase name}}{{#unless @last}}, {{/unless}}{{/each}}); @InsertProvider(type=SqlProviderAdapter.class, method="insert") - @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="row.id", before=false, resultType=Integer.class) + @SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="row.id", before=false, resultType={{> 'id_type.partial.hbs' columns=table.columns}}.class) int insert(InsertStatementProvider<{{pascalCase table.name}}> insertStatement); @SelectProvider(type=SqlProviderAdapter.class, method="select") @@ -144,11 +145,11 @@ public class {{pascalCase table.name}}Mapper extends CommonCountMapper, CommonDe default int updateByPrimaryKeySelective({{pascalCase table.name}} row) { return update(c -> c {{#each table.columns}} - {{#if (ne name 'id')}} + {{#unless isPrimaryKey}} .set({{camelCase name}}).equalToWhenPresent(row::get{{upperFirst (camelCase name)}}) - {{/if}} + {{/unless}} {{/each}} - .where(id, isEqualTo(row::getId)) + .where({{> 'id_name.partial.hbs' columns=table.columns}}, isEqualTo(row::getId)) ); } diff --git a/e2e/mds/templates/partials/id_name.partial.hbs b/e2e/mds/templates/partials/id_name.partial.hbs new file mode 100644 index 0000000..d7af9e5 --- /dev/null +++ b/e2e/mds/templates/partials/id_name.partial.hbs @@ -0,0 +1,5 @@ +{{#each table.columns}} +{{~#if isPrimaryKey}} +{{name}} +{{~/if}} +{{/each}} \ No newline at end of file diff --git a/e2e/mds/templates/partials/id_type.partial.hbs b/e2e/mds/templates/partials/id_type.partial.hbs new file mode 100644 index 0000000..3909a51 --- /dev/null +++ b/e2e/mds/templates/partials/id_type.partial.hbs @@ -0,0 +1,5 @@ +{{#each columns}} +{{~#if isPrimaryKey}} +{{> 'java_type.partial.hbs' columnType=type}} +{{~/if}} +{{/each}} \ No newline at end of file diff --git a/e2e/mds/templates/java_type.partial.hbs b/e2e/mds/templates/partials/java_type.partial.hbs similarity index 100% rename from e2e/mds/templates/java_type.partial.hbs rename to e2e/mds/templates/partials/java_type.partial.hbs diff --git a/e2e/mds/templates/jdbc_type.partial.hbs b/e2e/mds/templates/partials/jdbc_type.partial.hbs similarity index 100% rename from e2e/mds/templates/jdbc_type.partial.hbs rename to e2e/mds/templates/partials/jdbc_type.partial.hbs From af3591f8573f5e349d43f08a48e84658565dfdbd Mon Sep 17 00:00:00 2001 From: Freeman Liu Date: Thu, 19 Sep 2024 22:09:26 +0800 Subject: [PATCH 7/7] update mod --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3df25b4..668ee58 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/DanielLiu1123/gencoder go 1.23.1 require ( - github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 + github.com/dop251/goja v0.0.0-20240919115326-6c7d1df7ff05 github.com/go-sql-driver/mysql v1.8.1 github.com/lib/pq v1.10.9 github.com/mattn/go-sqlite3 v1.14.23 diff --git a/go.sum b/go.sum index 6169e66..7482d59 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 h1:YIxvsQAoCLGScK2c9ag+4sFCgiQFpMzywJG6dQZFu9k= github.com/dop251/goja v0.0.0-20240828124009-016eb7256539/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4= +github.com/dop251/goja v0.0.0-20240919115326-6c7d1df7ff05 h1:oK4+QcKsczZjHYTHD0JAdkvq5w74JEkG95J0XNBx/BI= +github.com/dop251/goja v0.0.0-20240919115326-6c7d1df7ff05/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4= github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q= github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=