Skip to content

Commit

Permalink
database/gdb: add unscoped tag support for orm struct (#3464)
Browse files Browse the repository at this point in the history
  • Loading branch information
fainc committed May 22, 2024
1 parent 17385ee commit b675d01
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 9 deletions.
110 changes: 110 additions & 0 deletions contrib/drivers/mysql/mysql_z_unit_feature_with_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"fmt"
"testing"

"github.com/gogf/gf/v2/os/gtime"

"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/test/gtest"
Expand Down Expand Up @@ -1988,3 +1990,111 @@ PRIMARY KEY (id)
t.Assert(user.UserScores[4].Score, 5)
})
}

func Test_Table_Relation_WithAll_Unscoped(t *testing.T) {
var (
tableUser = "user101"
tableUserDetail = "user_detail101"
)
if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUser)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUser)

if _, err := db.Exec(ctx, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
user_id int(10) unsigned NOT NULL,
address varchar(45) NOT NULL,
deleted_at datetime default NULL ,
PRIMARY KEY (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableUserDetail)); err != nil {
gtest.Error(err)
}
defer dropTable(tableUserDetail)

type UserDetail struct {
gmeta.Meta `orm:"table:user_detail101"`
UserID int `json:"user_id"`
Address string `json:"address"`
DeletedAt *gtime.Time `json:"deleted_at"`
}

// For Test Only
type UserEmbedded struct {
ID int `json:"id"`
Name string `json:"name"`
}

type User struct {
gmeta.Meta `orm:"table:user101"`
UserEmbedded
UserDetail *UserDetail `orm:"with:user_id=id"`
}
type UserWithDeletedDetail struct {
gmeta.Meta `orm:"table:user101"`
UserEmbedded
UserDetail *UserDetail `orm:"with:user_id=id, unscoped:true"`
}

// Initialize the data.
var err error
for i := 1; i <= 5; i++ {
// User.
_, err = db.Insert(ctx, tableUser, g.Map{
"id": i,
"name": fmt.Sprintf(`name_%d`, i),
})
gtest.AssertNil(err)
// Detail.
_, err = db.Insert(ctx, tableUserDetail, g.Map{
"user_id": i,
"address": fmt.Sprintf(`address_%d`, i),
})
// Delete detail where i = 3
if i == 3 {
_, err = db.Delete(ctx, tableUserDetail, g.Map{
"user_id": i,
})
}
gtest.AssertNil(err)
}
gtest.C(t, func(t *gtest.T) {
var user0 User
err := db.Model(tableUser).WithAll().Where("id", 4).Scan(&user0)
t.AssertNil(err)
t.Assert(user0.ID, 4)
t.AssertNE(user0.UserDetail, nil)
t.AssertNil(user0.UserDetail.DeletedAt)
t.Assert(user0.UserDetail.UserID, 4)
t.Assert(user0.UserDetail.Address, `address_4`)

var user1 User
err = db.Model(tableUser).WithAll().Where("id", 3).Scan(&user1)
t.AssertNil(err)
t.Assert(user1.ID, 3)
t.AssertNil(user1.UserDetail)

var user2 UserWithDeletedDetail
err = db.Model(tableUser).WithAll().Where("id", 3).Scan(&user2)
t.AssertNil(err)
t.Assert(user2.ID, 3)
t.AssertNE(user2.UserDetail, nil)
t.AssertNE(user2.UserDetail.DeletedAt, nil)
t.Assert(user2.UserDetail.UserID, 3)
t.Assert(user2.UserDetail.Address, `address_3`)

// Unscoped outside test
var user3 User
err = db.Model(tableUser).Unscoped().WithAll().Where("id", 3).Scan(&user3)
t.AssertNil(err)
t.Assert(user3.ID, 3)
t.AssertNil(user3.UserDetail)
})
}
13 changes: 7 additions & 6 deletions database/gdb/gdb_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ type iTableName interface {
}

const (
OrmTagForStruct = "orm"
OrmTagForTable = "table"
OrmTagForWith = "with"
OrmTagForWithWhere = "where"
OrmTagForWithOrder = "order"
OrmTagForDo = "do"
OrmTagForStruct = "orm"
OrmTagForTable = "table"
OrmTagForWith = "with"
OrmTagForWithWhere = "where"
OrmTagForWithOrder = "order"
OrmTagForWithUnscoped = "unscoped"
OrmTagForDo = "do"
)

var (
Expand Down
14 changes: 11 additions & 3 deletions database/gdb/gdb_model_with.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ func (m *Model) doWithScanStruct(pointer interface{}) error {
if parsedTagOutput.Order != "" {
model = model.Order(parsedTagOutput.Order)
}
if parsedTagOutput.Unscoped == "true" {
model = model.Unscoped()
}
// With cache feature.
if m.cacheEnabled && m.cacheOption.Name == "" {
model = model.Cache(m.cacheOption)
Expand Down Expand Up @@ -277,6 +280,9 @@ func (m *Model) doWithScanStructs(pointer interface{}) error {
if parsedTagOutput.Order != "" {
model = model.Order(parsedTagOutput.Order)
}
if parsedTagOutput.Unscoped == "true" {
model = model.Unscoped()
}
// With cache feature.
if m.cacheEnabled && m.cacheOption.Name == "" {
model = model.Cache(m.cacheOption)
Expand All @@ -293,9 +299,10 @@ func (m *Model) doWithScanStructs(pointer interface{}) error {
}

type parseWithTagInFieldStructOutput struct {
With string
Where string
Order string
With string
Where string
Order string
Unscoped string
}

func (m *Model) parseWithTagInFieldStruct(field gstructs.Field) (output parseWithTagInFieldStructOutput) {
Expand All @@ -320,5 +327,6 @@ func (m *Model) parseWithTagInFieldStruct(field gstructs.Field) (output parseWit
output.With = data[OrmTagForWith]
output.Where = data[OrmTagForWithWhere]
output.Order = data[OrmTagForWithOrder]
output.Unscoped = data[OrmTagForWithUnscoped]
return
}

0 comments on commit b675d01

Please sign in to comment.