Skip to content

Commit cb43436

Browse files
SpencerCMDobakhuandugitter-badgerzhongr3n
authored
Merge remote-tracking branch 'upstream/master' (#2)
* ignore unexported fields that are not embedded structs * fix #74 [BREAKING CHANGE] Select#GroupBy and Select#OrderBy behavior change. Previous, GroupBy and OrderBy only keep the columns in the last call. Now, all columns are kept. * fix #75 add Struct#Columns/ColumnsForTag and Struct#Values/ValuesForTag * remove a call to StructField.IsExported as it is not in go1.13 * refs #78 add new `fieldas` tag to set AS name for SELECT * update docs * fix #81 refactory struct field parser to make fieldas correct in all cases * Add Gitter badge * Fix insert ignore for postgres and sqlite. * fix test Co-authored-by: Michał Dobaczewski <[email protected]> Co-authored-by: Huan Du <[email protected]> Co-authored-by: The Gitter Badger <[email protected]> Co-authored-by: Zhong Ren <[email protected]>
1 parent 989b698 commit cb43436

File tree

9 files changed

+487
-200
lines changed

9 files changed

+487
-200
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Go](https://github.com/huandu/go-sqlbuilder/workflows/Go/badge.svg)](https://github.com/huandu/go-sqlbuilder/actions)
44
[![GoDoc](https://godoc.org/github.com/huandu/go-sqlbuilder?status.svg)](https://pkg.go.dev/github.com/huandu/go-sqlbuilder)
55
[![Go Report](https://goreportcard.com/badge/github.com/huandu/go-sqlbuilder)](https://goreportcard.com/report/github.com/huandu/go-sqlbuilder)
6-
[![Coverage Status](https://coveralls.io/repos/github/huandu/go-sqlbuilder/badge.svg?branch=master)](https://coveralls.io/github/huandu/go-sqlbuilder?branch=master)
6+
[![Coverage Status](https://coveralls.io/repos/github/huandu/go-sqlbuilder/badge.svg?branch=master)](https://coveralls.io/github/huandu/go-sqlbuilder?branch=master) [![Join the chat at https://gitter.im/go-sqlbuilder/community](https://badges.gitter.im/go-sqlbuilder/community.svg)](https://gitter.im/go-sqlbuilder/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
77

88
- [Install](#install)
99
- [Usage](#usage)
@@ -134,8 +134,9 @@ We can define a struct type and use field tags to let `Struct` know how to creat
134134
type ATable struct {
135135
Field1 string // If a field doesn't has a tag, use "Field1" as column name in SQL.
136136
Field2 int `db:"field2"` // Use "db" in field tag to set column name used in SQL.
137-
Field3 int64 `db:"field3" fieldtag:"foo,bar"` // Set fieldtag to a field. We can use methods like `Struct#SelectForTag` to use it.
138-
Field4 int64 `db:"field4" fieldtag:"foo"` // If we use `s.SelectForTag(table, "foo")`, columnes of SELECT are field3 and field4.
137+
Field3 int64 `db:"field3" fieldtag:"foo,bar"` // Set fieldtag to a field. We can call `WithTag` to change default tag or call methods like `Struct#SelectForTag` to set tag explicitly.
138+
Field4 int64 `db:"field4" fieldtag:"foo"` // If we use `s.WithTag("foo").Select(table)`, 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`.

flavor.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,27 @@ func (f Flavor) Quote(name string) string {
138138

139139
return name
140140
}
141+
142+
// PrepareInsertIgnore prepares the insert builder to build insert ignore SQL statement based on the sql flavor
143+
func (f Flavor) PrepareInsertIgnore(table string, ib *InsertBuilder) {
144+
switch ib.args.Flavor {
145+
case MySQL:
146+
ib.verb = "INSERT IGNORE"
147+
case PostgreSQL:
148+
// see https://www.postgresql.org/docs/current/sql-insert.html
149+
ib.verb = "INSERT"
150+
// add sql statement at the end after values, i.e. INSERT INTO ... ON CONFLICT DO NOTHING
151+
ib.marker = insertMarkerAfterValues
152+
ib.SQL("ON CONFLICT DO NOTHING")
153+
case SQLite:
154+
// see https://www.sqlite.org/lang_insert.html
155+
ib.verb = "INSERT OR IGNORE"
156+
default:
157+
// panic if the db flavor is not supported
158+
panic(fmt.Errorf("unsupported db flavor: %s", ib.args.Flavor.String()))
159+
}
160+
161+
// Set the table and reset the marker right after insert into
162+
ib.table = Escape(table)
163+
ib.marker = insertMarkerAfterInsertInto
164+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/huandu/go-sqlbuilder
22

3-
go 1.12
3+
go 1.13
44

55
require (
66
github.com/huandu/go-assert v1.1.5

insert.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ func InsertIgnoreInto(table string) *InsertBuilder {
6464

6565
// InsertIgnoreInto sets table name in INSERT IGNORE.
6666
func (ib *InsertBuilder) InsertIgnoreInto(table string) *InsertBuilder {
67-
ib.verb = "INSERT IGNORE"
68-
ib.table = Escape(table)
69-
ib.marker = insertMarkerAfterInsertInto
67+
ib.args.Flavor.PrepareInsertIgnore(table, ib)
7068
return ib
7169
}
7270

insert_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,38 @@ func ExampleInsertBuilder_insertIgnore() {
8181
// [1 Huan Du 1 2 Charmy Liu 1 1234567890]
8282
}
8383

84+
func ExampleInsertBuilder_insertIgnore_postgres() {
85+
ib := PostgreSQL.NewInsertBuilder()
86+
ib.InsertIgnoreInto("demo.user")
87+
ib.Cols("id", "name", "status", "created_at")
88+
ib.Values(1, "Huan Du", 1, Raw("UNIX_TIMESTAMP(NOW())"))
89+
ib.Values(2, "Charmy Liu", 1, 1234567890)
90+
91+
sql, args := ib.Build()
92+
fmt.Println(sql)
93+
fmt.Println(args)
94+
95+
// Output:
96+
// INSERT INTO demo.user (id, name, status, created_at) VALUES ($1, $2, $3, UNIX_TIMESTAMP(NOW())), ($4, $5, $6, $7) ON CONFLICT DO NOTHING
97+
// [1 Huan Du 1 2 Charmy Liu 1 1234567890]
98+
}
99+
100+
func ExampleInsertBuilder_insertIgnore_sqlite() {
101+
ib := SQLite.NewInsertBuilder()
102+
ib.InsertIgnoreInto("demo.user")
103+
ib.Cols("id", "name", "status", "created_at")
104+
ib.Values(1, "Huan Du", 1, Raw("UNIX_TIMESTAMP(NOW())"))
105+
ib.Values(2, "Charmy Liu", 1, 1234567890)
106+
107+
sql, args := ib.Build()
108+
fmt.Println(sql)
109+
fmt.Println(args)
110+
111+
// Output:
112+
// INSERT OR IGNORE INTO demo.user (id, name, status, created_at) VALUES (?, ?, ?, UNIX_TIMESTAMP(NOW())), (?, ?, ?, ?)
113+
// [1 Huan Du 1 2 Charmy Liu 1 1234567890]
114+
}
115+
84116
func ExampleInsertBuilder_replaceInto() {
85117
ib := NewInsertBuilder()
86118
ib.ReplaceInto("demo.user")

select.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,14 @@ func (sb *SelectBuilder) Having(andExpr ...string) *SelectBuilder {
153153

154154
// GroupBy sets columns of GROUP BY in SELECT.
155155
func (sb *SelectBuilder) GroupBy(col ...string) *SelectBuilder {
156-
sb.groupByCols = col
156+
sb.groupByCols = append(sb.groupByCols, col...)
157157
sb.marker = selectMarkerAfterGroupBy
158158
return sb
159159
}
160160

161161
// OrderBy sets columns of ORDER BY in SELECT.
162162
func (sb *SelectBuilder) OrderBy(col ...string) *SelectBuilder {
163-
sb.orderByCols = col
163+
sb.orderByCols = append(sb.orderByCols, col...)
164164
sb.marker = selectMarkerAfterOrderBy
165165
return sb
166166
}

0 commit comments

Comments
 (0)