mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Limits, and tweaks.
This commit is contained in:
@@ -113,7 +113,7 @@ with `nolock=1` you must disable connection pooling by calling
|
||||
### Testing
|
||||
|
||||
This project aims for [high test coverage](https://github.com/ncruces/go-sqlite3/wiki/Test-coverage-report).
|
||||
It also benefits greatly from [SQLite's](https://www.sqlite.org/testing.html) and
|
||||
It also benefits greatly from [SQLite's](https://sqlite.org/testing.html) and
|
||||
[wazero's](https://tetrate.io/blog/introducing-wazero-from-tetrate/#:~:text=Rock%2Dsolid%20test%20approach) thorough testing.
|
||||
|
||||
The pure Go VFS is tested by running SQLite's
|
||||
|
||||
@@ -121,7 +121,7 @@ func (b *Backup) Step(nPage int) (done bool, err error) {
|
||||
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining
|
||||
func (b *Backup) Remaining() int {
|
||||
r := b.c.call("sqlite3_backup_remaining", uint64(b.handle))
|
||||
return int(r)
|
||||
return int(int32(r))
|
||||
}
|
||||
|
||||
// PageCount returns the total number of pages in the source database
|
||||
@@ -130,5 +130,5 @@ func (b *Backup) Remaining() int {
|
||||
// https://sqlite.org/c3ref/backup_finish.html#sqlite3backuppagecount
|
||||
func (b *Backup) PageCount() int {
|
||||
r := b.c.call("sqlite3_backup_pagecount", uint64(b.handle))
|
||||
return int(r)
|
||||
return int(int32(r))
|
||||
}
|
||||
|
||||
11
config.go
11
config.go
@@ -35,7 +35,7 @@ func (c *Conn) Config(op DBConfig, arg ...bool) (bool, error) {
|
||||
|
||||
// ConfigLog sets up the error logging callback for the connection.
|
||||
//
|
||||
// https://www.sqlite.org/errlog.html
|
||||
// https://sqlite.org/errlog.html
|
||||
func (c *Conn) ConfigLog(cb func(code ExtendedErrorCode, msg string)) error {
|
||||
var enable uint64
|
||||
if cb != nil {
|
||||
@@ -55,3 +55,12 @@ func logCallback(ctx context.Context, mod api.Module, _, iCode, zMsg uint32) {
|
||||
c.log(xErrorCode(iCode), msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Limit allows the size of various constructs to be
|
||||
// limited on a connection by connection basis.
|
||||
//
|
||||
// https://sqlite.org/c3ref/limit.html
|
||||
func (c *Conn) Limit(id LimitCategory, value int) int {
|
||||
r := c.call("sqlite3_limit", uint64(c.handle), uint64(id), uint64(value))
|
||||
return int(int32(r))
|
||||
}
|
||||
|
||||
2
conn.go
2
conn.go
@@ -217,7 +217,7 @@ func (c *Conn) ReadOnly(schema string) (ro bool, ok bool) {
|
||||
ptr = c.arena.string(schema)
|
||||
}
|
||||
r := c.call("sqlite3_db_readonly", uint64(c.handle), uint64(ptr))
|
||||
return int8(r) > 0, int8(r) < 0
|
||||
return int32(r) > 0, int32(r) < 0
|
||||
}
|
||||
|
||||
// GetAutocommit tests the connection for auto-commit mode.
|
||||
|
||||
20
const.go
20
const.go
@@ -229,6 +229,26 @@ const (
|
||||
DBCONFIG_REVERSE_SCANORDER DBConfig = 1019
|
||||
)
|
||||
|
||||
// LimitCategory are the available run-time limit categories.
|
||||
//
|
||||
// https://sqlite.org/c3ref/c_limit_attached.html
|
||||
type LimitCategory uint32
|
||||
|
||||
const (
|
||||
LIMIT_LENGTH LimitCategory = 0
|
||||
LIMIT_SQL_LENGTH LimitCategory = 1
|
||||
LIMIT_COLUMN LimitCategory = 2
|
||||
LIMIT_EXPR_DEPTH LimitCategory = 3
|
||||
LIMIT_COMPOUND_SELECT LimitCategory = 4
|
||||
LIMIT_VDBE_OP LimitCategory = 5
|
||||
LIMIT_FUNCTION_ARG LimitCategory = 6
|
||||
LIMIT_ATTACHED LimitCategory = 7
|
||||
LIMIT_LIKE_PATTERN_LENGTH LimitCategory = 8
|
||||
LIMIT_VARIABLE_NUMBER LimitCategory = 9
|
||||
LIMIT_TRIGGER_DEPTH LimitCategory = 10
|
||||
LIMIT_WORKER_THREADS LimitCategory = 11
|
||||
)
|
||||
|
||||
// TxnState are the allowed return values from [Conn.TxnState].
|
||||
//
|
||||
// https://sqlite.org/c3ref/c_txn_none.html
|
||||
|
||||
@@ -222,7 +222,7 @@ func (ctx Context) ResultError(err error) {
|
||||
// VTabNoChange may return true if a column is being fetched as part
|
||||
// of an update during which the column value will not change.
|
||||
//
|
||||
// https://www.sqlite.org/c3ref/vtab_nochange.html
|
||||
// https://sqlite.org/c3ref/vtab_nochange.html
|
||||
func (ctx Context) VTabNoChange() bool {
|
||||
r := ctx.c.call("sqlite3_vtab_nochange", uint64(ctx.handle))
|
||||
return r != 0
|
||||
|
||||
3
stmt.go
3
stmt.go
@@ -111,6 +111,9 @@ func (s *Stmt) Exec() error {
|
||||
//
|
||||
// https://sqlite.org/c3ref/stmt_status.html
|
||||
func (s *Stmt) Status(op StmtStatus, reset bool) int {
|
||||
if op > STMTSTATUS_FILTER_HIT && op != STMTSTATUS_MEMUSED {
|
||||
return 0
|
||||
}
|
||||
var i uint64
|
||||
if reset {
|
||||
i = 1
|
||||
|
||||
@@ -3,6 +3,7 @@ package tests
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -365,6 +366,36 @@ func TestConn_ConfigLog(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestConn_Limit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, err := sqlite3.Open(":memory:")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
l := db.Limit(sqlite3.LIMIT_COLUMN, -1)
|
||||
if l != 2000 {
|
||||
t.Errorf("got %d, want 2000", l)
|
||||
}
|
||||
|
||||
l = db.Limit(sqlite3.LIMIT_COLUMN, 100)
|
||||
if l != 2000 {
|
||||
t.Errorf("got %d, want 2000", l)
|
||||
}
|
||||
|
||||
l = db.Limit(sqlite3.LIMIT_COLUMN, -1)
|
||||
if l != 100 {
|
||||
t.Errorf("got %d, want 100", l)
|
||||
}
|
||||
|
||||
l = db.Limit(math.MaxUint32, -1)
|
||||
if l != -1 {
|
||||
t.Errorf("got %d, want -1", l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConn_ReleaseMemory(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
4
value.go
4
value.go
@@ -204,7 +204,7 @@ func (v Value) NoChange() bool {
|
||||
// InFirst returns the first element
|
||||
// on the right-hand side of an IN constraint.
|
||||
//
|
||||
// https://www.sqlite.org/c3ref/vtab_in_first.html
|
||||
// https://sqlite.org/c3ref/vtab_in_first.html
|
||||
func (v Value) InFirst() (Value, error) {
|
||||
defer v.c.arena.mark()()
|
||||
valPtr := v.c.arena.new(ptrlen)
|
||||
@@ -221,7 +221,7 @@ func (v Value) InFirst() (Value, error) {
|
||||
// InNext returns the next element
|
||||
// on the right-hand side of an IN constraint.
|
||||
//
|
||||
// https://www.sqlite.org/c3ref/vtab_in_first.html
|
||||
// https://sqlite.org/c3ref/vtab_in_first.html
|
||||
func (v Value) InNext() (Value, error) {
|
||||
defer v.c.arena.mark()()
|
||||
valPtr := v.c.arena.new(ptrlen)
|
||||
|
||||
Reference in New Issue
Block a user