Skip to content

Commit 91b7f95

Browse files
committed
support "returning" on insert
1 parent 09248db commit 91b7f95

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

insert.go

+26-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ package sqlbuilder
33
type InsertColumns map[*BasicColumn]AsExpr
44

55
type InsertStatement struct {
6-
table *Table
7-
columns InsertColumns
6+
table *Table
7+
columns InsertColumns
8+
returning []AsExpr
89
}
910

1011
func (s *InsertStatement) clone() *InsertStatement {
1112
return &InsertStatement{
12-
table: s.table,
13-
columns: s.columns,
13+
table: s.table,
14+
columns: s.columns,
15+
returning: s.returning,
1416
}
1517
}
1618

@@ -30,6 +32,12 @@ func (s *InsertStatement) Columns(columns InsertColumns) *InsertStatement {
3032
return c
3133
}
3234

35+
func (s *InsertStatement) Returning(returning ...AsExpr) *InsertStatement {
36+
c := s.clone()
37+
c.returning = returning
38+
return c
39+
}
40+
3341
func (q *InsertStatement) AsStatement(s *Serializer) {
3442
s.D("INSERT INTO ").F(q.table.AsNamed).D(" ")
3543

@@ -50,4 +58,18 @@ func (q *InsertStatement) AsStatement(s *Serializer) {
5058
s.F(k.AsExpr).DC(", ", i < len(keys)-1)
5159
}
5260
s.D(")")
61+
62+
if len(q.returning) > 0 {
63+
s.D(" RETURNING ")
64+
65+
for i, c := range q.returning {
66+
if a, ok := c.(AsResultColumn); ok {
67+
s.F(a.AsResultColumn)
68+
} else {
69+
s.F(c.AsExpr)
70+
}
71+
72+
s.DC(", ", i < len(q.returning)-1)
73+
}
74+
}
5375
}

sqlbuilder_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,40 @@ import (
77
"github.com/stretchr/testify/assert"
88
)
99

10+
func TestInsert(t *testing.T) {
11+
a := assert.New(t)
12+
13+
tbl := NewTable("users", "id", "name", "email")
14+
15+
q := Insert().Table(tbl).Columns(InsertColumns{
16+
tbl.C("name"): Bind("jim"),
17+
tbl.C("email"): Bind("[email protected]"),
18+
})
19+
20+
qs, qv, err := NewSerializer(DialectPostgres{}).F(q.AsStatement).ToSQL()
21+
22+
a.NoError(err)
23+
a.Equal("INSERT INTO \"users\" (\"name\", \"email\") VALUES ($1, $2)", qs)
24+
a.Equal([]interface{}{"jim", "[email protected]"}, qv)
25+
}
26+
27+
func TestInsertReturning(t *testing.T) {
28+
a := assert.New(t)
29+
30+
tbl := NewTable("users", "id", "name", "email")
31+
32+
q := Insert().Table(tbl).Columns(InsertColumns{
33+
tbl.C("name"): Bind("jim"),
34+
tbl.C("email"): Bind("[email protected]"),
35+
}).Returning(tbl.C("id"))
36+
37+
qs, qv, err := NewSerializer(DialectPostgres{}).F(q.AsStatement).ToSQL()
38+
39+
a.NoError(err)
40+
a.Equal("INSERT INTO \"users\" (\"name\", \"email\") VALUES ($1, $2) RETURNING \"users\".\"id\"", qs)
41+
a.Equal([]interface{}{"jim", "[email protected]"}, qv)
42+
}
43+
1044
func TestUpdate(t *testing.T) {
1145
a := assert.New(t)
1246

0 commit comments

Comments
 (0)