@@ -10,6 +10,7 @@ package sqlite3
10
10
11
11
import (
12
12
"bytes"
13
+ "context"
13
14
"database/sql"
14
15
"database/sql/driver"
15
16
"errors"
@@ -1090,6 +1091,67 @@ func TestExecer(t *testing.T) {
1090
1091
}
1091
1092
}
1092
1093
1094
+ func TestExecDriverResult (t * testing.T ) {
1095
+ setup := func (t * testing.T ) * sql.DB {
1096
+ db , err := sql .Open ("sqlite3" , t .TempDir ()+ "/test.sqlite3" )
1097
+ if err != nil {
1098
+ t .Fatal ("Failed to open database:" , err )
1099
+ }
1100
+ if _ , err := db .Exec (`CREATE TABLE foo (id INTEGER PRIMARY KEY);` ); err != nil {
1101
+ t .Fatal (err )
1102
+ }
1103
+ t .Cleanup (func () { db .Close () })
1104
+ return db
1105
+ }
1106
+
1107
+ test := func (t * testing.T , execStmt string , args ... any ) {
1108
+ db := setup (t )
1109
+ res , err := db .Exec (execStmt , args ... )
1110
+ if err != nil {
1111
+ t .Fatal (err )
1112
+ }
1113
+ rows , err := res .RowsAffected ()
1114
+ if err != nil {
1115
+ t .Fatal (err )
1116
+ }
1117
+ // We only return the changes from the last statement.
1118
+ if rows != 1 {
1119
+ t .Errorf ("RowsAffected got: %d want: %d" , rows , 1 )
1120
+ }
1121
+ id , err := res .LastInsertId ()
1122
+ if err != nil {
1123
+ t .Fatal (err )
1124
+ }
1125
+ if id != 3 {
1126
+ t .Errorf ("LastInsertId got: %d want: %d" , id , 3 )
1127
+ }
1128
+ var count int64
1129
+ err = db .QueryRow (`SELECT COUNT(*) FROM foo WHERE id IN (1, 2, 3);` ).Scan (& count )
1130
+ if err != nil {
1131
+ t .Fatal (err )
1132
+ }
1133
+ if count != 3 {
1134
+ t .Errorf ("Expected count to be %d got: %d" , 3 , count )
1135
+ }
1136
+ }
1137
+
1138
+ t .Run ("NoArgs" , func (t * testing.T ) {
1139
+ const stmt = `
1140
+ INSERT INTO foo(id) VALUES(1);
1141
+ INSERT INTO foo(id) VALUES(2);
1142
+ INSERT INTO foo(id) VALUES(3);`
1143
+ test (t , stmt )
1144
+ })
1145
+
1146
+ t .Run ("WithArgs" , func (t * testing.T ) {
1147
+ const stmt = `
1148
+ INSERT INTO foo(id) VALUES(?);
1149
+ INSERT INTO foo(id) VALUES(?);
1150
+ INSERT INTO foo(id) VALUES(?);`
1151
+ test (t , stmt , 1 , 2 , 3 )
1152
+ })
1153
+ }
1154
+
1093
1155
func TestQueryer (t * testing.T ) {
1094
1156
tempFilename := TempFilename (t )
1095
1157
defer os .Remove (tempFilename )
@@ -2106,6 +2168,10 @@ var tests = []testing.InternalTest{
2106
2168
2107
2169
var benchmarks = []testing.InternalBenchmark {
2108
2170
{Name : "BenchmarkExec" , F : benchmarkExec },
2171
+ {Name : "BenchmarkExecContext" , F : benchmarkExecContext },
2172
+ {Name : "BenchmarkExecStep" , F : benchmarkExecStep },
2173
+ {Name : "BenchmarkExecContextStep" , F : benchmarkExecContextStep },
2174
+ {Name : "BenchmarkExecTx" , F : benchmarkExecTx },
2109
2175
{Name : "BenchmarkQuery" , F : benchmarkQuery },
2110
2176
{Name : "BenchmarkParams" , F : benchmarkParams },
2111
2177
{Name : "BenchmarkStmt" , F : benchmarkStmt },
@@ -2459,13 +2525,78 @@ func testExecEmptyQuery(t *testing.T) {
2459
2525
2460
2526
// benchmarkExec is benchmark for exec
2461
2527
func benchmarkExec (b * testing.B ) {
2528
+ b .Run ("Params" , func (b * testing.B ) {
2529
+ for i := 0 ; i < b .N ; i ++ {
2530
+ if _ , err := db .Exec ("select ?;" , int64 (1 )); err != nil {
2531
+ panic (err )
2532
+ }
2533
+ }
2534
+ })
2535
+ b .Run ("NoParams" , func (b * testing.B ) {
2536
+ for i := 0 ; i < b .N ; i ++ {
2537
+ if _ , err := db .Exec ("select 1;" ); err != nil {
2538
+ panic (err )
2539
+ }
2540
+ }
2541
+ })
2542
+ }
2543
+
2544
+ func benchmarkExecContext (b * testing.B ) {
2545
+ b .Run ("Params" , func (b * testing.B ) {
2546
+ ctx , cancel := context .WithCancel (context .Background ())
2547
+ defer cancel ()
2548
+ for i := 0 ; i < b .N ; i ++ {
2549
+ if _ , err := db .ExecContext (ctx , "select ?;" , int64 (1 )); err != nil {
2550
+ panic (err )
2551
+ }
2552
+ }
2553
+ })
2554
+ b .Run ("NoParams" , func (b * testing.B ) {
2555
+ ctx , cancel := context .WithCancel (context .Background ())
2556
+ defer cancel ()
2557
+ for i := 0 ; i < b .N ; i ++ {
2558
+ if _ , err := db .ExecContext (ctx , "select 1;" ); err != nil {
2559
+ panic (err )
2560
+ }
2561
+ }
2562
+ })
2563
+ }
2564
+
2565
+ func benchmarkExecTx (b * testing.B ) {
2462
2566
for i := 0 ; i < b .N ; i ++ {
2463
- if _ , err := db .Exec ("select 1" ); err != nil {
2567
+ tx , err := db .Begin ()
2568
+ if err != nil {
2569
+ panic (err )
2570
+ }
2571
+ if _ , err := tx .Exec ("select 1;" ); err != nil {
2572
+ panic (err )
2573
+ }
2574
+ if err := tx .Commit (); err != nil {
2464
2575
panic (err )
2465
2576
}
2466
2577
}
2467
2578
}
2468
2579
2580
+ var largeSelectStmt = strings .Repeat ("select 1;\n " , 1_000 )
2581
+
2582
+ func benchmarkExecStep (b * testing.B ) {
2583
+ for n := 0 ; n < b .N ; n ++ {
2584
+ if _ , err := db .Exec (largeSelectStmt ); err != nil {
2585
+ b .Fatal (err )
2586
+ }
2587
+ }
2588
+ }
2589
+
2590
+ func benchmarkExecContextStep (b * testing.B ) {
2591
+ ctx , cancel := context .WithCancel (context .Background ())
2592
+ defer cancel ()
2593
+ for n := 0 ; n < b .N ; n ++ {
2594
+ if _ , err := db .ExecContext (ctx , largeSelectStmt ); err != nil {
2595
+ b .Fatal (err )
2596
+ }
2597
+ }
2598
+ }
2599
+
2469
2600
// benchmarkQuery is benchmark for query
2470
2601
func benchmarkQuery (b * testing.B ) {
2471
2602
for i := 0 ; i < b .N ; i ++ {
0 commit comments