From 7eeed220db4a01ba892f6c0a16ae5904fc1c426d Mon Sep 17 00:00:00 2001 From: miya-masa Date: Thu, 28 Nov 2024 09:33:33 +0900 Subject: [PATCH 1/4] chore(expect): regenerate `dal_test` --- tests/.expect/dal_test/model/people.gen.go | 1 + tests/.expect/dal_test/model/users.gen.go | 7 +++- tests/.expect/dal_test/query/banks.gen.go | 15 ++++++-- .../dal_test/query/credit_cards.gen.go | 15 ++++++-- tests/.expect/dal_test/query/customers.gen.go | 16 +++++++-- tests/.expect/dal_test/query/gen.go | 35 +++++++++++++------ tests/.expect/dal_test/query/people.gen.go | 22 ++++++++++-- tests/.expect/dal_test/query/users.gen.go | 16 +++++++-- 8 files changed, 103 insertions(+), 24 deletions(-) diff --git a/tests/.expect/dal_test/model/people.gen.go b/tests/.expect/dal_test/model/people.gen.go index b388fabe..74888ce6 100644 --- a/tests/.expect/dal_test/model/people.gen.go +++ b/tests/.expect/dal_test/model/people.gen.go @@ -16,6 +16,7 @@ const TableNamePerson = "people" type Person struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` Name string `gorm:"column:name" json:"name"` + Alias_ string `gorm:"column:alias" json:"alias"` Age int32 `gorm:"column:age" json:"age"` Flag bool `gorm:"column:flag" json:"flag"` AnotherFlag int32 `gorm:"column:another_flag" json:"another_flag"` diff --git a/tests/.expect/dal_test/model/users.gen.go b/tests/.expect/dal_test/model/users.gen.go index 1de375ad..941c5727 100644 --- a/tests/.expect/dal_test/model/users.gen.go +++ b/tests/.expect/dal_test/model/users.gen.go @@ -14,9 +14,14 @@ const TableNameUser = "users" type User struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` - Name string `gorm:"column:name;comment:oneline" json:"name"` + Name string `gorm:"column:name;comment:oneline" json:"name"` // oneline Address string `gorm:"column:address" json:"address"` RegisterTime time.Time `gorm:"column:register_time" json:"register_time"` + /* + multiline + line1 + line2 + */ Alive bool `gorm:"column:alive;comment:multiline\nline1\nline2" json:"alive"` CompanyID int64 `gorm:"column:company_id;default:666" json:"company_id"` PrivateURL string `gorm:"column:private_url;default:https://a.b.c" json:"private_url"` diff --git a/tests/.expect/dal_test/query/banks.gen.go b/tests/.expect/dal_test/query/banks.gen.go index 0aa8df09..d21ca348 100644 --- a/tests/.expect/dal_test/query/banks.gen.go +++ b/tests/.expect/dal_test/query/banks.gen.go @@ -19,10 +19,10 @@ import ( "gorm.io/gen/tests/.expect/dal_test/model" ) -func newBank(db *gorm.DB) bank { +func newBank(db *gorm.DB, opts ...gen.DOOption) bank { _bank := bank{} - _bank.bankDo.UseDB(db) + _bank.bankDo.UseDB(db, opts...) _bank.bankDo.UseModel(&model.Bank{}) tableName := _bank.bankDo.TableName() @@ -77,6 +77,8 @@ func (b bank) TableName() string { return b.bankDo.TableName() } func (b bank) Alias() string { return b.bankDo.Alias() } +func (b bank) Columns(cols ...field.Expr) gen.Columns { return b.bankDo.Columns(cols...) } + func (b *bank) GetFieldByName(fieldName string) (field.OrderExpr, bool) { _f, ok := b.fieldMap[fieldName] if !ok || _f == nil { @@ -95,6 +97,11 @@ func (b *bank) fillFieldMap() { } func (b bank) clone(db *gorm.DB) bank { + b.bankDo.ReplaceConnPool(db.Statement.ConnPool) + return b +} + +func (b bank) replaceDB(db *gorm.DB) bank { b.bankDo.ReplaceDB(db) return b } @@ -117,6 +124,10 @@ func (b bankDo) WriteDB() *bankDo { return b.Clauses(dbresolver.Write) } +func (b bankDo) Session(config *gorm.Session) *bankDo { + return b.withDO(b.DO.Session(config)) +} + func (b bankDo) Clauses(conds ...clause.Expression) *bankDo { return b.withDO(b.DO.Clauses(conds...)) } diff --git a/tests/.expect/dal_test/query/credit_cards.gen.go b/tests/.expect/dal_test/query/credit_cards.gen.go index 1f2cf526..1d7500fb 100644 --- a/tests/.expect/dal_test/query/credit_cards.gen.go +++ b/tests/.expect/dal_test/query/credit_cards.gen.go @@ -19,10 +19,10 @@ import ( "gorm.io/gen/tests/.expect/dal_test/model" ) -func newCreditCard(db *gorm.DB) creditCard { +func newCreditCard(db *gorm.DB, opts ...gen.DOOption) creditCard { _creditCard := creditCard{} - _creditCard.creditCardDo.UseDB(db) + _creditCard.creditCardDo.UseDB(db, opts...) _creditCard.creditCardDo.UseModel(&model.CreditCard{}) tableName := _creditCard.creditCardDo.TableName() @@ -88,6 +88,8 @@ func (c creditCard) TableName() string { return c.creditCardDo.TableName() } func (c creditCard) Alias() string { return c.creditCardDo.Alias() } +func (c creditCard) Columns(cols ...field.Expr) gen.Columns { return c.creditCardDo.Columns(cols...) } + func (c *creditCard) GetFieldByName(fieldName string) (field.OrderExpr, bool) { _f, ok := c.fieldMap[fieldName] if !ok || _f == nil { @@ -109,6 +111,11 @@ func (c *creditCard) fillFieldMap() { } func (c creditCard) clone(db *gorm.DB) creditCard { + c.creditCardDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c creditCard) replaceDB(db *gorm.DB) creditCard { c.creditCardDo.ReplaceDB(db) return c } @@ -131,6 +138,10 @@ func (c creditCardDo) WriteDB() *creditCardDo { return c.Clauses(dbresolver.Write) } +func (c creditCardDo) Session(config *gorm.Session) *creditCardDo { + return c.withDO(c.DO.Session(config)) +} + func (c creditCardDo) Clauses(conds ...clause.Expression) *creditCardDo { return c.withDO(c.DO.Clauses(conds...)) } diff --git a/tests/.expect/dal_test/query/customers.gen.go b/tests/.expect/dal_test/query/customers.gen.go index 8420d353..75684f85 100644 --- a/tests/.expect/dal_test/query/customers.gen.go +++ b/tests/.expect/dal_test/query/customers.gen.go @@ -19,10 +19,10 @@ import ( "gorm.io/gen/tests/.expect/dal_test/model" ) -func newCustomer(db *gorm.DB) customer { +func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { _customer := customer{} - _customer.customerDo.UseDB(db) + _customer.customerDo.UseDB(db, opts...) _customer.customerDo.UseModel(&model.Customer{}) tableName := _customer.customerDo.TableName() @@ -80,6 +80,8 @@ func (c customer) TableName() string { return c.customerDo.TableName() } func (c customer) Alias() string { return c.customerDo.Alias() } +func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } + func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { _f, ok := c.fieldMap[fieldName] if !ok || _f == nil { @@ -99,6 +101,11 @@ func (c *customer) fillFieldMap() { } func (c customer) clone(db *gorm.DB) customer { + c.customerDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c customer) replaceDB(db *gorm.DB) customer { c.customerDo.ReplaceDB(db) return c } @@ -121,6 +128,10 @@ func (c customerDo) WriteDB() *customerDo { return c.Clauses(dbresolver.Write) } +func (c customerDo) Session(config *gorm.Session) *customerDo { + return c.withDO(c.DO.Session(config)) +} + func (c customerDo) Clauses(conds ...clause.Expression) *customerDo { return c.withDO(c.DO.Clauses(conds...)) } @@ -144,6 +155,7 @@ func (c customerDo) Select(conds ...field.Expr) *customerDo { func (c customerDo) Where(conds ...gen.Condition) *customerDo { return c.withDO(c.DO.Where(conds...)) } + func (c customerDo) Order(conds ...field.Expr) *customerDo { return c.withDO(c.DO.Order(conds...)) } diff --git a/tests/.expect/dal_test/query/gen.go b/tests/.expect/dal_test/query/gen.go index 845f24bb..d8df34cb 100644 --- a/tests/.expect/dal_test/query/gen.go +++ b/tests/.expect/dal_test/query/gen.go @@ -10,6 +10,8 @@ import ( "gorm.io/gorm" + "gorm.io/gen" + "gorm.io/plugin/dbresolver" ) @@ -22,8 +24,8 @@ var ( User *user ) -func SetDefault(db *gorm.DB) { - *Q = *Use(db) +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) Bank = &Q.Bank CreditCard = &Q.CreditCard Customer = &Q.Customer @@ -31,14 +33,14 @@ func SetDefault(db *gorm.DB) { User = &Q.User } -func Use(db *gorm.DB) *Query { +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { return &Query{ db: db, - Bank: newBank(db), - CreditCard: newCreditCard(db), - Customer: newCustomer(db), - Person: newPerson(db), - User: newUser(db), + Bank: newBank(db, opts...), + CreditCard: newCreditCard(db, opts...), + Customer: newCustomer(db, opts...), + Person: newPerson(db, opts...), + User: newUser(db, opts...), } } @@ -74,7 +76,14 @@ func (q *Query) WriteDB() *Query { } func (q *Query) ReplaceDB(db *gorm.DB) *Query { - return q.clone(db) + return &Query{ + db: db, + Bank: q.Bank.replaceDB(db), + CreditCard: q.CreditCard.replaceDB(db), + Customer: q.Customer.replaceDB(db), + Person: q.Person.replaceDB(db), + User: q.User.replaceDB(db), + } } type queryCtx struct { @@ -100,10 +109,14 @@ func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) er } func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { - return &QueryTx{q.clone(q.db.Begin(opts...))} + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} } -type QueryTx struct{ *Query } +type QueryTx struct { + *Query + Error error +} func (q *QueryTx) Commit() error { return q.db.Commit().Error diff --git a/tests/.expect/dal_test/query/people.gen.go b/tests/.expect/dal_test/query/people.gen.go index 36d1adab..20492dcd 100644 --- a/tests/.expect/dal_test/query/people.gen.go +++ b/tests/.expect/dal_test/query/people.gen.go @@ -19,16 +19,17 @@ import ( "gorm.io/gen/tests/.expect/dal_test/model" ) -func newPerson(db *gorm.DB) person { +func newPerson(db *gorm.DB, opts ...gen.DOOption) person { _person := person{} - _person.personDo.UseDB(db) + _person.personDo.UseDB(db, opts...) _person.personDo.UseModel(&model.Person{}) tableName := _person.personDo.TableName() _person.ALL = field.NewAsterisk(tableName) _person.ID = field.NewInt64(tableName, "id") _person.Name = field.NewString(tableName, "name") + _person.Alias_ = field.NewString(tableName, "alias") _person.Age = field.NewInt32(tableName, "age") _person.Flag = field.NewBool(tableName, "flag") _person.AnotherFlag = field.NewInt32(tableName, "another_flag") @@ -59,6 +60,7 @@ type person struct { ALL field.Asterisk ID field.Int64 Name field.String + Alias_ field.String Age field.Int32 Flag field.Bool AnotherFlag field.Int32 @@ -95,6 +97,7 @@ func (p *person) updateTableName(table string) *person { p.ALL = field.NewAsterisk(table) p.ID = field.NewInt64(table, "id") p.Name = field.NewString(table, "name") + p.Alias_ = field.NewString(table, "alias") p.Age = field.NewInt32(table, "age") p.Flag = field.NewBool(table, "flag") p.AnotherFlag = field.NewInt32(table, "another_flag") @@ -125,6 +128,8 @@ func (p person) TableName() string { return p.personDo.TableName() } func (p person) Alias() string { return p.personDo.Alias() } +func (p person) Columns(cols ...field.Expr) gen.Columns { return p.personDo.Columns(cols...) } + func (p *person) GetFieldByName(fieldName string) (field.OrderExpr, bool) { _f, ok := p.fieldMap[fieldName] if !ok || _f == nil { @@ -135,9 +140,10 @@ func (p *person) GetFieldByName(fieldName string) (field.OrderExpr, bool) { } func (p *person) fillFieldMap() { - p.fieldMap = make(map[string]field.Expr, 20) + p.fieldMap = make(map[string]field.Expr, 21) p.fieldMap["id"] = p.ID p.fieldMap["name"] = p.Name + p.fieldMap["alias"] = p.Alias_ p.fieldMap["age"] = p.Age p.fieldMap["flag"] = p.Flag p.fieldMap["another_flag"] = p.AnotherFlag @@ -159,6 +165,11 @@ func (p *person) fillFieldMap() { } func (p person) clone(db *gorm.DB) person { + p.personDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p person) replaceDB(db *gorm.DB) person { p.personDo.ReplaceDB(db) return p } @@ -181,6 +192,10 @@ func (p personDo) WriteDB() *personDo { return p.Clauses(dbresolver.Write) } +func (p personDo) Session(config *gorm.Session) *personDo { + return p.withDO(p.DO.Session(config)) +} + func (p personDo) Clauses(conds ...clause.Expression) *personDo { return p.withDO(p.DO.Clauses(conds...)) } @@ -204,6 +219,7 @@ func (p personDo) Select(conds ...field.Expr) *personDo { func (p personDo) Where(conds ...gen.Condition) *personDo { return p.withDO(p.DO.Where(conds...)) } + func (p personDo) Order(conds ...field.Expr) *personDo { return p.withDO(p.DO.Order(conds...)) } diff --git a/tests/.expect/dal_test/query/users.gen.go b/tests/.expect/dal_test/query/users.gen.go index 1f03f87e..fd50fed9 100644 --- a/tests/.expect/dal_test/query/users.gen.go +++ b/tests/.expect/dal_test/query/users.gen.go @@ -19,10 +19,10 @@ import ( "gorm.io/gen/tests/.expect/dal_test/model" ) -func newUser(db *gorm.DB) user { +func newUser(db *gorm.DB, opts ...gen.DOOption) user { _user := user{} - _user.userDo.UseDB(db) + _user.userDo.UseDB(db, opts...) _user.userDo.UseModel(&model.User{}) tableName := _user.userDo.TableName() @@ -94,6 +94,8 @@ func (u user) TableName() string { return u.userDo.TableName() } func (u user) Alias() string { return u.userDo.Alias() } +func (u user) Columns(cols ...field.Expr) gen.Columns { return u.userDo.Columns(cols...) } + func (u *user) GetFieldByName(fieldName string) (field.OrderExpr, bool) { _f, ok := u.fieldMap[fieldName] if !ok || _f == nil { @@ -116,6 +118,11 @@ func (u *user) fillFieldMap() { } func (u user) clone(db *gorm.DB) user { + u.userDo.ReplaceConnPool(db.Statement.ConnPool) + return u +} + +func (u user) replaceDB(db *gorm.DB) user { u.userDo.ReplaceDB(db) return u } @@ -138,6 +145,10 @@ func (u userDo) WriteDB() *userDo { return u.Clauses(dbresolver.Write) } +func (u userDo) Session(config *gorm.Session) *userDo { + return u.withDO(u.DO.Session(config)) +} + func (u userDo) Clauses(conds ...clause.Expression) *userDo { return u.withDO(u.DO.Clauses(conds...)) } @@ -162,7 +173,6 @@ func (u userDo) Where(conds ...gen.Condition) *userDo { return u.withDO(u.DO.Where(conds...)) } - func (u userDo) Order(conds ...field.Expr) *userDo { return u.withDO(u.DO.Order(conds...)) } From 08cab3983451a7181c032849c7b04b732e5172de Mon Sep 17 00:00:00 2001 From: miya-masa Date: Thu, 28 Nov 2024 09:33:55 +0900 Subject: [PATCH 2/4] fix(relation-tx): fix association bug(1070) --- internal/template/struct.go | 31 +- tests/.expect/dal_7/model/banks.gen.go | 20 + tests/.expect/dal_7/model/credit_cards.gen.go | 29 + tests/.expect/dal_7/model/customers.gen.go | 29 + tests/.expect/dal_7/query/customers.gen.go | 567 ++++++++++++++++++ .../.expect/dal_7/query/customers.gen_test.go | 145 +++++ tests/.expect/dal_7/query/gen.go | 103 ++++ tests/.expect/dal_7/query/gen_test.go | 118 ++++ .../dal_test_relation/model/banks.gen.go | 20 + .../model/credit_cards.gen.go | 29 + .../dal_test_relation/model/customers.gen.go | 29 + .../dal_test_relation/query/banks.gen.go | 339 +++++++++++ .../query/credit_cards.gen.go | 353 +++++++++++ .../dal_test_relation/query/customers.gen.go | 505 ++++++++++++++++ tests/.expect/dal_test_relation/query/gen.go | 119 ++++ tests/gen_test.go | 9 +- tests/generate_test.go | 64 +- tests/transaction_test.go | 111 ++++ 18 files changed, 2603 insertions(+), 17 deletions(-) create mode 100644 tests/.expect/dal_7/model/banks.gen.go create mode 100644 tests/.expect/dal_7/model/credit_cards.gen.go create mode 100644 tests/.expect/dal_7/model/customers.gen.go create mode 100644 tests/.expect/dal_7/query/customers.gen.go create mode 100644 tests/.expect/dal_7/query/customers.gen_test.go create mode 100644 tests/.expect/dal_7/query/gen.go create mode 100644 tests/.expect/dal_7/query/gen_test.go create mode 100644 tests/.expect/dal_test_relation/model/banks.gen.go create mode 100644 tests/.expect/dal_test_relation/model/credit_cards.gen.go create mode 100644 tests/.expect/dal_test_relation/model/customers.gen.go create mode 100644 tests/.expect/dal_test_relation/query/banks.gen.go create mode 100644 tests/.expect/dal_test_relation/query/credit_cards.gen.go create mode 100644 tests/.expect/dal_test_relation/query/customers.gen.go create mode 100644 tests/.expect/dal_test_relation/query/gen.go create mode 100644 tests/transaction_test.go diff --git a/internal/template/struct.go b/internal/template/struct.go index 8b83a12e..867da13f 100644 --- a/internal/template/struct.go +++ b/internal/template/struct.go @@ -18,10 +18,10 @@ const ( ` + fields + ` } ` + tableMethod + asMethond + updateFieldMethod + ` - + func ({{.S}} *{{.QueryStructName}}) WithContext(ctx context.Context) {{.ReturnObject}} { return {{.S}}.{{.QueryStructName}}Do.WithContext(ctx)} - func ({{.S}} {{.QueryStructName}}) TableName() string { return {{.S}}.{{.QueryStructName}}Do.TableName() } + func ({{.S}} {{.QueryStructName}}) TableName() string { return {{.S}}.{{.QueryStructName}}Do.TableName() } func ({{.S}} {{.QueryStructName}}) Alias() string { return {{.S}}.{{.QueryStructName}}Do.Alias() } @@ -37,10 +37,10 @@ const ( createMethod = ` func new{{.ModelStructName}}(db *gorm.DB, opts ...gen.DOOption) {{.QueryStructName}} { _{{.QueryStructName}} := {{.QueryStructName}}{} - + _{{.QueryStructName}}.{{.QueryStructName}}Do.UseDB(db,opts...) _{{.QueryStructName}}.{{.QueryStructName}}Do.UseModel(&{{.StructInfo.Package}}.{{.StructInfo.Type}}{}) - + tableName := _{{.QueryStructName}}.{{.QueryStructName}}Do.TableName() _{{$.QueryStructName}}.ALL = field.NewAsterisk(tableName) {{range .Fields -}} @@ -56,7 +56,7 @@ const ( {{end}} _{{$.QueryStructName}}.fillFieldMap() - + return _{{.QueryStructName}} } ` @@ -78,27 +78,27 @@ const ( fieldMap map[string]field.Expr ` tableMethod = ` -func ({{.S}} {{.QueryStructName}}) Table(newTableName string) *{{.QueryStructName}} { +func ({{.S}} {{.QueryStructName}}) Table(newTableName string) *{{.QueryStructName}} { {{.S}}.{{.QueryStructName}}Do.UseTable(newTableName) return {{.S}}.updateTableName(newTableName) } ` - asMethond = ` -func ({{.S}} {{.QueryStructName}}) As(alias string) *{{.QueryStructName}} { + asMethond = ` +func ({{.S}} {{.QueryStructName}}) As(alias string) *{{.QueryStructName}} { {{.S}}.{{.QueryStructName}}Do.DO = *({{.S}}.{{.QueryStructName}}Do.As(alias).(*gen.DO)) return {{.S}}.updateTableName(alias) } ` updateFieldMethod = ` -func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStructName}} { +func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStructName}} { {{.S}}.ALL = field.NewAsterisk(table) {{range .Fields -}} {{if not .IsRelation -}} {{- if .ColumnName -}}{{$.S}}.{{.Name}} = field.New{{.GenType}}(table, "{{.ColumnName}}"){{- end -}} {{end}} {{end}} - + {{.S}}.fillFieldMap() return {{.S}} @@ -107,13 +107,16 @@ func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStruc cloneMethod = ` func ({{.S}} {{.QueryStructName}}) clone(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool) + {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool){{range .Fields }}{{if .IsRelation}} + {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{Initialized: true}) + {{$.S}}.{{.Relation.Name}}.db.Statement.ConnPool = db.Statement.ConnPool{{end}}{{end}} return {{.S}} } ` replaceMethod = ` func ({{.S}} {{.QueryStructName}}) replaceDB(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db) + {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db){{range .Fields}}{{if .IsRelation}} + {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{}){{end}}{{end}} return {{.S}} } ` @@ -217,9 +220,9 @@ const ( relationStruct = ` type {{$.QueryStructName}}{{$relationship}}{{$relation.Name}} struct{ db *gorm.DB - + field.RelationField - + {{$relation.StructField}} } diff --git a/tests/.expect/dal_7/model/banks.gen.go b/tests/.expect/dal_7/model/banks.gen.go new file mode 100644 index 00000000..47ce6f40 --- /dev/null +++ b/tests/.expect/dal_7/model/banks.gen.go @@ -0,0 +1,20 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +const TableNameBank = "banks" + +// Bank mapped from table +type Bank struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + Name *string `gorm:"column:name" json:"-"` + Address *string `gorm:"column:address" json:"-"` + Scale *int64 `gorm:"column:scale" json:"-"` +} + +// TableName Bank's table name +func (*Bank) TableName() string { + return TableNameBank +} diff --git a/tests/.expect/dal_7/model/credit_cards.gen.go b/tests/.expect/dal_7/model/credit_cards.gen.go new file mode 100644 index 00000000..7a7d0202 --- /dev/null +++ b/tests/.expect/dal_7/model/credit_cards.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCreditCard = "credit_cards" + +// CreditCard mapped from table +type CreditCard struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + CreatedAt *time.Time `gorm:"column:created_at" json:"-"` + UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_credit_cards_deleted_at,priority:1" json:"-"` + Number *string `gorm:"column:number" json:"-"` + CustomerRefer *int64 `gorm:"column:customer_refer" json:"-"` + BankID *int64 `gorm:"column:bank_id" json:"-"` +} + +// TableName CreditCard's table name +func (*CreditCard) TableName() string { + return TableNameCreditCard +} diff --git a/tests/.expect/dal_7/model/customers.gen.go b/tests/.expect/dal_7/model/customers.gen.go new file mode 100644 index 00000000..ddbd7ada --- /dev/null +++ b/tests/.expect/dal_7/model/customers.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCustomer = "customers" + +// Customer mapped from table +type Customer struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + CreatedAt *time.Time `gorm:"column:created_at" json:"-"` + UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_customers_deleted_at,priority:1" json:"-"` + BankID *int64 `gorm:"column:bank_id" json:"-"` + Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` + CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` +} + +// TableName Customer's table name +func (*Customer) TableName() string { + return TableNameCustomer +} diff --git a/tests/.expect/dal_7/query/customers.gen.go b/tests/.expect/dal_7/query/customers.gen.go new file mode 100644 index 00000000..a4dc3283 --- /dev/null +++ b/tests/.expect/dal_7/query/customers.gen.go @@ -0,0 +1,567 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.gen/dal_7/model" +) + +func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { + _customer := customer{} + + _customer.customerDo.UseDB(db, opts...) + _customer.customerDo.UseModel(&model.Customer{}) + + tableName := _customer.customerDo.TableName() + _customer.ALL = field.NewAsterisk(tableName) + _customer.ID = field.NewInt64(tableName, "id") + _customer.CreatedAt = field.NewTime(tableName, "created_at") + _customer.UpdatedAt = field.NewTime(tableName, "updated_at") + _customer.DeletedAt = field.NewField(tableName, "deleted_at") + _customer.BankID = field.NewInt64(tableName, "bank_id") + _customer.Bank = customerHasOneBank{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Bank", "model.Bank"), + } + + _customer.CreditCards = customerHasManyCreditCards{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("CreditCards", "model.CreditCard"), + } + + _customer.fillFieldMap() + + return _customer +} + +type customer struct { + customerDo customerDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + BankID field.Int64 + Bank customerHasOneBank + + CreditCards customerHasManyCreditCards + + fieldMap map[string]field.Expr +} + +func (c customer) Table(newTableName string) *customer { + c.customerDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c customer) As(alias string) *customer { + c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *customer) updateTableName(table string) *customer { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *customer) WithContext(ctx context.Context) ICustomerDo { return c.customerDo.WithContext(ctx) } + +func (c customer) TableName() string { return c.customerDo.TableName() } + +func (c customer) Alias() string { return c.customerDo.Alias() } + +func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } + +func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *customer) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["bank_id"] = c.BankID + +} + +func (c customer) clone(db *gorm.DB) customer { + c.customerDo.ReplaceConnPool(db.Statement.ConnPool) + c.Bank.db = db.Session(&gorm.Session{Initialized: true}) + c.Bank.db.Statement.ConnPool = db.Statement.ConnPool + c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) + c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool + return c +} + +func (c customer) replaceDB(db *gorm.DB) customer { + c.customerDo.ReplaceDB(db) + c.Bank.db = db.Session(&gorm.Session{}) + c.CreditCards.db = db.Session(&gorm.Session{}) + return c +} + +type customerHasOneBank struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { + return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasOneBankTx struct{ tx *gorm.Association } + +func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasOneBankTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasOneBankTx) Count() int64 { + return a.tx.Count() +} + +type customerHasManyCreditCards struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { + return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasManyCreditCardsTx struct{ tx *gorm.Association } + +func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasManyCreditCardsTx) Count() int64 { + return a.tx.Count() +} + +type customerDo struct{ gen.DO } + +type ICustomerDo interface { + gen.SubQuery + Debug() ICustomerDo + WithContext(ctx context.Context) ICustomerDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() ICustomerDo + WriteDB() ICustomerDo + As(alias string) gen.Dao + Session(config *gorm.Session) ICustomerDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) ICustomerDo + Not(conds ...gen.Condition) ICustomerDo + Or(conds ...gen.Condition) ICustomerDo + Select(conds ...field.Expr) ICustomerDo + Where(conds ...gen.Condition) ICustomerDo + Order(conds ...field.Expr) ICustomerDo + Distinct(cols ...field.Expr) ICustomerDo + Omit(cols ...field.Expr) ICustomerDo + Join(table schema.Tabler, on ...field.Expr) ICustomerDo + LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo + RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo + Group(cols ...field.Expr) ICustomerDo + Having(conds ...gen.Condition) ICustomerDo + Limit(limit int) ICustomerDo + Offset(offset int) ICustomerDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo + Unscoped() ICustomerDo + Create(values ...*model.Customer) error + CreateInBatches(values []*model.Customer, batchSize int) error + Save(values ...*model.Customer) error + First() (*model.Customer, error) + Take() (*model.Customer, error) + Last() (*model.Customer, error) + Find() ([]*model.Customer, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) + FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*model.Customer) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) ICustomerDo + Assign(attrs ...field.AssignExpr) ICustomerDo + Joins(fields ...field.RelationField) ICustomerDo + Preload(fields ...field.RelationField) ICustomerDo + FirstOrInit() (*model.Customer, error) + FirstOrCreate() (*model.Customer, error) + FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) ICustomerDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (c customerDo) Debug() ICustomerDo { + return c.withDO(c.DO.Debug()) +} + +func (c customerDo) WithContext(ctx context.Context) ICustomerDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c customerDo) ReadDB() ICustomerDo { + return c.Clauses(dbresolver.Read) +} + +func (c customerDo) WriteDB() ICustomerDo { + return c.Clauses(dbresolver.Write) +} + +func (c customerDo) Session(config *gorm.Session) ICustomerDo { + return c.withDO(c.DO.Session(config)) +} + +func (c customerDo) Clauses(conds ...clause.Expression) ICustomerDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c customerDo) Returning(value interface{}, columns ...string) ICustomerDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c customerDo) Not(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c customerDo) Or(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c customerDo) Select(conds ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c customerDo) Where(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c customerDo) Order(conds ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c customerDo) Distinct(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c customerDo) Omit(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c customerDo) Join(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c customerDo) Group(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c customerDo) Having(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c customerDo) Limit(limit int) ICustomerDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c customerDo) Offset(offset int) ICustomerDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c customerDo) Unscoped() ICustomerDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c customerDo) Create(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c customerDo) Save(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c customerDo) First() (*model.Customer, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Take() (*model.Customer, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Last() (*model.Customer, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Find() ([]*model.Customer, error) { + result, err := c.DO.Find() + return result.([]*model.Customer), err +} + +func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { + buf := make([]*model.Customer, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c customerDo) Attrs(attrs ...field.AssignExpr) ICustomerDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c customerDo) Assign(attrs ...field.AssignExpr) ICustomerDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c customerDo) Joins(fields ...field.RelationField) ICustomerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c customerDo) Preload(fields ...field.RelationField) ICustomerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c customerDo) FirstOrInit() (*model.Customer, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FirstOrCreate() (*model.Customer, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c customerDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *customerDo) withDO(do gen.Dao) *customerDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_7/query/customers.gen_test.go b/tests/.expect/dal_7/query/customers.gen_test.go new file mode 100644 index 00000000..f625fdca --- /dev/null +++ b/tests/.expect/dal_7/query/customers.gen_test.go @@ -0,0 +1,145 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "testing" + + "gorm.io/gen" + "gorm.io/gen/field" + "gorm.io/gen/tests/.gen/dal_7/model" + "gorm.io/gorm/clause" +) + +func init() { + InitializeDB() + err := _gen_test_db.AutoMigrate(&model.Customer{}) + if err != nil { + fmt.Printf("Error: AutoMigrate(&model.Customer{}) fail: %s", err) + } +} + +func Test_customerQuery(t *testing.T) { + customer := newCustomer(_gen_test_db) + customer = *customer.As(customer.TableName()) + _do := customer.WithContext(context.Background()).Debug() + + primaryKey := field.NewString(customer.TableName(), clause.PrimaryKey) + _, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete() + if err != nil { + t.Error("clean table fail:", err) + return + } + + _, ok := customer.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from customer success") + } + + err = _do.Create(&model.Customer{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.Save(&model.Customer{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.CreateInBatches([]*model.Customer{{}, {}}, 10) + if err != nil { + t.Error("create item in table fail:", err) + } + + _, err = _do.Select(customer.ALL).Take() + if err != nil { + t.Error("Take() on table fail:", err) + } + + _, err = _do.First() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Last() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table fail:", err) + } + + err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*model.Customer{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table fail:", err) + } + + _, err = _do.Select(customer.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table fail:", err) + } + + _, err = _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table fail:", err) + } + + _, err = _do.Select(customer.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table fail:", err) + } + + _, err = _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table fail:", err) + } + + _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table fail:", err) + } + + _, _, err = _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table fail:", err) + } + + _, err = _do.ScanByPage(&model.Customer{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table fail:", err) + } + + var _a _another + var _aPK = field.NewString(_a.TableName(), "id") + + err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table fail:", err) + } + + err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table fail:", err) + } + + _, err = _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table fail:", err) + } +} diff --git a/tests/.expect/dal_7/query/gen.go b/tests/.expect/dal_7/query/gen.go new file mode 100644 index 00000000..11cd3da4 --- /dev/null +++ b/tests/.expect/dal_7/query/gen.go @@ -0,0 +1,103 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +var ( + Q = new(Query) + Customer *customer +) + +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) + Customer = &Q.Customer +} + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + Customer: newCustomer(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + Customer customer +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + Customer: q.Customer.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + Customer: q.Customer.replaceDB(db), + } +} + +type queryCtx struct { + Customer ICustomerDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + Customer: q.Customer.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/tests/.expect/dal_7/query/gen_test.go b/tests/.expect/dal_7/query/gen_test.go new file mode 100644 index 00000000..7e81714a --- /dev/null +++ b/tests/.expect/dal_7/query/gen_test.go @@ -0,0 +1,118 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "reflect" + "sync" + "testing" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +type Input struct { + Args []interface{} +} + +type Expectation struct { + Ret []interface{} +} + +type TestCase struct { + Input + Expectation +} + +const _gen_test_db_name = "gen_test.db" + +var _gen_test_db *gorm.DB +var _gen_test_once sync.Once + +func init() { + InitializeDB() + _gen_test_db.AutoMigrate(&_another{}) +} + +func InitializeDB() { + _gen_test_once.Do(func() { + var err error + _gen_test_db, err = gorm.Open(sqlite.Open(_gen_test_db_name), &gorm.Config{}) + if err != nil { + panic(fmt.Errorf("open sqlite %q fail: %w", _gen_test_db_name, err)) + } + }) +} + +func assert(t *testing.T, methodName string, res, exp interface{}) { + if !reflect.DeepEqual(res, exp) { + t.Errorf("%v() gotResult = %v, want %v", methodName, res, exp) + } +} + +type _another struct { + ID uint64 `gorm:"primaryKey"` +} + +func (*_another) TableName() string { return "another_for_unit_test" } + +func Test_Available(t *testing.T) { + if !Use(_gen_test_db).Available() { + t.Errorf("query.Available() == false") + } +} + +func Test_WithContext(t *testing.T) { + query := Use(_gen_test_db) + if !query.Available() { + t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") + } + + type Content string + var key, value Content = "gen_tag", "unit_test" + qCtx := query.WithContext(context.WithValue(context.Background(), key, value)) + + for _, ctx := range []context.Context{ + qCtx.Customer.UnderlyingDB().Statement.Context, + } { + if v := ctx.Value(key); v != value { + t.Errorf("get value from context fail, expect %q, got %q", value, v) + } + } +} + +func Test_Transaction(t *testing.T) { + query := Use(_gen_test_db) + if !query.Available() { + t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") + } + + err := query.Transaction(func(tx *Query) error { return nil }) + if err != nil { + t.Errorf("query.Transaction execute fail: %s", err) + } + + tx := query.Begin() + + err = tx.SavePoint("point") + if err != nil { + t.Errorf("query tx SavePoint fail: %s", err) + } + err = tx.RollbackTo("point") + if err != nil { + t.Errorf("query tx RollbackTo fail: %s", err) + } + err = tx.Commit() + if err != nil { + t.Errorf("query tx Commit fail: %s", err) + } + + err = query.Begin().Rollback() + if err != nil { + t.Errorf("query tx Rollback fail: %s", err) + } +} diff --git a/tests/.expect/dal_test_relation/model/banks.gen.go b/tests/.expect/dal_test_relation/model/banks.gen.go new file mode 100644 index 00000000..689bd855 --- /dev/null +++ b/tests/.expect/dal_test_relation/model/banks.gen.go @@ -0,0 +1,20 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +const TableNameBank = "banks" + +// Bank mapped from table +type Bank struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + Name string `gorm:"column:name" json:"name"` + Address string `gorm:"column:address" json:"address"` + Scale int64 `gorm:"column:scale" json:"scale"` +} + +// TableName Bank's table name +func (*Bank) TableName() string { + return TableNameBank +} diff --git a/tests/.expect/dal_test_relation/model/credit_cards.gen.go b/tests/.expect/dal_test_relation/model/credit_cards.gen.go new file mode 100644 index 00000000..427684c0 --- /dev/null +++ b/tests/.expect/dal_test_relation/model/credit_cards.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCreditCard = "credit_cards" + +// CreditCard mapped from table +type CreditCard struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` + Number string `gorm:"column:number" json:"number"` + CustomerRefer int64 `gorm:"column:customer_refer" json:"customer_refer"` + BankID int64 `gorm:"column:bank_id" json:"bank_id"` +} + +// TableName CreditCard's table name +func (*CreditCard) TableName() string { + return TableNameCreditCard +} diff --git a/tests/.expect/dal_test_relation/model/customers.gen.go b/tests/.expect/dal_test_relation/model/customers.gen.go new file mode 100644 index 00000000..d59e6dde --- /dev/null +++ b/tests/.expect/dal_test_relation/model/customers.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCustomer = "customers" + +// Customer mapped from table +type Customer struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` + BankID int64 `gorm:"column:bank_id" json:"bank_id"` + Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` + CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` +} + +// TableName Customer's table name +func (*Customer) TableName() string { + return TableNameCustomer +} diff --git a/tests/.expect/dal_test_relation/query/banks.gen.go b/tests/.expect/dal_test_relation/query/banks.gen.go new file mode 100644 index 00000000..2a5a334d --- /dev/null +++ b/tests/.expect/dal_test_relation/query/banks.gen.go @@ -0,0 +1,339 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newBank(db *gorm.DB, opts ...gen.DOOption) bank { + _bank := bank{} + + _bank.bankDo.UseDB(db, opts...) + _bank.bankDo.UseModel(&model.Bank{}) + + tableName := _bank.bankDo.TableName() + _bank.ALL = field.NewAsterisk(tableName) + _bank.ID = field.NewInt64(tableName, "id") + _bank.Name = field.NewString(tableName, "name") + _bank.Address = field.NewString(tableName, "address") + _bank.Scale = field.NewInt64(tableName, "scale") + + _bank.fillFieldMap() + + return _bank +} + +type bank struct { + bankDo bankDo + + ALL field.Asterisk + ID field.Int64 + Name field.String + Address field.String + Scale field.Int64 + + fieldMap map[string]field.Expr +} + +func (b bank) Table(newTableName string) *bank { + b.bankDo.UseTable(newTableName) + return b.updateTableName(newTableName) +} + +func (b bank) As(alias string) *bank { + b.bankDo.DO = *(b.bankDo.As(alias).(*gen.DO)) + return b.updateTableName(alias) +} + +func (b *bank) updateTableName(table string) *bank { + b.ALL = field.NewAsterisk(table) + b.ID = field.NewInt64(table, "id") + b.Name = field.NewString(table, "name") + b.Address = field.NewString(table, "address") + b.Scale = field.NewInt64(table, "scale") + + b.fillFieldMap() + + return b +} + +func (b *bank) WithContext(ctx context.Context) *bankDo { return b.bankDo.WithContext(ctx) } + +func (b bank) TableName() string { return b.bankDo.TableName() } + +func (b bank) Alias() string { return b.bankDo.Alias() } + +func (b bank) Columns(cols ...field.Expr) gen.Columns { return b.bankDo.Columns(cols...) } + +func (b *bank) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := b.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (b *bank) fillFieldMap() { + b.fieldMap = make(map[string]field.Expr, 4) + b.fieldMap["id"] = b.ID + b.fieldMap["name"] = b.Name + b.fieldMap["address"] = b.Address + b.fieldMap["scale"] = b.Scale +} + +func (b bank) clone(db *gorm.DB) bank { + b.bankDo.ReplaceConnPool(db.Statement.ConnPool) + return b +} + +func (b bank) replaceDB(db *gorm.DB) bank { + b.bankDo.ReplaceDB(db) + return b +} + +type bankDo struct{ gen.DO } + +func (b bankDo) Debug() *bankDo { + return b.withDO(b.DO.Debug()) +} + +func (b bankDo) WithContext(ctx context.Context) *bankDo { + return b.withDO(b.DO.WithContext(ctx)) +} + +func (b bankDo) ReadDB() *bankDo { + return b.Clauses(dbresolver.Read) +} + +func (b bankDo) WriteDB() *bankDo { + return b.Clauses(dbresolver.Write) +} + +func (b bankDo) Session(config *gorm.Session) *bankDo { + return b.withDO(b.DO.Session(config)) +} + +func (b bankDo) Clauses(conds ...clause.Expression) *bankDo { + return b.withDO(b.DO.Clauses(conds...)) +} + +func (b bankDo) Returning(value interface{}, columns ...string) *bankDo { + return b.withDO(b.DO.Returning(value, columns...)) +} + +func (b bankDo) Not(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Not(conds...)) +} + +func (b bankDo) Or(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Or(conds...)) +} + +func (b bankDo) Select(conds ...field.Expr) *bankDo { + return b.withDO(b.DO.Select(conds...)) +} + +func (b bankDo) Where(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Where(conds...)) +} + +func (b bankDo) Order(conds ...field.Expr) *bankDo { + return b.withDO(b.DO.Order(conds...)) +} + +func (b bankDo) Distinct(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Distinct(cols...)) +} + +func (b bankDo) Omit(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Omit(cols...)) +} + +func (b bankDo) Join(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.Join(table, on...)) +} + +func (b bankDo) LeftJoin(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.LeftJoin(table, on...)) +} + +func (b bankDo) RightJoin(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.RightJoin(table, on...)) +} + +func (b bankDo) Group(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Group(cols...)) +} + +func (b bankDo) Having(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Having(conds...)) +} + +func (b bankDo) Limit(limit int) *bankDo { + return b.withDO(b.DO.Limit(limit)) +} + +func (b bankDo) Offset(offset int) *bankDo { + return b.withDO(b.DO.Offset(offset)) +} + +func (b bankDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *bankDo { + return b.withDO(b.DO.Scopes(funcs...)) +} + +func (b bankDo) Unscoped() *bankDo { + return b.withDO(b.DO.Unscoped()) +} + +func (b bankDo) Create(values ...*model.Bank) error { + if len(values) == 0 { + return nil + } + return b.DO.Create(values) +} + +func (b bankDo) CreateInBatches(values []*model.Bank, batchSize int) error { + return b.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (b bankDo) Save(values ...*model.Bank) error { + if len(values) == 0 { + return nil + } + return b.DO.Save(values) +} + +func (b bankDo) First() (*model.Bank, error) { + if result, err := b.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Take() (*model.Bank, error) { + if result, err := b.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Last() (*model.Bank, error) { + if result, err := b.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Find() ([]*model.Bank, error) { + result, err := b.DO.Find() + return result.([]*model.Bank), err +} + +func (b bankDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Bank, err error) { + buf := make([]*model.Bank, 0, batchSize) + err = b.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (b bankDo) FindInBatches(result *[]*model.Bank, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return b.DO.FindInBatches(result, batchSize, fc) +} + +func (b bankDo) Attrs(attrs ...field.AssignExpr) *bankDo { + return b.withDO(b.DO.Attrs(attrs...)) +} + +func (b bankDo) Assign(attrs ...field.AssignExpr) *bankDo { + return b.withDO(b.DO.Assign(attrs...)) +} + +func (b bankDo) Joins(fields ...field.RelationField) *bankDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Joins(_f)) + } + return &b +} + +func (b bankDo) Preload(fields ...field.RelationField) *bankDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Preload(_f)) + } + return &b +} + +func (b bankDo) FirstOrInit() (*model.Bank, error) { + if result, err := b.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) FirstOrCreate() (*model.Bank, error) { + if result, err := b.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) FindByPage(offset int, limit int) (result []*model.Bank, count int64, err error) { + result, err = b.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = b.Offset(-1).Limit(-1).Count() + return +} + +func (b bankDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = b.Count() + if err != nil { + return + } + + err = b.Offset(offset).Limit(limit).Scan(result) + return +} + +func (b bankDo) Scan(result interface{}) (err error) { + return b.DO.Scan(result) +} + +func (b bankDo) Delete(models ...*model.Bank) (result gen.ResultInfo, err error) { + return b.DO.Delete(models) +} + +func (b *bankDo) withDO(do gen.Dao) *bankDo { + b.DO = *do.(*gen.DO) + return b +} diff --git a/tests/.expect/dal_test_relation/query/credit_cards.gen.go b/tests/.expect/dal_test_relation/query/credit_cards.gen.go new file mode 100644 index 00000000..5d12e6cb --- /dev/null +++ b/tests/.expect/dal_test_relation/query/credit_cards.gen.go @@ -0,0 +1,353 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newCreditCard(db *gorm.DB, opts ...gen.DOOption) creditCard { + _creditCard := creditCard{} + + _creditCard.creditCardDo.UseDB(db, opts...) + _creditCard.creditCardDo.UseModel(&model.CreditCard{}) + + tableName := _creditCard.creditCardDo.TableName() + _creditCard.ALL = field.NewAsterisk(tableName) + _creditCard.ID = field.NewInt64(tableName, "id") + _creditCard.CreatedAt = field.NewTime(tableName, "created_at") + _creditCard.UpdatedAt = field.NewTime(tableName, "updated_at") + _creditCard.DeletedAt = field.NewField(tableName, "deleted_at") + _creditCard.Number = field.NewString(tableName, "number") + _creditCard.CustomerRefer = field.NewInt64(tableName, "customer_refer") + _creditCard.BankID = field.NewInt64(tableName, "bank_id") + + _creditCard.fillFieldMap() + + return _creditCard +} + +type creditCard struct { + creditCardDo creditCardDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + Number field.String + CustomerRefer field.Int64 + BankID field.Int64 + + fieldMap map[string]field.Expr +} + +func (c creditCard) Table(newTableName string) *creditCard { + c.creditCardDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c creditCard) As(alias string) *creditCard { + c.creditCardDo.DO = *(c.creditCardDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *creditCard) updateTableName(table string) *creditCard { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.Number = field.NewString(table, "number") + c.CustomerRefer = field.NewInt64(table, "customer_refer") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *creditCard) WithContext(ctx context.Context) *creditCardDo { + return c.creditCardDo.WithContext(ctx) +} + +func (c creditCard) TableName() string { return c.creditCardDo.TableName() } + +func (c creditCard) Alias() string { return c.creditCardDo.Alias() } + +func (c creditCard) Columns(cols ...field.Expr) gen.Columns { return c.creditCardDo.Columns(cols...) } + +func (c *creditCard) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *creditCard) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["number"] = c.Number + c.fieldMap["customer_refer"] = c.CustomerRefer + c.fieldMap["bank_id"] = c.BankID +} + +func (c creditCard) clone(db *gorm.DB) creditCard { + c.creditCardDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c creditCard) replaceDB(db *gorm.DB) creditCard { + c.creditCardDo.ReplaceDB(db) + return c +} + +type creditCardDo struct{ gen.DO } + +func (c creditCardDo) Debug() *creditCardDo { + return c.withDO(c.DO.Debug()) +} + +func (c creditCardDo) WithContext(ctx context.Context) *creditCardDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c creditCardDo) ReadDB() *creditCardDo { + return c.Clauses(dbresolver.Read) +} + +func (c creditCardDo) WriteDB() *creditCardDo { + return c.Clauses(dbresolver.Write) +} + +func (c creditCardDo) Session(config *gorm.Session) *creditCardDo { + return c.withDO(c.DO.Session(config)) +} + +func (c creditCardDo) Clauses(conds ...clause.Expression) *creditCardDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c creditCardDo) Returning(value interface{}, columns ...string) *creditCardDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c creditCardDo) Not(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c creditCardDo) Or(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c creditCardDo) Select(conds ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c creditCardDo) Where(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c creditCardDo) Order(conds ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c creditCardDo) Distinct(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c creditCardDo) Omit(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c creditCardDo) Join(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c creditCardDo) LeftJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c creditCardDo) RightJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c creditCardDo) Group(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c creditCardDo) Having(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c creditCardDo) Limit(limit int) *creditCardDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c creditCardDo) Offset(offset int) *creditCardDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c creditCardDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *creditCardDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c creditCardDo) Unscoped() *creditCardDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c creditCardDo) Create(values ...*model.CreditCard) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c creditCardDo) CreateInBatches(values []*model.CreditCard, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c creditCardDo) Save(values ...*model.CreditCard) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c creditCardDo) First() (*model.CreditCard, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Take() (*model.CreditCard, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Last() (*model.CreditCard, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Find() ([]*model.CreditCard, error) { + result, err := c.DO.Find() + return result.([]*model.CreditCard), err +} + +func (c creditCardDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.CreditCard, err error) { + buf := make([]*model.CreditCard, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c creditCardDo) FindInBatches(result *[]*model.CreditCard, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c creditCardDo) Attrs(attrs ...field.AssignExpr) *creditCardDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c creditCardDo) Assign(attrs ...field.AssignExpr) *creditCardDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c creditCardDo) Joins(fields ...field.RelationField) *creditCardDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c creditCardDo) Preload(fields ...field.RelationField) *creditCardDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c creditCardDo) FirstOrInit() (*model.CreditCard, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) FirstOrCreate() (*model.CreditCard, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) FindByPage(offset int, limit int) (result []*model.CreditCard, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c creditCardDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c creditCardDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c creditCardDo) Delete(models ...*model.CreditCard) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *creditCardDo) withDO(do gen.Dao) *creditCardDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_test_relation/query/customers.gen.go b/tests/.expect/dal_test_relation/query/customers.gen.go new file mode 100644 index 00000000..9219df28 --- /dev/null +++ b/tests/.expect/dal_test_relation/query/customers.gen.go @@ -0,0 +1,505 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { + _customer := customer{} + + _customer.customerDo.UseDB(db, opts...) + _customer.customerDo.UseModel(&model.Customer{}) + + tableName := _customer.customerDo.TableName() + _customer.ALL = field.NewAsterisk(tableName) + _customer.ID = field.NewInt64(tableName, "id") + _customer.CreatedAt = field.NewTime(tableName, "created_at") + _customer.UpdatedAt = field.NewTime(tableName, "updated_at") + _customer.DeletedAt = field.NewField(tableName, "deleted_at") + _customer.BankID = field.NewInt64(tableName, "bank_id") + _customer.Bank = customerHasOneBank{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Bank", "model.Bank"), + } + + _customer.CreditCards = customerHasManyCreditCards{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("CreditCards", "model.CreditCard"), + } + + _customer.fillFieldMap() + + return _customer +} + +type customer struct { + customerDo customerDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + BankID field.Int64 + Bank customerHasOneBank + + CreditCards customerHasManyCreditCards + + fieldMap map[string]field.Expr +} + +func (c customer) Table(newTableName string) *customer { + c.customerDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c customer) As(alias string) *customer { + c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *customer) updateTableName(table string) *customer { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *customer) WithContext(ctx context.Context) *customerDo { return c.customerDo.WithContext(ctx) } + +func (c customer) TableName() string { return c.customerDo.TableName() } + +func (c customer) Alias() string { return c.customerDo.Alias() } + +func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } + +func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *customer) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["bank_id"] = c.BankID +} + +func (c customer) clone(db *gorm.DB) customer { + c.customerDo.ReplaceConnPool(db.Statement.ConnPool) + c.Bank.db = db.Session(&gorm.Session{Initialized: true}) + c.Bank.db.Statement.ConnPool = db.Statement.ConnPool + c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) + c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool + return c +} + +func (c customer) replaceDB(db *gorm.DB) customer { + c.customerDo.ReplaceDB(db) + c.Bank.db = db.Session(&gorm.Session{}) + c.CreditCards.db = db.Session(&gorm.Session{}) + return c +} + +type customerHasOneBank struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { + return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasOneBankTx struct{ tx *gorm.Association } + +func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasOneBankTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasOneBankTx) Count() int64 { + return a.tx.Count() +} + +type customerHasManyCreditCards struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { + return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasManyCreditCardsTx struct{ tx *gorm.Association } + +func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasManyCreditCardsTx) Count() int64 { + return a.tx.Count() +} + +type customerDo struct{ gen.DO } + +func (c customerDo) Debug() *customerDo { + return c.withDO(c.DO.Debug()) +} + +func (c customerDo) WithContext(ctx context.Context) *customerDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c customerDo) ReadDB() *customerDo { + return c.Clauses(dbresolver.Read) +} + +func (c customerDo) WriteDB() *customerDo { + return c.Clauses(dbresolver.Write) +} + +func (c customerDo) Session(config *gorm.Session) *customerDo { + return c.withDO(c.DO.Session(config)) +} + +func (c customerDo) Clauses(conds ...clause.Expression) *customerDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c customerDo) Returning(value interface{}, columns ...string) *customerDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c customerDo) Not(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c customerDo) Or(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c customerDo) Select(conds ...field.Expr) *customerDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c customerDo) Where(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c customerDo) Order(conds ...field.Expr) *customerDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c customerDo) Distinct(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c customerDo) Omit(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c customerDo) Join(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c customerDo) Group(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c customerDo) Having(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c customerDo) Limit(limit int) *customerDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c customerDo) Offset(offset int) *customerDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *customerDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c customerDo) Unscoped() *customerDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c customerDo) Create(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c customerDo) Save(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c customerDo) First() (*model.Customer, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Take() (*model.Customer, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Last() (*model.Customer, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Find() ([]*model.Customer, error) { + result, err := c.DO.Find() + return result.([]*model.Customer), err +} + +func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { + buf := make([]*model.Customer, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c customerDo) Attrs(attrs ...field.AssignExpr) *customerDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c customerDo) Assign(attrs ...field.AssignExpr) *customerDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c customerDo) Joins(fields ...field.RelationField) *customerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c customerDo) Preload(fields ...field.RelationField) *customerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c customerDo) FirstOrInit() (*model.Customer, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FirstOrCreate() (*model.Customer, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c customerDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *customerDo) withDO(do gen.Dao) *customerDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_test_relation/query/gen.go b/tests/.expect/dal_test_relation/query/gen.go new file mode 100644 index 00000000..761abbfa --- /dev/null +++ b/tests/.expect/dal_test_relation/query/gen.go @@ -0,0 +1,119 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +var ( + Q = new(Query) + Bank *bank + CreditCard *creditCard + Customer *customer +) + +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) + Bank = &Q.Bank + CreditCard = &Q.CreditCard + Customer = &Q.Customer +} + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + Bank: newBank(db, opts...), + CreditCard: newCreditCard(db, opts...), + Customer: newCustomer(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + Bank bank + CreditCard creditCard + Customer customer +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + Bank: q.Bank.clone(db), + CreditCard: q.CreditCard.clone(db), + Customer: q.Customer.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + Bank: q.Bank.replaceDB(db), + CreditCard: q.CreditCard.replaceDB(db), + Customer: q.Customer.replaceDB(db), + } +} + +type queryCtx struct { + Bank *bankDo + CreditCard *creditCardDo + Customer *customerDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + Bank: q.Bank.WithContext(ctx), + CreditCard: q.CreditCard.WithContext(ctx), + Customer: q.Customer.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/tests/gen_test.go b/tests/gen_test.go index 69d1ad80..15dad843 100644 --- a/tests/gen_test.go +++ b/tests/gen_test.go @@ -5,12 +5,17 @@ import ( "sync" "gorm.io/gen/tests/.expect/dal_test/query" + relquery "gorm.io/gen/tests/.expect/dal_test_relation/query" ) -var useOnce sync.Once -var ctx = context.Background() +var ( + useOnce sync.Once + ctx = context.Background() +) func CRUDInit() { query.Use(DB) query.SetDefault(DB) + relquery.Use(DB) + relquery.SetDefault(DB) } diff --git a/tests/generate_test.go b/tests/generate_test.go index 9b1bec22..a05d5da9 100644 --- a/tests/generate_test.go +++ b/tests/generate_test.go @@ -62,7 +62,7 @@ var generateCase = map[string]func(dir string) *gen.Generator{ g.UseDB(DB) g.WithJSONTagNameStrategy(func(c string) string { return "-" }) g.ApplyBasic(g.GenerateAllTable(gen.FieldGORMTagReg(".", func(tag field.GormTag) field.GormTag { - //tag.Set("serialize","json") + // tag.Set("serialize","json") tag.Remove("comment") return tag }))...) @@ -118,6 +118,41 @@ var generateCase = map[string]func(dir string) *gen.Generator{ g.ApplyBasic(g.GenerateModelAs("users", DB.Config.NamingStrategy.SchemaName("users"), gen.WithMethod(diy_method.TestForWithMethod{}))) return g }, + generateDirPrefix + "dal_7": func(dir string) *gen.Generator { + g := gen.NewGenerator(gen.Config{ + OutPath: dir + "/query", + Mode: gen.WithDefaultQuery | gen.WithQueryInterface, + + WithUnitTest: true, + + FieldNullable: true, + FieldCoverable: true, + FieldWithIndexTag: true, + }) + g.UseDB(DB) + g.WithJSONTagNameStrategy(func(c string) string { return "-" }) + + banks := g.GenerateModel("banks") + creditCards := g.GenerateModel("credit_cards") + customers := g.GenerateModel("customers", + gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ + JSONTag: "bank", + GORMTag: field.GormTag{ + "foreignKey": []string{"BankID"}, + "references": []string{"ID"}, + }, + }), + gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ + JSONTag: "credit_cards", + GORMTag: field.GormTag{ + "foreignKey": []string{"CustomerRefer"}, + "references": []string{"ID"}, + }, + }), + ) + g.ApplyBasic(customers) + return g + }, } func TestGenerate(t *testing.T) { @@ -161,4 +196,31 @@ func TestGenerate_expect(t *testing.T) { g.UseDB(DB) g.ApplyBasic(g.GenerateAllTable()...) g.Execute() + + g = gen.NewGenerator(gen.Config{ + OutPath: expectDirPrefix + "dal_test_relation" + "/query", + Mode: gen.WithDefaultQuery, + }) + g.UseDB(DB) + + banks := g.GenerateModel("banks") + creditCards := g.GenerateModel("credit_cards") + customers := g.GenerateModel("customers", + gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ + JSONTag: "bank", + GORMTag: field.GormTag{ + "foreignKey": []string{"BankID"}, + "references": []string{"ID"}, + }, + }), + gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ + JSONTag: "credit_cards", + GORMTag: field.GormTag{ + "foreignKey": []string{"CustomerRefer"}, + "references": []string{"ID"}, + }, + }), + ) + g.ApplyBasic(customers, creditCards, banks) + g.Execute() } diff --git a/tests/transaction_test.go b/tests/transaction_test.go new file mode 100644 index 00000000..97d94325 --- /dev/null +++ b/tests/transaction_test.go @@ -0,0 +1,111 @@ +package tests_test + +import ( + "fmt" + "testing" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" + "gorm.io/gen/tests/.expect/dal_test_relation/query" +) + +func TestQuery_Transaction_Relation(t *testing.T) { + useOnce.Do(CRUDInit) + + t.Run("transaction has many", func(t *testing.T) { + if err := query.Q.Transaction(func(tx *query.Query) error { + c := tx.Customer + customer := &model.Customer{ + Bank: model.Bank{ + Name: "bank1", + Address: "bank-address1", + Scale: 1, + }, + CreditCards: []model.CreditCard{ + {Number: "num1"}, + {Number: "num2"}, + }, + } + if err := c.WithContext(ctx).Create(customer); err != nil { + return fmt.Errorf("create model fail: %s", err) + } + + got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if len(got.CreditCards) != 2 { + return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) + } + + if err := c.CreditCards.WithContext(ctx).Model(customer).Replace(&model.CreditCard{ + Number: "num_replace", + }); err != nil { + return fmt.Errorf("replace model fail: %s", err) + } + + got, err = c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if len(got.CreditCards) != 1 { + return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) + } + if got.CreditCards[0].Number != "num_replace" { + return fmt.Errorf("replace model fail, expect %q, got %q", "num_replace", got.CreditCards[0].Number) + } + + return nil + }); err != nil { + t.Errorf("transaction execute fail: %s", err) + } + }) + + t.Run("transaction has one", func(t *testing.T) { + if err := query.Q.Transaction(func(tx *query.Query) error { + c := tx.Customer + customer := &model.Customer{ + Bank: model.Bank{ + Name: "bank1", + Address: "bank-address1", + Scale: 1, + }, + CreditCards: []model.CreditCard{ + {Number: "num1"}, + {Number: "num2"}, + }, + } + + if err := c.WithContext(ctx).Create(customer); err != nil { + return fmt.Errorf("create model fail: %s", err) + } + if err := c.Bank.WithContext(ctx).Model(customer).Replace(&model.Bank{ + Name: "bank-replace", + Address: "bank-replace-address", + Scale: 2, + }); err != nil { + return fmt.Errorf("replace model fail: %s", err) + } + + got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if got.Bank.Name != "bank-replace" { + return fmt.Errorf("replace model fail, expect %q, got %q", "bank-replace", got.Bank.Name) + } + + return nil + }); err != nil { + t.Errorf("transaction execute fail: %s", err) + } + }) +} From 1e34d656c67efef647fa3ac906a1f5fd3f529667 Mon Sep 17 00:00:00 2001 From: miya-masa Date: Fri, 29 Nov 2024 17:39:30 +0900 Subject: [PATCH 3/4] Revert "fix(relation-tx): fix association bug(1070)" This reverts commit 08cab3983451a7181c032849c7b04b732e5172de. --- internal/template/struct.go | 31 +- tests/.expect/dal_7/model/banks.gen.go | 20 - tests/.expect/dal_7/model/credit_cards.gen.go | 29 - tests/.expect/dal_7/model/customers.gen.go | 29 - tests/.expect/dal_7/query/customers.gen.go | 567 ------------------ .../.expect/dal_7/query/customers.gen_test.go | 145 ----- tests/.expect/dal_7/query/gen.go | 103 ---- tests/.expect/dal_7/query/gen_test.go | 118 ---- .../dal_test_relation/model/banks.gen.go | 20 - .../model/credit_cards.gen.go | 29 - .../dal_test_relation/model/customers.gen.go | 29 - .../dal_test_relation/query/banks.gen.go | 339 ----------- .../query/credit_cards.gen.go | 353 ----------- .../dal_test_relation/query/customers.gen.go | 505 ---------------- tests/.expect/dal_test_relation/query/gen.go | 119 ---- tests/gen_test.go | 9 +- tests/generate_test.go | 64 +- tests/transaction_test.go | 111 ---- 18 files changed, 17 insertions(+), 2603 deletions(-) delete mode 100644 tests/.expect/dal_7/model/banks.gen.go delete mode 100644 tests/.expect/dal_7/model/credit_cards.gen.go delete mode 100644 tests/.expect/dal_7/model/customers.gen.go delete mode 100644 tests/.expect/dal_7/query/customers.gen.go delete mode 100644 tests/.expect/dal_7/query/customers.gen_test.go delete mode 100644 tests/.expect/dal_7/query/gen.go delete mode 100644 tests/.expect/dal_7/query/gen_test.go delete mode 100644 tests/.expect/dal_test_relation/model/banks.gen.go delete mode 100644 tests/.expect/dal_test_relation/model/credit_cards.gen.go delete mode 100644 tests/.expect/dal_test_relation/model/customers.gen.go delete mode 100644 tests/.expect/dal_test_relation/query/banks.gen.go delete mode 100644 tests/.expect/dal_test_relation/query/credit_cards.gen.go delete mode 100644 tests/.expect/dal_test_relation/query/customers.gen.go delete mode 100644 tests/.expect/dal_test_relation/query/gen.go delete mode 100644 tests/transaction_test.go diff --git a/internal/template/struct.go b/internal/template/struct.go index 867da13f..8b83a12e 100644 --- a/internal/template/struct.go +++ b/internal/template/struct.go @@ -18,10 +18,10 @@ const ( ` + fields + ` } ` + tableMethod + asMethond + updateFieldMethod + ` - + func ({{.S}} *{{.QueryStructName}}) WithContext(ctx context.Context) {{.ReturnObject}} { return {{.S}}.{{.QueryStructName}}Do.WithContext(ctx)} - func ({{.S}} {{.QueryStructName}}) TableName() string { return {{.S}}.{{.QueryStructName}}Do.TableName() } + func ({{.S}} {{.QueryStructName}}) TableName() string { return {{.S}}.{{.QueryStructName}}Do.TableName() } func ({{.S}} {{.QueryStructName}}) Alias() string { return {{.S}}.{{.QueryStructName}}Do.Alias() } @@ -37,10 +37,10 @@ const ( createMethod = ` func new{{.ModelStructName}}(db *gorm.DB, opts ...gen.DOOption) {{.QueryStructName}} { _{{.QueryStructName}} := {{.QueryStructName}}{} - + _{{.QueryStructName}}.{{.QueryStructName}}Do.UseDB(db,opts...) _{{.QueryStructName}}.{{.QueryStructName}}Do.UseModel(&{{.StructInfo.Package}}.{{.StructInfo.Type}}{}) - + tableName := _{{.QueryStructName}}.{{.QueryStructName}}Do.TableName() _{{$.QueryStructName}}.ALL = field.NewAsterisk(tableName) {{range .Fields -}} @@ -56,7 +56,7 @@ const ( {{end}} _{{$.QueryStructName}}.fillFieldMap() - + return _{{.QueryStructName}} } ` @@ -78,27 +78,27 @@ const ( fieldMap map[string]field.Expr ` tableMethod = ` -func ({{.S}} {{.QueryStructName}}) Table(newTableName string) *{{.QueryStructName}} { +func ({{.S}} {{.QueryStructName}}) Table(newTableName string) *{{.QueryStructName}} { {{.S}}.{{.QueryStructName}}Do.UseTable(newTableName) return {{.S}}.updateTableName(newTableName) } ` - asMethond = ` -func ({{.S}} {{.QueryStructName}}) As(alias string) *{{.QueryStructName}} { + asMethond = ` +func ({{.S}} {{.QueryStructName}}) As(alias string) *{{.QueryStructName}} { {{.S}}.{{.QueryStructName}}Do.DO = *({{.S}}.{{.QueryStructName}}Do.As(alias).(*gen.DO)) return {{.S}}.updateTableName(alias) } ` updateFieldMethod = ` -func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStructName}} { +func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStructName}} { {{.S}}.ALL = field.NewAsterisk(table) {{range .Fields -}} {{if not .IsRelation -}} {{- if .ColumnName -}}{{$.S}}.{{.Name}} = field.New{{.GenType}}(table, "{{.ColumnName}}"){{- end -}} {{end}} {{end}} - + {{.S}}.fillFieldMap() return {{.S}} @@ -107,16 +107,13 @@ func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStruc cloneMethod = ` func ({{.S}} {{.QueryStructName}}) clone(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool){{range .Fields }}{{if .IsRelation}} - {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{Initialized: true}) - {{$.S}}.{{.Relation.Name}}.db.Statement.ConnPool = db.Statement.ConnPool{{end}}{{end}} + {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool) return {{.S}} } ` replaceMethod = ` func ({{.S}} {{.QueryStructName}}) replaceDB(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db){{range .Fields}}{{if .IsRelation}} - {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{}){{end}}{{end}} + {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db) return {{.S}} } ` @@ -220,9 +217,9 @@ const ( relationStruct = ` type {{$.QueryStructName}}{{$relationship}}{{$relation.Name}} struct{ db *gorm.DB - + field.RelationField - + {{$relation.StructField}} } diff --git a/tests/.expect/dal_7/model/banks.gen.go b/tests/.expect/dal_7/model/banks.gen.go deleted file mode 100644 index 47ce6f40..00000000 --- a/tests/.expect/dal_7/model/banks.gen.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -const TableNameBank = "banks" - -// Bank mapped from table -type Bank struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - Name *string `gorm:"column:name" json:"-"` - Address *string `gorm:"column:address" json:"-"` - Scale *int64 `gorm:"column:scale" json:"-"` -} - -// TableName Bank's table name -func (*Bank) TableName() string { - return TableNameBank -} diff --git a/tests/.expect/dal_7/model/credit_cards.gen.go b/tests/.expect/dal_7/model/credit_cards.gen.go deleted file mode 100644 index 7a7d0202..00000000 --- a/tests/.expect/dal_7/model/credit_cards.gen.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -import ( - "time" - - "gorm.io/gorm" -) - -const TableNameCreditCard = "credit_cards" - -// CreditCard mapped from table -type CreditCard struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - CreatedAt *time.Time `gorm:"column:created_at" json:"-"` - UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_credit_cards_deleted_at,priority:1" json:"-"` - Number *string `gorm:"column:number" json:"-"` - CustomerRefer *int64 `gorm:"column:customer_refer" json:"-"` - BankID *int64 `gorm:"column:bank_id" json:"-"` -} - -// TableName CreditCard's table name -func (*CreditCard) TableName() string { - return TableNameCreditCard -} diff --git a/tests/.expect/dal_7/model/customers.gen.go b/tests/.expect/dal_7/model/customers.gen.go deleted file mode 100644 index ddbd7ada..00000000 --- a/tests/.expect/dal_7/model/customers.gen.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -import ( - "time" - - "gorm.io/gorm" -) - -const TableNameCustomer = "customers" - -// Customer mapped from table -type Customer struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - CreatedAt *time.Time `gorm:"column:created_at" json:"-"` - UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_customers_deleted_at,priority:1" json:"-"` - BankID *int64 `gorm:"column:bank_id" json:"-"` - Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` - CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` -} - -// TableName Customer's table name -func (*Customer) TableName() string { - return TableNameCustomer -} diff --git a/tests/.expect/dal_7/query/customers.gen.go b/tests/.expect/dal_7/query/customers.gen.go deleted file mode 100644 index a4dc3283..00000000 --- a/tests/.expect/dal_7/query/customers.gen.go +++ /dev/null @@ -1,567 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - - "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/schema" - - "gorm.io/gen" - "gorm.io/gen/field" - - "gorm.io/plugin/dbresolver" - - "gorm.io/gen/tests/.gen/dal_7/model" -) - -func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { - _customer := customer{} - - _customer.customerDo.UseDB(db, opts...) - _customer.customerDo.UseModel(&model.Customer{}) - - tableName := _customer.customerDo.TableName() - _customer.ALL = field.NewAsterisk(tableName) - _customer.ID = field.NewInt64(tableName, "id") - _customer.CreatedAt = field.NewTime(tableName, "created_at") - _customer.UpdatedAt = field.NewTime(tableName, "updated_at") - _customer.DeletedAt = field.NewField(tableName, "deleted_at") - _customer.BankID = field.NewInt64(tableName, "bank_id") - _customer.Bank = customerHasOneBank{ - db: db.Session(&gorm.Session{}), - - RelationField: field.NewRelation("Bank", "model.Bank"), - } - - _customer.CreditCards = customerHasManyCreditCards{ - db: db.Session(&gorm.Session{}), - - RelationField: field.NewRelation("CreditCards", "model.CreditCard"), - } - - _customer.fillFieldMap() - - return _customer -} - -type customer struct { - customerDo customerDo - - ALL field.Asterisk - ID field.Int64 - CreatedAt field.Time - UpdatedAt field.Time - DeletedAt field.Field - BankID field.Int64 - Bank customerHasOneBank - - CreditCards customerHasManyCreditCards - - fieldMap map[string]field.Expr -} - -func (c customer) Table(newTableName string) *customer { - c.customerDo.UseTable(newTableName) - return c.updateTableName(newTableName) -} - -func (c customer) As(alias string) *customer { - c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) - return c.updateTableName(alias) -} - -func (c *customer) updateTableName(table string) *customer { - c.ALL = field.NewAsterisk(table) - c.ID = field.NewInt64(table, "id") - c.CreatedAt = field.NewTime(table, "created_at") - c.UpdatedAt = field.NewTime(table, "updated_at") - c.DeletedAt = field.NewField(table, "deleted_at") - c.BankID = field.NewInt64(table, "bank_id") - - c.fillFieldMap() - - return c -} - -func (c *customer) WithContext(ctx context.Context) ICustomerDo { return c.customerDo.WithContext(ctx) } - -func (c customer) TableName() string { return c.customerDo.TableName() } - -func (c customer) Alias() string { return c.customerDo.Alias() } - -func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } - -func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { - _f, ok := c.fieldMap[fieldName] - if !ok || _f == nil { - return nil, false - } - _oe, ok := _f.(field.OrderExpr) - return _oe, ok -} - -func (c *customer) fillFieldMap() { - c.fieldMap = make(map[string]field.Expr, 7) - c.fieldMap["id"] = c.ID - c.fieldMap["created_at"] = c.CreatedAt - c.fieldMap["updated_at"] = c.UpdatedAt - c.fieldMap["deleted_at"] = c.DeletedAt - c.fieldMap["bank_id"] = c.BankID - -} - -func (c customer) clone(db *gorm.DB) customer { - c.customerDo.ReplaceConnPool(db.Statement.ConnPool) - c.Bank.db = db.Session(&gorm.Session{Initialized: true}) - c.Bank.db.Statement.ConnPool = db.Statement.ConnPool - c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) - c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool - return c -} - -func (c customer) replaceDB(db *gorm.DB) customer { - c.customerDo.ReplaceDB(db) - c.Bank.db = db.Session(&gorm.Session{}) - c.CreditCards.db = db.Session(&gorm.Session{}) - return c -} - -type customerHasOneBank struct { - db *gorm.DB - - field.RelationField -} - -func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { - if len(conds) == 0 { - return &a - } - - exprs := make([]clause.Expression, 0, len(conds)) - for _, cond := range conds { - exprs = append(exprs, cond.BeCond().(clause.Expression)) - } - a.db = a.db.Clauses(clause.Where{Exprs: exprs}) - return &a -} - -func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { - a.db = a.db.WithContext(ctx) - return &a -} - -func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { - a.db = a.db.Session(session) - return &a -} - -func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { - return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} -} - -type customerHasOneBankTx struct{ tx *gorm.Association } - -func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { - return result, a.tx.Find(&result) -} - -func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Append(targetValues...) -} - -func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Replace(targetValues...) -} - -func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Delete(targetValues...) -} - -func (a customerHasOneBankTx) Clear() error { - return a.tx.Clear() -} - -func (a customerHasOneBankTx) Count() int64 { - return a.tx.Count() -} - -type customerHasManyCreditCards struct { - db *gorm.DB - - field.RelationField -} - -func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { - if len(conds) == 0 { - return &a - } - - exprs := make([]clause.Expression, 0, len(conds)) - for _, cond := range conds { - exprs = append(exprs, cond.BeCond().(clause.Expression)) - } - a.db = a.db.Clauses(clause.Where{Exprs: exprs}) - return &a -} - -func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { - a.db = a.db.WithContext(ctx) - return &a -} - -func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { - a.db = a.db.Session(session) - return &a -} - -func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { - return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} -} - -type customerHasManyCreditCardsTx struct{ tx *gorm.Association } - -func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { - return result, a.tx.Find(&result) -} - -func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Append(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Replace(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Delete(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Clear() error { - return a.tx.Clear() -} - -func (a customerHasManyCreditCardsTx) Count() int64 { - return a.tx.Count() -} - -type customerDo struct{ gen.DO } - -type ICustomerDo interface { - gen.SubQuery - Debug() ICustomerDo - WithContext(ctx context.Context) ICustomerDo - WithResult(fc func(tx gen.Dao)) gen.ResultInfo - ReplaceDB(db *gorm.DB) - ReadDB() ICustomerDo - WriteDB() ICustomerDo - As(alias string) gen.Dao - Session(config *gorm.Session) ICustomerDo - Columns(cols ...field.Expr) gen.Columns - Clauses(conds ...clause.Expression) ICustomerDo - Not(conds ...gen.Condition) ICustomerDo - Or(conds ...gen.Condition) ICustomerDo - Select(conds ...field.Expr) ICustomerDo - Where(conds ...gen.Condition) ICustomerDo - Order(conds ...field.Expr) ICustomerDo - Distinct(cols ...field.Expr) ICustomerDo - Omit(cols ...field.Expr) ICustomerDo - Join(table schema.Tabler, on ...field.Expr) ICustomerDo - LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo - RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo - Group(cols ...field.Expr) ICustomerDo - Having(conds ...gen.Condition) ICustomerDo - Limit(limit int) ICustomerDo - Offset(offset int) ICustomerDo - Count() (count int64, err error) - Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo - Unscoped() ICustomerDo - Create(values ...*model.Customer) error - CreateInBatches(values []*model.Customer, batchSize int) error - Save(values ...*model.Customer) error - First() (*model.Customer, error) - Take() (*model.Customer, error) - Last() (*model.Customer, error) - Find() ([]*model.Customer, error) - FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) - FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error - Pluck(column field.Expr, dest interface{}) error - Delete(...*model.Customer) (info gen.ResultInfo, err error) - Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) - UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) - Updates(value interface{}) (info gen.ResultInfo, err error) - UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) - UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) - UpdateColumns(value interface{}) (info gen.ResultInfo, err error) - UpdateFrom(q gen.SubQuery) gen.Dao - Attrs(attrs ...field.AssignExpr) ICustomerDo - Assign(attrs ...field.AssignExpr) ICustomerDo - Joins(fields ...field.RelationField) ICustomerDo - Preload(fields ...field.RelationField) ICustomerDo - FirstOrInit() (*model.Customer, error) - FirstOrCreate() (*model.Customer, error) - FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) - ScanByPage(result interface{}, offset int, limit int) (count int64, err error) - Scan(result interface{}) (err error) - Returning(value interface{}, columns ...string) ICustomerDo - UnderlyingDB() *gorm.DB - schema.Tabler -} - -func (c customerDo) Debug() ICustomerDo { - return c.withDO(c.DO.Debug()) -} - -func (c customerDo) WithContext(ctx context.Context) ICustomerDo { - return c.withDO(c.DO.WithContext(ctx)) -} - -func (c customerDo) ReadDB() ICustomerDo { - return c.Clauses(dbresolver.Read) -} - -func (c customerDo) WriteDB() ICustomerDo { - return c.Clauses(dbresolver.Write) -} - -func (c customerDo) Session(config *gorm.Session) ICustomerDo { - return c.withDO(c.DO.Session(config)) -} - -func (c customerDo) Clauses(conds ...clause.Expression) ICustomerDo { - return c.withDO(c.DO.Clauses(conds...)) -} - -func (c customerDo) Returning(value interface{}, columns ...string) ICustomerDo { - return c.withDO(c.DO.Returning(value, columns...)) -} - -func (c customerDo) Not(conds ...gen.Condition) ICustomerDo { - return c.withDO(c.DO.Not(conds...)) -} - -func (c customerDo) Or(conds ...gen.Condition) ICustomerDo { - return c.withDO(c.DO.Or(conds...)) -} - -func (c customerDo) Select(conds ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Select(conds...)) -} - -func (c customerDo) Where(conds ...gen.Condition) ICustomerDo { - return c.withDO(c.DO.Where(conds...)) -} - -func (c customerDo) Order(conds ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Order(conds...)) -} - -func (c customerDo) Distinct(cols ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Distinct(cols...)) -} - -func (c customerDo) Omit(cols ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Omit(cols...)) -} - -func (c customerDo) Join(table schema.Tabler, on ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Join(table, on...)) -} - -func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { - return c.withDO(c.DO.LeftJoin(table, on...)) -} - -func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { - return c.withDO(c.DO.RightJoin(table, on...)) -} - -func (c customerDo) Group(cols ...field.Expr) ICustomerDo { - return c.withDO(c.DO.Group(cols...)) -} - -func (c customerDo) Having(conds ...gen.Condition) ICustomerDo { - return c.withDO(c.DO.Having(conds...)) -} - -func (c customerDo) Limit(limit int) ICustomerDo { - return c.withDO(c.DO.Limit(limit)) -} - -func (c customerDo) Offset(offset int) ICustomerDo { - return c.withDO(c.DO.Offset(offset)) -} - -func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo { - return c.withDO(c.DO.Scopes(funcs...)) -} - -func (c customerDo) Unscoped() ICustomerDo { - return c.withDO(c.DO.Unscoped()) -} - -func (c customerDo) Create(values ...*model.Customer) error { - if len(values) == 0 { - return nil - } - return c.DO.Create(values) -} - -func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { - return c.DO.CreateInBatches(values, batchSize) -} - -// Save : !!! underlying implementation is different with GORM -// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) -func (c customerDo) Save(values ...*model.Customer) error { - if len(values) == 0 { - return nil - } - return c.DO.Save(values) -} - -func (c customerDo) First() (*model.Customer, error) { - if result, err := c.DO.First(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Take() (*model.Customer, error) { - if result, err := c.DO.Take(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Last() (*model.Customer, error) { - if result, err := c.DO.Last(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Find() ([]*model.Customer, error) { - result, err := c.DO.Find() - return result.([]*model.Customer), err -} - -func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { - buf := make([]*model.Customer, 0, batchSize) - err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { - defer func() { results = append(results, buf...) }() - return fc(tx, batch) - }) - return results, err -} - -func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { - return c.DO.FindInBatches(result, batchSize, fc) -} - -func (c customerDo) Attrs(attrs ...field.AssignExpr) ICustomerDo { - return c.withDO(c.DO.Attrs(attrs...)) -} - -func (c customerDo) Assign(attrs ...field.AssignExpr) ICustomerDo { - return c.withDO(c.DO.Assign(attrs...)) -} - -func (c customerDo) Joins(fields ...field.RelationField) ICustomerDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Joins(_f)) - } - return &c -} - -func (c customerDo) Preload(fields ...field.RelationField) ICustomerDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Preload(_f)) - } - return &c -} - -func (c customerDo) FirstOrInit() (*model.Customer, error) { - if result, err := c.DO.FirstOrInit(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) FirstOrCreate() (*model.Customer, error) { - if result, err := c.DO.FirstOrCreate(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { - result, err = c.Offset(offset).Limit(limit).Find() - if err != nil { - return - } - - if size := len(result); 0 < limit && 0 < size && size < limit { - count = int64(size + offset) - return - } - - count, err = c.Offset(-1).Limit(-1).Count() - return -} - -func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { - count, err = c.Count() - if err != nil { - return - } - - err = c.Offset(offset).Limit(limit).Scan(result) - return -} - -func (c customerDo) Scan(result interface{}) (err error) { - return c.DO.Scan(result) -} - -func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { - return c.DO.Delete(models) -} - -func (c *customerDo) withDO(do gen.Dao) *customerDo { - c.DO = *do.(*gen.DO) - return c -} diff --git a/tests/.expect/dal_7/query/customers.gen_test.go b/tests/.expect/dal_7/query/customers.gen_test.go deleted file mode 100644 index f625fdca..00000000 --- a/tests/.expect/dal_7/query/customers.gen_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - "fmt" - "testing" - - "gorm.io/gen" - "gorm.io/gen/field" - "gorm.io/gen/tests/.gen/dal_7/model" - "gorm.io/gorm/clause" -) - -func init() { - InitializeDB() - err := _gen_test_db.AutoMigrate(&model.Customer{}) - if err != nil { - fmt.Printf("Error: AutoMigrate(&model.Customer{}) fail: %s", err) - } -} - -func Test_customerQuery(t *testing.T) { - customer := newCustomer(_gen_test_db) - customer = *customer.As(customer.TableName()) - _do := customer.WithContext(context.Background()).Debug() - - primaryKey := field.NewString(customer.TableName(), clause.PrimaryKey) - _, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete() - if err != nil { - t.Error("clean table fail:", err) - return - } - - _, ok := customer.GetFieldByName("") - if ok { - t.Error("GetFieldByName(\"\") from customer success") - } - - err = _do.Create(&model.Customer{}) - if err != nil { - t.Error("create item in table fail:", err) - } - - err = _do.Save(&model.Customer{}) - if err != nil { - t.Error("create item in table fail:", err) - } - - err = _do.CreateInBatches([]*model.Customer{{}, {}}, 10) - if err != nil { - t.Error("create item in table fail:", err) - } - - _, err = _do.Select(customer.ALL).Take() - if err != nil { - t.Error("Take() on table fail:", err) - } - - _, err = _do.First() - if err != nil { - t.Error("First() on table fail:", err) - } - - _, err = _do.Last() - if err != nil { - t.Error("First() on table fail:", err) - } - - _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatch() on table fail:", err) - } - - err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*model.Customer{}, 10, func(tx gen.Dao, batch int) error { return nil }) - if err != nil { - t.Error("FindInBatches() on table fail:", err) - } - - _, err = _do.Select(customer.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() - if err != nil { - t.Error("Find() on table fail:", err) - } - - _, err = _do.Distinct(primaryKey).Take() - if err != nil { - t.Error("select Distinct() on table fail:", err) - } - - _, err = _do.Select(customer.ALL).Omit(primaryKey).Take() - if err != nil { - t.Error("Omit() on table fail:", err) - } - - _, err = _do.Group(primaryKey).Find() - if err != nil { - t.Error("Group() on table fail:", err) - } - - _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() - if err != nil { - t.Error("Scopes() on table fail:", err) - } - - _, _, err = _do.FindByPage(0, 1) - if err != nil { - t.Error("FindByPage() on table fail:", err) - } - - _, err = _do.ScanByPage(&model.Customer{}, 0, 1) - if err != nil { - t.Error("ScanByPage() on table fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() - if err != nil { - t.Error("FirstOrInit() on table fail:", err) - } - - _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() - if err != nil { - t.Error("FirstOrCreate() on table fail:", err) - } - - var _a _another - var _aPK = field.NewString(_a.TableName(), "id") - - err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("Join() on table fail:", err) - } - - err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) - if err != nil { - t.Error("LeftJoin() on table fail:", err) - } - - _, err = _do.Not().Or().Clauses().Take() - if err != nil { - t.Error("Not/Or/Clauses on table fail:", err) - } -} diff --git a/tests/.expect/dal_7/query/gen.go b/tests/.expect/dal_7/query/gen.go deleted file mode 100644 index 11cd3da4..00000000 --- a/tests/.expect/dal_7/query/gen.go +++ /dev/null @@ -1,103 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - "database/sql" - - "gorm.io/gorm" - - "gorm.io/gen" - - "gorm.io/plugin/dbresolver" -) - -var ( - Q = new(Query) - Customer *customer -) - -func SetDefault(db *gorm.DB, opts ...gen.DOOption) { - *Q = *Use(db, opts...) - Customer = &Q.Customer -} - -func Use(db *gorm.DB, opts ...gen.DOOption) *Query { - return &Query{ - db: db, - Customer: newCustomer(db, opts...), - } -} - -type Query struct { - db *gorm.DB - - Customer customer -} - -func (q *Query) Available() bool { return q.db != nil } - -func (q *Query) clone(db *gorm.DB) *Query { - return &Query{ - db: db, - Customer: q.Customer.clone(db), - } -} - -func (q *Query) ReadDB() *Query { - return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) -} - -func (q *Query) WriteDB() *Query { - return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) -} - -func (q *Query) ReplaceDB(db *gorm.DB) *Query { - return &Query{ - db: db, - Customer: q.Customer.replaceDB(db), - } -} - -type queryCtx struct { - Customer ICustomerDo -} - -func (q *Query) WithContext(ctx context.Context) *queryCtx { - return &queryCtx{ - Customer: q.Customer.WithContext(ctx), - } -} - -func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { - return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) -} - -func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { - tx := q.db.Begin(opts...) - return &QueryTx{Query: q.clone(tx), Error: tx.Error} -} - -type QueryTx struct { - *Query - Error error -} - -func (q *QueryTx) Commit() error { - return q.db.Commit().Error -} - -func (q *QueryTx) Rollback() error { - return q.db.Rollback().Error -} - -func (q *QueryTx) SavePoint(name string) error { - return q.db.SavePoint(name).Error -} - -func (q *QueryTx) RollbackTo(name string) error { - return q.db.RollbackTo(name).Error -} diff --git a/tests/.expect/dal_7/query/gen_test.go b/tests/.expect/dal_7/query/gen_test.go deleted file mode 100644 index 7e81714a..00000000 --- a/tests/.expect/dal_7/query/gen_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - "fmt" - "reflect" - "sync" - "testing" - - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -type Input struct { - Args []interface{} -} - -type Expectation struct { - Ret []interface{} -} - -type TestCase struct { - Input - Expectation -} - -const _gen_test_db_name = "gen_test.db" - -var _gen_test_db *gorm.DB -var _gen_test_once sync.Once - -func init() { - InitializeDB() - _gen_test_db.AutoMigrate(&_another{}) -} - -func InitializeDB() { - _gen_test_once.Do(func() { - var err error - _gen_test_db, err = gorm.Open(sqlite.Open(_gen_test_db_name), &gorm.Config{}) - if err != nil { - panic(fmt.Errorf("open sqlite %q fail: %w", _gen_test_db_name, err)) - } - }) -} - -func assert(t *testing.T, methodName string, res, exp interface{}) { - if !reflect.DeepEqual(res, exp) { - t.Errorf("%v() gotResult = %v, want %v", methodName, res, exp) - } -} - -type _another struct { - ID uint64 `gorm:"primaryKey"` -} - -func (*_another) TableName() string { return "another_for_unit_test" } - -func Test_Available(t *testing.T) { - if !Use(_gen_test_db).Available() { - t.Errorf("query.Available() == false") - } -} - -func Test_WithContext(t *testing.T) { - query := Use(_gen_test_db) - if !query.Available() { - t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") - } - - type Content string - var key, value Content = "gen_tag", "unit_test" - qCtx := query.WithContext(context.WithValue(context.Background(), key, value)) - - for _, ctx := range []context.Context{ - qCtx.Customer.UnderlyingDB().Statement.Context, - } { - if v := ctx.Value(key); v != value { - t.Errorf("get value from context fail, expect %q, got %q", value, v) - } - } -} - -func Test_Transaction(t *testing.T) { - query := Use(_gen_test_db) - if !query.Available() { - t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") - } - - err := query.Transaction(func(tx *Query) error { return nil }) - if err != nil { - t.Errorf("query.Transaction execute fail: %s", err) - } - - tx := query.Begin() - - err = tx.SavePoint("point") - if err != nil { - t.Errorf("query tx SavePoint fail: %s", err) - } - err = tx.RollbackTo("point") - if err != nil { - t.Errorf("query tx RollbackTo fail: %s", err) - } - err = tx.Commit() - if err != nil { - t.Errorf("query tx Commit fail: %s", err) - } - - err = query.Begin().Rollback() - if err != nil { - t.Errorf("query tx Rollback fail: %s", err) - } -} diff --git a/tests/.expect/dal_test_relation/model/banks.gen.go b/tests/.expect/dal_test_relation/model/banks.gen.go deleted file mode 100644 index 689bd855..00000000 --- a/tests/.expect/dal_test_relation/model/banks.gen.go +++ /dev/null @@ -1,20 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -const TableNameBank = "banks" - -// Bank mapped from table -type Bank struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` - Name string `gorm:"column:name" json:"name"` - Address string `gorm:"column:address" json:"address"` - Scale int64 `gorm:"column:scale" json:"scale"` -} - -// TableName Bank's table name -func (*Bank) TableName() string { - return TableNameBank -} diff --git a/tests/.expect/dal_test_relation/model/credit_cards.gen.go b/tests/.expect/dal_test_relation/model/credit_cards.gen.go deleted file mode 100644 index 427684c0..00000000 --- a/tests/.expect/dal_test_relation/model/credit_cards.gen.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -import ( - "time" - - "gorm.io/gorm" -) - -const TableNameCreditCard = "credit_cards" - -// CreditCard mapped from table -type CreditCard struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` - CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` - UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` - Number string `gorm:"column:number" json:"number"` - CustomerRefer int64 `gorm:"column:customer_refer" json:"customer_refer"` - BankID int64 `gorm:"column:bank_id" json:"bank_id"` -} - -// TableName CreditCard's table name -func (*CreditCard) TableName() string { - return TableNameCreditCard -} diff --git a/tests/.expect/dal_test_relation/model/customers.gen.go b/tests/.expect/dal_test_relation/model/customers.gen.go deleted file mode 100644 index d59e6dde..00000000 --- a/tests/.expect/dal_test_relation/model/customers.gen.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package model - -import ( - "time" - - "gorm.io/gorm" -) - -const TableNameCustomer = "customers" - -// Customer mapped from table -type Customer struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` - CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` - UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` - DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` - BankID int64 `gorm:"column:bank_id" json:"bank_id"` - Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` - CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` -} - -// TableName Customer's table name -func (*Customer) TableName() string { - return TableNameCustomer -} diff --git a/tests/.expect/dal_test_relation/query/banks.gen.go b/tests/.expect/dal_test_relation/query/banks.gen.go deleted file mode 100644 index 2a5a334d..00000000 --- a/tests/.expect/dal_test_relation/query/banks.gen.go +++ /dev/null @@ -1,339 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - - "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/schema" - - "gorm.io/gen" - "gorm.io/gen/field" - - "gorm.io/plugin/dbresolver" - - "gorm.io/gen/tests/.expect/dal_test_relation/model" -) - -func newBank(db *gorm.DB, opts ...gen.DOOption) bank { - _bank := bank{} - - _bank.bankDo.UseDB(db, opts...) - _bank.bankDo.UseModel(&model.Bank{}) - - tableName := _bank.bankDo.TableName() - _bank.ALL = field.NewAsterisk(tableName) - _bank.ID = field.NewInt64(tableName, "id") - _bank.Name = field.NewString(tableName, "name") - _bank.Address = field.NewString(tableName, "address") - _bank.Scale = field.NewInt64(tableName, "scale") - - _bank.fillFieldMap() - - return _bank -} - -type bank struct { - bankDo bankDo - - ALL field.Asterisk - ID field.Int64 - Name field.String - Address field.String - Scale field.Int64 - - fieldMap map[string]field.Expr -} - -func (b bank) Table(newTableName string) *bank { - b.bankDo.UseTable(newTableName) - return b.updateTableName(newTableName) -} - -func (b bank) As(alias string) *bank { - b.bankDo.DO = *(b.bankDo.As(alias).(*gen.DO)) - return b.updateTableName(alias) -} - -func (b *bank) updateTableName(table string) *bank { - b.ALL = field.NewAsterisk(table) - b.ID = field.NewInt64(table, "id") - b.Name = field.NewString(table, "name") - b.Address = field.NewString(table, "address") - b.Scale = field.NewInt64(table, "scale") - - b.fillFieldMap() - - return b -} - -func (b *bank) WithContext(ctx context.Context) *bankDo { return b.bankDo.WithContext(ctx) } - -func (b bank) TableName() string { return b.bankDo.TableName() } - -func (b bank) Alias() string { return b.bankDo.Alias() } - -func (b bank) Columns(cols ...field.Expr) gen.Columns { return b.bankDo.Columns(cols...) } - -func (b *bank) GetFieldByName(fieldName string) (field.OrderExpr, bool) { - _f, ok := b.fieldMap[fieldName] - if !ok || _f == nil { - return nil, false - } - _oe, ok := _f.(field.OrderExpr) - return _oe, ok -} - -func (b *bank) fillFieldMap() { - b.fieldMap = make(map[string]field.Expr, 4) - b.fieldMap["id"] = b.ID - b.fieldMap["name"] = b.Name - b.fieldMap["address"] = b.Address - b.fieldMap["scale"] = b.Scale -} - -func (b bank) clone(db *gorm.DB) bank { - b.bankDo.ReplaceConnPool(db.Statement.ConnPool) - return b -} - -func (b bank) replaceDB(db *gorm.DB) bank { - b.bankDo.ReplaceDB(db) - return b -} - -type bankDo struct{ gen.DO } - -func (b bankDo) Debug() *bankDo { - return b.withDO(b.DO.Debug()) -} - -func (b bankDo) WithContext(ctx context.Context) *bankDo { - return b.withDO(b.DO.WithContext(ctx)) -} - -func (b bankDo) ReadDB() *bankDo { - return b.Clauses(dbresolver.Read) -} - -func (b bankDo) WriteDB() *bankDo { - return b.Clauses(dbresolver.Write) -} - -func (b bankDo) Session(config *gorm.Session) *bankDo { - return b.withDO(b.DO.Session(config)) -} - -func (b bankDo) Clauses(conds ...clause.Expression) *bankDo { - return b.withDO(b.DO.Clauses(conds...)) -} - -func (b bankDo) Returning(value interface{}, columns ...string) *bankDo { - return b.withDO(b.DO.Returning(value, columns...)) -} - -func (b bankDo) Not(conds ...gen.Condition) *bankDo { - return b.withDO(b.DO.Not(conds...)) -} - -func (b bankDo) Or(conds ...gen.Condition) *bankDo { - return b.withDO(b.DO.Or(conds...)) -} - -func (b bankDo) Select(conds ...field.Expr) *bankDo { - return b.withDO(b.DO.Select(conds...)) -} - -func (b bankDo) Where(conds ...gen.Condition) *bankDo { - return b.withDO(b.DO.Where(conds...)) -} - -func (b bankDo) Order(conds ...field.Expr) *bankDo { - return b.withDO(b.DO.Order(conds...)) -} - -func (b bankDo) Distinct(cols ...field.Expr) *bankDo { - return b.withDO(b.DO.Distinct(cols...)) -} - -func (b bankDo) Omit(cols ...field.Expr) *bankDo { - return b.withDO(b.DO.Omit(cols...)) -} - -func (b bankDo) Join(table schema.Tabler, on ...field.Expr) *bankDo { - return b.withDO(b.DO.Join(table, on...)) -} - -func (b bankDo) LeftJoin(table schema.Tabler, on ...field.Expr) *bankDo { - return b.withDO(b.DO.LeftJoin(table, on...)) -} - -func (b bankDo) RightJoin(table schema.Tabler, on ...field.Expr) *bankDo { - return b.withDO(b.DO.RightJoin(table, on...)) -} - -func (b bankDo) Group(cols ...field.Expr) *bankDo { - return b.withDO(b.DO.Group(cols...)) -} - -func (b bankDo) Having(conds ...gen.Condition) *bankDo { - return b.withDO(b.DO.Having(conds...)) -} - -func (b bankDo) Limit(limit int) *bankDo { - return b.withDO(b.DO.Limit(limit)) -} - -func (b bankDo) Offset(offset int) *bankDo { - return b.withDO(b.DO.Offset(offset)) -} - -func (b bankDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *bankDo { - return b.withDO(b.DO.Scopes(funcs...)) -} - -func (b bankDo) Unscoped() *bankDo { - return b.withDO(b.DO.Unscoped()) -} - -func (b bankDo) Create(values ...*model.Bank) error { - if len(values) == 0 { - return nil - } - return b.DO.Create(values) -} - -func (b bankDo) CreateInBatches(values []*model.Bank, batchSize int) error { - return b.DO.CreateInBatches(values, batchSize) -} - -// Save : !!! underlying implementation is different with GORM -// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) -func (b bankDo) Save(values ...*model.Bank) error { - if len(values) == 0 { - return nil - } - return b.DO.Save(values) -} - -func (b bankDo) First() (*model.Bank, error) { - if result, err := b.DO.First(); err != nil { - return nil, err - } else { - return result.(*model.Bank), nil - } -} - -func (b bankDo) Take() (*model.Bank, error) { - if result, err := b.DO.Take(); err != nil { - return nil, err - } else { - return result.(*model.Bank), nil - } -} - -func (b bankDo) Last() (*model.Bank, error) { - if result, err := b.DO.Last(); err != nil { - return nil, err - } else { - return result.(*model.Bank), nil - } -} - -func (b bankDo) Find() ([]*model.Bank, error) { - result, err := b.DO.Find() - return result.([]*model.Bank), err -} - -func (b bankDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Bank, err error) { - buf := make([]*model.Bank, 0, batchSize) - err = b.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { - defer func() { results = append(results, buf...) }() - return fc(tx, batch) - }) - return results, err -} - -func (b bankDo) FindInBatches(result *[]*model.Bank, batchSize int, fc func(tx gen.Dao, batch int) error) error { - return b.DO.FindInBatches(result, batchSize, fc) -} - -func (b bankDo) Attrs(attrs ...field.AssignExpr) *bankDo { - return b.withDO(b.DO.Attrs(attrs...)) -} - -func (b bankDo) Assign(attrs ...field.AssignExpr) *bankDo { - return b.withDO(b.DO.Assign(attrs...)) -} - -func (b bankDo) Joins(fields ...field.RelationField) *bankDo { - for _, _f := range fields { - b = *b.withDO(b.DO.Joins(_f)) - } - return &b -} - -func (b bankDo) Preload(fields ...field.RelationField) *bankDo { - for _, _f := range fields { - b = *b.withDO(b.DO.Preload(_f)) - } - return &b -} - -func (b bankDo) FirstOrInit() (*model.Bank, error) { - if result, err := b.DO.FirstOrInit(); err != nil { - return nil, err - } else { - return result.(*model.Bank), nil - } -} - -func (b bankDo) FirstOrCreate() (*model.Bank, error) { - if result, err := b.DO.FirstOrCreate(); err != nil { - return nil, err - } else { - return result.(*model.Bank), nil - } -} - -func (b bankDo) FindByPage(offset int, limit int) (result []*model.Bank, count int64, err error) { - result, err = b.Offset(offset).Limit(limit).Find() - if err != nil { - return - } - - if size := len(result); 0 < limit && 0 < size && size < limit { - count = int64(size + offset) - return - } - - count, err = b.Offset(-1).Limit(-1).Count() - return -} - -func (b bankDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { - count, err = b.Count() - if err != nil { - return - } - - err = b.Offset(offset).Limit(limit).Scan(result) - return -} - -func (b bankDo) Scan(result interface{}) (err error) { - return b.DO.Scan(result) -} - -func (b bankDo) Delete(models ...*model.Bank) (result gen.ResultInfo, err error) { - return b.DO.Delete(models) -} - -func (b *bankDo) withDO(do gen.Dao) *bankDo { - b.DO = *do.(*gen.DO) - return b -} diff --git a/tests/.expect/dal_test_relation/query/credit_cards.gen.go b/tests/.expect/dal_test_relation/query/credit_cards.gen.go deleted file mode 100644 index 5d12e6cb..00000000 --- a/tests/.expect/dal_test_relation/query/credit_cards.gen.go +++ /dev/null @@ -1,353 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - - "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/schema" - - "gorm.io/gen" - "gorm.io/gen/field" - - "gorm.io/plugin/dbresolver" - - "gorm.io/gen/tests/.expect/dal_test_relation/model" -) - -func newCreditCard(db *gorm.DB, opts ...gen.DOOption) creditCard { - _creditCard := creditCard{} - - _creditCard.creditCardDo.UseDB(db, opts...) - _creditCard.creditCardDo.UseModel(&model.CreditCard{}) - - tableName := _creditCard.creditCardDo.TableName() - _creditCard.ALL = field.NewAsterisk(tableName) - _creditCard.ID = field.NewInt64(tableName, "id") - _creditCard.CreatedAt = field.NewTime(tableName, "created_at") - _creditCard.UpdatedAt = field.NewTime(tableName, "updated_at") - _creditCard.DeletedAt = field.NewField(tableName, "deleted_at") - _creditCard.Number = field.NewString(tableName, "number") - _creditCard.CustomerRefer = field.NewInt64(tableName, "customer_refer") - _creditCard.BankID = field.NewInt64(tableName, "bank_id") - - _creditCard.fillFieldMap() - - return _creditCard -} - -type creditCard struct { - creditCardDo creditCardDo - - ALL field.Asterisk - ID field.Int64 - CreatedAt field.Time - UpdatedAt field.Time - DeletedAt field.Field - Number field.String - CustomerRefer field.Int64 - BankID field.Int64 - - fieldMap map[string]field.Expr -} - -func (c creditCard) Table(newTableName string) *creditCard { - c.creditCardDo.UseTable(newTableName) - return c.updateTableName(newTableName) -} - -func (c creditCard) As(alias string) *creditCard { - c.creditCardDo.DO = *(c.creditCardDo.As(alias).(*gen.DO)) - return c.updateTableName(alias) -} - -func (c *creditCard) updateTableName(table string) *creditCard { - c.ALL = field.NewAsterisk(table) - c.ID = field.NewInt64(table, "id") - c.CreatedAt = field.NewTime(table, "created_at") - c.UpdatedAt = field.NewTime(table, "updated_at") - c.DeletedAt = field.NewField(table, "deleted_at") - c.Number = field.NewString(table, "number") - c.CustomerRefer = field.NewInt64(table, "customer_refer") - c.BankID = field.NewInt64(table, "bank_id") - - c.fillFieldMap() - - return c -} - -func (c *creditCard) WithContext(ctx context.Context) *creditCardDo { - return c.creditCardDo.WithContext(ctx) -} - -func (c creditCard) TableName() string { return c.creditCardDo.TableName() } - -func (c creditCard) Alias() string { return c.creditCardDo.Alias() } - -func (c creditCard) Columns(cols ...field.Expr) gen.Columns { return c.creditCardDo.Columns(cols...) } - -func (c *creditCard) GetFieldByName(fieldName string) (field.OrderExpr, bool) { - _f, ok := c.fieldMap[fieldName] - if !ok || _f == nil { - return nil, false - } - _oe, ok := _f.(field.OrderExpr) - return _oe, ok -} - -func (c *creditCard) fillFieldMap() { - c.fieldMap = make(map[string]field.Expr, 7) - c.fieldMap["id"] = c.ID - c.fieldMap["created_at"] = c.CreatedAt - c.fieldMap["updated_at"] = c.UpdatedAt - c.fieldMap["deleted_at"] = c.DeletedAt - c.fieldMap["number"] = c.Number - c.fieldMap["customer_refer"] = c.CustomerRefer - c.fieldMap["bank_id"] = c.BankID -} - -func (c creditCard) clone(db *gorm.DB) creditCard { - c.creditCardDo.ReplaceConnPool(db.Statement.ConnPool) - return c -} - -func (c creditCard) replaceDB(db *gorm.DB) creditCard { - c.creditCardDo.ReplaceDB(db) - return c -} - -type creditCardDo struct{ gen.DO } - -func (c creditCardDo) Debug() *creditCardDo { - return c.withDO(c.DO.Debug()) -} - -func (c creditCardDo) WithContext(ctx context.Context) *creditCardDo { - return c.withDO(c.DO.WithContext(ctx)) -} - -func (c creditCardDo) ReadDB() *creditCardDo { - return c.Clauses(dbresolver.Read) -} - -func (c creditCardDo) WriteDB() *creditCardDo { - return c.Clauses(dbresolver.Write) -} - -func (c creditCardDo) Session(config *gorm.Session) *creditCardDo { - return c.withDO(c.DO.Session(config)) -} - -func (c creditCardDo) Clauses(conds ...clause.Expression) *creditCardDo { - return c.withDO(c.DO.Clauses(conds...)) -} - -func (c creditCardDo) Returning(value interface{}, columns ...string) *creditCardDo { - return c.withDO(c.DO.Returning(value, columns...)) -} - -func (c creditCardDo) Not(conds ...gen.Condition) *creditCardDo { - return c.withDO(c.DO.Not(conds...)) -} - -func (c creditCardDo) Or(conds ...gen.Condition) *creditCardDo { - return c.withDO(c.DO.Or(conds...)) -} - -func (c creditCardDo) Select(conds ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Select(conds...)) -} - -func (c creditCardDo) Where(conds ...gen.Condition) *creditCardDo { - return c.withDO(c.DO.Where(conds...)) -} - -func (c creditCardDo) Order(conds ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Order(conds...)) -} - -func (c creditCardDo) Distinct(cols ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Distinct(cols...)) -} - -func (c creditCardDo) Omit(cols ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Omit(cols...)) -} - -func (c creditCardDo) Join(table schema.Tabler, on ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Join(table, on...)) -} - -func (c creditCardDo) LeftJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { - return c.withDO(c.DO.LeftJoin(table, on...)) -} - -func (c creditCardDo) RightJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { - return c.withDO(c.DO.RightJoin(table, on...)) -} - -func (c creditCardDo) Group(cols ...field.Expr) *creditCardDo { - return c.withDO(c.DO.Group(cols...)) -} - -func (c creditCardDo) Having(conds ...gen.Condition) *creditCardDo { - return c.withDO(c.DO.Having(conds...)) -} - -func (c creditCardDo) Limit(limit int) *creditCardDo { - return c.withDO(c.DO.Limit(limit)) -} - -func (c creditCardDo) Offset(offset int) *creditCardDo { - return c.withDO(c.DO.Offset(offset)) -} - -func (c creditCardDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *creditCardDo { - return c.withDO(c.DO.Scopes(funcs...)) -} - -func (c creditCardDo) Unscoped() *creditCardDo { - return c.withDO(c.DO.Unscoped()) -} - -func (c creditCardDo) Create(values ...*model.CreditCard) error { - if len(values) == 0 { - return nil - } - return c.DO.Create(values) -} - -func (c creditCardDo) CreateInBatches(values []*model.CreditCard, batchSize int) error { - return c.DO.CreateInBatches(values, batchSize) -} - -// Save : !!! underlying implementation is different with GORM -// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) -func (c creditCardDo) Save(values ...*model.CreditCard) error { - if len(values) == 0 { - return nil - } - return c.DO.Save(values) -} - -func (c creditCardDo) First() (*model.CreditCard, error) { - if result, err := c.DO.First(); err != nil { - return nil, err - } else { - return result.(*model.CreditCard), nil - } -} - -func (c creditCardDo) Take() (*model.CreditCard, error) { - if result, err := c.DO.Take(); err != nil { - return nil, err - } else { - return result.(*model.CreditCard), nil - } -} - -func (c creditCardDo) Last() (*model.CreditCard, error) { - if result, err := c.DO.Last(); err != nil { - return nil, err - } else { - return result.(*model.CreditCard), nil - } -} - -func (c creditCardDo) Find() ([]*model.CreditCard, error) { - result, err := c.DO.Find() - return result.([]*model.CreditCard), err -} - -func (c creditCardDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.CreditCard, err error) { - buf := make([]*model.CreditCard, 0, batchSize) - err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { - defer func() { results = append(results, buf...) }() - return fc(tx, batch) - }) - return results, err -} - -func (c creditCardDo) FindInBatches(result *[]*model.CreditCard, batchSize int, fc func(tx gen.Dao, batch int) error) error { - return c.DO.FindInBatches(result, batchSize, fc) -} - -func (c creditCardDo) Attrs(attrs ...field.AssignExpr) *creditCardDo { - return c.withDO(c.DO.Attrs(attrs...)) -} - -func (c creditCardDo) Assign(attrs ...field.AssignExpr) *creditCardDo { - return c.withDO(c.DO.Assign(attrs...)) -} - -func (c creditCardDo) Joins(fields ...field.RelationField) *creditCardDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Joins(_f)) - } - return &c -} - -func (c creditCardDo) Preload(fields ...field.RelationField) *creditCardDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Preload(_f)) - } - return &c -} - -func (c creditCardDo) FirstOrInit() (*model.CreditCard, error) { - if result, err := c.DO.FirstOrInit(); err != nil { - return nil, err - } else { - return result.(*model.CreditCard), nil - } -} - -func (c creditCardDo) FirstOrCreate() (*model.CreditCard, error) { - if result, err := c.DO.FirstOrCreate(); err != nil { - return nil, err - } else { - return result.(*model.CreditCard), nil - } -} - -func (c creditCardDo) FindByPage(offset int, limit int) (result []*model.CreditCard, count int64, err error) { - result, err = c.Offset(offset).Limit(limit).Find() - if err != nil { - return - } - - if size := len(result); 0 < limit && 0 < size && size < limit { - count = int64(size + offset) - return - } - - count, err = c.Offset(-1).Limit(-1).Count() - return -} - -func (c creditCardDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { - count, err = c.Count() - if err != nil { - return - } - - err = c.Offset(offset).Limit(limit).Scan(result) - return -} - -func (c creditCardDo) Scan(result interface{}) (err error) { - return c.DO.Scan(result) -} - -func (c creditCardDo) Delete(models ...*model.CreditCard) (result gen.ResultInfo, err error) { - return c.DO.Delete(models) -} - -func (c *creditCardDo) withDO(do gen.Dao) *creditCardDo { - c.DO = *do.(*gen.DO) - return c -} diff --git a/tests/.expect/dal_test_relation/query/customers.gen.go b/tests/.expect/dal_test_relation/query/customers.gen.go deleted file mode 100644 index 9219df28..00000000 --- a/tests/.expect/dal_test_relation/query/customers.gen.go +++ /dev/null @@ -1,505 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - - "gorm.io/gorm" - "gorm.io/gorm/clause" - "gorm.io/gorm/schema" - - "gorm.io/gen" - "gorm.io/gen/field" - - "gorm.io/plugin/dbresolver" - - "gorm.io/gen/tests/.expect/dal_test_relation/model" -) - -func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { - _customer := customer{} - - _customer.customerDo.UseDB(db, opts...) - _customer.customerDo.UseModel(&model.Customer{}) - - tableName := _customer.customerDo.TableName() - _customer.ALL = field.NewAsterisk(tableName) - _customer.ID = field.NewInt64(tableName, "id") - _customer.CreatedAt = field.NewTime(tableName, "created_at") - _customer.UpdatedAt = field.NewTime(tableName, "updated_at") - _customer.DeletedAt = field.NewField(tableName, "deleted_at") - _customer.BankID = field.NewInt64(tableName, "bank_id") - _customer.Bank = customerHasOneBank{ - db: db.Session(&gorm.Session{}), - - RelationField: field.NewRelation("Bank", "model.Bank"), - } - - _customer.CreditCards = customerHasManyCreditCards{ - db: db.Session(&gorm.Session{}), - - RelationField: field.NewRelation("CreditCards", "model.CreditCard"), - } - - _customer.fillFieldMap() - - return _customer -} - -type customer struct { - customerDo customerDo - - ALL field.Asterisk - ID field.Int64 - CreatedAt field.Time - UpdatedAt field.Time - DeletedAt field.Field - BankID field.Int64 - Bank customerHasOneBank - - CreditCards customerHasManyCreditCards - - fieldMap map[string]field.Expr -} - -func (c customer) Table(newTableName string) *customer { - c.customerDo.UseTable(newTableName) - return c.updateTableName(newTableName) -} - -func (c customer) As(alias string) *customer { - c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) - return c.updateTableName(alias) -} - -func (c *customer) updateTableName(table string) *customer { - c.ALL = field.NewAsterisk(table) - c.ID = field.NewInt64(table, "id") - c.CreatedAt = field.NewTime(table, "created_at") - c.UpdatedAt = field.NewTime(table, "updated_at") - c.DeletedAt = field.NewField(table, "deleted_at") - c.BankID = field.NewInt64(table, "bank_id") - - c.fillFieldMap() - - return c -} - -func (c *customer) WithContext(ctx context.Context) *customerDo { return c.customerDo.WithContext(ctx) } - -func (c customer) TableName() string { return c.customerDo.TableName() } - -func (c customer) Alias() string { return c.customerDo.Alias() } - -func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } - -func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { - _f, ok := c.fieldMap[fieldName] - if !ok || _f == nil { - return nil, false - } - _oe, ok := _f.(field.OrderExpr) - return _oe, ok -} - -func (c *customer) fillFieldMap() { - c.fieldMap = make(map[string]field.Expr, 7) - c.fieldMap["id"] = c.ID - c.fieldMap["created_at"] = c.CreatedAt - c.fieldMap["updated_at"] = c.UpdatedAt - c.fieldMap["deleted_at"] = c.DeletedAt - c.fieldMap["bank_id"] = c.BankID -} - -func (c customer) clone(db *gorm.DB) customer { - c.customerDo.ReplaceConnPool(db.Statement.ConnPool) - c.Bank.db = db.Session(&gorm.Session{Initialized: true}) - c.Bank.db.Statement.ConnPool = db.Statement.ConnPool - c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) - c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool - return c -} - -func (c customer) replaceDB(db *gorm.DB) customer { - c.customerDo.ReplaceDB(db) - c.Bank.db = db.Session(&gorm.Session{}) - c.CreditCards.db = db.Session(&gorm.Session{}) - return c -} - -type customerHasOneBank struct { - db *gorm.DB - - field.RelationField -} - -func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { - if len(conds) == 0 { - return &a - } - - exprs := make([]clause.Expression, 0, len(conds)) - for _, cond := range conds { - exprs = append(exprs, cond.BeCond().(clause.Expression)) - } - a.db = a.db.Clauses(clause.Where{Exprs: exprs}) - return &a -} - -func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { - a.db = a.db.WithContext(ctx) - return &a -} - -func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { - a.db = a.db.Session(session) - return &a -} - -func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { - return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} -} - -type customerHasOneBankTx struct{ tx *gorm.Association } - -func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { - return result, a.tx.Find(&result) -} - -func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Append(targetValues...) -} - -func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Replace(targetValues...) -} - -func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Delete(targetValues...) -} - -func (a customerHasOneBankTx) Clear() error { - return a.tx.Clear() -} - -func (a customerHasOneBankTx) Count() int64 { - return a.tx.Count() -} - -type customerHasManyCreditCards struct { - db *gorm.DB - - field.RelationField -} - -func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { - if len(conds) == 0 { - return &a - } - - exprs := make([]clause.Expression, 0, len(conds)) - for _, cond := range conds { - exprs = append(exprs, cond.BeCond().(clause.Expression)) - } - a.db = a.db.Clauses(clause.Where{Exprs: exprs}) - return &a -} - -func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { - a.db = a.db.WithContext(ctx) - return &a -} - -func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { - a.db = a.db.Session(session) - return &a -} - -func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { - return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} -} - -type customerHasManyCreditCardsTx struct{ tx *gorm.Association } - -func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { - return result, a.tx.Find(&result) -} - -func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Append(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Replace(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { - targetValues := make([]interface{}, len(values)) - for i, v := range values { - targetValues[i] = v - } - return a.tx.Delete(targetValues...) -} - -func (a customerHasManyCreditCardsTx) Clear() error { - return a.tx.Clear() -} - -func (a customerHasManyCreditCardsTx) Count() int64 { - return a.tx.Count() -} - -type customerDo struct{ gen.DO } - -func (c customerDo) Debug() *customerDo { - return c.withDO(c.DO.Debug()) -} - -func (c customerDo) WithContext(ctx context.Context) *customerDo { - return c.withDO(c.DO.WithContext(ctx)) -} - -func (c customerDo) ReadDB() *customerDo { - return c.Clauses(dbresolver.Read) -} - -func (c customerDo) WriteDB() *customerDo { - return c.Clauses(dbresolver.Write) -} - -func (c customerDo) Session(config *gorm.Session) *customerDo { - return c.withDO(c.DO.Session(config)) -} - -func (c customerDo) Clauses(conds ...clause.Expression) *customerDo { - return c.withDO(c.DO.Clauses(conds...)) -} - -func (c customerDo) Returning(value interface{}, columns ...string) *customerDo { - return c.withDO(c.DO.Returning(value, columns...)) -} - -func (c customerDo) Not(conds ...gen.Condition) *customerDo { - return c.withDO(c.DO.Not(conds...)) -} - -func (c customerDo) Or(conds ...gen.Condition) *customerDo { - return c.withDO(c.DO.Or(conds...)) -} - -func (c customerDo) Select(conds ...field.Expr) *customerDo { - return c.withDO(c.DO.Select(conds...)) -} - -func (c customerDo) Where(conds ...gen.Condition) *customerDo { - return c.withDO(c.DO.Where(conds...)) -} - -func (c customerDo) Order(conds ...field.Expr) *customerDo { - return c.withDO(c.DO.Order(conds...)) -} - -func (c customerDo) Distinct(cols ...field.Expr) *customerDo { - return c.withDO(c.DO.Distinct(cols...)) -} - -func (c customerDo) Omit(cols ...field.Expr) *customerDo { - return c.withDO(c.DO.Omit(cols...)) -} - -func (c customerDo) Join(table schema.Tabler, on ...field.Expr) *customerDo { - return c.withDO(c.DO.Join(table, on...)) -} - -func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) *customerDo { - return c.withDO(c.DO.LeftJoin(table, on...)) -} - -func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) *customerDo { - return c.withDO(c.DO.RightJoin(table, on...)) -} - -func (c customerDo) Group(cols ...field.Expr) *customerDo { - return c.withDO(c.DO.Group(cols...)) -} - -func (c customerDo) Having(conds ...gen.Condition) *customerDo { - return c.withDO(c.DO.Having(conds...)) -} - -func (c customerDo) Limit(limit int) *customerDo { - return c.withDO(c.DO.Limit(limit)) -} - -func (c customerDo) Offset(offset int) *customerDo { - return c.withDO(c.DO.Offset(offset)) -} - -func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *customerDo { - return c.withDO(c.DO.Scopes(funcs...)) -} - -func (c customerDo) Unscoped() *customerDo { - return c.withDO(c.DO.Unscoped()) -} - -func (c customerDo) Create(values ...*model.Customer) error { - if len(values) == 0 { - return nil - } - return c.DO.Create(values) -} - -func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { - return c.DO.CreateInBatches(values, batchSize) -} - -// Save : !!! underlying implementation is different with GORM -// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) -func (c customerDo) Save(values ...*model.Customer) error { - if len(values) == 0 { - return nil - } - return c.DO.Save(values) -} - -func (c customerDo) First() (*model.Customer, error) { - if result, err := c.DO.First(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Take() (*model.Customer, error) { - if result, err := c.DO.Take(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Last() (*model.Customer, error) { - if result, err := c.DO.Last(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) Find() ([]*model.Customer, error) { - result, err := c.DO.Find() - return result.([]*model.Customer), err -} - -func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { - buf := make([]*model.Customer, 0, batchSize) - err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { - defer func() { results = append(results, buf...) }() - return fc(tx, batch) - }) - return results, err -} - -func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { - return c.DO.FindInBatches(result, batchSize, fc) -} - -func (c customerDo) Attrs(attrs ...field.AssignExpr) *customerDo { - return c.withDO(c.DO.Attrs(attrs...)) -} - -func (c customerDo) Assign(attrs ...field.AssignExpr) *customerDo { - return c.withDO(c.DO.Assign(attrs...)) -} - -func (c customerDo) Joins(fields ...field.RelationField) *customerDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Joins(_f)) - } - return &c -} - -func (c customerDo) Preload(fields ...field.RelationField) *customerDo { - for _, _f := range fields { - c = *c.withDO(c.DO.Preload(_f)) - } - return &c -} - -func (c customerDo) FirstOrInit() (*model.Customer, error) { - if result, err := c.DO.FirstOrInit(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) FirstOrCreate() (*model.Customer, error) { - if result, err := c.DO.FirstOrCreate(); err != nil { - return nil, err - } else { - return result.(*model.Customer), nil - } -} - -func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { - result, err = c.Offset(offset).Limit(limit).Find() - if err != nil { - return - } - - if size := len(result); 0 < limit && 0 < size && size < limit { - count = int64(size + offset) - return - } - - count, err = c.Offset(-1).Limit(-1).Count() - return -} - -func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { - count, err = c.Count() - if err != nil { - return - } - - err = c.Offset(offset).Limit(limit).Scan(result) - return -} - -func (c customerDo) Scan(result interface{}) (err error) { - return c.DO.Scan(result) -} - -func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { - return c.DO.Delete(models) -} - -func (c *customerDo) withDO(do gen.Dao) *customerDo { - c.DO = *do.(*gen.DO) - return c -} diff --git a/tests/.expect/dal_test_relation/query/gen.go b/tests/.expect/dal_test_relation/query/gen.go deleted file mode 100644 index 761abbfa..00000000 --- a/tests/.expect/dal_test_relation/query/gen.go +++ /dev/null @@ -1,119 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package query - -import ( - "context" - "database/sql" - - "gorm.io/gorm" - - "gorm.io/gen" - - "gorm.io/plugin/dbresolver" -) - -var ( - Q = new(Query) - Bank *bank - CreditCard *creditCard - Customer *customer -) - -func SetDefault(db *gorm.DB, opts ...gen.DOOption) { - *Q = *Use(db, opts...) - Bank = &Q.Bank - CreditCard = &Q.CreditCard - Customer = &Q.Customer -} - -func Use(db *gorm.DB, opts ...gen.DOOption) *Query { - return &Query{ - db: db, - Bank: newBank(db, opts...), - CreditCard: newCreditCard(db, opts...), - Customer: newCustomer(db, opts...), - } -} - -type Query struct { - db *gorm.DB - - Bank bank - CreditCard creditCard - Customer customer -} - -func (q *Query) Available() bool { return q.db != nil } - -func (q *Query) clone(db *gorm.DB) *Query { - return &Query{ - db: db, - Bank: q.Bank.clone(db), - CreditCard: q.CreditCard.clone(db), - Customer: q.Customer.clone(db), - } -} - -func (q *Query) ReadDB() *Query { - return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) -} - -func (q *Query) WriteDB() *Query { - return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) -} - -func (q *Query) ReplaceDB(db *gorm.DB) *Query { - return &Query{ - db: db, - Bank: q.Bank.replaceDB(db), - CreditCard: q.CreditCard.replaceDB(db), - Customer: q.Customer.replaceDB(db), - } -} - -type queryCtx struct { - Bank *bankDo - CreditCard *creditCardDo - Customer *customerDo -} - -func (q *Query) WithContext(ctx context.Context) *queryCtx { - return &queryCtx{ - Bank: q.Bank.WithContext(ctx), - CreditCard: q.CreditCard.WithContext(ctx), - Customer: q.Customer.WithContext(ctx), - } -} - -func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { - return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) -} - -func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { - tx := q.db.Begin(opts...) - return &QueryTx{Query: q.clone(tx), Error: tx.Error} -} - -type QueryTx struct { - *Query - Error error -} - -func (q *QueryTx) Commit() error { - return q.db.Commit().Error -} - -func (q *QueryTx) Rollback() error { - return q.db.Rollback().Error -} - -func (q *QueryTx) SavePoint(name string) error { - return q.db.SavePoint(name).Error -} - -func (q *QueryTx) RollbackTo(name string) error { - return q.db.RollbackTo(name).Error -} diff --git a/tests/gen_test.go b/tests/gen_test.go index 15dad843..69d1ad80 100644 --- a/tests/gen_test.go +++ b/tests/gen_test.go @@ -5,17 +5,12 @@ import ( "sync" "gorm.io/gen/tests/.expect/dal_test/query" - relquery "gorm.io/gen/tests/.expect/dal_test_relation/query" ) -var ( - useOnce sync.Once - ctx = context.Background() -) +var useOnce sync.Once +var ctx = context.Background() func CRUDInit() { query.Use(DB) query.SetDefault(DB) - relquery.Use(DB) - relquery.SetDefault(DB) } diff --git a/tests/generate_test.go b/tests/generate_test.go index a05d5da9..9b1bec22 100644 --- a/tests/generate_test.go +++ b/tests/generate_test.go @@ -62,7 +62,7 @@ var generateCase = map[string]func(dir string) *gen.Generator{ g.UseDB(DB) g.WithJSONTagNameStrategy(func(c string) string { return "-" }) g.ApplyBasic(g.GenerateAllTable(gen.FieldGORMTagReg(".", func(tag field.GormTag) field.GormTag { - // tag.Set("serialize","json") + //tag.Set("serialize","json") tag.Remove("comment") return tag }))...) @@ -118,41 +118,6 @@ var generateCase = map[string]func(dir string) *gen.Generator{ g.ApplyBasic(g.GenerateModelAs("users", DB.Config.NamingStrategy.SchemaName("users"), gen.WithMethod(diy_method.TestForWithMethod{}))) return g }, - generateDirPrefix + "dal_7": func(dir string) *gen.Generator { - g := gen.NewGenerator(gen.Config{ - OutPath: dir + "/query", - Mode: gen.WithDefaultQuery | gen.WithQueryInterface, - - WithUnitTest: true, - - FieldNullable: true, - FieldCoverable: true, - FieldWithIndexTag: true, - }) - g.UseDB(DB) - g.WithJSONTagNameStrategy(func(c string) string { return "-" }) - - banks := g.GenerateModel("banks") - creditCards := g.GenerateModel("credit_cards") - customers := g.GenerateModel("customers", - gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ - JSONTag: "bank", - GORMTag: field.GormTag{ - "foreignKey": []string{"BankID"}, - "references": []string{"ID"}, - }, - }), - gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ - JSONTag: "credit_cards", - GORMTag: field.GormTag{ - "foreignKey": []string{"CustomerRefer"}, - "references": []string{"ID"}, - }, - }), - ) - g.ApplyBasic(customers) - return g - }, } func TestGenerate(t *testing.T) { @@ -196,31 +161,4 @@ func TestGenerate_expect(t *testing.T) { g.UseDB(DB) g.ApplyBasic(g.GenerateAllTable()...) g.Execute() - - g = gen.NewGenerator(gen.Config{ - OutPath: expectDirPrefix + "dal_test_relation" + "/query", - Mode: gen.WithDefaultQuery, - }) - g.UseDB(DB) - - banks := g.GenerateModel("banks") - creditCards := g.GenerateModel("credit_cards") - customers := g.GenerateModel("customers", - gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ - JSONTag: "bank", - GORMTag: field.GormTag{ - "foreignKey": []string{"BankID"}, - "references": []string{"ID"}, - }, - }), - gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ - JSONTag: "credit_cards", - GORMTag: field.GormTag{ - "foreignKey": []string{"CustomerRefer"}, - "references": []string{"ID"}, - }, - }), - ) - g.ApplyBasic(customers, creditCards, banks) - g.Execute() } diff --git a/tests/transaction_test.go b/tests/transaction_test.go deleted file mode 100644 index 97d94325..00000000 --- a/tests/transaction_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package tests_test - -import ( - "fmt" - "testing" - - "gorm.io/gen/tests/.expect/dal_test_relation/model" - "gorm.io/gen/tests/.expect/dal_test_relation/query" -) - -func TestQuery_Transaction_Relation(t *testing.T) { - useOnce.Do(CRUDInit) - - t.Run("transaction has many", func(t *testing.T) { - if err := query.Q.Transaction(func(tx *query.Query) error { - c := tx.Customer - customer := &model.Customer{ - Bank: model.Bank{ - Name: "bank1", - Address: "bank-address1", - Scale: 1, - }, - CreditCards: []model.CreditCard{ - {Number: "num1"}, - {Number: "num2"}, - }, - } - if err := c.WithContext(ctx).Create(customer); err != nil { - return fmt.Errorf("create model fail: %s", err) - } - - got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). - Preload(c.CreditCards). - Preload(c.Bank). - First() - if err != nil { - return fmt.Errorf("find model fail: %s", err) - } - if len(got.CreditCards) != 2 { - return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) - } - - if err := c.CreditCards.WithContext(ctx).Model(customer).Replace(&model.CreditCard{ - Number: "num_replace", - }); err != nil { - return fmt.Errorf("replace model fail: %s", err) - } - - got, err = c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). - Preload(c.CreditCards). - Preload(c.Bank). - First() - if err != nil { - return fmt.Errorf("find model fail: %s", err) - } - if len(got.CreditCards) != 1 { - return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) - } - if got.CreditCards[0].Number != "num_replace" { - return fmt.Errorf("replace model fail, expect %q, got %q", "num_replace", got.CreditCards[0].Number) - } - - return nil - }); err != nil { - t.Errorf("transaction execute fail: %s", err) - } - }) - - t.Run("transaction has one", func(t *testing.T) { - if err := query.Q.Transaction(func(tx *query.Query) error { - c := tx.Customer - customer := &model.Customer{ - Bank: model.Bank{ - Name: "bank1", - Address: "bank-address1", - Scale: 1, - }, - CreditCards: []model.CreditCard{ - {Number: "num1"}, - {Number: "num2"}, - }, - } - - if err := c.WithContext(ctx).Create(customer); err != nil { - return fmt.Errorf("create model fail: %s", err) - } - if err := c.Bank.WithContext(ctx).Model(customer).Replace(&model.Bank{ - Name: "bank-replace", - Address: "bank-replace-address", - Scale: 2, - }); err != nil { - return fmt.Errorf("replace model fail: %s", err) - } - - got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). - Preload(c.CreditCards). - Preload(c.Bank). - First() - if err != nil { - return fmt.Errorf("find model fail: %s", err) - } - if got.Bank.Name != "bank-replace" { - return fmt.Errorf("replace model fail, expect %q, got %q", "bank-replace", got.Bank.Name) - } - - return nil - }); err != nil { - t.Errorf("transaction execute fail: %s", err) - } - }) -} From 81aa676b833275b42bb0dfca999b6f62a8142ca3 Mon Sep 17 00:00:00 2001 From: miya-masa Date: Fri, 29 Nov 2024 17:42:36 +0900 Subject: [PATCH 4/4] style(*): fix format --- internal/template/struct.go | 7 +- tests/.expect/dal_7/model/banks.gen.go | 20 + tests/.expect/dal_7/model/credit_cards.gen.go | 29 + tests/.expect/dal_7/model/customers.gen.go | 29 + tests/.expect/dal_7/query/customers.gen.go | 567 ++++++++++++++++++ .../.expect/dal_7/query/customers.gen_test.go | 145 +++++ tests/.expect/dal_7/query/gen.go | 103 ++++ tests/.expect/dal_7/query/gen_test.go | 118 ++++ .../dal_test_relation/model/banks.gen.go | 20 + .../model/credit_cards.gen.go | 29 + .../dal_test_relation/model/customers.gen.go | 29 + .../dal_test_relation/query/banks.gen.go | 339 +++++++++++ .../query/credit_cards.gen.go | 353 +++++++++++ .../dal_test_relation/query/customers.gen.go | 505 ++++++++++++++++ tests/.expect/dal_test_relation/query/gen.go | 119 ++++ tests/gen_test.go | 3 + tests/generate_test.go | 62 ++ tests/transaction_test.go | 111 ++++ 18 files changed, 2586 insertions(+), 2 deletions(-) create mode 100644 tests/.expect/dal_7/model/banks.gen.go create mode 100644 tests/.expect/dal_7/model/credit_cards.gen.go create mode 100644 tests/.expect/dal_7/model/customers.gen.go create mode 100644 tests/.expect/dal_7/query/customers.gen.go create mode 100644 tests/.expect/dal_7/query/customers.gen_test.go create mode 100644 tests/.expect/dal_7/query/gen.go create mode 100644 tests/.expect/dal_7/query/gen_test.go create mode 100644 tests/.expect/dal_test_relation/model/banks.gen.go create mode 100644 tests/.expect/dal_test_relation/model/credit_cards.gen.go create mode 100644 tests/.expect/dal_test_relation/model/customers.gen.go create mode 100644 tests/.expect/dal_test_relation/query/banks.gen.go create mode 100644 tests/.expect/dal_test_relation/query/credit_cards.gen.go create mode 100644 tests/.expect/dal_test_relation/query/customers.gen.go create mode 100644 tests/.expect/dal_test_relation/query/gen.go create mode 100644 tests/transaction_test.go diff --git a/internal/template/struct.go b/internal/template/struct.go index 8b83a12e..74ba269b 100644 --- a/internal/template/struct.go +++ b/internal/template/struct.go @@ -107,13 +107,16 @@ func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStruc cloneMethod = ` func ({{.S}} {{.QueryStructName}}) clone(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool) + {{.S}}.{{.QueryStructName}}Do.ReplaceConnPool(db.Statement.ConnPool){{range .Fields }}{{if .IsRelation}} + {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{Initialized: true}) + {{$.S}}.{{.Relation.Name}}.db.Statement.ConnPool = db.Statement.ConnPool{{end}}{{end}} return {{.S}} } ` replaceMethod = ` func ({{.S}} {{.QueryStructName}}) replaceDB(db *gorm.DB) {{.QueryStructName}} { - {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db) + {{.S}}.{{.QueryStructName}}Do.ReplaceDB(db){{range .Fields}}{{if .IsRelation}} + {{$.S}}.{{.Relation.Name}}.db = db.Session(&gorm.Session{}){{end}}{{end}} return {{.S}} } ` diff --git a/tests/.expect/dal_7/model/banks.gen.go b/tests/.expect/dal_7/model/banks.gen.go new file mode 100644 index 00000000..47ce6f40 --- /dev/null +++ b/tests/.expect/dal_7/model/banks.gen.go @@ -0,0 +1,20 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +const TableNameBank = "banks" + +// Bank mapped from table +type Bank struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + Name *string `gorm:"column:name" json:"-"` + Address *string `gorm:"column:address" json:"-"` + Scale *int64 `gorm:"column:scale" json:"-"` +} + +// TableName Bank's table name +func (*Bank) TableName() string { + return TableNameBank +} diff --git a/tests/.expect/dal_7/model/credit_cards.gen.go b/tests/.expect/dal_7/model/credit_cards.gen.go new file mode 100644 index 00000000..7a7d0202 --- /dev/null +++ b/tests/.expect/dal_7/model/credit_cards.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCreditCard = "credit_cards" + +// CreditCard mapped from table +type CreditCard struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + CreatedAt *time.Time `gorm:"column:created_at" json:"-"` + UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_credit_cards_deleted_at,priority:1" json:"-"` + Number *string `gorm:"column:number" json:"-"` + CustomerRefer *int64 `gorm:"column:customer_refer" json:"-"` + BankID *int64 `gorm:"column:bank_id" json:"-"` +} + +// TableName CreditCard's table name +func (*CreditCard) TableName() string { + return TableNameCreditCard +} diff --git a/tests/.expect/dal_7/model/customers.gen.go b/tests/.expect/dal_7/model/customers.gen.go new file mode 100644 index 00000000..ddbd7ada --- /dev/null +++ b/tests/.expect/dal_7/model/customers.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCustomer = "customers" + +// Customer mapped from table +type Customer struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + CreatedAt *time.Time `gorm:"column:created_at" json:"-"` + UpdatedAt *time.Time `gorm:"column:updated_at" json:"-"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index:idx_customers_deleted_at,priority:1" json:"-"` + BankID *int64 `gorm:"column:bank_id" json:"-"` + Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` + CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` +} + +// TableName Customer's table name +func (*Customer) TableName() string { + return TableNameCustomer +} diff --git a/tests/.expect/dal_7/query/customers.gen.go b/tests/.expect/dal_7/query/customers.gen.go new file mode 100644 index 00000000..a4dc3283 --- /dev/null +++ b/tests/.expect/dal_7/query/customers.gen.go @@ -0,0 +1,567 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.gen/dal_7/model" +) + +func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { + _customer := customer{} + + _customer.customerDo.UseDB(db, opts...) + _customer.customerDo.UseModel(&model.Customer{}) + + tableName := _customer.customerDo.TableName() + _customer.ALL = field.NewAsterisk(tableName) + _customer.ID = field.NewInt64(tableName, "id") + _customer.CreatedAt = field.NewTime(tableName, "created_at") + _customer.UpdatedAt = field.NewTime(tableName, "updated_at") + _customer.DeletedAt = field.NewField(tableName, "deleted_at") + _customer.BankID = field.NewInt64(tableName, "bank_id") + _customer.Bank = customerHasOneBank{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Bank", "model.Bank"), + } + + _customer.CreditCards = customerHasManyCreditCards{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("CreditCards", "model.CreditCard"), + } + + _customer.fillFieldMap() + + return _customer +} + +type customer struct { + customerDo customerDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + BankID field.Int64 + Bank customerHasOneBank + + CreditCards customerHasManyCreditCards + + fieldMap map[string]field.Expr +} + +func (c customer) Table(newTableName string) *customer { + c.customerDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c customer) As(alias string) *customer { + c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *customer) updateTableName(table string) *customer { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *customer) WithContext(ctx context.Context) ICustomerDo { return c.customerDo.WithContext(ctx) } + +func (c customer) TableName() string { return c.customerDo.TableName() } + +func (c customer) Alias() string { return c.customerDo.Alias() } + +func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } + +func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *customer) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["bank_id"] = c.BankID + +} + +func (c customer) clone(db *gorm.DB) customer { + c.customerDo.ReplaceConnPool(db.Statement.ConnPool) + c.Bank.db = db.Session(&gorm.Session{Initialized: true}) + c.Bank.db.Statement.ConnPool = db.Statement.ConnPool + c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) + c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool + return c +} + +func (c customer) replaceDB(db *gorm.DB) customer { + c.customerDo.ReplaceDB(db) + c.Bank.db = db.Session(&gorm.Session{}) + c.CreditCards.db = db.Session(&gorm.Session{}) + return c +} + +type customerHasOneBank struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { + return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasOneBankTx struct{ tx *gorm.Association } + +func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasOneBankTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasOneBankTx) Count() int64 { + return a.tx.Count() +} + +type customerHasManyCreditCards struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { + return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasManyCreditCardsTx struct{ tx *gorm.Association } + +func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasManyCreditCardsTx) Count() int64 { + return a.tx.Count() +} + +type customerDo struct{ gen.DO } + +type ICustomerDo interface { + gen.SubQuery + Debug() ICustomerDo + WithContext(ctx context.Context) ICustomerDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() ICustomerDo + WriteDB() ICustomerDo + As(alias string) gen.Dao + Session(config *gorm.Session) ICustomerDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) ICustomerDo + Not(conds ...gen.Condition) ICustomerDo + Or(conds ...gen.Condition) ICustomerDo + Select(conds ...field.Expr) ICustomerDo + Where(conds ...gen.Condition) ICustomerDo + Order(conds ...field.Expr) ICustomerDo + Distinct(cols ...field.Expr) ICustomerDo + Omit(cols ...field.Expr) ICustomerDo + Join(table schema.Tabler, on ...field.Expr) ICustomerDo + LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo + RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo + Group(cols ...field.Expr) ICustomerDo + Having(conds ...gen.Condition) ICustomerDo + Limit(limit int) ICustomerDo + Offset(offset int) ICustomerDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo + Unscoped() ICustomerDo + Create(values ...*model.Customer) error + CreateInBatches(values []*model.Customer, batchSize int) error + Save(values ...*model.Customer) error + First() (*model.Customer, error) + Take() (*model.Customer, error) + Last() (*model.Customer, error) + Find() ([]*model.Customer, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) + FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*model.Customer) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) ICustomerDo + Assign(attrs ...field.AssignExpr) ICustomerDo + Joins(fields ...field.RelationField) ICustomerDo + Preload(fields ...field.RelationField) ICustomerDo + FirstOrInit() (*model.Customer, error) + FirstOrCreate() (*model.Customer, error) + FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) ICustomerDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (c customerDo) Debug() ICustomerDo { + return c.withDO(c.DO.Debug()) +} + +func (c customerDo) WithContext(ctx context.Context) ICustomerDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c customerDo) ReadDB() ICustomerDo { + return c.Clauses(dbresolver.Read) +} + +func (c customerDo) WriteDB() ICustomerDo { + return c.Clauses(dbresolver.Write) +} + +func (c customerDo) Session(config *gorm.Session) ICustomerDo { + return c.withDO(c.DO.Session(config)) +} + +func (c customerDo) Clauses(conds ...clause.Expression) ICustomerDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c customerDo) Returning(value interface{}, columns ...string) ICustomerDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c customerDo) Not(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c customerDo) Or(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c customerDo) Select(conds ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c customerDo) Where(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c customerDo) Order(conds ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c customerDo) Distinct(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c customerDo) Omit(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c customerDo) Join(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) ICustomerDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c customerDo) Group(cols ...field.Expr) ICustomerDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c customerDo) Having(conds ...gen.Condition) ICustomerDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c customerDo) Limit(limit int) ICustomerDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c customerDo) Offset(offset int) ICustomerDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICustomerDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c customerDo) Unscoped() ICustomerDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c customerDo) Create(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c customerDo) Save(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c customerDo) First() (*model.Customer, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Take() (*model.Customer, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Last() (*model.Customer, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Find() ([]*model.Customer, error) { + result, err := c.DO.Find() + return result.([]*model.Customer), err +} + +func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { + buf := make([]*model.Customer, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c customerDo) Attrs(attrs ...field.AssignExpr) ICustomerDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c customerDo) Assign(attrs ...field.AssignExpr) ICustomerDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c customerDo) Joins(fields ...field.RelationField) ICustomerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c customerDo) Preload(fields ...field.RelationField) ICustomerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c customerDo) FirstOrInit() (*model.Customer, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FirstOrCreate() (*model.Customer, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c customerDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *customerDo) withDO(do gen.Dao) *customerDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_7/query/customers.gen_test.go b/tests/.expect/dal_7/query/customers.gen_test.go new file mode 100644 index 00000000..f625fdca --- /dev/null +++ b/tests/.expect/dal_7/query/customers.gen_test.go @@ -0,0 +1,145 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "testing" + + "gorm.io/gen" + "gorm.io/gen/field" + "gorm.io/gen/tests/.gen/dal_7/model" + "gorm.io/gorm/clause" +) + +func init() { + InitializeDB() + err := _gen_test_db.AutoMigrate(&model.Customer{}) + if err != nil { + fmt.Printf("Error: AutoMigrate(&model.Customer{}) fail: %s", err) + } +} + +func Test_customerQuery(t *testing.T) { + customer := newCustomer(_gen_test_db) + customer = *customer.As(customer.TableName()) + _do := customer.WithContext(context.Background()).Debug() + + primaryKey := field.NewString(customer.TableName(), clause.PrimaryKey) + _, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete() + if err != nil { + t.Error("clean table fail:", err) + return + } + + _, ok := customer.GetFieldByName("") + if ok { + t.Error("GetFieldByName(\"\") from customer success") + } + + err = _do.Create(&model.Customer{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.Save(&model.Customer{}) + if err != nil { + t.Error("create item in table fail:", err) + } + + err = _do.CreateInBatches([]*model.Customer{{}, {}}, 10) + if err != nil { + t.Error("create item in table fail:", err) + } + + _, err = _do.Select(customer.ALL).Take() + if err != nil { + t.Error("Take() on table fail:", err) + } + + _, err = _do.First() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Last() + if err != nil { + t.Error("First() on table fail:", err) + } + + _, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatch() on table fail:", err) + } + + err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*model.Customer{}, 10, func(tx gen.Dao, batch int) error { return nil }) + if err != nil { + t.Error("FindInBatches() on table fail:", err) + } + + _, err = _do.Select(customer.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find() + if err != nil { + t.Error("Find() on table fail:", err) + } + + _, err = _do.Distinct(primaryKey).Take() + if err != nil { + t.Error("select Distinct() on table fail:", err) + } + + _, err = _do.Select(customer.ALL).Omit(primaryKey).Take() + if err != nil { + t.Error("Omit() on table fail:", err) + } + + _, err = _do.Group(primaryKey).Find() + if err != nil { + t.Error("Group() on table fail:", err) + } + + _, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find() + if err != nil { + t.Error("Scopes() on table fail:", err) + } + + _, _, err = _do.FindByPage(0, 1) + if err != nil { + t.Error("FindByPage() on table fail:", err) + } + + _, err = _do.ScanByPage(&model.Customer{}, 0, 1) + if err != nil { + t.Error("ScanByPage() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit() + if err != nil { + t.Error("FirstOrInit() on table fail:", err) + } + + _, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate() + if err != nil { + t.Error("FirstOrCreate() on table fail:", err) + } + + var _a _another + var _aPK = field.NewString(_a.TableName(), "id") + + err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("Join() on table fail:", err) + } + + err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{}) + if err != nil { + t.Error("LeftJoin() on table fail:", err) + } + + _, err = _do.Not().Or().Clauses().Take() + if err != nil { + t.Error("Not/Or/Clauses on table fail:", err) + } +} diff --git a/tests/.expect/dal_7/query/gen.go b/tests/.expect/dal_7/query/gen.go new file mode 100644 index 00000000..11cd3da4 --- /dev/null +++ b/tests/.expect/dal_7/query/gen.go @@ -0,0 +1,103 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +var ( + Q = new(Query) + Customer *customer +) + +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) + Customer = &Q.Customer +} + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + Customer: newCustomer(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + Customer customer +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + Customer: q.Customer.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + Customer: q.Customer.replaceDB(db), + } +} + +type queryCtx struct { + Customer ICustomerDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + Customer: q.Customer.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/tests/.expect/dal_7/query/gen_test.go b/tests/.expect/dal_7/query/gen_test.go new file mode 100644 index 00000000..7e81714a --- /dev/null +++ b/tests/.expect/dal_7/query/gen_test.go @@ -0,0 +1,118 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "fmt" + "reflect" + "sync" + "testing" + + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +type Input struct { + Args []interface{} +} + +type Expectation struct { + Ret []interface{} +} + +type TestCase struct { + Input + Expectation +} + +const _gen_test_db_name = "gen_test.db" + +var _gen_test_db *gorm.DB +var _gen_test_once sync.Once + +func init() { + InitializeDB() + _gen_test_db.AutoMigrate(&_another{}) +} + +func InitializeDB() { + _gen_test_once.Do(func() { + var err error + _gen_test_db, err = gorm.Open(sqlite.Open(_gen_test_db_name), &gorm.Config{}) + if err != nil { + panic(fmt.Errorf("open sqlite %q fail: %w", _gen_test_db_name, err)) + } + }) +} + +func assert(t *testing.T, methodName string, res, exp interface{}) { + if !reflect.DeepEqual(res, exp) { + t.Errorf("%v() gotResult = %v, want %v", methodName, res, exp) + } +} + +type _another struct { + ID uint64 `gorm:"primaryKey"` +} + +func (*_another) TableName() string { return "another_for_unit_test" } + +func Test_Available(t *testing.T) { + if !Use(_gen_test_db).Available() { + t.Errorf("query.Available() == false") + } +} + +func Test_WithContext(t *testing.T) { + query := Use(_gen_test_db) + if !query.Available() { + t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") + } + + type Content string + var key, value Content = "gen_tag", "unit_test" + qCtx := query.WithContext(context.WithValue(context.Background(), key, value)) + + for _, ctx := range []context.Context{ + qCtx.Customer.UnderlyingDB().Statement.Context, + } { + if v := ctx.Value(key); v != value { + t.Errorf("get value from context fail, expect %q, got %q", value, v) + } + } +} + +func Test_Transaction(t *testing.T) { + query := Use(_gen_test_db) + if !query.Available() { + t.Errorf("query Use(_gen_test_db) fail: query.Available() == false") + } + + err := query.Transaction(func(tx *Query) error { return nil }) + if err != nil { + t.Errorf("query.Transaction execute fail: %s", err) + } + + tx := query.Begin() + + err = tx.SavePoint("point") + if err != nil { + t.Errorf("query tx SavePoint fail: %s", err) + } + err = tx.RollbackTo("point") + if err != nil { + t.Errorf("query tx RollbackTo fail: %s", err) + } + err = tx.Commit() + if err != nil { + t.Errorf("query tx Commit fail: %s", err) + } + + err = query.Begin().Rollback() + if err != nil { + t.Errorf("query tx Rollback fail: %s", err) + } +} diff --git a/tests/.expect/dal_test_relation/model/banks.gen.go b/tests/.expect/dal_test_relation/model/banks.gen.go new file mode 100644 index 00000000..689bd855 --- /dev/null +++ b/tests/.expect/dal_test_relation/model/banks.gen.go @@ -0,0 +1,20 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +const TableNameBank = "banks" + +// Bank mapped from table +type Bank struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + Name string `gorm:"column:name" json:"name"` + Address string `gorm:"column:address" json:"address"` + Scale int64 `gorm:"column:scale" json:"scale"` +} + +// TableName Bank's table name +func (*Bank) TableName() string { + return TableNameBank +} diff --git a/tests/.expect/dal_test_relation/model/credit_cards.gen.go b/tests/.expect/dal_test_relation/model/credit_cards.gen.go new file mode 100644 index 00000000..427684c0 --- /dev/null +++ b/tests/.expect/dal_test_relation/model/credit_cards.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCreditCard = "credit_cards" + +// CreditCard mapped from table +type CreditCard struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` + Number string `gorm:"column:number" json:"number"` + CustomerRefer int64 `gorm:"column:customer_refer" json:"customer_refer"` + BankID int64 `gorm:"column:bank_id" json:"bank_id"` +} + +// TableName CreditCard's table name +func (*CreditCard) TableName() string { + return TableNameCreditCard +} diff --git a/tests/.expect/dal_test_relation/model/customers.gen.go b/tests/.expect/dal_test_relation/model/customers.gen.go new file mode 100644 index 00000000..d59e6dde --- /dev/null +++ b/tests/.expect/dal_test_relation/model/customers.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" + + "gorm.io/gorm" +) + +const TableNameCustomer = "customers" + +// Customer mapped from table +type Customer struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"` + BankID int64 `gorm:"column:bank_id" json:"bank_id"` + Bank Bank `gorm:"foreignKey:BankID;references:ID" json:"bank"` + CreditCards []CreditCard `gorm:"foreignKey:CustomerRefer;references:ID" json:"credit_cards"` +} + +// TableName Customer's table name +func (*Customer) TableName() string { + return TableNameCustomer +} diff --git a/tests/.expect/dal_test_relation/query/banks.gen.go b/tests/.expect/dal_test_relation/query/banks.gen.go new file mode 100644 index 00000000..2a5a334d --- /dev/null +++ b/tests/.expect/dal_test_relation/query/banks.gen.go @@ -0,0 +1,339 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newBank(db *gorm.DB, opts ...gen.DOOption) bank { + _bank := bank{} + + _bank.bankDo.UseDB(db, opts...) + _bank.bankDo.UseModel(&model.Bank{}) + + tableName := _bank.bankDo.TableName() + _bank.ALL = field.NewAsterisk(tableName) + _bank.ID = field.NewInt64(tableName, "id") + _bank.Name = field.NewString(tableName, "name") + _bank.Address = field.NewString(tableName, "address") + _bank.Scale = field.NewInt64(tableName, "scale") + + _bank.fillFieldMap() + + return _bank +} + +type bank struct { + bankDo bankDo + + ALL field.Asterisk + ID field.Int64 + Name field.String + Address field.String + Scale field.Int64 + + fieldMap map[string]field.Expr +} + +func (b bank) Table(newTableName string) *bank { + b.bankDo.UseTable(newTableName) + return b.updateTableName(newTableName) +} + +func (b bank) As(alias string) *bank { + b.bankDo.DO = *(b.bankDo.As(alias).(*gen.DO)) + return b.updateTableName(alias) +} + +func (b *bank) updateTableName(table string) *bank { + b.ALL = field.NewAsterisk(table) + b.ID = field.NewInt64(table, "id") + b.Name = field.NewString(table, "name") + b.Address = field.NewString(table, "address") + b.Scale = field.NewInt64(table, "scale") + + b.fillFieldMap() + + return b +} + +func (b *bank) WithContext(ctx context.Context) *bankDo { return b.bankDo.WithContext(ctx) } + +func (b bank) TableName() string { return b.bankDo.TableName() } + +func (b bank) Alias() string { return b.bankDo.Alias() } + +func (b bank) Columns(cols ...field.Expr) gen.Columns { return b.bankDo.Columns(cols...) } + +func (b *bank) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := b.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (b *bank) fillFieldMap() { + b.fieldMap = make(map[string]field.Expr, 4) + b.fieldMap["id"] = b.ID + b.fieldMap["name"] = b.Name + b.fieldMap["address"] = b.Address + b.fieldMap["scale"] = b.Scale +} + +func (b bank) clone(db *gorm.DB) bank { + b.bankDo.ReplaceConnPool(db.Statement.ConnPool) + return b +} + +func (b bank) replaceDB(db *gorm.DB) bank { + b.bankDo.ReplaceDB(db) + return b +} + +type bankDo struct{ gen.DO } + +func (b bankDo) Debug() *bankDo { + return b.withDO(b.DO.Debug()) +} + +func (b bankDo) WithContext(ctx context.Context) *bankDo { + return b.withDO(b.DO.WithContext(ctx)) +} + +func (b bankDo) ReadDB() *bankDo { + return b.Clauses(dbresolver.Read) +} + +func (b bankDo) WriteDB() *bankDo { + return b.Clauses(dbresolver.Write) +} + +func (b bankDo) Session(config *gorm.Session) *bankDo { + return b.withDO(b.DO.Session(config)) +} + +func (b bankDo) Clauses(conds ...clause.Expression) *bankDo { + return b.withDO(b.DO.Clauses(conds...)) +} + +func (b bankDo) Returning(value interface{}, columns ...string) *bankDo { + return b.withDO(b.DO.Returning(value, columns...)) +} + +func (b bankDo) Not(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Not(conds...)) +} + +func (b bankDo) Or(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Or(conds...)) +} + +func (b bankDo) Select(conds ...field.Expr) *bankDo { + return b.withDO(b.DO.Select(conds...)) +} + +func (b bankDo) Where(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Where(conds...)) +} + +func (b bankDo) Order(conds ...field.Expr) *bankDo { + return b.withDO(b.DO.Order(conds...)) +} + +func (b bankDo) Distinct(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Distinct(cols...)) +} + +func (b bankDo) Omit(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Omit(cols...)) +} + +func (b bankDo) Join(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.Join(table, on...)) +} + +func (b bankDo) LeftJoin(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.LeftJoin(table, on...)) +} + +func (b bankDo) RightJoin(table schema.Tabler, on ...field.Expr) *bankDo { + return b.withDO(b.DO.RightJoin(table, on...)) +} + +func (b bankDo) Group(cols ...field.Expr) *bankDo { + return b.withDO(b.DO.Group(cols...)) +} + +func (b bankDo) Having(conds ...gen.Condition) *bankDo { + return b.withDO(b.DO.Having(conds...)) +} + +func (b bankDo) Limit(limit int) *bankDo { + return b.withDO(b.DO.Limit(limit)) +} + +func (b bankDo) Offset(offset int) *bankDo { + return b.withDO(b.DO.Offset(offset)) +} + +func (b bankDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *bankDo { + return b.withDO(b.DO.Scopes(funcs...)) +} + +func (b bankDo) Unscoped() *bankDo { + return b.withDO(b.DO.Unscoped()) +} + +func (b bankDo) Create(values ...*model.Bank) error { + if len(values) == 0 { + return nil + } + return b.DO.Create(values) +} + +func (b bankDo) CreateInBatches(values []*model.Bank, batchSize int) error { + return b.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (b bankDo) Save(values ...*model.Bank) error { + if len(values) == 0 { + return nil + } + return b.DO.Save(values) +} + +func (b bankDo) First() (*model.Bank, error) { + if result, err := b.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Take() (*model.Bank, error) { + if result, err := b.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Last() (*model.Bank, error) { + if result, err := b.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) Find() ([]*model.Bank, error) { + result, err := b.DO.Find() + return result.([]*model.Bank), err +} + +func (b bankDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Bank, err error) { + buf := make([]*model.Bank, 0, batchSize) + err = b.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (b bankDo) FindInBatches(result *[]*model.Bank, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return b.DO.FindInBatches(result, batchSize, fc) +} + +func (b bankDo) Attrs(attrs ...field.AssignExpr) *bankDo { + return b.withDO(b.DO.Attrs(attrs...)) +} + +func (b bankDo) Assign(attrs ...field.AssignExpr) *bankDo { + return b.withDO(b.DO.Assign(attrs...)) +} + +func (b bankDo) Joins(fields ...field.RelationField) *bankDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Joins(_f)) + } + return &b +} + +func (b bankDo) Preload(fields ...field.RelationField) *bankDo { + for _, _f := range fields { + b = *b.withDO(b.DO.Preload(_f)) + } + return &b +} + +func (b bankDo) FirstOrInit() (*model.Bank, error) { + if result, err := b.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) FirstOrCreate() (*model.Bank, error) { + if result, err := b.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Bank), nil + } +} + +func (b bankDo) FindByPage(offset int, limit int) (result []*model.Bank, count int64, err error) { + result, err = b.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = b.Offset(-1).Limit(-1).Count() + return +} + +func (b bankDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = b.Count() + if err != nil { + return + } + + err = b.Offset(offset).Limit(limit).Scan(result) + return +} + +func (b bankDo) Scan(result interface{}) (err error) { + return b.DO.Scan(result) +} + +func (b bankDo) Delete(models ...*model.Bank) (result gen.ResultInfo, err error) { + return b.DO.Delete(models) +} + +func (b *bankDo) withDO(do gen.Dao) *bankDo { + b.DO = *do.(*gen.DO) + return b +} diff --git a/tests/.expect/dal_test_relation/query/credit_cards.gen.go b/tests/.expect/dal_test_relation/query/credit_cards.gen.go new file mode 100644 index 00000000..5d12e6cb --- /dev/null +++ b/tests/.expect/dal_test_relation/query/credit_cards.gen.go @@ -0,0 +1,353 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newCreditCard(db *gorm.DB, opts ...gen.DOOption) creditCard { + _creditCard := creditCard{} + + _creditCard.creditCardDo.UseDB(db, opts...) + _creditCard.creditCardDo.UseModel(&model.CreditCard{}) + + tableName := _creditCard.creditCardDo.TableName() + _creditCard.ALL = field.NewAsterisk(tableName) + _creditCard.ID = field.NewInt64(tableName, "id") + _creditCard.CreatedAt = field.NewTime(tableName, "created_at") + _creditCard.UpdatedAt = field.NewTime(tableName, "updated_at") + _creditCard.DeletedAt = field.NewField(tableName, "deleted_at") + _creditCard.Number = field.NewString(tableName, "number") + _creditCard.CustomerRefer = field.NewInt64(tableName, "customer_refer") + _creditCard.BankID = field.NewInt64(tableName, "bank_id") + + _creditCard.fillFieldMap() + + return _creditCard +} + +type creditCard struct { + creditCardDo creditCardDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + Number field.String + CustomerRefer field.Int64 + BankID field.Int64 + + fieldMap map[string]field.Expr +} + +func (c creditCard) Table(newTableName string) *creditCard { + c.creditCardDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c creditCard) As(alias string) *creditCard { + c.creditCardDo.DO = *(c.creditCardDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *creditCard) updateTableName(table string) *creditCard { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.Number = field.NewString(table, "number") + c.CustomerRefer = field.NewInt64(table, "customer_refer") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *creditCard) WithContext(ctx context.Context) *creditCardDo { + return c.creditCardDo.WithContext(ctx) +} + +func (c creditCard) TableName() string { return c.creditCardDo.TableName() } + +func (c creditCard) Alias() string { return c.creditCardDo.Alias() } + +func (c creditCard) Columns(cols ...field.Expr) gen.Columns { return c.creditCardDo.Columns(cols...) } + +func (c *creditCard) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *creditCard) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["number"] = c.Number + c.fieldMap["customer_refer"] = c.CustomerRefer + c.fieldMap["bank_id"] = c.BankID +} + +func (c creditCard) clone(db *gorm.DB) creditCard { + c.creditCardDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c creditCard) replaceDB(db *gorm.DB) creditCard { + c.creditCardDo.ReplaceDB(db) + return c +} + +type creditCardDo struct{ gen.DO } + +func (c creditCardDo) Debug() *creditCardDo { + return c.withDO(c.DO.Debug()) +} + +func (c creditCardDo) WithContext(ctx context.Context) *creditCardDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c creditCardDo) ReadDB() *creditCardDo { + return c.Clauses(dbresolver.Read) +} + +func (c creditCardDo) WriteDB() *creditCardDo { + return c.Clauses(dbresolver.Write) +} + +func (c creditCardDo) Session(config *gorm.Session) *creditCardDo { + return c.withDO(c.DO.Session(config)) +} + +func (c creditCardDo) Clauses(conds ...clause.Expression) *creditCardDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c creditCardDo) Returning(value interface{}, columns ...string) *creditCardDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c creditCardDo) Not(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c creditCardDo) Or(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c creditCardDo) Select(conds ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c creditCardDo) Where(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c creditCardDo) Order(conds ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c creditCardDo) Distinct(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c creditCardDo) Omit(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c creditCardDo) Join(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c creditCardDo) LeftJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c creditCardDo) RightJoin(table schema.Tabler, on ...field.Expr) *creditCardDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c creditCardDo) Group(cols ...field.Expr) *creditCardDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c creditCardDo) Having(conds ...gen.Condition) *creditCardDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c creditCardDo) Limit(limit int) *creditCardDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c creditCardDo) Offset(offset int) *creditCardDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c creditCardDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *creditCardDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c creditCardDo) Unscoped() *creditCardDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c creditCardDo) Create(values ...*model.CreditCard) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c creditCardDo) CreateInBatches(values []*model.CreditCard, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c creditCardDo) Save(values ...*model.CreditCard) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c creditCardDo) First() (*model.CreditCard, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Take() (*model.CreditCard, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Last() (*model.CreditCard, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) Find() ([]*model.CreditCard, error) { + result, err := c.DO.Find() + return result.([]*model.CreditCard), err +} + +func (c creditCardDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.CreditCard, err error) { + buf := make([]*model.CreditCard, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c creditCardDo) FindInBatches(result *[]*model.CreditCard, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c creditCardDo) Attrs(attrs ...field.AssignExpr) *creditCardDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c creditCardDo) Assign(attrs ...field.AssignExpr) *creditCardDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c creditCardDo) Joins(fields ...field.RelationField) *creditCardDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c creditCardDo) Preload(fields ...field.RelationField) *creditCardDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c creditCardDo) FirstOrInit() (*model.CreditCard, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) FirstOrCreate() (*model.CreditCard, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.CreditCard), nil + } +} + +func (c creditCardDo) FindByPage(offset int, limit int) (result []*model.CreditCard, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c creditCardDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c creditCardDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c creditCardDo) Delete(models ...*model.CreditCard) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *creditCardDo) withDO(do gen.Dao) *creditCardDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_test_relation/query/customers.gen.go b/tests/.expect/dal_test_relation/query/customers.gen.go new file mode 100644 index 00000000..9219df28 --- /dev/null +++ b/tests/.expect/dal_test_relation/query/customers.gen.go @@ -0,0 +1,505 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" +) + +func newCustomer(db *gorm.DB, opts ...gen.DOOption) customer { + _customer := customer{} + + _customer.customerDo.UseDB(db, opts...) + _customer.customerDo.UseModel(&model.Customer{}) + + tableName := _customer.customerDo.TableName() + _customer.ALL = field.NewAsterisk(tableName) + _customer.ID = field.NewInt64(tableName, "id") + _customer.CreatedAt = field.NewTime(tableName, "created_at") + _customer.UpdatedAt = field.NewTime(tableName, "updated_at") + _customer.DeletedAt = field.NewField(tableName, "deleted_at") + _customer.BankID = field.NewInt64(tableName, "bank_id") + _customer.Bank = customerHasOneBank{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("Bank", "model.Bank"), + } + + _customer.CreditCards = customerHasManyCreditCards{ + db: db.Session(&gorm.Session{}), + + RelationField: field.NewRelation("CreditCards", "model.CreditCard"), + } + + _customer.fillFieldMap() + + return _customer +} + +type customer struct { + customerDo customerDo + + ALL field.Asterisk + ID field.Int64 + CreatedAt field.Time + UpdatedAt field.Time + DeletedAt field.Field + BankID field.Int64 + Bank customerHasOneBank + + CreditCards customerHasManyCreditCards + + fieldMap map[string]field.Expr +} + +func (c customer) Table(newTableName string) *customer { + c.customerDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c customer) As(alias string) *customer { + c.customerDo.DO = *(c.customerDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *customer) updateTableName(table string) *customer { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt64(table, "id") + c.CreatedAt = field.NewTime(table, "created_at") + c.UpdatedAt = field.NewTime(table, "updated_at") + c.DeletedAt = field.NewField(table, "deleted_at") + c.BankID = field.NewInt64(table, "bank_id") + + c.fillFieldMap() + + return c +} + +func (c *customer) WithContext(ctx context.Context) *customerDo { return c.customerDo.WithContext(ctx) } + +func (c customer) TableName() string { return c.customerDo.TableName() } + +func (c customer) Alias() string { return c.customerDo.Alias() } + +func (c customer) Columns(cols ...field.Expr) gen.Columns { return c.customerDo.Columns(cols...) } + +func (c *customer) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *customer) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 7) + c.fieldMap["id"] = c.ID + c.fieldMap["created_at"] = c.CreatedAt + c.fieldMap["updated_at"] = c.UpdatedAt + c.fieldMap["deleted_at"] = c.DeletedAt + c.fieldMap["bank_id"] = c.BankID +} + +func (c customer) clone(db *gorm.DB) customer { + c.customerDo.ReplaceConnPool(db.Statement.ConnPool) + c.Bank.db = db.Session(&gorm.Session{Initialized: true}) + c.Bank.db.Statement.ConnPool = db.Statement.ConnPool + c.CreditCards.db = db.Session(&gorm.Session{Initialized: true}) + c.CreditCards.db.Statement.ConnPool = db.Statement.ConnPool + return c +} + +func (c customer) replaceDB(db *gorm.DB) customer { + c.customerDo.ReplaceDB(db) + c.Bank.db = db.Session(&gorm.Session{}) + c.CreditCards.db = db.Session(&gorm.Session{}) + return c +} + +type customerHasOneBank struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasOneBank) Where(conds ...field.Expr) *customerHasOneBank { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasOneBank) WithContext(ctx context.Context) *customerHasOneBank { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasOneBank) Session(session *gorm.Session) *customerHasOneBank { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasOneBank) Model(m *model.Customer) *customerHasOneBankTx { + return &customerHasOneBankTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasOneBankTx struct{ tx *gorm.Association } + +func (a customerHasOneBankTx) Find() (result *model.Bank, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasOneBankTx) Append(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasOneBankTx) Replace(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasOneBankTx) Delete(values ...*model.Bank) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasOneBankTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasOneBankTx) Count() int64 { + return a.tx.Count() +} + +type customerHasManyCreditCards struct { + db *gorm.DB + + field.RelationField +} + +func (a customerHasManyCreditCards) Where(conds ...field.Expr) *customerHasManyCreditCards { + if len(conds) == 0 { + return &a + } + + exprs := make([]clause.Expression, 0, len(conds)) + for _, cond := range conds { + exprs = append(exprs, cond.BeCond().(clause.Expression)) + } + a.db = a.db.Clauses(clause.Where{Exprs: exprs}) + return &a +} + +func (a customerHasManyCreditCards) WithContext(ctx context.Context) *customerHasManyCreditCards { + a.db = a.db.WithContext(ctx) + return &a +} + +func (a customerHasManyCreditCards) Session(session *gorm.Session) *customerHasManyCreditCards { + a.db = a.db.Session(session) + return &a +} + +func (a customerHasManyCreditCards) Model(m *model.Customer) *customerHasManyCreditCardsTx { + return &customerHasManyCreditCardsTx{a.db.Model(m).Association(a.Name())} +} + +type customerHasManyCreditCardsTx struct{ tx *gorm.Association } + +func (a customerHasManyCreditCardsTx) Find() (result []*model.CreditCard, err error) { + return result, a.tx.Find(&result) +} + +func (a customerHasManyCreditCardsTx) Append(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Append(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Replace(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Replace(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Delete(values ...*model.CreditCard) (err error) { + targetValues := make([]interface{}, len(values)) + for i, v := range values { + targetValues[i] = v + } + return a.tx.Delete(targetValues...) +} + +func (a customerHasManyCreditCardsTx) Clear() error { + return a.tx.Clear() +} + +func (a customerHasManyCreditCardsTx) Count() int64 { + return a.tx.Count() +} + +type customerDo struct{ gen.DO } + +func (c customerDo) Debug() *customerDo { + return c.withDO(c.DO.Debug()) +} + +func (c customerDo) WithContext(ctx context.Context) *customerDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c customerDo) ReadDB() *customerDo { + return c.Clauses(dbresolver.Read) +} + +func (c customerDo) WriteDB() *customerDo { + return c.Clauses(dbresolver.Write) +} + +func (c customerDo) Session(config *gorm.Session) *customerDo { + return c.withDO(c.DO.Session(config)) +} + +func (c customerDo) Clauses(conds ...clause.Expression) *customerDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c customerDo) Returning(value interface{}, columns ...string) *customerDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c customerDo) Not(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c customerDo) Or(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c customerDo) Select(conds ...field.Expr) *customerDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c customerDo) Where(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c customerDo) Order(conds ...field.Expr) *customerDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c customerDo) Distinct(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c customerDo) Omit(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c customerDo) Join(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c customerDo) LeftJoin(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c customerDo) RightJoin(table schema.Tabler, on ...field.Expr) *customerDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c customerDo) Group(cols ...field.Expr) *customerDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c customerDo) Having(conds ...gen.Condition) *customerDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c customerDo) Limit(limit int) *customerDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c customerDo) Offset(offset int) *customerDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c customerDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *customerDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c customerDo) Unscoped() *customerDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c customerDo) Create(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c customerDo) CreateInBatches(values []*model.Customer, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c customerDo) Save(values ...*model.Customer) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c customerDo) First() (*model.Customer, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Take() (*model.Customer, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Last() (*model.Customer, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) Find() ([]*model.Customer, error) { + result, err := c.DO.Find() + return result.([]*model.Customer), err +} + +func (c customerDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Customer, err error) { + buf := make([]*model.Customer, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c customerDo) FindInBatches(result *[]*model.Customer, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c customerDo) Attrs(attrs ...field.AssignExpr) *customerDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c customerDo) Assign(attrs ...field.AssignExpr) *customerDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c customerDo) Joins(fields ...field.RelationField) *customerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c customerDo) Preload(fields ...field.RelationField) *customerDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c customerDo) FirstOrInit() (*model.Customer, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FirstOrCreate() (*model.Customer, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Customer), nil + } +} + +func (c customerDo) FindByPage(offset int, limit int) (result []*model.Customer, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c customerDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c customerDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c customerDo) Delete(models ...*model.Customer) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *customerDo) withDO(do gen.Dao) *customerDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/tests/.expect/dal_test_relation/query/gen.go b/tests/.expect/dal_test_relation/query/gen.go new file mode 100644 index 00000000..761abbfa --- /dev/null +++ b/tests/.expect/dal_test_relation/query/gen.go @@ -0,0 +1,119 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +var ( + Q = new(Query) + Bank *bank + CreditCard *creditCard + Customer *customer +) + +func SetDefault(db *gorm.DB, opts ...gen.DOOption) { + *Q = *Use(db, opts...) + Bank = &Q.Bank + CreditCard = &Q.CreditCard + Customer = &Q.Customer +} + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + Bank: newBank(db, opts...), + CreditCard: newCreditCard(db, opts...), + Customer: newCustomer(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + Bank bank + CreditCard creditCard + Customer customer +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + Bank: q.Bank.clone(db), + CreditCard: q.CreditCard.clone(db), + Customer: q.Customer.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + Bank: q.Bank.replaceDB(db), + CreditCard: q.CreditCard.replaceDB(db), + Customer: q.Customer.replaceDB(db), + } +} + +type queryCtx struct { + Bank *bankDo + CreditCard *creditCardDo + Customer *customerDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + Bank: q.Bank.WithContext(ctx), + CreditCard: q.CreditCard.WithContext(ctx), + Customer: q.Customer.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/tests/gen_test.go b/tests/gen_test.go index 69d1ad80..ca258e94 100644 --- a/tests/gen_test.go +++ b/tests/gen_test.go @@ -5,6 +5,7 @@ import ( "sync" "gorm.io/gen/tests/.expect/dal_test/query" + relquery "gorm.io/gen/tests/.expect/dal_test_relation/query" ) var useOnce sync.Once @@ -13,4 +14,6 @@ var ctx = context.Background() func CRUDInit() { query.Use(DB) query.SetDefault(DB) + relquery.Use(DB) + relquery.SetDefault(DB) } diff --git a/tests/generate_test.go b/tests/generate_test.go index 9b1bec22..47be92b1 100644 --- a/tests/generate_test.go +++ b/tests/generate_test.go @@ -118,6 +118,41 @@ var generateCase = map[string]func(dir string) *gen.Generator{ g.ApplyBasic(g.GenerateModelAs("users", DB.Config.NamingStrategy.SchemaName("users"), gen.WithMethod(diy_method.TestForWithMethod{}))) return g }, + generateDirPrefix + "dal_7": func(dir string) *gen.Generator { + g := gen.NewGenerator(gen.Config{ + OutPath: dir + "/query", + Mode: gen.WithDefaultQuery | gen.WithQueryInterface, + + WithUnitTest: true, + + FieldNullable: true, + FieldCoverable: true, + FieldWithIndexTag: true, + }) + g.UseDB(DB) + g.WithJSONTagNameStrategy(func(c string) string { return "-" }) + + banks := g.GenerateModel("banks") + creditCards := g.GenerateModel("credit_cards") + customers := g.GenerateModel("customers", + gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ + JSONTag: "bank", + GORMTag: field.GormTag{ + "foreignKey": []string{"BankID"}, + "references": []string{"ID"}, + }, + }), + gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ + JSONTag: "credit_cards", + GORMTag: field.GormTag{ + "foreignKey": []string{"CustomerRefer"}, + "references": []string{"ID"}, + }, + }), + ) + g.ApplyBasic(customers) + return g + }, } func TestGenerate(t *testing.T) { @@ -161,4 +196,31 @@ func TestGenerate_expect(t *testing.T) { g.UseDB(DB) g.ApplyBasic(g.GenerateAllTable()...) g.Execute() + + g = gen.NewGenerator(gen.Config{ + OutPath: expectDirPrefix + "dal_test_relation" + "/query", + Mode: gen.WithDefaultQuery, + }) + g.UseDB(DB) + + banks := g.GenerateModel("banks") + creditCards := g.GenerateModel("credit_cards") + customers := g.GenerateModel("customers", + gen.FieldRelate(field.HasOne, "Bank", banks, &field.RelateConfig{ + JSONTag: "bank", + GORMTag: field.GormTag{ + "foreignKey": []string{"BankID"}, + "references": []string{"ID"}, + }, + }), + gen.FieldRelate(field.HasMany, "CreditCards", creditCards, &field.RelateConfig{ + JSONTag: "credit_cards", + GORMTag: field.GormTag{ + "foreignKey": []string{"CustomerRefer"}, + "references": []string{"ID"}, + }, + }), + ) + g.ApplyBasic(customers, creditCards, banks) + g.Execute() } diff --git a/tests/transaction_test.go b/tests/transaction_test.go new file mode 100644 index 00000000..97d94325 --- /dev/null +++ b/tests/transaction_test.go @@ -0,0 +1,111 @@ +package tests_test + +import ( + "fmt" + "testing" + + "gorm.io/gen/tests/.expect/dal_test_relation/model" + "gorm.io/gen/tests/.expect/dal_test_relation/query" +) + +func TestQuery_Transaction_Relation(t *testing.T) { + useOnce.Do(CRUDInit) + + t.Run("transaction has many", func(t *testing.T) { + if err := query.Q.Transaction(func(tx *query.Query) error { + c := tx.Customer + customer := &model.Customer{ + Bank: model.Bank{ + Name: "bank1", + Address: "bank-address1", + Scale: 1, + }, + CreditCards: []model.CreditCard{ + {Number: "num1"}, + {Number: "num2"}, + }, + } + if err := c.WithContext(ctx).Create(customer); err != nil { + return fmt.Errorf("create model fail: %s", err) + } + + got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if len(got.CreditCards) != 2 { + return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) + } + + if err := c.CreditCards.WithContext(ctx).Model(customer).Replace(&model.CreditCard{ + Number: "num_replace", + }); err != nil { + return fmt.Errorf("replace model fail: %s", err) + } + + got, err = c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if len(got.CreditCards) != 1 { + return fmt.Errorf("replace model fail, expect %d, got %d", 1, len(got.CreditCards)) + } + if got.CreditCards[0].Number != "num_replace" { + return fmt.Errorf("replace model fail, expect %q, got %q", "num_replace", got.CreditCards[0].Number) + } + + return nil + }); err != nil { + t.Errorf("transaction execute fail: %s", err) + } + }) + + t.Run("transaction has one", func(t *testing.T) { + if err := query.Q.Transaction(func(tx *query.Query) error { + c := tx.Customer + customer := &model.Customer{ + Bank: model.Bank{ + Name: "bank1", + Address: "bank-address1", + Scale: 1, + }, + CreditCards: []model.CreditCard{ + {Number: "num1"}, + {Number: "num2"}, + }, + } + + if err := c.WithContext(ctx).Create(customer); err != nil { + return fmt.Errorf("create model fail: %s", err) + } + if err := c.Bank.WithContext(ctx).Model(customer).Replace(&model.Bank{ + Name: "bank-replace", + Address: "bank-replace-address", + Scale: 2, + }); err != nil { + return fmt.Errorf("replace model fail: %s", err) + } + + got, err := c.WithContext(ctx).Where(c.ID.Eq(customer.ID)). + Preload(c.CreditCards). + Preload(c.Bank). + First() + if err != nil { + return fmt.Errorf("find model fail: %s", err) + } + if got.Bank.Name != "bank-replace" { + return fmt.Errorf("replace model fail, expect %q, got %q", "bank-replace", got.Bank.Name) + } + + return nil + }); err != nil { + t.Errorf("transaction execute fail: %s", err) + } + }) +}