mirror of
https://gitee.com/johng/gf
synced 2026-07-03 03:39:35 +08:00
feat: add custom field type mapping support for command gf gen dao (#3498)
This commit is contained in:
@ -71,6 +71,7 @@ func Test_Gen_Dao_Default(t *testing.T) {
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
TypeMapping: nil,
|
||||
FieldMapping: nil,
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
@ -171,6 +172,7 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) {
|
||||
Import: "github.com/shopspring/decimal",
|
||||
},
|
||||
},
|
||||
FieldMapping: nil,
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
@ -213,6 +215,108 @@ func Test_Gen_Dao_TypeMapping(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Gen_Dao_FieldMapping(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
err error
|
||||
db = testDB
|
||||
table = "table_user"
|
||||
sqlContent = fmt.Sprintf(
|
||||
gtest.DataContent(`gendao`, `user.tpl.sql`),
|
||||
table,
|
||||
)
|
||||
)
|
||||
defer dropTableWithDb(db, table)
|
||||
array := gstr.SplitAndTrim(sqlContent, ";")
|
||||
for _, v := range array {
|
||||
if _, err = db.Exec(ctx, v); err != nil {
|
||||
t.AssertNil(err)
|
||||
}
|
||||
}
|
||||
defer dropTableWithDb(db, table)
|
||||
|
||||
var (
|
||||
path = gfile.Temp(guid.S())
|
||||
group = "test"
|
||||
in = gendao.CGenDaoInput{
|
||||
Path: path,
|
||||
Link: link,
|
||||
Tables: "table_user",
|
||||
TablesEx: "",
|
||||
Group: group,
|
||||
Prefix: "",
|
||||
RemovePrefix: "",
|
||||
JsonCase: "",
|
||||
ImportPrefix: "",
|
||||
DaoPath: "",
|
||||
DoPath: "",
|
||||
EntityPath: "",
|
||||
TplDaoIndexPath: "",
|
||||
TplDaoInternalPath: "",
|
||||
TplDaoDoPath: "",
|
||||
TplDaoEntityPath: "",
|
||||
StdTime: false,
|
||||
WithTime: false,
|
||||
GJsonSupport: false,
|
||||
OverwriteDao: false,
|
||||
DescriptionTag: false,
|
||||
NoJsonTag: false,
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
TypeMapping: map[gendao.DBFieldTypeName]gendao.CustomAttributeType{
|
||||
"int": {
|
||||
Type: "int64",
|
||||
Import: "",
|
||||
},
|
||||
},
|
||||
FieldMapping: map[gendao.DBTableFieldName]gendao.CustomAttributeType{
|
||||
"table_user.score": {
|
||||
Type: "decimal.Decimal",
|
||||
Import: "github.com/shopspring/decimal",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
t.AssertNil(err)
|
||||
|
||||
err = gfile.Mkdir(path)
|
||||
t.AssertNil(err)
|
||||
|
||||
// for go mod import path auto retrieve.
|
||||
err = gfile.Copy(
|
||||
gtest.DataPath("gendao", "go.mod.txt"),
|
||||
gfile.Join(path, "go.mod"),
|
||||
)
|
||||
t.AssertNil(err)
|
||||
|
||||
_, err = gendao.CGenDao{}.Dao(ctx, in)
|
||||
t.AssertNil(err)
|
||||
defer gfile.Remove(path)
|
||||
|
||||
// files
|
||||
files, err := gfile.ScanDir(path, "*.go", true)
|
||||
t.AssertNil(err)
|
||||
t.Assert(files, []string{
|
||||
filepath.FromSlash(path + "/dao/internal/table_user.go"),
|
||||
filepath.FromSlash(path + "/dao/table_user.go"),
|
||||
filepath.FromSlash(path + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(path + "/model/entity/table_user.go"),
|
||||
})
|
||||
// content
|
||||
testPath := gtest.DataPath("gendao", "generated_user_field_mapping")
|
||||
expectFiles := []string{
|
||||
filepath.FromSlash(testPath + "/dao/internal/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/dao/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/do/table_user.go"),
|
||||
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
|
||||
}
|
||||
for i, _ := range files {
|
||||
t.Assert(gfile.GetContents(files[i]), gfile.GetContents(expectFiles[i]))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func execSqlFile(db gdb.DB, filePath string, args ...any) error {
|
||||
sqlContent := fmt.Sprintf(
|
||||
gfile.GetContents(filePath),
|
||||
@ -271,6 +375,7 @@ func Test_Gen_Dao_Issue2572(t *testing.T) {
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
TypeMapping: nil,
|
||||
FieldMapping: nil,
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
@ -359,6 +464,7 @@ func Test_Gen_Dao_Issue2616(t *testing.T) {
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
TypeMapping: nil,
|
||||
FieldMapping: nil,
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
@ -469,6 +575,7 @@ func Test_Gen_Dao_Issue2746(t *testing.T) {
|
||||
NoModelComment: false,
|
||||
Clear: false,
|
||||
TypeMapping: nil,
|
||||
FieldMapping: nil,
|
||||
}
|
||||
)
|
||||
err = gutil.FillStructWithDefault(&in)
|
||||
|
||||
@ -58,6 +58,10 @@ CONFIGURATION SUPPORT
|
||||
import: github.com/shopspring/decimal
|
||||
numeric:
|
||||
type: string
|
||||
fieldMapping:
|
||||
table_name.field_name:
|
||||
type: decimal.Decimal
|
||||
import: github.com/shopspring/decimal
|
||||
`
|
||||
CGenDaoBriefPath = `directory path for generated files`
|
||||
CGenDaoBriefLink = `database configuration, the same as the ORM configuration of GoFrame`
|
||||
@ -81,6 +85,7 @@ CONFIGURATION SUPPORT
|
||||
CGenDaoBriefNoModelComment = `no model comment will be added for each field`
|
||||
CGenDaoBriefClear = `delete all generated go files that do not exist in database`
|
||||
CGenDaoBriefTypeMapping = `custom local type mapping for generated struct attributes relevant to fields of table`
|
||||
CGenDaoBriefFieldMapping = `custom local type mapping for generated struct attributes relevant to specific fields of table`
|
||||
CGenDaoBriefGroup = `
|
||||
specifying the configuration group name of database for generated ORM instance,
|
||||
it's not necessary and the default value is "default"
|
||||
@ -162,6 +167,7 @@ func init() {
|
||||
`CGenDaoBriefNoModelComment`: CGenDaoBriefNoModelComment,
|
||||
`CGenDaoBriefClear`: CGenDaoBriefClear,
|
||||
`CGenDaoBriefTypeMapping`: CGenDaoBriefTypeMapping,
|
||||
`CGenDaoBriefFieldMapping`: CGenDaoBriefFieldMapping,
|
||||
`CGenDaoBriefGroup`: CGenDaoBriefGroup,
|
||||
`CGenDaoBriefJsonCase`: CGenDaoBriefJsonCase,
|
||||
`CGenDaoBriefTplDaoIndexPath`: CGenDaoBriefTplDaoIndexPath,
|
||||
@ -201,8 +207,9 @@ type (
|
||||
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
|
||||
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
|
||||
|
||||
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
|
||||
genItems *CGenDaoInternalGenItems
|
||||
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
|
||||
FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`
|
||||
genItems *CGenDaoInternalGenItems
|
||||
}
|
||||
CGenDaoOutput struct{}
|
||||
|
||||
@ -212,7 +219,7 @@ type (
|
||||
TableNames []string
|
||||
NewTableNames []string
|
||||
}
|
||||
|
||||
DBTableFieldName = string
|
||||
DBFieldTypeName = string
|
||||
CustomAttributeType struct {
|
||||
Type string `brief:"custom attribute type name"`
|
||||
@ -363,7 +370,7 @@ func getImportPartContent(ctx context.Context, source string, isDo bool, appendI
|
||||
}
|
||||
|
||||
// Check and update imports in go.mod
|
||||
if appendImports != nil && len(appendImports) > 0 {
|
||||
if len(appendImports) > 0 {
|
||||
goModPath := utils.GetModPath()
|
||||
if goModPath == "" {
|
||||
mlog.Fatal("go.mod not found in current project")
|
||||
@ -381,8 +388,9 @@ func getImportPartContent(ctx context.Context, source string, isDo bool, appendI
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
err = gproc.ShellRun(ctx, `go get `+appendImport)
|
||||
mlog.Fatalf(`%+v`, err)
|
||||
if err = gproc.ShellRun(ctx, `go get `+appendImport); err != nil {
|
||||
mlog.Fatalf(`%+v`, err)
|
||||
}
|
||||
}
|
||||
packageImportsArray.Append(fmt.Sprintf(`"%s"`, appendImport))
|
||||
}
|
||||
|
||||
@ -131,6 +131,14 @@ func generateStructFieldDefinition(
|
||||
for _, v := range removeFieldPrefixArray {
|
||||
newFiledName = gstr.TrimLeftStr(newFiledName, v, 1)
|
||||
}
|
||||
|
||||
if in.FieldMapping != nil && len(in.FieldMapping) > 0 {
|
||||
if typeMapping, ok := in.FieldMapping[fmt.Sprintf("%s.%s", in.Tables, newFiledName)]; ok {
|
||||
localTypeNameStr = typeMapping.Type
|
||||
appendImport = typeMapping.Import
|
||||
}
|
||||
}
|
||||
|
||||
attrLines = []string{
|
||||
" #" + gstr.CaseCamel(newFiledName),
|
||||
" #" + localTypeNameStr,
|
||||
|
||||
85
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/dao/internal/table_user.go
vendored
Normal file
85
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/dao/internal/table_user.go
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
// ==========================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
)
|
||||
|
||||
// TableUserDao is the data access object for table table_user.
|
||||
type TableUserDao struct {
|
||||
table string // table is the underlying table name of the DAO.
|
||||
group string // group is the database configuration group name of current DAO.
|
||||
columns TableUserColumns // columns contains all the column names of Table for convenient usage.
|
||||
}
|
||||
|
||||
// TableUserColumns defines and stores column names for table table_user.
|
||||
type TableUserColumns struct {
|
||||
Id string // User ID
|
||||
Passport string // User Passport
|
||||
Password string // User Password
|
||||
Nickname string // User Nickname
|
||||
Score string // Total score amount.
|
||||
CreateAt string // Created Time
|
||||
UpdateAt string // Updated Time
|
||||
}
|
||||
|
||||
// tableUserColumns holds the columns for table table_user.
|
||||
var tableUserColumns = TableUserColumns{
|
||||
Id: "id",
|
||||
Passport: "passport",
|
||||
Password: "password",
|
||||
Nickname: "nickname",
|
||||
Score: "score",
|
||||
CreateAt: "create_at",
|
||||
UpdateAt: "update_at",
|
||||
}
|
||||
|
||||
// NewTableUserDao creates and returns a new DAO object for table data access.
|
||||
func NewTableUserDao() *TableUserDao {
|
||||
return &TableUserDao{
|
||||
group: "test",
|
||||
table: "table_user",
|
||||
columns: tableUserColumns,
|
||||
}
|
||||
}
|
||||
|
||||
// DB retrieves and returns the underlying raw database management object of current DAO.
|
||||
func (dao *TableUserDao) DB() gdb.DB {
|
||||
return g.DB(dao.group)
|
||||
}
|
||||
|
||||
// Table returns the table name of current dao.
|
||||
func (dao *TableUserDao) Table() string {
|
||||
return dao.table
|
||||
}
|
||||
|
||||
// Columns returns all column names of current dao.
|
||||
func (dao *TableUserDao) Columns() TableUserColumns {
|
||||
return dao.columns
|
||||
}
|
||||
|
||||
// Group returns the configuration group name of database of current dao.
|
||||
func (dao *TableUserDao) Group() string {
|
||||
return dao.group
|
||||
}
|
||||
|
||||
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
|
||||
func (dao *TableUserDao) Ctx(ctx context.Context) *gdb.Model {
|
||||
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
|
||||
}
|
||||
|
||||
// Transaction wraps the transaction logic using function f.
|
||||
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
|
||||
// It commits the transaction and returns nil if function f returns nil.
|
||||
//
|
||||
// Note that, you should not Commit or Rollback the transaction in function f
|
||||
// as it is automatically handled by this function.
|
||||
func (dao *TableUserDao) Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) (err error) {
|
||||
return dao.Ctx(ctx).Transaction(ctx, f)
|
||||
}
|
||||
27
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/dao/table_user.go
vendored
Normal file
27
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/dao/table_user.go
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// =================================================================================
|
||||
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
|
||||
// =================================================================================
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"for-gendao-test/pkg/dao/internal"
|
||||
)
|
||||
|
||||
// internalTableUserDao is internal type for wrapping internal DAO implements.
|
||||
type internalTableUserDao = *internal.TableUserDao
|
||||
|
||||
// tableUserDao is the data access object for table table_user.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type tableUserDao struct {
|
||||
internalTableUserDao
|
||||
}
|
||||
|
||||
var (
|
||||
// TableUser is globally public accessible object for table table_user operations.
|
||||
TableUser = tableUserDao{
|
||||
internal.NewTableUserDao(),
|
||||
}
|
||||
)
|
||||
|
||||
// Fill with you ideas below.
|
||||
22
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/model/do/table_user.go
vendored
Normal file
22
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/model/do/table_user.go
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package do
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
// TableUser is the golang structure of table table_user for DAO operations like Where/Data.
|
||||
type TableUser struct {
|
||||
g.Meta `orm:"table:table_user, do:true"`
|
||||
Id interface{} // User ID
|
||||
Passport interface{} // User Passport
|
||||
Password interface{} // User Password
|
||||
Nickname interface{} // User Nickname
|
||||
Score interface{} // Total score amount.
|
||||
CreateAt *gtime.Time // Created Time
|
||||
UpdateAt *gtime.Time // Updated Time
|
||||
}
|
||||
21
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/model/entity/table_user.go
vendored
Normal file
21
cmd/gf/internal/cmd/testdata/gendao/generated_user_field_mapping/model/entity/table_user.go
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// =================================================================================
|
||||
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
|
||||
// =================================================================================
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// TableUser is the golang structure for table table_user.
|
||||
type TableUser struct {
|
||||
Id int64 `json:"id" orm:"id" ` // User ID
|
||||
Passport string `json:"passport" orm:"passport" ` // User Passport
|
||||
Password string `json:"password" orm:"password" ` // User Password
|
||||
Nickname string `json:"nickname" orm:"nickname" ` // User Nickname
|
||||
Score decimal.Decimal `json:"score" orm:"score" ` // Total score amount.
|
||||
CreateAt *gtime.Time `json:"createAt" orm:"create_at" ` // Created Time
|
||||
UpdateAt *gtime.Time `json:"updateAt" orm:"update_at" ` // Updated Time
|
||||
}
|
||||
Reference in New Issue
Block a user