-
Notifications
You must be signed in to change notification settings - Fork 0
/
dml_delete.go
70 lines (62 loc) · 1.92 KB
/
dml_delete.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
package spnr
import (
"context"
"fmt"
"reflect"
"strings"
"cloud.google.com/go/spanner"
"github.com/pkg/errors"
)
// Delete build and execute delete statement from the passed struct.
// You can pass either a struct or a slice of structs to target.
// If you pass a slice of structs, this method will build statement which deletes multiple records in one statement like the following.
// DELETE FROM `T` WHERE (`COL1` = 'a' AND `COL2` = 'b') OR (`COL1` = 'c' AND `COL2` = 'd');
func (d *DML) Delete(ctx context.Context, tx *spanner.ReadWriteTransaction, target any) (rowCount int64, err error) {
isStruct, err := validateStructOrStructSliceType(target)
if err != nil {
return 0, err
}
if isStruct {
rowCount, err = tx.Update(ctx, *d.buildDeleteStmt(target))
return rowCount, errors.WithStack(err)
} else {
rowCount, err := tx.Update(ctx, *d.buildDeleteAllStmt(target))
return rowCount, errors.WithStack(err)
}
}
func (d *DML) buildDeleteStmt(target any) *spanner.Statement {
fields := toFields(target)
whereClause, params := buildWherePK(fields)
sql := fmt.Sprintf("DELETE FROM %s WHERE %s",
d.getTableName(),
whereClause,
)
d.log(sql, params)
return &spanner.Statement{
SQL: sql,
Params: params,
}
}
func (d *DML) buildDeleteAllStmt(target any) *spanner.Statement {
var valuesList []string
params := map[string]any{}
slice := reflect.ValueOf(target).Elem()
for i := 0; i < slice.Len(); i++ {
var values []string
for _, field := range extractPks(structValToFields(slice.Index(i))) {
param := addW(addIdx(field.name, i))
values = append(values, quote(field.name)+"="+addPlaceHolder(param))
params[param] = field.value
}
valuesList = append(valuesList, fmt.Sprintf("(%s)", strings.Join(values, " AND ")))
}
sql := fmt.Sprintf("DELETE FROM %s WHERE %s",
d.getTableName(),
strings.Join(valuesList, " OR "),
)
d.log(sql, params)
return &spanner.Statement{
SQL: sql,
Params: params,
}
}