github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/bulk/gorm-bulk/bulk_insert_extend.go (about) 1 package gormbulk 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/angenalZZZ/gofunc/f" 8 "github.com/dop251/goja" 9 "github.com/jinzhu/gorm" 10 ) 11 12 // BulkInsertByJs executes the query to insert multiple records at once. 13 func BulkInsertByJs(db *gorm.DB, objects []map[string]interface{}, chunkSize int, javascript string, interval time.Duration, varRecords ...string) error { 14 var ( 15 fnName = "records" 16 vm = goja.New() 17 res goja.Value 18 err error 19 ) 20 21 if len(varRecords) > 0 { 22 fnName = varRecords[0] 23 } 24 25 defer func() { vm.ClearInterrupt() }() 26 27 // Split records with specified size not to exceed Database parameter limit 28 for _, records := range f.SplitObjectMaps(objects, chunkSize) { 29 // Input records 30 vm.Set(fnName, records) 31 32 // Output sql 33 if res, err = vm.RunString(javascript); err != nil { 34 return fmt.Errorf("the table script error, must contain array %q, error: %s", fnName, err.Error()) 35 } else if res == nil { 36 continue 37 } 38 39 val := res.Export() 40 if val == nil { 41 continue 42 } 43 44 switch sql := val.(type) { 45 case string: 46 if len(sql) < 20 { 47 continue 48 } 49 if err := db.Exec(sql).Error; err != nil { 50 return err 51 } 52 case []string: 53 for _, s := range sql { 54 if len(s) < 20 { 55 continue 56 } 57 if err := db.Exec(s).Error; err != nil { 58 return err 59 } 60 } 61 } 62 63 if interval > 0 { 64 time.Sleep(interval) 65 } 66 } 67 return nil 68 } 69 70 // BulkInsertByJsFunction executes the query to insert multiple records at once. 71 func BulkInsertByJsFunction(db *gorm.DB, objects []map[string]interface{}, chunkSize int, javascript, functionName string, interval time.Duration) error { 72 var ( 73 vm = goja.New() 74 fn func([]map[string]interface{}) interface{} 75 ) 76 77 defer func() { vm.ClearInterrupt() }() 78 79 if _, err := vm.RunString(javascript); err != nil { 80 return err 81 } 82 83 val := vm.Get(functionName) 84 if val == nil { 85 return fmt.Errorf("js function %q not found", functionName) 86 } 87 88 if err := vm.ExportTo(val, &fn); err != nil { 89 return fmt.Errorf("js function %q not exported %s", functionName, err.Error()) 90 } 91 92 // Split records with specified size not to exceed Database parameter limit 93 for _, records := range f.SplitObjectMaps(objects, chunkSize) { 94 // Output sql 95 val := fn(records) 96 if val == nil { 97 continue 98 } 99 100 switch sql := val.(type) { 101 case string: 102 if len(sql) < 20 { 103 continue 104 } 105 if err := db.Exec(sql).Error; err != nil { 106 return err 107 } 108 case []string: 109 for _, s := range sql { 110 if len(s) < 20 { 111 continue 112 } 113 if err := db.Exec(s).Error; err != nil { 114 return err 115 } 116 } 117 } 118 119 if interval > 0 { 120 time.Sleep(interval) 121 } 122 } 123 return nil 124 }