Skip to content

Commit

Permalink
Fix automatic column selection not working in joins
Browse files Browse the repository at this point in the history
  • Loading branch information
System-Glitch committed Oct 18, 2022
1 parent 1bc1b01 commit 8026ed8
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 16 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/stretchr/testify v1.7.0
gorm.io/gorm v1.23.2
gorm.io/gorm v1.23.10
goyave.dev/goyave/v4 v4.2.0
)

Expand All @@ -14,7 +14,7 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.4 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -207,8 +208,9 @@ gorm.io/driver/postgres v1.3.1/go.mod h1:WwvWOuR9unCLpGWCL6Y3JOeBWvbKi6JLhayiVcl
gorm.io/driver/sqlite v1.3.1/go.mod h1:wJx0hJspfycZ6myN38x1O/AqLtNS6c5o9TndewFbELg=
gorm.io/driver/sqlserver v1.3.1/go.mod h1:w25Vrx2BG+CJNUu/xKbFhaKlGxT/nzRkhWCCoptX8tQ=
gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.2 h1:xmq9QRMWL8HTJyhAUBXy8FqIIQCYESeKfJL4DoGKiWQ=
gorm.io/gorm v1.23.2/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.10 h1:4Ne9ZbzID9GUxRkllxN4WjJKpsHx8YbKvekVdgyWh24=
gorm.io/gorm v1.23.10/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
goyave.dev/goyave/v4 v4.2.0 h1:M0ZRtP3OXSda0+8dBdYRRCdbG3Wxg630FxS6rqdwLBw=
goyave.dev/goyave/v4 v4.2.0/go.mod h1:AHpLpWiV3Qf+5onrNkkd9GF7LWm+i0lcNXjOcNp25nk=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
13 changes: 9 additions & 4 deletions join.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,16 @@ func (j *Join) applyRelation(schema *schema.Schema, blacklist *Blacklist, relati
}

func joinScope(relationName string, rel *schema.Relationship, fields []string, blacklist *Blacklist) func(*gorm.DB) *gorm.DB {
var b []string
if blacklist != nil {
b = blacklist.FieldsBlacklist
var columns []*schema.Field
if fields == nil {
columns = getSelectableFields(blacklist, rel.FieldSchema.FieldsByDBName)
} else {
var b []string
if blacklist != nil {
b = blacklist.FieldsBlacklist
}
columns = cleanColumns(rel.FieldSchema, fields, b)
}
columns := cleanColumns(rel.FieldSchema, fields, b)

return func(tx *gorm.DB) *gorm.DB {
if rel.FieldSchema.Table == "" {
Expand Down
44 changes: 44 additions & 0 deletions join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,50 @@ func TestJoinScope(t *testing.T) {
assert.Equal(t, []string{"a", "b", "notacolumn"}, join.selectCache["Relation"])
}

func TestJoinScopeAutoSelectFieldsNoBlacklist(t *testing.T) {
db, _ := gorm.Open(&tests.DummyDialector{}, nil)
join := &Join{Relation: "Relation", Fields: nil}
join.selectCache = map[string][]string{}
schema, err := parseModel(db, &JoinTestModel{})
if !assert.Nil(t, err) {
return
}

results := map[string]interface{}{}
db = db.Scopes(join.Scopes(&Settings{}, schema)...).Table("table").Find(&results)
if assert.Contains(t, db.Statement.Preloads, "Relation") {
tx := db.Scopes(db.Statement.Preloads["Relation"][0].(func(*gorm.DB) *gorm.DB)).Find(nil)
assert.ElementsMatch(t, []string{"`relation`.`a`", "`relation`.`b`"}, tx.Statement.Selects)
}
assert.Nil(t, join.selectCache["Relation"])
}

func TestJoinScopeAutoSelectFieldsWithBlacklist(t *testing.T) {
db, _ := gorm.Open(&tests.DummyDialector{}, nil)
join := &Join{Relation: "Relation", Fields: nil}
join.selectCache = map[string][]string{}
schema, err := parseModel(db, &JoinTestModel{})
if !assert.Nil(t, err) {
return
}

blacklist := Blacklist{
Relations: map[string]*Blacklist{
"Relation": {
FieldsBlacklist: []string{"b"},
},
},
}

results := map[string]interface{}{}
db = db.Scopes(join.Scopes(&Settings{Blacklist: blacklist}, schema)...).Table("table").Find(&results)
if assert.Contains(t, db.Statement.Preloads, "Relation") {
tx := db.Scopes(db.Statement.Preloads["Relation"][0].(func(*gorm.DB) *gorm.DB)).Find(nil)
assert.ElementsMatch(t, []string{"`relation`.`a`"}, tx.Statement.Selects)
}
assert.Nil(t, join.selectCache["Relation"])
}

func TestJoinScopeAnonymousRelation(t *testing.T) {
db, _ := gorm.Open(&tests.DummyDialector{}, nil)
join := &Join{Relation: "notarelation", Fields: []string{"a", "b", "notacolumn"}}
Expand Down
14 changes: 7 additions & 7 deletions settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (s *Settings) scopeFields(db *gorm.DB, request *goyave.Request, schema *sch
}
return db.Scopes(selectScope(schema.Table, cleanColumns(schema, fields, s.FieldsBlacklist), false))
}
return db.Scopes(selectScope(schema.Table, s.getSelectableFields(schema.FieldsByDBName), false))
return db.Scopes(selectScope(schema.Table, getSelectableFields(&s.Blacklist, schema.FieldsByDBName), false))
}

func (s *Settings) scopeSort(db *gorm.DB, request *goyave.Request, schema *schema.Schema) *gorm.DB {
Expand Down Expand Up @@ -258,7 +258,7 @@ func (s *Settings) applySearch(request *goyave.Request, schema *schema.Schema) *
if ok {
fields := s.FieldsSearch
if fields == nil {
for _, f := range s.getSelectableFields(schema.FieldsByDBName) {
for _, f := range getSelectableFields(&s.Blacklist, schema.FieldsByDBName) {
fields = append(fields, f.DBName)
}
}
Expand All @@ -280,14 +280,14 @@ func (s *Settings) applySearch(request *goyave.Request, schema *schema.Schema) *
return nil
}

func (b *Blacklist) getSelectableFields(fields map[string]*schema.Field) []*schema.Field {
blacklist := []string{}
if b.FieldsBlacklist != nil {
blacklist = b.FieldsBlacklist
func getSelectableFields(blacklist *Blacklist, fields map[string]*schema.Field) []*schema.Field {
b := []string{}
if blacklist != nil && blacklist.FieldsBlacklist != nil {
b = blacklist.FieldsBlacklist
}
columns := make([]*schema.Field, 0, len(fields))
for k, f := range fields {
if !sliceutil.ContainsStr(blacklist, k) {
if !sliceutil.ContainsStr(b, k) {
columns = append(columns, f)
}
}
Expand Down
3 changes: 2 additions & 1 deletion settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,8 @@ func TestBlacklistGetSelectableFields(t *testing.T) {
"email": {},
}

assert.ElementsMatch(t, []*schema.Field{fields["id"], fields["email"]}, blacklist.getSelectableFields(fields))
assert.ElementsMatch(t, []*schema.Field{fields["id"], fields["email"]}, getSelectableFields(blacklist, fields))
assert.ElementsMatch(t, []*schema.Field{fields["id"], fields["email"], fields["name"]}, getSelectableFields(nil, fields))
}

type TestFilterScopeModel struct {
Expand Down

0 comments on commit 8026ed8

Please sign in to comment.