forked from gocraft/dbr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
insert_builder.go
126 lines (106 loc) · 2.76 KB
/
insert_builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package dbr
import (
"context"
"database/sql"
"reflect"
)
type InsertBuilder struct {
runner
EventReceiver
Dialect Dialect
RecordID reflect.Value
*InsertStmt
}
func (sess *Session) InsertInto(table string) *InsertBuilder {
return &InsertBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
InsertStmt: InsertInto(table),
}
}
func (tx *Tx) InsertInto(table string) *InsertBuilder {
return &InsertBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
InsertStmt: InsertInto(table),
}
}
func (sess *Session) InsertBySql(query string, value ...interface{}) *InsertBuilder {
return &InsertBuilder{
runner: sess,
EventReceiver: sess,
Dialect: sess.Dialect,
InsertStmt: InsertBySql(query, value...),
}
}
func (tx *Tx) InsertBySql(query string, value ...interface{}) *InsertBuilder {
return &InsertBuilder{
runner: tx,
EventReceiver: tx,
Dialect: tx.Dialect,
InsertStmt: InsertBySql(query, value...),
}
}
func (b *InsertBuilder) Pair(column string, value interface{}) *InsertBuilder {
b.Column = append(b.Column, column)
switch len(b.Value) {
case 0:
b.InsertStmt.Values(value)
case 1:
b.Value[0] = append(b.Value[0], value)
default:
panic("pair only allows one record to insert")
}
return b
}
func (b *InsertBuilder) Exec() (sql.Result, error) {
return b.ExecContext(context.Background())
}
func (b *InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
result, err := exec(ctx, b.runner, b.EventReceiver, b, b.Dialect)
if err != nil {
return nil, err
}
if b.RecordID.IsValid() {
if id, err := result.LastInsertId(); err == nil {
b.RecordID.SetInt(id)
}
}
return result, nil
}
func (b *InsertBuilder) LoadContext(ctx context.Context, value interface{}) error {
_, err := query(ctx, b.runner, b.EventReceiver, b, b.Dialect, value)
return err
}
func (b *InsertBuilder) Load(value interface{}) error {
return b.LoadContext(context.Background(), value)
}
func (b *InsertBuilder) Columns(column ...string) *InsertBuilder {
b.InsertStmt.Columns(column...)
return b
}
func (b *InsertBuilder) Returning(column ...string) *InsertBuilder {
b.InsertStmt.Returning(column...)
return b
}
func (b *InsertBuilder) Record(structValue interface{}) *InsertBuilder {
v := reflect.Indirect(reflect.ValueOf(structValue))
if v.Kind() == reflect.Struct && v.CanSet() {
// ID is recommended by golint here
for _, name := range []string{"Id", "ID"} {
field := v.FieldByName(name)
if field.IsValid() && field.Kind() == reflect.Int64 {
b.RecordID = field
break
}
}
}
b.InsertStmt.Record(structValue)
return b
}
func (b *InsertBuilder) Values(value ...interface{}) *InsertBuilder {
b.InsertStmt.Values(value...)
return b
}