Skip to content

Commit a283436

Browse files
authored
Merge pull request #79 from huandu/feature-fieldas
Add new `fieldas` tag to set AS name for SELECT
2 parents 20e19b9 + ebd3252 commit a283436

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ type ATable struct {
136136
Field2 int `db:"field2"` // Use "db" in field tag to set column name used in SQL.
137137
Field3 int64 `db:"field3" fieldtag:"foo,bar"` // Set fieldtag to a field. We can use methods like `Struct#SelectForTag` to use it.
138138
Field4 int64 `db:"field4" fieldtag:"foo"` // If we use `s.SelectForTag(table, "foo")`, columnes of SELECT are field3 and field4.
139+
Field5 string `db:"field5" fieldas:"f5_alias"` // Use "fieldas" in field tag to set a column alias (AS) used in SELECT.
139140
Ignored int32 `db:"-"` // If we set field name as "-", Struct will ignore it.
140141
unexported int // Unexported field is not visible to Struct.
141142
Quoted string `db:"quoted" fieldopt:"withquote"` // Add quote to the field using back quote or double quote. See `Flavor#Quote`.

struct.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ var (
2222
// FieldOpt is the options for a struct field.
2323
// As db column can contain "," in theory, field options should be provided in a separated tag.
2424
FieldOpt = "fieldopt"
25+
26+
// FieldAs is the column alias (AS) for a struct field.
27+
FieldAs = "fieldas"
2528
)
2629

2730
const (
@@ -117,7 +120,13 @@ func (s *Struct) SelectFromForTag(table string, tag string) *SelectBuilder {
117120
for _, field := range fields {
118121
buf.WriteString(table)
119122
buf.WriteRune('.')
120-
buf.WriteString(field)
123+
124+
if fieldas, exists := sf.fieldAs[field]; exists {
125+
buf.WriteString(sb.As(field, fieldas))
126+
} else {
127+
buf.WriteString(field)
128+
}
129+
121130
cols = append(cols, buf.String())
122131
buf.Reset()
123132
}

struct_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,22 @@ func TestStructFieldMapper(t *testing.T) {
776776
a.Equal(sql, "SELECT t.`FieldName1`, t.set_by_tag, t.field_name1, t.EmbeddedField2, t.EmbeddedAndEmbeddedField1 FROM t")
777777
}
778778

779+
type structWithAs struct {
780+
T1 string `db:"t1" fieldas:"f1"`
781+
T2 string `db:"t2" fieldas:""` // Empty fieldas is the same as the tag is not set.
782+
T3 string `fieldas:"f3"` // AS works without db tag.
783+
T4 string `db:"t4" fieldas:"f3"` // fieldas tag can duplicate.
784+
}
785+
786+
func TestStructFieldAs(t *testing.T) {
787+
a := assert.New(t)
788+
s := NewStruct(new(structWithAs))
789+
sb := s.SelectFrom("t")
790+
b := Build(`COPY ($?) TO '/path/to/file.csv' (FORMAT CSV, HEADER)`, sb)
791+
sql, _ := b.Build()
792+
a.Equal(sql, `COPY (SELECT t.t1 AS f1, t.t2, t.T3 AS f3, t.t4 AS f3 FROM t) TO '/path/to/file.csv' (FORMAT CSV, HEADER)`)
793+
}
794+
779795
func SomeOtherMapper(string) string {
780796
return ""
781797
}

structfields.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
type structFields struct {
99
fieldAlias map[string]string
10+
fieldAs map[string]string
1011
taggedFields map[string][]string
1112
quotedFields map[string]struct{}
1213
omitEmptyFields map[string]omitEmptyTagMap
@@ -26,6 +27,7 @@ func makeFieldsParser(t reflect.Type, mapper FieldMapperFunc, useDefault bool) s
2627
var once sync.Once
2728
sf := &structFields{
2829
fieldAlias: map[string]string{},
30+
fieldAs: map[string]string{},
2931
taggedFields: map[string][]string{},
3032
quotedFields: map[string]struct{}{},
3133
omitEmptyFields: map[string]omitEmptyTagMap{},
@@ -118,6 +120,13 @@ func (sf *structFields) parse(t reflect.Type, mapper FieldMapperFunc, prefix str
118120
sf.quotedFields[alias] = struct{}{}
119121
}
120122
}
123+
124+
// Parse FieldAs.
125+
fieldas := field.Tag.Get(FieldAs)
126+
127+
if fieldas != "" {
128+
sf.fieldAs[alias] = fieldas
129+
}
121130
}
122131

123132
for _, field := range anonymous {

0 commit comments

Comments
 (0)