move reset/clear into putCachedStmt and always finalize on failure
This avoids an unnecessary reset when the cache is full, guarantees a statement cannot enter the cache without being reset/cleared, and fixes a leak where sqlite3_finalize was not called when reset failed.
This commit is contained in:
14
sqlite3.go
14
sqlite3.go
@@ -1942,6 +1942,10 @@ func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
|
||||
if c.db == nil || c.stmtCacheCount >= c.stmtCacheSize {
|
||||
return false
|
||||
}
|
||||
rv := C._sqlite3_reset_clear(s.s)
|
||||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
||||
return false
|
||||
}
|
||||
c.stmtCache[s.cacheKey] = append(c.stmtCache[s.cacheKey], s)
|
||||
c.stmtCacheCount++
|
||||
return true
|
||||
@@ -2116,17 +2120,9 @@ func (s *SQLiteStmt) Close() error {
|
||||
if !conn.dbConnOpen() {
|
||||
return errors.New("sqlite statement with already closed database connection")
|
||||
}
|
||||
if s.cacheKey != "" {
|
||||
rv := C._sqlite3_reset_clear(stmt)
|
||||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
||||
s.s = nil
|
||||
s.c = nil
|
||||
return conn.lastError()
|
||||
}
|
||||
if conn.putCachedStmt(s) {
|
||||
if s.cacheKey != "" && conn.putCachedStmt(s) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
s.s = nil
|
||||
s.c = nil
|
||||
rv := C.sqlite3_finalize(stmt)
|
||||
|
||||
Reference in New Issue
Block a user