Skip to content

Commit a8ccad7

Browse files
committed
fix #83: Support RETURNING in InsertBuilder
1 parent e83d572 commit a8ccad7

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

insert.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const (
1414
insertMarkerAfterCols
1515
insertMarkerAfterValues
1616
insertMarkerAfterSelect
17+
insertMarkerAfterReturning
1718
)
1819

1920
// NewInsertBuilder creates a new INSERT builder.
@@ -32,10 +33,11 @@ func newInsertBuilder() *InsertBuilder {
3233

3334
// InsertBuilder is a builder to build INSERT.
3435
type InsertBuilder struct {
35-
verb string
36-
table string
37-
cols []string
38-
values [][]string
36+
verb string
37+
table string
38+
cols []string
39+
values [][]string
40+
returning []string
3941

4042
args *Args
4143

@@ -112,6 +114,14 @@ func (ib *InsertBuilder) Values(value ...interface{}) *InsertBuilder {
112114
return ib
113115
}
114116

117+
// Returning sets returning columns.
118+
// For DBMS that doesn't support RETURNING, e.g. MySQL, it will be ignored.
119+
func (ib *InsertBuilder) Returning(col ...string) *InsertBuilder {
120+
ib.returning = col
121+
ib.marker = insertMarkerAfterReturning
122+
return ib
123+
}
124+
115125
// NumValue returns the number of values to insert.
116126
func (ib *InsertBuilder) NumValue() int {
117127
return len(ib.values)
@@ -203,6 +213,15 @@ func (ib *InsertBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{
203213

204214
ib.injection.WriteTo(buf, insertMarkerAfterValues)
205215

216+
if flavor == PostgreSQL || flavor == SQLite {
217+
if len(ib.returning) > 0 {
218+
buf.WriteLeadingString("RETURNING ")
219+
buf.WriteStrings(ib.returning, ", ")
220+
}
221+
222+
ib.injection.WriteTo(buf, insertMarkerAfterReturning)
223+
}
224+
206225
return ib.args.CompileWithFlavor(buf.String(), flavor, initialArg...)
207226
}
208227

insert_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,54 @@ func ExampleInsertBuilder_NumValue() {
245245
// 2
246246
}
247247

248+
func ExampleInsertBuilder_Returning() {
249+
sql, args := InsertInto("user").
250+
Cols("name").Values("Huan Du").
251+
Returning("id").
252+
BuildWithFlavor(PostgreSQL)
253+
254+
fmt.Println(sql)
255+
fmt.Println(args)
256+
257+
// Output:
258+
// INSERT INTO user (name) VALUES ($1) RETURNING id
259+
// [Huan Du]
260+
}
261+
262+
func TestInsertBuilderReturning(test *testing.T) {
263+
a := assert.New(test)
264+
ib := InsertInto("user").
265+
Cols("name").Values("Huan Du").
266+
Returning("id")
267+
268+
sql, _ := ib.BuildWithFlavor(MySQL)
269+
a.Equal("INSERT INTO user (name) VALUES (?)", sql)
270+
271+
sql, _ = ib.BuildWithFlavor(PostgreSQL)
272+
a.Equal("INSERT INTO user (name) VALUES ($1) RETURNING id", sql)
273+
274+
sql, _ = ib.BuildWithFlavor(SQLite)
275+
a.Equal("INSERT INTO user (name) VALUES (?) RETURNING id", sql)
276+
277+
sql, _ = ib.BuildWithFlavor(SQLServer)
278+
a.Equal("INSERT INTO user (name) VALUES (@p1)", sql)
279+
280+
sql, _ = ib.BuildWithFlavor(CQL)
281+
a.Equal("INSERT INTO user (name) VALUES (?)", sql)
282+
283+
sql, _ = ib.BuildWithFlavor(ClickHouse)
284+
a.Equal("INSERT INTO user (name) VALUES (?)", sql)
285+
286+
sql, _ = ib.BuildWithFlavor(Presto)
287+
a.Equal("INSERT INTO user (name) VALUES (?)", sql)
288+
289+
sql, _ = ib.BuildWithFlavor(Oracle)
290+
a.Equal("INSERT INTO user (name) VALUES (:1)", sql)
291+
292+
sql, _ = ib.BuildWithFlavor(Informix)
293+
a.Equal("INSERT INTO user (name) VALUES (?)", sql)
294+
}
295+
248296
func TestInsertBuilderGetFlavor(t *testing.T) {
249297
a := assert.New(t)
250298
ib := newInsertBuilder()

0 commit comments

Comments
 (0)