Skip to content

feat(cmd/gf): support generating pointer type field in DO files for command gf gen dao#4653

Open
smzgl wants to merge 4 commits into
gogf:masterfrom
smzgl:feat(gfcmd)-gf-gen-do-support-generate-pointer-type-field-for-do-object-
Open

feat(cmd/gf): support generating pointer type field in DO files for command gf gen dao#4653
smzgl wants to merge 4 commits into
gogf:masterfrom
smzgl:feat(gfcmd)-gf-gen-do-support-generate-pointer-type-field-for-do-object-

Conversation

@smzgl

@smzgl smzgl commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

feat: gf gen dao 增加一个参数 doUseTypePtr , 使得生成do结构体的时候, 字段类型都是指针, 而不是interface{} #4582

@lingcoder

lingcoder commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

这个能加点场景测试么?有点怕怕,会不会在orm使用环节出现问题。。。

@smzgl

smzgl commented Jan 23, 2026

Copy link
Copy Markdown
Contributor Author

生成代码是从生成entity复制过来,增加了* 感觉不用怕:)

@smzgl

smzgl commented Jan 23, 2026

Copy link
Copy Markdown
Contributor Author

可以参考现有的场景补充一下。

@smzgl

smzgl commented Jan 25, 2026

Copy link
Copy Markdown
Contributor Author

测试用例已添加

NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
GenTable bool `name:"genTable" short:"gt" brief:"{CGenDaoBriefGenTable}" orphan:"true"`
TypePointerSupport bool `name:"typePointerSupport" short:"tp" brief:"{CGenDoBriefTypePointerSupport}" orphan:"true"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. TypePointerSupport -> PtrTypeInDoField
  2. 默认使用any,当用户显式配置该选项才启用该特性。

@gqcn gqcn changed the title feat: gf gen do support generate pointer type field feat(cmd/gf): support generating pointer type field in do file for command gf gen dao Feb 11, 2026
@gqcn gqcn changed the title feat(cmd/gf): support generating pointer type field in do file for command gf gen dao feat(cmd/gf): support generating pointer type field in DO files for command gf gen dao Feb 11, 2026
@gqcn gqcn requested a review from Copilot February 11, 2026 07:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new gf gen dao option to generate DO structs with pointer-typed fields (instead of any/interface{}), improving type validation when using DO models.

Changes:

  • Introduces typePointerSupport option to generate DO fields as pointers when possible.
  • Updates DO generation logic to emit *T (unless already pointer/slice/map) instead of any.
  • Adds/updates unit tests and golden testdata fixtures for pointer-typed DO output.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
cmd/gf/internal/cmd/gendao/gendao.go Adds a new CLI flag field (TypePointerSupport) to the gf gen dao input struct.
cmd/gf/internal/cmd/gendao/gendao_tag.go Adds the flag’s brief/help text constant and registers it for templated CLI help.
cmd/gf/internal/cmd/gendao/gendao_do.go Updates DO struct post-processing to optionally convert field types to pointers.
cmd/gf/internal/cmd/cmd_z_unit_gen_dao_test.go Adds new tests for pointer-typed DO generation across default/typeMapping/fieldMapping scenarios.
cmd/gf/internal/cmd/testdata/gendao/**/do_type_pointer/table_user.go New golden fixtures for pointer-typed DO output.
cmd/gf/internal/cmd/testdata/gendao/**/do_pointer_type/table_user.go Additional golden fixtures (currently appear unused).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +21
// =================================================================================
// 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 *int //
Passport *string //
Password *string //
Nickname *string //
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
}

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sqlite3 golden file is under model/do_pointer_type, but the sqlite3 test asserts against model/do/table_user.go and there are no repo references to do_pointer_type. If this fixture isn’t used by any test, it should be removed to avoid confusion.

Suggested change
// =================================================================================
// 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 *int //
Passport *string //
Password *string //
Nickname *string //
CreatedAt *gtime.Time //
UpdatedAt *gtime.Time //
}
// This file previously contained a sqlite3 golden fixture for `table_user` under
// `model/do_pointer_type`, but it is no longer used by any tests. It is
// intentionally left blank to avoid confusion with the active fixtures under
// `model/do/`.
package do

Copilot uses AI. Check for mistakes.
Comment on lines +55 to 59
if in.TypePointerSupport {
return fmt.Sprintf(`%s *%s %s`, match[1], match[2], match[3])
}

return fmt.Sprintf(`%s any %s`, match[1], match[3])

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With TypePointerSupport enabled this replacement path changes field types to pointers; the nearby comment above this block says "replace all types to any" which is no longer accurate. Please update that comment to reflect the conditional behavior (any vs pointer) to avoid misleading future maintenance.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +70
StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
GenTable bool `name:"genTable" short:"gt" brief:"{CGenDaoBriefGenTable}" orphan:"true"`
TypePointerSupport bool `name:"typePointerSupport" short:"tp" brief:"{CGenDoBriefTypePointerSupport}" orphan:"true"`
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new flag typePointerSupport reuses short option tp, which is already used by tablePath. Short option collisions can make the CLI parsing ambiguous or fail. Please choose a unique short name (or remove the short alias) for typePointerSupport while keeping tablePath’s existing tp for backward compatibility.

Suggested change
StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
GenTable bool `name:"genTable" short:"gt" brief:"{CGenDaoBriefGenTable}" orphan:"true"`
TypePointerSupport bool `name:"typePointerSupport" short:"tp" brief:"{CGenDoBriefTypePointerSupport}" orphan:"true"`
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`
StdTime bool `name:"stdTime" short:"s" brief:"{CGenDaoBriefStdTime}" orphan:"true"`
WithTime bool `name:"withTime" short:"w" brief:"{CGenDaoBriefWithTime}" orphan:"true"`
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{CGenDaoBriefGJsonSupport}" orphan:"true"`
OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{CGenDaoBriefOverwriteDao}" orphan:"true"`
DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{CGenDaoBriefDescriptionTag}" orphan:"true"`
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{CGenDaoBriefNoJsonTag}" orphan:"true"`
NoModelComment bool `name:"noModelComment" short:"m" brief:"{CGenDaoBriefNoModelComment}" orphan:"true"`
Clear bool `name:"clear" short:"a" brief:"{CGenDaoBriefClear}" orphan:"true"`
GenTable bool `name:"genTable" short:"gt" brief:"{CGenDaoBriefGenTable}" orphan:"true"`
TypePointerSupport bool `name:"typePointerSupport" short:"tps" brief:"{CGenDoBriefTypePointerSupport}" orphan:"true"`
TypeMapping map[DBFieldTypeName]CustomAttributeType `name:"typeMapping" short:"y" brief:"{CGenDaoBriefTypeMapping}" orphan:"true"`
FieldMapping map[DBTableFieldName]CustomAttributeType `name:"fieldMapping" short:"fm" brief:"{CGenDaoBriefFieldMapping}" orphan:"true"`

Copilot uses AI. Check for mistakes.
filepath.FromSlash(testPath + "/model/entity/table_user.go"),
}
for i := range files {
_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test currently overwrites the golden testdata files via gfile.PutContents(...), which will mutate the repository fixture on local runs/CI and can hide regressions. This line should be removed or kept commented out like the other tests.

Suggested change
_ = gfile.PutContents(expectFiles[i], gfile.GetContents(files[i]))
// Do not overwrite golden files here; just compare contents.

Copilot uses AI. Check for mistakes.
Comment on lines +523 to +529
defer dropTableWithDb(db, table)
array := gstr.SplitAndTrim(sqlContent, ";")
for _, v := range array {
if _, err = db.Exec(ctx, v); err != nil {
t.AssertNil(err)
}
}

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test sets up the table without dropping it first, and also defers dropTableWithDb twice. If the table already exists (e.g., when running this test in isolation), the CREATE will fail before the deferred drop runs. Consider calling dropTableWithDb(db, table) before executing the SQL and keep only a single defer dropTableWithDb(db, table) after successful setup.

Suggested change
defer dropTableWithDb(db, table)
array := gstr.SplitAndTrim(sqlContent, ";")
for _, v := range array {
if _, err = db.Exec(ctx, v); err != nil {
t.AssertNil(err)
}
}
// Ensure the table does not already exist before setup.
dropTableWithDb(db, table)
array := gstr.SplitAndTrim(sqlContent, ";")
for _, v := range array {
if _, err = db.Exec(ctx, v); err != nil {
t.AssertNil(err)
}
}
// Drop the table after the test finishes.

Copilot uses AI. Check for mistakes.
Comment on lines +627 to +635
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)

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same table setup pattern issue as above: there’s no upfront dropTableWithDb before running the CREATE statements, and dropTableWithDb is deferred twice. This can make the test flaky when the table already exists. Prefer dropping before setup and using a single deferred cleanup.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +23
// =================================================================================
// 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"
"github.com/shopspring/decimal"
)

// 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 *int64 // User ID
Passport *string // User Passport
Password *string // User Password
Nickname *string // User Nickname
Score *decimal.Decimal // Total score amount.
CreateAt *gtime.Time // Created Time
UpdateAt *gtime.Time // Updated Time
}

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This golden file appears to be unused: there are no references to the do_pointer_type fixture directory anywhere in the repo, and the tests use do_type_pointer instead. Consider removing this duplicate fixture (or renaming/aligning fixtures to a single convention) to reduce testdata clutter.

Suggested change
// =================================================================================
// 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"
"github.com/shopspring/decimal"
)
// 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 *int64 // User ID
Passport *string // User Passport
Password *string // User Password
Nickname *string // User Nickname
Score *decimal.Decimal // Total score amount.
CreateAt *gtime.Time // Created Time
UpdateAt *gtime.Time // Updated Time
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants