mattn / go-sqlite3

sqlite3 driver for go using database/sql
http://mattn.github.io/go-sqlite3
MIT License
8.05k stars 1.11k forks source link

`sql.DB.Close` does not close the DB after a query error #1280

Closed Andrew-Morozko closed 1 month ago

Andrew-Morozko commented 1 month ago

Incorrect sql.DB.Query (with incorrect number of arguments in my case) results in sql.DB.Close not fully closing the db. On windows this leads to The process cannot access the file because it is being used by another process. error if you attempt to interact with the db file.

This is similar to #906, but it seems to be much more fixable if sql.DB.Query (or lower-level function) cleans up after themselves before returning an error.

Code sample ```go package main import ( "database/sql" "fmt" "os" _ "github.com/mattn/go-sqlite3" ) func check(err error) { if err != nil { panic(err) } } func initDb() { db, err := sql.Open("sqlite3", "file:dbdir/db.sqlite") check(err) defer func() { check(db.Close()) }() db.Exec("CREATE TABLE testdata (id INTEGER PRIMARY KEY, text_val TEXT)") _, err = db.Exec("INSERT INTO testdata (id, text_val) VALUES (?,?)", 1, "text_1") check(err) } func runQuery() { db, err := sql.Open("sqlite3", "file:dbdir/db.sqlite") check(err) defer func() { check(db.Close()) }() // Bug here: incorrect number of arguments rows, err := db.Query("SELECT * FROM testdata WHERE id = $1;") if err != nil { fmt.Printf("expected error occurred: %s\n", err) return } defer func() { check(rows.Close()) }() } func main() { _ = os.RemoveAll("dbdir") err := os.MkdirAll("dbdir", 0o700) check(err) defer func() { // panic: remove dbdir\db.sqlite: The process cannot access the file because it is being used by another process. check(os.RemoveAll("dbdir")) }() initDb() runQuery() } ```
mattn commented 1 month ago

Good point. Thanks.