refactor: extracted common logic for column aliasing

This commit is contained in:
Yosyp Buchma 2024-07-26 14:51:45 +02:00
parent c599fca5ea
commit 583ecba4a1
4 changed files with 27 additions and 19 deletions

View file

@ -1,7 +1,5 @@
package jet package jet
import "strings"
// ColumnList is a helper type to support list of columns as single projection // ColumnList is a helper type to support list of columns as single projection
type ColumnList []ColumnExpression type ColumnList []ColumnExpression
@ -46,12 +44,9 @@ func (cl ColumnList) Except(excludedColumns ...Column) ColumnList {
// For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will // For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will
// have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name'). // have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name').
func (cl ColumnList) As(tableAlias string) ProjectionList { func (cl ColumnList) As(tableAlias string) ProjectionList {
if tableAlias > "" {
tableAlias = strings.TrimRight(tableAlias, ".*") + "."
}
ret := make(ProjectionList, 0, len(cl)) ret := make(ProjectionList, 0, len(cl))
for _, c := range cl { for _, c := range cl {
ret = append(ret, c.AS(tableAlias+c.Name())) ret = append(ret, c.AS(joinAlias(tableAlias, c.Name())))
} }
return ret return ret
} }

View file

@ -1,7 +1,5 @@
package jet package jet
import "strings"
// Projection is interface for all projection types. Types that can be part of, for instance SELECT clause. // Projection is interface for all projection types. Types that can be part of, for instance SELECT clause.
type Projection interface { type Projection interface {
serializeForProjection(statement StatementType, out *SQLBuilder) serializeForProjection(statement StatementType, out *SQLBuilder)
@ -35,12 +33,6 @@ func (pl ProjectionList) serializeForProjection(statement StatementType, out *SQ
// For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will // For instance: If projection list has a column 'Artist.Name', and tableAlias is 'Musician.*', returned projection list will
// have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name'). // have a column wrapped in alias 'Musician.Name'. If tableAlias is empty string, it removes existing table alias ('Artist.Name' becomes 'Name').
func (pl ProjectionList) As(tableAlias string) ProjectionList { func (pl ProjectionList) As(tableAlias string) ProjectionList {
tableAliasWithDot := ""
if tableAlias != "" {
tableAlias = strings.TrimRight(tableAlias, ".*")
tableAliasWithDot = tableAlias + "."
}
newProjectionList := ProjectionList{} newProjectionList := ProjectionList{}
for _, projection := range pl { for _, projection := range pl {
@ -50,11 +42,11 @@ func (pl ProjectionList) As(tableAlias string) ProjectionList {
case ColumnList: case ColumnList:
newProjectionList = append(newProjectionList, p.As(tableAlias)) newProjectionList = append(newProjectionList, p.As(tableAlias))
case ColumnExpression: case ColumnExpression:
newProjectionList = append(newProjectionList, newAlias(p, tableAliasWithDot+p.Name())) newProjectionList = append(newProjectionList, newAlias(p, joinAlias(tableAlias, p.Name())))
case *alias: case *alias:
newAlias := *p newAlias := *p
_, columnName := extractTableAndColumnName(newAlias.alias) _, columnName := extractTableAndColumnName(newAlias.alias)
newAlias.alias = tableAliasWithDot + columnName newAlias.alias = joinAlias(tableAlias, columnName)
newProjectionList = append(newProjectionList, &newAlias) newProjectionList = append(newProjectionList, &newAlias)
} }
} }

View file

@ -1,10 +1,11 @@
package jet package jet
import ( import (
"github.com/go-jet/jet/v2/internal/utils/dbidentifier"
"github.com/go-jet/jet/v2/internal/utils/must"
"reflect" "reflect"
"strings" "strings"
"github.com/go-jet/jet/v2/internal/utils/dbidentifier"
"github.com/go-jet/jet/v2/internal/utils/must"
) )
// SerializeClauseList func // SerializeClauseList func
@ -278,3 +279,15 @@ func serializeToDefaultDebugString(expr Serializer) string {
expr.serialize(SelectStatementType, &out) expr.serialize(SelectStatementType, &out)
return out.Buff.String() return out.Buff.String()
} }
// joinAlias examples:
//
// joinAlias("foo", "bar") // "foo.bar"
// joinAlias("foo.*", "bar") // "foo.bar"
// joinAlias("", "bar") // "bar"
func joinAlias(tableAlias, columnAlias string) string {
if tableAlias == "" {
return columnAlias
}
return strings.TrimRight(tableAlias, ".*") + "." + columnAlias
}

View file

@ -1,8 +1,9 @@
package jet package jet
import ( import (
"github.com/stretchr/testify/require"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func TestOptionalOrDefaultString(t *testing.T) { func TestOptionalOrDefaultString(t *testing.T) {
@ -17,3 +18,10 @@ func TestOptionalOrDefaultExpression(t *testing.T) {
require.Equal(t, OptionalOrDefaultExpression(defaultExpression), defaultExpression) require.Equal(t, OptionalOrDefaultExpression(defaultExpression), defaultExpression)
require.Equal(t, OptionalOrDefaultExpression(defaultExpression, optionalExpression), optionalExpression) require.Equal(t, OptionalOrDefaultExpression(defaultExpression, optionalExpression), optionalExpression)
} }
func TestJoinAlias(t *testing.T) {
require.Equal(t, joinAlias("", ""), "")
require.Equal(t, joinAlias("foo", "bar"), "foo.bar")
require.Equal(t, joinAlias("foo.*", "bar"), "foo.bar")
require.Equal(t, joinAlias("", "bar"), "bar")
}