forked from modernc-org/sqlite
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdbstatus.go
More file actions
98 lines (88 loc) · 4.43 KB
/
Copy pathdbstatus.go
File metadata and controls
98 lines (88 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2026 The Sqlite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sqlite // import "modernc.org/sqlite"
import (
"unsafe"
sqlite3 "modernc.org/sqlite/lib"
)
// DBStatusOp identifies a per-connection runtime counter readable through
// [DBStatus.Status]. The values mirror the SQLITE_DBSTATUS_* verbs of the C
// API; the distinct type keeps a counter from a different family (for example
// a file-control or db-config op) from compiling in its place.
//
// See https://www.sqlite.org/c3ref/c_dbstatus_options.html for the per-op
// semantics.
type DBStatusOp int32
// DBStatus* are the operations accepted by [DBStatus.Status]. They report
// their value differently depending on the op:
//
// - DBStatusLookasideUsed: current is the lookaside memory in use now; high
// is its high-water mark. The reset flag rebases the high-water mark to
// current. This is the only op that maintains a high-water mark.
// - Memory-usage ops (DBStatusCacheUsed, DBStatusSchemaUsed,
// DBStatusStmtUsed, DBStatusCacheUsedShared): current is the bytes in use
// now; high is always 0; the reset flag is ignored.
// - Running-counter ops (DBStatusCacheHit, DBStatusCacheMiss,
// DBStatusCacheWrite, DBStatusCacheSpill, DBStatusTempbufSpill): current
// is the cumulative count (bytes spilled, for DBStatusTempbufSpill); high
// is always 0. The reset flag zeroes current.
// - Lookaside event ops (DBStatusLookasideHit, DBStatusLookasideMissSize,
// DBStatusLookasideMissFull): the count is reported in high, not current
// (current is always 0). The reset flag zeroes high.
// - DBStatusDeferredFKs: current is 1 if the connection has unresolved
// deferred foreign-key constraints, else 0; high is always 0; the reset
// flag is ignored.
const (
DBStatusLookasideUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_USED)
DBStatusCacheUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_USED)
DBStatusSchemaUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_SCHEMA_USED)
DBStatusStmtUsed = DBStatusOp(sqlite3.SQLITE_DBSTATUS_STMT_USED)
DBStatusLookasideHit = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_HIT)
DBStatusLookasideMissSize = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE)
DBStatusLookasideMissFull = DBStatusOp(sqlite3.SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL)
DBStatusCacheHit = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_HIT)
DBStatusCacheMiss = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_MISS)
DBStatusCacheWrite = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_WRITE)
DBStatusDeferredFKs = DBStatusOp(sqlite3.SQLITE_DBSTATUS_DEFERRED_FKS)
DBStatusCacheUsedShared = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_USED_SHARED)
DBStatusCacheSpill = DBStatusOp(sqlite3.SQLITE_DBSTATUS_CACHE_SPILL)
DBStatusTempbufSpill = DBStatusOp(sqlite3.SQLITE_DBSTATUS_TEMPBUF_SPILL)
)
// DBStatus exposes sqlite3_db_status, the per-connection runtime counters
// (cache hit/miss/write/spill rates, schema and prepared-statement memory,
// lookaside usage, deferred foreign keys). Reach it through the
// database/sql escape hatch, the same way as [FileControl]:
//
// err := sqlConn.Raw(func(dc any) error {
// cur, _, err := dc.(sqlite.DBStatus).Status(sqlite.DBStatusCacheSpill, false)
// if err != nil {
// return err
// }
// // use cur
// return nil
// })
type DBStatus interface {
// Status returns the current and high-water values of the per-connection
// counter identified by op. When reset is true the counter is reset after
// the read; which value the reset affects depends on the op's family, see
// the DBStatus* constant documentation. The returned error is non-nil only
// when SQLite rejects op as out of range.
Status(op DBStatusOp, reset bool) (current, high int, err error)
}
var _ DBStatus = (*conn)(nil)
func (c *conn) Status(op DBStatusOp, reset bool) (current, high int, err error) {
// Two int32 out-params: pCurrent, pHighwater. sqlite3_db_status writes
// C int (32-bit) through both, so a single 8-byte buffer holds the pair.
p := c.tls.Alloc(8)
defer c.tls.Free(8)
pCur, pHi := p, p+4
resetFlag := int32(0)
if reset {
resetFlag = 1
}
if rc := sqlite3.Xsqlite3_db_status(c.tls, c.db, int32(op), pCur, pHi, resetFlag); rc != sqlite3.SQLITE_OK {
return 0, 0, c.errstr(rc)
}
return int(*(*int32)(unsafe.Pointer(pCur))), int(*(*int32)(unsafe.Pointer(pHi))), nil
}