gen
gen copied to clipboard
unknow param type: &{Func:4040 TypeParams:<nil> Params:0x14000466a50 Results:<nil>}
Your Question
package users
import (
"go.uber.org/zap"
"my-wifi/pkg/logs"
"gorm.io/gen"
"gorm.io/gorm"
)
// Dynamic SQL
type Querier interface {
// SELECT * FROM @@table WHERE uuid = @uuid{{if phone !=""}} AND phone = @phone{{end}}
//FilterWithUUIDAndPhone(uuid, phone string) ([]gen.T, error)
// SELECT * FROM @@table WHERE uuid = @uuid{{if username !=""}} AND username = @username{{end}}
//FilterWithUUIDAndName(uuid, username string) ([]gen.T, error)
}
type User struct {
Name string
}
func GenUser(db *gorm.DB) error {
//if err := db.AutoMigrate(models.Users{}); err != nil {
// logs.Z.Error("gen", zap.Error(err))
// return err
//}
logs.Z.Info("gen", zap.Any("user", "AutoMigrate"))
g := gen.NewGenerator(gen.Config{
OutPath: "../../internal/dao/users",
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
})
g.UseDB(db) // reuse your gorm db
logs.Z.Info("gen", zap.Any("user", "UseDB"))
// Generate basic type-safe DAO API for struct `model.User` following conventions
g.ApplyBasic(User{})
logs.Z.Info("gen", zap.Any("user", "ApplyBasic"))
// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`
g.ApplyInterface(func(Querier) {}, User{})
logs.Z.Info("gen", zap.Any("user", "ApplyInterface"))
// Generate the code
g.Execute()
logs.Z.Info("gen", zap.Any("user", "Execute"))
return nil
}
exec res
[my-wifi]2023/06/26 - 00:09:48.124 info /gorm.go:25 db {"init": "success"}
[my-wifi]2023/06/26 - 00:09:48.124 info users.tpl.go:28 gen {"user": "AutoMigrate"}
[my-wifi]2023/06/26 - 00:09:48.124 info users.tpl.go:35 gen {"user": "UseDB"}
[my-wifi]2023/06/26 - 00:09:48.124 info users.tpl.go:38 gen {"user": "ApplyBasic"}
2023/06/26 00:09:48 unknow param type: &{Func:4040 TypeParams:<nil> Params:0x14000466a50 Results:<nil>}
@itcuihao 是用的最新版吗,本地试了下没问题
好的,估计要回家试试,在公司没有这个错误,这个错误与什么有关呢,给点排查的线索,或者如何debug,ApplyInterface报的,不过没看到是啥问题
@itcuihao 是用的最新版吗,本地试了下没问题
@qqxhb 有限制只能执行一次 Gen 方法吗,修改 model,后再执行就会必现此错误。
ApplyInterface
用官网例子,此方法重复执行时会出发此问题
ApplyInterface用官网例子,此方法重复执行时会出发此问题
没有限制。每次都是覆盖更新的
è¿ç»æ§è¡ä¸¤æ¬¡ï¼æ·»å äºæå°ä¿¡æ¯
eddy/cmd/gen via ð¹ took 3s
⯠go run main.go
path 0
path 0
path 1
2023/06/27 14:15:23 Start generating code.
2023/06/27 14:15:23 generate query file: /Users/c/mygo/ch/demo/eddy/internal/dao/merchant/merchant_wifis.gen.go
2023/06/27 14:15:23 generate query file: /Users/c/mygo/ch/demo/eddy/internal/dao/merchant/merchants.gen.go
2023/06/27 14:15:23 generate query file: /Users/c/mygo/ch/demo/eddy/internal/dao/merchant/gen.go
2023/06/27 14:15:23 Generate code done.
eddy/cmd/gen via ð¹ took 2s
⯠go run main.go
path 0
path 0
path 1
&ast.FuncType{Func:2123, TypeParams:(*ast.FieldList)(nil), Params:(*ast.FieldList)(0xc00034d380), Results:(*ast.FieldList)(nil)}
2139
0 &ast.Ident{NamePos:2120, Name:"fc", Obj:(*ast.Object)(0xc00030dea0)}
2023/06/27 14:15:50 unknow param type1: &{Func:2123 TypeParams:<nil> Params:0xc00034d380 Results:<nil>}
exit status 1
// éè¯¯è¡ gen/internal/parse/parse.go
func (p *Param) astGetParamType(param *ast.Field) {
switch v := param.Type.(type) {
case *ast.Ident:
p.Type = v.Name
if v.Obj != nil {
p.Package = "UNDEFINED" // set a placeholder
}
case *ast.SelectorExpr:
p.astGetEltType(v)
case *ast.ArrayType:
p.astGetEltType(v.Elt)
p.IsArray = true
case *ast.Ellipsis:
p.astGetEltType(v.Elt)
p.IsArray = true
case *ast.MapType:
p.astGetMapType(v)
case *ast.InterfaceType:
p.Type = "interface{}"
case *ast.StarExpr:
p.IsPointer = true
p.astGetEltType(v.X)
default:
fmt.Printf("%#v\n", param.Type)
fmt.Printf("%#v\n", param.Type.End())
for i, n := range param.Names {
fmt.Printf("%d %#v\n", i, n)
}
log.Fatalf("unknow param type1: %+v", v)
}
}
æ§è¡ä»£ç
// Dynamic SQL
type Querier interface {
// SELECT * FROM @@table WHERE username = @name{{if role !=""}} AND role = @role{{end}}
//FilterWithNameAndRole(username, role string) ([]gen.T, error)
// SELECT * FROM @@table WHERE name = @name
FilterWithName(name string) ([]gen.T, error)
}
func Gen(gormdb *gorm.DB) {
g := gen.NewGenerator(gen.Config{
OutPath: "../../internal/dao/merchant",
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
})
g.UseDB(gormdb) // reuse your gorm db
// Generate basic type-safe DAO API for struct `model.User` following conventions
g.ApplyBasic(Merchant{})
g.ApplyBasic(MerchantWifi{})
// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`
g.ApplyInterface(func(Querier) {},Merchant{},MerchantWifi{})
// Generate the code
g.Execute()
}
type Merchant struct {
Name string
}
type MerchantWifi struct {
Name string
}
func main() {
gormdb, _ := gorm.Open(mysql.Open("c:123@(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"))
//gormdb.AutoMigrate(models.User{})
merchant.Gen(gormdb)
}
@itcuihao 本地最新版本跑了两次都没复现
@itcuihao 本地最新版本跑了两次都没复现
可否麻烦贴一下代码,我粘贴试试,我也觉得挺奇怪的,注释调就好了 ApplyInterface,不知道是不是我写的不对 @qqxhb
g.ApplyInterface(func(Querier) {},Merchant{},MerchantWifi{})
// GEN Guideline: https://bytedance.feishu.cn/wiki/wikcnbYLEL78aOYLBsT2ExUGiEd
// generate code func main() { //init db mysql.Init() db := mysql.DB(context.Background())
// specify the output directory (default: "./query")
// ### if you want to query without context constrain, set mode gen.WithoutContext ###
g := gen.NewGenerator(gen.Config{
OutPath: "../../dal/query",
ModelPkgPath: "../../model/db_model",
Mode: gen.WithDefaultQuery,
/* Mode: gen.WithoutContext,*/
//if you want the nullable field generation property to be pointer type, set FieldNullable true
/* FieldNullable: true,*/
})
// reuse the database connection in Project or create a connection here
// if you want to use GenerateModel/GenerateModelAs, UseDB is necessray or it will panic
g.UseDB(db)
// apply basic crud api on structs or table models which is specified by table name with function
// GenerateModel/GenerateModelAs. And generator will generate table models' code when calling Excute.
// g.ApplyBasic(model.User{}, g.GenerateModel("company"), g.GenerateModelAs("people", "Person", gen.FieldIgnore("address")))
g.ApplyInterface(func(Querier) {},Merchant{},MerchantWifi{})
// apply diy interfaces on structs or table models
// g.ApplyInterface(func(method model.Method) {}, model.User{}, g.GenerateModel("company"))
// execute the action of code generation
g.Execute()
} // Dynamic SQL type Querier interface { // SELECT * FROM @@table WHERE username = @name{{if role !=""}} AND role = @role{{end}} //FilterWithNameAndRole(username, role string) ([]gen.T, error)
// SELECT * FROM @@table WHERE name = @name
FilterWithName(name string) ([]gen.T, error)
}
type Merchant struct { Name string }
type MerchantWifi struct { Name string }
g.ApplyInterface(func(query.UserQuerier) {}, model.User{}) vs g.ApplyInterface(func(UserQuerier) {}, model.User{}) 通过import引入的UserQuerier会导致报错的。
ApplyInterface用官网例子,此方法重复执行时会出发此问题
解决了吗?我也出现了这样的问题