-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinsert_dsl.go
96 lines (86 loc) · 1.99 KB
/
insert_dsl.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
package q
import (
"context"
"github.com/wxy365/basal/fn"
"github.com/wxy365/basal/lei"
"reflect"
"strings"
)
type InsertDsl[T any] struct {
rows []T
table *Table
}
func (i *InsertDsl[T]) Build() *Insertion[T] {
return &Insertion[T]{
rows: i.rows,
table: i.table,
}
}
func (i *InsertDsl[T]) Action(ctx context.Context, db *DB) error {
renderCtx := &RenderCtx{
dbType: db.dbType,
cnt: new(fn.Counter),
}
stm, params := i.Build().GetStatement(renderCtx).prepare()
result, err := db.ExecContext(ctx, stm, params...)
id, err := result.LastInsertId()
if err != nil {
return err
}
inserted := i.rows[len(i.rows)-1]
val := reflect.ValueOf(inserted)
for j := 0; j < val.NumField(); j++ {
if col, ok := val.Type().Field(j).Tag.Lookup("db"); ok && strings.HasSuffix(col, ":auto_incr") {
val.Field(j).SetInt(id)
break
}
}
return nil
}
func (i *InsertDsl[T]) ActionTx(ctx context.Context, tx *TX) error {
renderCtx := &RenderCtx{
dbType: tx.dbType,
cnt: new(fn.Counter),
}
stm, params := i.Build().GetStatement(renderCtx).prepare()
result, err := tx.ExecContext(ctx, stm, params...)
id, err := result.LastInsertId()
if err != nil {
return err
}
inserted := i.rows[len(i.rows)-1]
val := reflect.ValueOf(inserted)
for j := 0; j < val.NumField(); j++ {
if col, ok := val.Type().Field(j).Tag.Lookup("db"); ok && strings.HasSuffix(col, ":auto_incr") {
val.Field(j).SetInt(id)
break
}
}
return nil
}
func Insert[T any](rows ...T) *IntoGather[T] {
if len(rows) == 0 {
panic(lei.New("Nothing to insert"))
}
return &IntoGather[T]{
rows: rows,
}
}
func InsertDO[T DO](rows ...T) *InsertDsl[T] {
if len(rows) == 0 {
panic(lei.New("Nothing to insert"))
}
return Insert(rows...).Into(rows[0].TableName())
}
type IntoGather[T any] struct {
rows []T
}
func (i *IntoGather[T]) Into(table string) *InsertDsl[T] {
return i.IntoT(Tbl(table))
}
func (i *IntoGather[T]) IntoT(table *Table) *InsertDsl[T] {
return &InsertDsl[T]{
rows: i.rows,
table: table,
}
}