Skip to content

Commit

Permalink
Add column name referecer
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop committed Jun 19, 2023
1 parent 953676f commit 48e017a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 18 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/bool64/ctxd v1.2.1
github.com/bool64/dev v0.2.27
github.com/jmoiron/sqlx v1.3.5
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.2
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/swaggest/usecase v1.2.0 h1:cHVFqxIbHfyTXp02JmWXk+ZADaSa87UZP+b3qL5Nz90=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
41 changes: 26 additions & 15 deletions referencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ type Referencer struct {
// Default QuoteNoop.
IdentifierQuoter func(tableAndColumn ...string) string

refs map[interface{}]string
columns map[interface{}][]string
refs map[interface{}]string
columnNames map[interface{}]string
structColumns map[interface{}][]string
}

// ColumnsOf makes a Mapper option to prefix columns with table alias.
Expand Down Expand Up @@ -99,8 +100,12 @@ func (r *Referencer) AddTableAlias(rowStructPtr interface{}, alias string) {
r.refs = make(map[interface{}]string, len(f)+1)
}

if r.columns == nil {
r.columns = make(map[interface{}][]string)
if r.columnNames == nil {
r.columnNames = make(map[interface{}]string, len(f))
}

if r.structColumns == nil {
r.structColumns = make(map[interface{}][]string)
}

if alias != "" {
Expand All @@ -109,7 +114,7 @@ func (r *Referencer) AddTableAlias(rowStructPtr interface{}, alias string) {

columns := make([]string, 0, len(f))

for _, fieldName := range f {
for ptr, fieldName := range f {
var col string

if alias == "" {
Expand All @@ -119,19 +124,13 @@ func (r *Referencer) AddTableAlias(rowStructPtr interface{}, alias string) {
}

columns = append(columns, col)
r.refs[ptr] = col
r.columnNames[ptr] = fieldName
}

sort.Strings(columns)

r.columns[rowStructPtr] = columns

for ptr, fieldName := range f {
if alias == "" {
r.refs[ptr] = r.Q(fieldName)
} else {
r.refs[ptr] = r.Q(alias, fieldName)
}
}
r.structColumns[rowStructPtr] = columns
}

// Q quotes identifier.
Expand All @@ -154,6 +153,18 @@ func (r *Referencer) Ref(ptr interface{}) string {
panic(errUnknownFieldOrRow)
}

// Col returns unescaped column name for field pointer that was previously added with AddTableAlias.
//
// It panics if pointer is unknown.
// Might be used with Options.Columns.
func (r *Referencer) Col(ptr interface{}) string {
if col, found := r.columnNames[ptr]; found {
return col
}

panic(errUnknownFieldOrRow)
}

// Fmt formats according to a format specified replacing ptrs with their reference strings where possible.
//
// It panics if pointer is unknown.
Expand All @@ -173,7 +184,7 @@ func (r *Referencer) Fmt(format string, ptrs ...interface{}) string {

// Cols returns column references of a row structure.
func (r *Referencer) Cols(ptr interface{}) []string {
if cols, found := r.columns[ptr]; found {
if cols, found := r.structColumns[ptr]; found {
return cols
}

Expand Down
8 changes: 8 additions & 0 deletions referencer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,21 @@ func TestReferencer_Ref(t *testing.T) {
rf.AddTableAlias(row2, "")
assert.Equal(t, `"some_table"`, rf.Ref(row))
assert.Equal(t, `"some_table"."id"`, rf.Ref(&row.ID))
assert.Equal(t, `id`, rf.Col(&row.ID))
assert.Panics(t, func() {
rf.Ref(row2)
})
assert.Panics(t, func() {
rf.Col(row2)
})
assert.Equal(t, `"id"`, rf.Ref(&row2.ID))
assert.Equal(t, `id`, rf.Col(&row2.ID))
assert.Panics(t, func() {
rf.Ref(nil)
})
assert.Panics(t, func() {
rf.Col(nil)
})
assert.Panics(t, func() {
// Must not be nil.
rf.AddTableAlias(nil, "some_table")
Expand Down

0 comments on commit 48e017a

Please sign in to comment.