Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package bui
- import (
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- )
- var (
- ErrEmptyQuery = errors.New("empty query")
- chunkSize = 100
- )
- func BulkSaveBuilder(objects []map[string]interface{}, tableName string) ([]string, error) {
- if len(objects) == 0 {
- return []string{}, ErrEmptyQuery
- }
- chunks := splitToChunks(objects, chunkSize)
- keys := getKeys(objects[0])
- rawKeys := strings.Join(keys, ", ")
- var updateKeys []string
- for _, key := range keys {
- updateKeys = append(updateKeys, fmt.Sprintf("%s = VALUES(%s)", key, key))
- }
- rawUpdate := strings.Join(updateKeys, ", ")
- var queries []string
- for _, chunk := range chunks {
- var valueGroups [][]interface{}
- for _, obj := range chunk {
- var valueGroup []interface{}
- for _, key := range keys {
- valueGroup = append(valueGroup, obj[key])
- }
- valueGroups = append(valueGroups, valueGroup)
- }
- JSONValues, err := json.Marshal(valueGroups)
- if err != nil {
- return []string{}, err
- }
- rawValues := strings.ReplaceAll(fmt.Sprintf("%s", JSONValues), "[", "(")
- rawValues = strings.ReplaceAll(rawValues, "]", ")")
- q := fmt.Sprintf(
- "INSERT INTO `%s` (%s) VALUES %s ON DUPLICATE KEY UPDATE %s",
- tableName, rawKeys, rawValues[1:len(rawValues)-1], rawUpdate,
- )
- queries = append(queries, q)
- }
- return queries, nil
- }
- func getKeys(myMap map[string]interface{}) []string {
- keys := make([]string, 0, len(myMap))
- for key := range myMap {
- keys = append(keys, key)
- }
- return keys
- }
- func splitToChunks(arr []map[string]interface{}, lim int) [][]map[string]interface{} {
- var chunk []map[string]interface{}
- chunks := make([][]map[string]interface{}, 0, len(arr)/lim+1)
- for len(arr) >= lim {
- chunk, arr = arr[:lim], arr[lim:]
- chunks = append(chunks, chunk)
- }
- if len(arr) > 0 {
- chunks = append(chunks, arr[:])
- }
- return chunks
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement