diff --git a/internal/sqladapter/testing/adapter.go.tpl b/internal/sqladapter/testing/adapter.go.tpl index c8f05b1f31a41fa844c1174a0427c4e42eac1c64..e015ff4501c6c15334e9a3f46b8adf5bc0a1f7de 100644 --- a/internal/sqladapter/testing/adapter.go.tpl +++ b/internal/sqladapter/testing/adapter.go.tpl @@ -1115,6 +1115,42 @@ func TestBatchInsert(t *testing.T) { } } +func TestBatchInsertNoColumns(t *testing.T) { + sess := mustOpen() + defer sess.Close() + + for batchSize := 0; batchSize < 17; batchSize++ { + err := sess.Collection("artist").Truncate() + assert.NoError(t, err) + + batch := sess.InsertInto("artist").Batch(batchSize) + + totalItems := int(rand.Int31n(21)) + + go func() { + defer batch.Done() + for i := 0; i < totalItems; i++ { + value := struct{Name string `db:"name"`}{fmt.Sprintf("artist-%d", i)} + batch.Values(value) + } + }() + + err = batch.Wait() + assert.NoError(t, err) + assert.NoError(t, batch.Err()) + + c, err := sess.Collection("artist").Find().Count() + assert.NoError(t, err) + assert.Equal(t, uint64(totalItems), c) + + for i := 0; i < totalItems; i++ { + c, err := sess.Collection("artist").Find(db.Cond{"name": fmt.Sprintf("artist-%d", i)}).Count() + assert.NoError(t, err) + assert.Equal(t, uint64(1), c) + } + } +} + func TestBatchInsertReturningKeys(t *testing.T) { if Adapter != "postgresql" { t.Skip("Currently not supported.") diff --git a/lib/sqlbuilder/builder_test.go b/lib/sqlbuilder/builder_test.go index 0be5715244feee81bfd704893c5aefb4d991df06..00e01e430a7d0a71d5e724be8eab9edcbd2e1c8b 100644 --- a/lib/sqlbuilder/builder_test.go +++ b/lib/sqlbuilder/builder_test.go @@ -539,6 +539,20 @@ func TestInsert(t *testing.T) { }{12, "Chavela Vargas"}).String(), ) + assert.Equal( + `INSERT INTO "artist" ("id", "name") VALUES ($1, $2), ($3, $4), ($5, $6)`, + b.InsertInto("artist").Values(struct { + ID int `db:"id"` + Name string `db:"name"` + }{12, "Chavela Vargas"}).Values(struct { + ID int `db:"id"` + Name string `db:"name"` + }{13, "Alondra de la Parra"}).Values(struct { + ID int `db:"id"` + Name string `db:"name"` + }{14, "Haruki Murakami"}).String(), + ) + assert.Equal( `INSERT INTO "artist" ("name", "id") VALUES ($1, $2)`, b.InsertInto("artist").Columns("name", "id").Values("Chavela Vargas", 12).String(), diff --git a/lib/sqlbuilder/insert.go b/lib/sqlbuilder/insert.go index d86991a7c357aca6c52128db7c82637e4e3c3c5b..775b13e72bd6d31d8c454d4d185a8829d2c72b88 100644 --- a/lib/sqlbuilder/insert.go +++ b/lib/sqlbuilder/insert.go @@ -65,18 +65,23 @@ func (qi *inserter) Columns(columns ...string) Inserter { } func (qi *inserter) Values(values ...interface{}) Inserter { - if len(qi.columns) == 0 && len(values) == 1 { - ff, vv, _ := Map(values[0]) - - columns, vals, arguments, _ := qi.builder.t.ToColumnsValuesAndArguments(ff, vv) - - qi.arguments = append(qi.arguments, arguments...) - qi.values = append(qi.values, vals) - - for _, c := range columns.Columns { - qi.columns = append(qi.columns, c) + if len(values) == 1 { + ff, vv, err := Map(values[0]) + if err == nil { + columns, vals, arguments, _ := qi.builder.t.ToColumnsValuesAndArguments(ff, vv) + + qi.arguments = append(qi.arguments, arguments...) + qi.values = append(qi.values, vals) + if len(qi.columns) == 0 { + for _, c := range columns.Columns { + qi.columns = append(qi.columns, c) + } + } + return qi } - } else if len(qi.columns) == 0 || len(values) == len(qi.columns) { + } + + if len(qi.columns) == 0 || len(values) == len(qi.columns) { qi.arguments = append(qi.arguments, values...) l := len(values)