diff --git a/benchmark_test.go b/benchmark_test.go index 5c9a046b..912e5414 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -93,7 +93,7 @@ func benchmarkQueryHelper(b *testing.B, compr bool) { defer wg.Wait() b.StartTimer() - for i := 0; i < concurrencyLevel; i++ { + for range concurrencyLevel { go func() { for { if atomic.AddInt64(&remain, -1) < 0 { @@ -130,7 +130,7 @@ func BenchmarkExec(b *testing.B) { defer wg.Wait() b.StartTimer() - for i := 0; i < concurrencyLevel; i++ { + for range concurrencyLevel { go func() { for { if atomic.AddInt64(&remain, -1) < 0 { @@ -345,7 +345,7 @@ func BenchmarkQueryRawBytes(b *testing.B) { for i := range blob { blob[i] = 42 } - for i := 0; i < 100; i++ { + for i := range 100 { _, err := db.Exec("INSERT INTO bench_rawbytes VALUES (?, ?)", i, blob) if err != nil { b.Fatal(err) @@ -401,7 +401,7 @@ func BenchmarkReceiveMassiveRows(b *testing.B) { } for i := 0; i < 10000; i += 100 { args := make([]any, 200) - for j := 0; j < 100; j++ { + for j := range 100 { args[j*2] = i + j args[j*2+1] = sval } diff --git a/connection_test.go b/connection_test.go index f7740898..440ecbff 100644 --- a/connection_test.go +++ b/connection_test.go @@ -141,7 +141,7 @@ func TestCleanCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() - for i := 0; i < 3; i++ { // Repeat same behavior + for range 3 { // Repeat same behavior err := mc.Ping(ctx) if err != context.Canceled { t.Errorf("expected context.Canceled, got %#v", err) diff --git a/driver_test.go b/driver_test.go index 00e82865..477770c6 100644 --- a/driver_test.go +++ b/driver_test.go @@ -26,6 +26,7 @@ import ( "os" "reflect" "runtime" + "slices" "strconv" "strings" "sync" @@ -1926,7 +1927,7 @@ func TestPreparedManyCols(t *testing.T) { rows.Close() // Create 0byte string which we can't send via STMT_LONG_DATA. - for i := 0; i < numParams; i++ { + for i := range numParams { params[i] = "" } rows, err = stmt.Query(params...) @@ -1971,7 +1972,7 @@ func TestConcurrent(t *testing.T) { }) } - for i := 0; i < max; i++ { + for i := range max { go func(id int) { defer wg.Done() @@ -2355,7 +2356,7 @@ func TestPing(t *testing.T) { q.Close() // Verify that Ping() clears both fields. - for i := 0; i < 2; i++ { + for range 2 { if err := c.Ping(ctx); err != nil { dbt.fail("Pinger", "Ping", err) } @@ -2558,7 +2559,7 @@ func TestMultiResultSet(t *testing.T) { } defer stmt.Close() - for j := 0; j < 2; j++ { + for j := range 2 { rows, err := stmt.Query() if err != nil { dbt.Fatalf("%v (i=%d) (j=%d)", err, i, j) @@ -2665,7 +2666,7 @@ func TestQueryMultipleResults(t *testing.T) { c := conn.(*mysqlConn) // Demonstrate that repeated queries reset the affectedRows - for i := 0; i < 2; i++ { + for range 2 { _, err := qr.Query(` INSERT INTO test (value) VALUES ('a'), ('b'); INSERT INTO test (value) VALUES ('c'), ('d'), ('e'); @@ -3293,11 +3294,11 @@ func TestRawBytesAreNotModified(t *testing.T) { runTests(t, dsn, func(dbt *DBTest) { dbt.mustExec("CREATE TABLE test (id int, value BLOB) CHARACTER SET utf8") - for i := 0; i < insertRows; i++ { + for i := range insertRows { dbt.mustExec("INSERT INTO test VALUES (?, ?)", i+1, sqlBlobs[i&1]) } - for i := 0; i < contextRaceIterations; i++ { + for i := range contextRaceIterations { func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -3552,8 +3553,8 @@ func TestConnectionAttributes(t *testing.T) { rowsMap[attrName] = attrValue } - connAttrs := append(append([]string{}, defaultAttrs...), customAttrs...) - expectedAttrValues := append(append([]string{}, defaultAttrValues...), customAttrValues...) + connAttrs := slices.Concat(defaultAttrs, customAttrs) + expectedAttrValues := slices.Concat(defaultAttrValues, customAttrValues) for i := range connAttrs { if gotValue := rowsMap[connAttrs[i]]; gotValue != expectedAttrValues[i] { dbt.Errorf("expected %q, got %q", expectedAttrValues[i], gotValue) @@ -3637,7 +3638,7 @@ func TestIssue1567(t *testing.T) { count = max } - for i := 0; i < count; i++ { + for range count { timeout := time.Duration(mrand.Int63n(int64(rtt))) ctx, cancel := context.WithTimeout(context.Background(), timeout) dbt.db.PingContext(ctx) diff --git a/dsn.go b/dsn.go index ecf62567..89556bfb 100644 --- a/dsn.go +++ b/dsn.go @@ -414,7 +414,7 @@ func ParseDSN(dsn string) (cfg *Config, err error) { if dsn[j] == '@' { // username[:password] // Find the first ':' in dsn[:j] - for k = 0; k < j; k++ { + for k = 0; k < j; k++ { // We cannot use k = range j here, because we use dsn[:k] below if dsn[k] == ':' { cfg.Passwd = dsn[k+1 : j] break diff --git a/infile.go b/infile.go index 453ae091..597b5e7f 100644 --- a/infile.go +++ b/infile.go @@ -95,10 +95,7 @@ const defaultPacketSize = 16 * 1024 // 16KB is small enough for disk readahead a func (mc *okHandler) handleInFileRequest(name string) (err error) { var rdr io.Reader - packetSize := defaultPacketSize - if mc.maxWriteSize < packetSize { - packetSize = mc.maxWriteSize - } + packetSize := min(mc.maxWriteSize, defaultPacketSize) if idx := strings.Index(name, "Reader::"); idx == 0 || (idx > 0 && name[idx-1] == '/') { // io.Reader // The server might return an an absolute path. See issue #355. diff --git a/packets.go b/packets.go index 4b836216..a497a50a 100644 --- a/packets.go +++ b/packets.go @@ -984,10 +984,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error { mc := stmt.mc // Determine threshold dynamically to avoid packet size shortage. - longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1) - if longDataSize < 64 { - longDataSize = 64 - } + longDataSize := max(mc.maxAllowedPacket/(stmt.paramCount+1), 64) // Reset packet-sequence mc.resetSequence() diff --git a/result.go b/result.go index d5163146..82dc0f9b 100644 --- a/result.go +++ b/result.go @@ -8,6 +8,8 @@ package mysql +import "slices" + import "database/sql/driver" // Result exposes data not available through *connection.Result. @@ -42,9 +44,9 @@ func (res *mysqlResult) RowsAffected() (int64, error) { } func (res *mysqlResult) AllLastInsertIds() []int64 { - return append([]int64{}, res.insertIds...) // defensive copy + return slices.Clone(res.insertIds) // defensive copy } func (res *mysqlResult) AllRowsAffected() []int64 { - return append([]int64{}, res.affectedRows...) // defensive copy + return slices.Clone(res.affectedRows) // defensive copy } diff --git a/utils.go b/utils.go index 8716c26c..b041804d 100644 --- a/utils.go +++ b/utils.go @@ -182,7 +182,7 @@ func parseDateTime(b []byte, loc *time.Location) (time.Time, error) { func parseByteYear(b []byte) (int, error) { year, n := 0, 1000 - for i := 0; i < 4; i++ { + for i := range 4 { v, err := bToi(b[i]) if err != nil { return 0, err @@ -207,7 +207,7 @@ func parseByte2Digits(b1, b2 byte) (int, error) { func parseByteNanoSec(b []byte) (int, error) { ns, digit := 0, 100000 // max is 6-digits - for i := 0; i < len(b); i++ { + for i := range b { v, err := bToi(b[i]) if err != nil { return 0, err @@ -678,7 +678,7 @@ func escapeStringBackslash(buf []byte, v string) []byte { pos := len(buf) buf = reserveBuffer(buf, len(v)*2) - for i := 0; i < len(v); i++ { + for i := range len(v) { c := v[i] switch c { case '\x00': @@ -746,7 +746,7 @@ func escapeStringQuotes(buf []byte, v string) []byte { pos := len(buf) buf = reserveBuffer(buf, len(v)*2) - for i := 0; i < len(v); i++ { + for i := range len(v) { c := v[i] if c == '\'' { buf[pos+1] = '\''