|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- package db
-
- import (
- "strings"
-
- "gorm.io/gorm"
- )
-
- const (
- maxPlaceholderCount = 65535
- )
-
- func BatchNamedExec[T any](ctx SQLContext, sql string, argCnt int, arr []T, callback func(result *gorm.DB) bool) error {
- if argCnt == 0 {
- result := ctx.Exec(sql, toInterfaceSlice(arr)...)
- if result.Error != nil {
- return result.Error
- }
-
- if callback != nil {
- callback(result)
- }
-
- return nil
- }
-
- batchSize := maxPlaceholderCount / argCnt
- for len(arr) > 0 {
- curBatchSize := min(batchSize, len(arr))
-
- result := ctx.Exec(sql, toInterfaceSlice(arr[:curBatchSize])...)
- if result.Error != nil {
- return result.Error
- }
- if callback != nil && !callback(result) {
- return nil
- }
-
- arr = arr[curBatchSize:]
- }
-
- return nil
- }
-
- // 将 []T 转换为 []interface{}
- func toInterfaceSlice[T any](arr []T) []interface{} {
- interfaceSlice := make([]interface{}, len(arr))
- for i, v := range arr {
- interfaceSlice[i] = v
- }
- return interfaceSlice
- }
-
- func min(a, b int) int {
- if a < b {
- return a
- }
- return b
- }
-
- func escapeLike(left, right, word string) string {
- var n int
- for i := range word {
- if c := word[i]; c == '%' || c == '_' || c == '\\' {
- n++
- }
- }
- // No characters to escape.
- if n == 0 {
- return left + word + right
- }
- var b strings.Builder
- b.Grow(len(word) + n)
- for _, c := range word {
- if c == '%' || c == '_' || c == '\\' {
- b.WriteByte('\\')
- }
- b.WriteRune(c)
- }
- return left + b.String() + right
- }
|