mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-05 15:56:52 +08:00
fix (*stmt).Close logic, closes #19
This commit is contained in:
111
all_test.go
111
all_test.go
@@ -540,3 +540,114 @@ outer:
|
||||
t.Fatalf("%s\nerror: summary line not found", out)
|
||||
}
|
||||
}
|
||||
|
||||
// https://gitlab.com/cznic/sqlite/issues/19
|
||||
func TestIssue19(t *testing.T) {
|
||||
const (
|
||||
drop = `
|
||||
drop table if exists products;
|
||||
`
|
||||
|
||||
up = `
|
||||
CREATE TABLE IF NOT EXISTS "products" (
|
||||
"id" VARCHAR(255),
|
||||
"user_id" VARCHAR(255),
|
||||
"name" VARCHAR(255),
|
||||
"description" VARCHAR(255),
|
||||
"created_at" BIGINT,
|
||||
"credits_price" BIGINT,
|
||||
"enabled" BOOLEAN,
|
||||
PRIMARY KEY("id")
|
||||
);
|
||||
`
|
||||
|
||||
productInsert = `
|
||||
INSERT INTO "products" ("id", "user_id", "name", "description", "created_at", "credits_price", "enabled") VALUES ('9be4398c-d527-4efb-93a4-fc532cbaf804', '16935690-348b-41a6-bb20-f8bb16011015', 'dqdwqdwqdwqwqdwqd', 'qwdwqwqdwqdwqdwqd', '1577448686', '1', '0');
|
||||
INSERT INTO "products" ("id", "user_id", "name", "description", "created_at", "credits_price", "enabled") VALUES ('759f10bd-9e1d-4ec7-b764-0868758d7b85', '16935690-348b-41a6-bb20-f8bb16011015', 'qdqwqwdwqdwqdwqwqd', 'wqdwqdwqdwqdwqdwq', '1577448692', '1', '1');
|
||||
INSERT INTO "products" ("id", "user_id", "name", "description", "created_at", "credits_price", "enabled") VALUES ('512956e7-224d-4b2a-9153-b83a52c4aa38', '16935690-348b-41a6-bb20-f8bb16011015', 'qwdwqwdqwdqdwqwqd', 'wqdwdqwqdwqdwqdwqdwqdqw', '1577448699', '2', '1');
|
||||
INSERT INTO "products" ("id", "user_id", "name", "description", "created_at", "credits_price", "enabled") VALUES ('02cd138f-6fa6-4909-9db7-a9d0eca4a7b7', '16935690-348b-41a6-bb20-f8bb16011015', 'qdwqdwqdwqwqdwdq', 'wqddwqwqdwqdwdqwdqwq', '1577448706', '3', '1');
|
||||
`
|
||||
)
|
||||
|
||||
dir, err := ioutil.TempDir("", "sqlite-test-")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defer os.Chdir(wd)
|
||||
|
||||
if err := os.Chdir(dir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite", "test.db")
|
||||
if err != nil {
|
||||
t.Fatal("failed to connect database")
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
db.SetMaxOpenConns(1)
|
||||
|
||||
if _, err = db.Exec(drop); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err = db.Exec(up); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err = db.Exec(productInsert); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var count int64
|
||||
if err = db.QueryRow("select count(*) from products where user_id = ?", "16935690-348b-41a6-bb20-f8bb16011015").Scan(&count); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if count != 4 {
|
||||
t.Fatalf("expected result for the count query %d, we received %d\n", 4, count)
|
||||
}
|
||||
|
||||
rows, err := db.Query("select * from products where user_id = ?", "16935690-348b-41a6-bb20-f8bb16011015")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
count = 0
|
||||
for rows.Next() {
|
||||
count++
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if count != 4 {
|
||||
t.Fatalf("expected result for the select query %d, we received %d\n", 4, count)
|
||||
}
|
||||
|
||||
rows, err = db.Query("select * from products where enabled = ?", true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
count = 0
|
||||
for rows.Next() {
|
||||
count++
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if count != 3 {
|
||||
t.Fatalf("expected result for the enabled select query %d, we received %d\n", 3, count)
|
||||
}
|
||||
}
|
||||
|
14
sqlite.go
14
sqlite.go
@@ -119,6 +119,7 @@ type rows struct {
|
||||
}
|
||||
|
||||
func newRows(s *stmt, pstmt crt.Intptr, rc0 int) (*rows, error) {
|
||||
s.owned = true
|
||||
r := &rows{
|
||||
stmt: s,
|
||||
pstmt: pstmt,
|
||||
@@ -149,7 +150,12 @@ func (r *rows) Columns() (c []string) {
|
||||
|
||||
// Close closes the rows iterator.
|
||||
func (r *rows) Close() (err error) {
|
||||
return r.finalize(r.pstmt)
|
||||
err = r.finalize(r.pstmt)
|
||||
r.stmt.owned = false
|
||||
if err2 := r.stmt.Close(); err2 != nil && err == nil {
|
||||
err = err2
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Next is called to populate the next row of data into the provided slice. The
|
||||
@@ -297,6 +303,8 @@ type stmt struct {
|
||||
psql crt.Intptr // *int8
|
||||
ppstmt crt.Intptr // **sqlite3_stmt
|
||||
pzTail crt.Intptr // **int8
|
||||
|
||||
owned bool
|
||||
}
|
||||
|
||||
func newStmt(c *conn, sql string) (*stmt, error) {
|
||||
@@ -329,6 +337,10 @@ func newStmt(c *conn, sql string) (*stmt, error) {
|
||||
//
|
||||
// As of Go 1.1, a Stmt will not be closed if it's in use by any queries.
|
||||
func (s *stmt) Close() (err error) {
|
||||
if s.owned {
|
||||
return
|
||||
}
|
||||
|
||||
if s.psql != 0 {
|
||||
err = s.free(s.psql)
|
||||
s.psql = 0
|
||||
|
Reference in New Issue
Block a user