From 28331bf1983527b791e616c14afbebef26bf380e Mon Sep 17 00:00:00 2001 From: Anton Kichaev Date: Thu, 31 Aug 2023 20:58:33 +0700 Subject: [PATCH 1/2] fix(finisher_api): compose sqls and vars statement --- finisher_api.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/finisher_api.go b/finisher_api.go index f80aa6c04..80249ed79 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -36,6 +36,9 @@ func (db *DB) CreateInBatches(value interface{}, batchSize int) (tx *DB) { // the reflection length judgment of the optimized value reflectLen := reflectValue.Len() + statementSql := strings.Builder{} + statementVars := make([]interface{}, 0, reflectLen) + callFc := func(tx *DB) error { for i := 0; i < reflectLen; i += batchSize { ends := i + batchSize @@ -49,6 +52,11 @@ func (db *DB) CreateInBatches(value interface{}, batchSize int) (tx *DB) { if subtx.Error != nil { return subtx.Error } + + statementSql.WriteString(subtx.Statement.SQL.String()) + statementSql.WriteString(";") + statementVars = append(statementVars, subtx.Statement.Vars...) + rowsAffected += subtx.RowsAffected } return nil @@ -59,6 +67,8 @@ func (db *DB) CreateInBatches(value interface{}, batchSize int) (tx *DB) { } else { tx.AddError(tx.Transaction(callFc)) } + tx.Statement.SQL = statementSql + tx.Statement.Vars = statementVars tx.RowsAffected = rowsAffected default: From df5d184baa3384312fb910056ce970503869a748 Mon Sep 17 00:00:00 2001 From: Anton Kichaev Date: Sat, 2 Sep 2023 12:38:59 +0700 Subject: [PATCH 2/2] test(sql_builder_test): add test for CreateInBatches sql statment --- tests/sql_builder_test.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/sql_builder_test.go b/tests/sql_builder_test.go index 022e0495e..1c4052949 100644 --- a/tests/sql_builder_test.go +++ b/tests/sql_builder_test.go @@ -453,6 +453,28 @@ func TestToSQL(t *testing.T) { }) }) assertEqualSQL(t, `SELECT * FROM users ORDER BY id DESC`, sql) + + // create batch, models are equal batch size + bs := 2 + m := gorm.Model{ + CreatedAt: date, + UpdatedAt: date, + } + sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB { + return tx.Model(&User{}). + CreateInBatches( + []User{ + { + Name: "foo", Age: 20, Model: m, + }, + { + Name: "bar", Age: 30, Model: m, + }, + }, + bs, + ) + }) + assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false),('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'bar',30,NULL,NULL,NULL,false) RETURNING "id";`, sql) } // assertEqualSQL for assert that the sql is equal, this method will ignore quote, and dialect specials. @@ -469,7 +491,7 @@ func assertEqualSQL(t *testing.T, expected string, actually string) { expected = updatedAtRe.ReplaceAllString(expected, `"updated_at"=?`) // ignore RETURNING "id" (only in PostgreSQL) - returningRe := regexp.MustCompile(`(?i)RETURNING "id"`) + returningRe := regexp.MustCompile(`\s?(?i)RETURNING "id"`) actually = returningRe.ReplaceAllString(actually, ``) expected = returningRe.ReplaceAllString(expected, ``)