Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.79 KB | None | 0 0
  1. package bui
  2.  
  3. import (
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. )
  9.  
  10. var (
  11. ErrEmptyQuery = errors.New("empty query")
  12. chunkSize = 100
  13. )
  14.  
  15. func BulkSaveBuilder(objects []map[string]interface{}, tableName string) ([]string, error) {
  16. if len(objects) == 0 {
  17. return []string{}, ErrEmptyQuery
  18. }
  19.  
  20. chunks := splitToChunks(objects, chunkSize)
  21. keys := getKeys(objects[0])
  22.  
  23. rawKeys := strings.Join(keys, ", ")
  24.  
  25. var updateKeys []string
  26. for _, key := range keys {
  27. updateKeys = append(updateKeys, fmt.Sprintf("%s = VALUES(%s)", key, key))
  28. }
  29.  
  30. rawUpdate := strings.Join(updateKeys, ", ")
  31.  
  32. var queries []string
  33. for _, chunk := range chunks {
  34. var valueGroups [][]interface{}
  35. for _, obj := range chunk {
  36. var valueGroup []interface{}
  37. for _, key := range keys {
  38. valueGroup = append(valueGroup, obj[key])
  39. }
  40. valueGroups = append(valueGroups, valueGroup)
  41. }
  42.  
  43. JSONValues, err := json.Marshal(valueGroups)
  44. if err != nil {
  45. return []string{}, err
  46. }
  47.  
  48. rawValues := strings.ReplaceAll(fmt.Sprintf("%s", JSONValues), "[", "(")
  49. rawValues = strings.ReplaceAll(rawValues, "]", ")")
  50.  
  51. q := fmt.Sprintf(
  52. "INSERT INTO `%s` (%s) VALUES %s ON DUPLICATE KEY UPDATE %s",
  53. tableName, rawKeys, rawValues[1:len(rawValues)-1], rawUpdate,
  54. )
  55. queries = append(queries, q)
  56. }
  57.  
  58. return queries, nil
  59. }
  60.  
  61. func getKeys(myMap map[string]interface{}) []string {
  62. keys := make([]string, 0, len(myMap))
  63. for key := range myMap {
  64. keys = append(keys, key)
  65. }
  66. return keys
  67. }
  68.  
  69. func splitToChunks(arr []map[string]interface{}, lim int) [][]map[string]interface{} {
  70. var chunk []map[string]interface{}
  71. chunks := make([][]map[string]interface{}, 0, len(arr)/lim+1)
  72. for len(arr) >= lim {
  73. chunk, arr = arr[:lim], arr[lim:]
  74. chunks = append(chunks, chunk)
  75. }
  76. if len(arr) > 0 {
  77. chunks = append(chunks, arr[:])
  78. }
  79. return chunks
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement