-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinsert.go
More file actions
103 lines (90 loc) · 2.55 KB
/
insert.go
File metadata and controls
103 lines (90 loc) · 2.55 KB
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
// A quickly mysql access component.
//
// Copyright 2023 The daog Authors. All rights reserved.
package daog
import (
"strings"
"time"
)
// Insert 插入一条数据到表中,如果表有自增id,那么生成的id赋值到ins对象中
//
// 参数: ins 表实体对象,对应表的struct由 compile生成,比如 GroupInfo, meta 表的元数据,由compile编译生成,比如 GroupInfo.GroupInfoMeta
//
// 返回值: 插入的记录数,是否出错
func Insert[T any](tc *TransContext, ins *T, meta *TableMeta[T]) (int64, error) {
tableName := GetTableName(tc.ctx, meta)
if BeforeInsertCallback != nil {
if err := BeforeInsertCallback(tableName, ins); err != nil {
return 0, err
}
}
exclude := meta.shouldExcludeColumns(ins, false)
var insertColumns []string
var holder []string
if len(exclude) == 0 {
insertColumns = meta.Columns
for range insertColumns {
holder = append(holder, "?")
}
} else {
for _, column := range meta.Columns {
if exclude[column] == 1 {
continue
}
insertColumns = append(insertColumns, column)
holder = append(holder, "?")
}
}
if err := auoFillField(tc, ins, meta); err != nil {
return 0, err
}
var builder strings.Builder
builder.WriteString("insert into ")
builder.WriteString(tableName)
builder.WriteString("(")
builder.WriteString(strings.Join(insertColumns, ","))
builder.WriteString(") values(")
builder.WriteString(strings.Join(holder, ","))
builder.WriteString(")")
sql := builder.String()
args := meta.ExtractFieldValues(ins, false, exclude)
affect, lastId, err := execInsert(tc, sql, args, meta.AutoColumn != "")
if err != nil {
return 0, err
}
if meta.AutoColumn != "" {
autoAddr := meta.LookupFieldFunc(meta.AutoColumn, ins, true)
*(autoAddr.(*int64)) = lastId
}
return affect, err
}
func execInsert(tc *TransContext, sql string, args []any, auto bool) (int64, int64, error) {
err := tc.check()
if err != nil {
return 0, 0, err
}
if tc.LogSQL {
sqlMd5 := traceLogSQLBefore(tc.ctx, sql, args)
defer traceLogSQLAfter(tc.ctx, sqlMd5, time.Now().UnixMilli())
}
result, err := tc.conn.ExecContext(tc.ctx, sql, args...)
if err != nil {
return 0, 0, err
}
affectRow, err := result.RowsAffected()
if !auto || err != nil {
return affectRow, 0, err
}
id, err := result.LastInsertId()
return affectRow, id, err
}
func auoFillField[T any](tc *TransContext, ins *T, meta *TableMeta[T]) error {
if ChangeFieldOfInsBeforeWrite != nil {
err := ChangeFieldOfInsBeforeWrite(tc.ExtInfo, &fieldExtractor[T]{
ins: ins,
meta: meta,
})
return err
}
return nil
}