@@ -10,6 +10,7 @@ package sqlite3
1010
1111import (
1212 "bytes"
13+ "context"
1314 "database/sql"
1415 "database/sql/driver"
1516 "errors"
@@ -1090,6 +1091,67 @@ func TestExecer(t *testing.T) {
10901091 }
10911092}
10921093
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+
10931155func TestQueryer (t * testing.T ) {
10941156 tempFilename := TempFilename (t )
10951157 defer os .Remove (tempFilename )
@@ -2106,6 +2168,10 @@ var tests = []testing.InternalTest{
21062168
21072169var benchmarks = []testing.InternalBenchmark {
21082170 {Name : "BenchmarkExec" , F : benchmarkExec },
2171+ {Name : "BenchmarkExecContext" , F : benchmarkExecContext },
2172+ {Name : "BenchmarkExecStep" , F : benchmarkExecStep },
2173+ {Name : "BenchmarkExecContextStep" , F : benchmarkExecContextStep },
2174+ {Name : "BenchmarkExecTx" , F : benchmarkExecTx },
21092175 {Name : "BenchmarkQuery" , F : benchmarkQuery },
21102176 {Name : "BenchmarkParams" , F : benchmarkParams },
21112177 {Name : "BenchmarkStmt" , F : benchmarkStmt },
@@ -2458,13 +2524,78 @@ func testExecEmptyQuery(t *testing.T) {
24582524
24592525// benchmarkExec is benchmark for exec
24602526func benchmarkExec (b * testing.B ) {
2527+ b .Run ("Params" , func (b * testing.B ) {
2528+ for i := 0 ; i < b .N ; i ++ {
2529+ if _ , err := db .Exec ("select ?;" , int64 (1 )); err != nil {
2530+ panic (err )
2531+ }
2532+ }
2533+ })
2534+ b .Run ("NoParams" , func (b * testing.B ) {
2535+ for i := 0 ; i < b .N ; i ++ {
2536+ if _ , err := db .Exec ("select 1;" ); err != nil {
2537+ panic (err )
2538+ }
2539+ }
2540+ })
2541+ }
2542+
2543+ func benchmarkExecContext (b * testing.B ) {
2544+ b .Run ("Params" , func (b * testing.B ) {
2545+ ctx , cancel := context .WithCancel (context .Background ())
2546+ defer cancel ()
2547+ for i := 0 ; i < b .N ; i ++ {
2548+ if _ , err := db .ExecContext (ctx , "select ?;" , int64 (1 )); err != nil {
2549+ panic (err )
2550+ }
2551+ }
2552+ })
2553+ b .Run ("NoParams" , func (b * testing.B ) {
2554+ ctx , cancel := context .WithCancel (context .Background ())
2555+ defer cancel ()
2556+ for i := 0 ; i < b .N ; i ++ {
2557+ if _ , err := db .ExecContext (ctx , "select 1;" ); err != nil {
2558+ panic (err )
2559+ }
2560+ }
2561+ })
2562+ }
2563+
2564+ func benchmarkExecTx (b * testing.B ) {
24612565 for i := 0 ; i < b .N ; i ++ {
2462- if _ , err := db .Exec ("select 1" ); err != nil {
2566+ tx , err := db .Begin ()
2567+ if err != nil {
2568+ panic (err )
2569+ }
2570+ if _ , err := tx .Exec ("select 1;" ); err != nil {
2571+ panic (err )
2572+ }
2573+ if err := tx .Commit (); err != nil {
24632574 panic (err )
24642575 }
24652576 }
24662577}
24672578
2579+ var largeSelectStmt = strings .Repeat ("select 1;\n " , 1_000 )
2580+
2581+ func benchmarkExecStep (b * testing.B ) {
2582+ for n := 0 ; n < b .N ; n ++ {
2583+ if _ , err := db .Exec (largeSelectStmt ); err != nil {
2584+ b .Fatal (err )
2585+ }
2586+ }
2587+ }
2588+
2589+ func benchmarkExecContextStep (b * testing.B ) {
2590+ ctx , cancel := context .WithCancel (context .Background ())
2591+ defer cancel ()
2592+ for n := 0 ; n < b .N ; n ++ {
2593+ if _ , err := db .ExecContext (ctx , largeSelectStmt ); err != nil {
2594+ b .Fatal (err )
2595+ }
2596+ }
2597+ }
2598+
24682599// benchmarkQuery is benchmark for query
24692600func benchmarkQuery (b * testing.B ) {
24702601 for i := 0 ; i < b .N ; i ++ {
0 commit comments