chore: reva bump -2.48.0 (#3230)

This commit is contained in:
Viktor Scharf authored and GitHub committed 2026-08-03 17:43:51 +02:00
1 parent e12966a4fd
commit bb4cd1ebf5
42 files changed
+9526 -5016

No files matched your search

+9 -9
View File
@@ -64,7 +64,7 @@ require (
github.com/open-policy-agent/opa v1.19.0
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
github.com/opencloud-eu/reva/v2 v2.47.0
github.com/opencloud-eu/reva/v2 v2.48.0
github.com/opensearch-project/opensearch-go/v4 v4.6.0
github.com/orcaman/concurrent-map v1.0.0
github.com/pkg/errors v0.9.1
@@ -135,7 +135,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/alexedwards/argon2id v1.0.0 // indirect
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.2-default-no-op // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.2 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -274,10 +274,10 @@ require (
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.23 // indirect
github.com/mattn/go-sqlite3 v1.14.42 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/mattn/go-runewidth v0.0.24 // indirect
github.com/mattn/go-sqlite3 v1.14.49 // indirect
github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect
github.com/miekg/dns v1.1.68 // indirect
@@ -342,8 +342,8 @@ require (
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
github.com/sergi/go-diff v1.4.0 // indirect
github.com/sethvargo/go-diceware v0.5.0 // indirect
github.com/sethvargo/go-password v0.3.1 // indirect
github.com/sethvargo/go-diceware v0.6.0 // indirect
github.com/sethvargo/go-password v0.4.0 // indirect
github.com/shirou/gopsutil/v4 v4.26.5 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
@@ -389,7 +389,7 @@ require (
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.47.0 // indirect
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/ini.v1 v1.67.3 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
+18 -18
View File
@@ -115,8 +115,8 @@ github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 h1:I9YN9WMo3SUh7p/
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964/go.mod h1:eFiR01PwTcpbzXtdMces7zxg6utvFM5puiWHpWB8D/k=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antithesishq/antithesis-sdk-go v0.7.2-default-no-op h1:p2zFsAzvhIpFya8AIOHIbWf7NGvO34QpLGclyf7nXj8=
github.com/antithesishq/antithesis-sdk-go v0.7.2-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/antithesishq/antithesis-sdk-go v0.7.2 h1:oEEedg1Xgi8drRjqB0f9tfjhLoInE0IYZfZ6zAhQUbY=
github.com/antithesishq/antithesis-sdk-go v0.7.2/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
@@ -799,23 +799,23 @@ github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo=
github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU=
github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w=
github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -942,8 +942,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
github.com/opencloud-eu/reva/v2 v2.47.0 h1:bYul45qS8GmmN9PKplSZ78ZTZ6A+9xp/FfogqFVud18=
github.com/opencloud-eu/reva/v2 v2.47.0/go.mod h1:zdpEKIMDT14w+MGUOWAi+rh+PAZBPUlb7AtIGFWx7Ds=
github.com/opencloud-eu/reva/v2 v2.48.0 h1:G/4Jbv0DWWOfA5u5DtV0CB75pi9Wwtj7JkJQOEBvErs=
github.com/opencloud-eu/reva/v2 v2.48.0/go.mod h1:ZCo/xQM6if+upZa7rJCmdifZ/Y5XHLCrscHytC39yI4=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -1100,10 +1100,10 @@ github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aep
github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-diceware v0.5.0 h1:exrQ7GpaBo00GqRVM1N8ChXSsi3oS7tjQiIehsD+yR0=
github.com/sethvargo/go-diceware v0.5.0/go.mod h1:Lg1SyPS7yQO6BBgTN5r4f2MUDkqGfLWsOjHPY0kA8iw=
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
github.com/sethvargo/go-diceware v0.6.0 h1:B3nhMhbBP7KwtTQ7hHRIOmv5FqeD8bJs77RFrV24iWk=
github.com/sethvargo/go-diceware v0.6.0/go.mod h1:lHmdB0xuWaJ06KCraW6bztRT+71Dp+lsXQvborhhsBc=
github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU=
github.com/sethvargo/go-password v0.4.0/go.mod h1:PO3nYHwUpcHPR0F9woy7a4abZPvzRuqJr0GaeIYTm3k=
github.com/shamaton/msgpack/v2 v2.4.1 h1:JtJ141QoQ3NqgPDsjq2v9VXlaON8SiQOwEaoNLEK/MQ=
github.com/shamaton/msgpack/v2 v2.4.1/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
@@ -1703,8 +1703,8 @@ google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgn
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 h1:mJiOtnGp0k/BcSgdu03G2NwnscCfCH+h2QKUBZr18KI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+1 -1
View File
@@ -34,7 +34,7 @@ var (
// LatestTag is the latest released version plus the dev meta version.
// Will be overwritten by the release pipeline
// Needs a manual change for every tagged release
LatestTag = "7.3.0+dev"
LatestTag = "7.4.0+dev"
// Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
// Package assert enables defining [test properties] about your program or [workload]. It is part of the [Antithesis Go SDK], which enables Go applications to integrate with the [Antithesis platform].
//
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !enable_antithesis_sdk
//go:build no_antithesis_sdk
package assert
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package assert
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package assert
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package assert
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package assert
@@ -1,4 +1,4 @@
//go:build !enable_antithesis_sdk
//go:build no_antithesis_sdk
package assert
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package assert
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk
//go:build !no_antithesis_sdk
package internal
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk && linux && amd64 && cgo
//go:build !no_antithesis_sdk && linux && amd64 && cgo
package internal
@@ -1,4 +1,4 @@
//go:build enable_antithesis_sdk && (!linux || !amd64 || !cgo)
//go:build !no_antithesis_sdk && (!linux || !amd64 || !cgo)
package internal
+19 -7
View File
@@ -5,13 +5,13 @@ package colorable
import (
"bytes"
syscall "golang.org/x/sys/windows"
"io"
"math"
"os"
"strconv"
"strings"
"sync"
syscall "golang.org/x/sys/windows"
"unsafe"
"github.com/mattn/go-isatty"
@@ -93,6 +93,7 @@ type writer struct {
handle syscall.Handle
althandle syscall.Handle
oldattr word
curattr word
oldpos coord
rest bytes.Buffer
mutex sync.Mutex
@@ -112,7 +113,7 @@ func NewColorable(file *os.File) io.Writer {
var csbi consoleScreenBufferInfo
handle := syscall.Handle(file.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
return &writer{out: file, handle: handle, oldattr: csbi.attributes, curattr: csbi.attributes, oldpos: coord{0, 0}}
}
return file
}
@@ -438,7 +439,11 @@ func (w *writer) Write(data []byte) (n int, err error) {
w.mutex.Lock()
defer w.mutex.Unlock()
var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
if w.rest.Len() == 0 && bytes.IndexByte(data, 0x1b) == -1 {
w.out.Write(data)
return len(data), nil
}
handle := w.handle
@@ -517,7 +522,7 @@ loop:
w.rest.Reset()
break
}
buf.Write([]byte(string(c)))
buf.WriteByte(c)
}
if m == 0 {
break loop
@@ -678,11 +683,11 @@ loop:
procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
case 'm':
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
attr := csbi.attributes
attr := w.curattr
cs := buf.String()
if cs == "" {
procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr))
w.curattr = w.oldattr
continue
}
token := strings.Split(cs, ";")
@@ -814,9 +819,12 @@ loop:
attr |= backgroundBlue
}
}
procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))
}
}
if attr != w.curattr {
procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))
w.curattr = attr
}
case 'h':
var ci consoleCursorInfo
cs := buf.String()
@@ -834,6 +842,8 @@ loop:
w.althandle = syscall.Handle(h)
if w.althandle != 0 {
handle = w.althandle
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
w.curattr = csbi.attributes
}
}
}
@@ -853,6 +863,8 @@ loop:
syscall.CloseHandle(w.althandle)
w.althandle = 0
handle = w.handle
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
w.curattr = csbi.attributes
}
}
case 's':
+2 -2
View File
@@ -1,5 +1,5 @@
//go:build (appengine || js || nacl || tinygo || wasm) && !windows
// +build appengine js nacl tinygo wasm
//go:build (appengine || js || nacl || tinygo || wasm || wasip1 || wasip2) && !windows
// +build appengine js nacl tinygo wasm wasip1 wasip2
// +build !windows
package isatty
+13 -2
View File
@@ -31,6 +31,10 @@ func init() {
if procGetFileInformationByHandleEx.Find() != nil {
procGetFileInformationByHandleEx = nil
}
// Check if NtQueryObject is available.
if procNtQueryObject.Find() != nil {
procNtQueryObject = nil
}
}
// IsTerminal return true if the file descriptor is terminal.
@@ -43,6 +47,7 @@ func IsTerminal(fd uintptr) bool {
// Check pipe name is used for cygwin/msys2 pty.
// Cygwin/MSYS2 PTY has a name like:
// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master
// On Windows 7 a trailing suffix (e.g. "-nat") may be appended.
func isCygwinPipeName(name string) bool {
token := strings.Split(name, "-")
if len(token) < 5 {
@@ -72,13 +77,19 @@ func isCygwinPipeName(name string) bool {
return false
}
for _, t := range token[5:] {
if t == "" {
return false
}
}
return true
}
// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler
// getFileNameByHandle use the undocumented ntdll NtQueryObject to get file full name from file handler
// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion
// guys are using Windows XP, this is a workaround for those guys, it will also work on system from
// Windows vista to 10
// Windows Vista to 10
// see https://stackoverflow.com/a/18792477 for details
func getFileNameByHandle(fd uintptr) (string, error) {
if procNtQueryObject == nil {
+25
View File
@@ -0,0 +1,25 @@
# Security Policy
## Supported Versions
The following versions of go-runewidth are currently supported with
security updates.
| Version | Supported |
| -------- | ------------------ |
| 0.0.23 | :white_check_mark: |
| < 0.0.23 | :x: |
## Reporting a Vulnerability
If you discover a security vulnerability in go-runewidth, please report it
privately via GitHub's "Report a vulnerability" feature on the Security tab
of the repository (https://github.com/mattn/go-runewidth/security), or by
emailing the maintainer at mattn.jp@gmail.com.
Please include a description of the issue, reproduction steps, and the
affected version. You can expect an initial response within one week. If
the vulnerability is accepted, a fix will be prepared and a new release
will be published; you will be credited in the release notes unless you
request otherwise. If the report is declined, you will receive an
explanation of the reasoning.
+118 -35
View File
@@ -2,6 +2,7 @@ package runewidth
import (
"os"
"sort"
"strings"
"unicode/utf8"
@@ -25,13 +26,19 @@ var (
)
var (
zerowidth table // combining + nonprint merged for faster zero-width lookup
widewidth table // ambiguous + doublewidth merged for EA path
zerowidth table // combining + nonprint merged for faster zero-width lookup
widewidth table // ambiguous + doublewidth merged for EA path
eastAsianWidth widthTable
eastAsianWidth0 [0x300]byte
)
func init() {
zerowidth = mergeIntervals(combining, nonprint)
widewidth = mergeIntervals(ambiguous, doublewidth)
eastAsianWidth = makeWidthTable(zerowidth, widewidth)
for r := range eastAsianWidth0 {
eastAsianWidth0[r] = byte(runeWidthEastAsian(rune(r)))
}
handleEnv()
}
@@ -90,6 +97,14 @@ type interval struct {
type table []interval
type widthInterval struct {
first rune
last rune
width byte
}
type widthTable []widthInterval
func inTable(r rune, t table) bool {
if r < t[0].first {
return false
@@ -116,6 +131,71 @@ func inTable(r rune, t table) bool {
return false
}
func makeWidthTable(zero, two table) widthTable {
wt := make(widthTable, 0, len(zero)+len(two))
zi := 0
for _, iv := range two {
start := iv.first
for zi < len(zero) && zero[zi].last < start {
zi++
}
for i := zi; i < len(zero) && zero[i].first <= iv.last; i++ {
if start < zero[i].first {
wt = append(wt, widthInterval{start, zero[i].first - 1, 2})
}
if start <= zero[i].last {
start = zero[i].last + 1
}
if start > iv.last {
break
}
}
if start <= iv.last {
wt = append(wt, widthInterval{start, iv.last, 2})
}
}
for _, iv := range zero {
wt = append(wt, widthInterval{iv.first, iv.last, 0})
}
sort.Slice(wt, func(i, j int) bool {
return wt[i].first < wt[j].first
})
return wt
}
func inWidthTable(r rune, t widthTable) (int, bool) {
if r < t[0].first {
return 0, false
}
if r > t[len(t)-1].last {
return 0, false
}
bot := 0
top := len(t) - 1
for top >= bot {
mid := (bot + top) >> 1
switch {
case t[mid].last < r:
bot = mid + 1
case t[mid].first > r:
top = mid - 1
default:
return int(t[mid].width), true
}
}
return 0, false
}
func runeWidthEastAsian(r rune) int {
if w, ok := inWidthTable(r, eastAsianWidth); ok {
return w
}
return 1
}
var private = table{
{0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
}
@@ -153,13 +233,16 @@ func (c *Condition) RuneWidth(r rune) int {
}
// optimized version, verified by TestRuneWidthChecksums()
if !c.EastAsianWidth {
switch {
case r < 0x20:
if r < 0x20 {
return 0
case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint
}
if (r >= 0x7F && r <= 0x9F) || r == 0xAD { // nonprint
return 0
case r < 0x300:
}
if r < 0x300 {
return 1
}
switch {
case inTable(r, zerowidth):
return 0
case inTable(r, doublewidth):
@@ -167,20 +250,18 @@ func (c *Condition) RuneWidth(r rune) int {
default:
return 1
}
} else {
switch {
case inTable(r, zerowidth):
return 0
case inTable(r, narrow):
return 1
case inTable(r, widewidth):
return 2
case !c.StrictEmojiNeutral && inTable(r, emoji):
return 2
default:
return 1
}
}
if r < 0x300 {
return int(eastAsianWidth0[r])
}
if w, ok := inWidthTable(r, eastAsianWidth); ok {
return w
}
if !c.StrictEmojiNeutral && inTable(r, emoji) {
return 2
}
return 1
}
// CreateLUT will create an in-memory lookup table of 557056 bytes for faster operation.
@@ -206,6 +287,13 @@ func (c *Condition) CreateLUT() {
// StringWidth return width as you can see
func (c *Condition) StringWidth(s string) (width int) {
if len(s) == 1 {
b := s[0]
if b < 0x20 || b == 0x7F {
return 0
}
return 1
}
if len(s) > 0 && len(s) <= utf8.UTFMax {
r, size := utf8.DecodeRuneInString(s)
if size == len(s) {
@@ -213,15 +301,19 @@ func (c *Condition) StringWidth(s string) (width int) {
}
}
// ASCII fast path: no grapheme clustering needed for pure ASCII
if isAllASCII(s) {
for i := 0; i < len(s); i++ {
b := s[i]
if b >= 0x20 && b != 0x7F {
width++
}
for i := 0; i < len(s); i++ {
b := s[i]
if b >= 0x80 {
goto graphemes
}
if b >= 0x20 && b != 0x7F {
width++
}
return
}
return
graphemes:
width = 0
g := graphemes.FromString(s)
for g.Next() {
var chWidth int
@@ -236,15 +328,6 @@ func (c *Condition) StringWidth(s string) (width int) {
return
}
func isAllASCII(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] >= 0x80 {
return false
}
}
return true
}
// Truncate return string truncated with w cells
func (c *Condition) Truncate(s string, w int, tail string) string {
if c.StringWidth(s) <= w {
+15
View File
@@ -0,0 +1,15 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
language: en-US
reviews:
# Skip the vendored SQLite amalgamation. These files are copied verbatim from
# upstream SQLite (see the License section in README.md) and are not code that
# this project authors or reviews.
path_filters:
- "!sqlite3-binding.c"
- "!sqlite3-binding.h"
- "!sqlite3ext.h"
auto_review:
enabled: true
drafts: false
chat:
auto_reply: true
+13 -2
View File
@@ -7,9 +7,18 @@ go-sqlite3
[![codecov](https://codecov.io/gh/mattn/go-sqlite3/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-sqlite3)
[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-sqlite3)](https://goreportcard.com/report/github.com/mattn/go-sqlite3)
Latest stable version is v1.14 or later, not v2.
## Sponsors
~~**NOTE:** The increase to v2 was an accident. There were no major changes or features.~~
This project is proudly sponsored by:
<a href="https://coderabbit.link/mattn">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://victorious-bubble-f69a016683.media.strapiapp.com/White_Typemark_79b9189d19.svg">
<img src="https://victorious-bubble-f69a016683.media.strapiapp.com/Orange_Typemark_43bf516c9d.svg" alt="CodeRabbit" width="320">
</picture>
</a>
Latest stable version is v1.14 or later, not v2.
# Description
@@ -125,6 +134,7 @@ Boolean values can be one of:
| Transaction Lock | `_txlock` | <ul><li>immediate</li><li>deferred</li><li>exclusive</li></ul> | Specify locking behavior for transactions. |
| Writable Schema | `_writable_schema` | `Boolean` | When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file. |
| Cache Size | `_cache_size` | `int` | Maximum cache size; default is 2000K (2M). See [PRAGMA cache_size](https://sqlite.org/pragma.html#pragma_cache_size) |
| Statement Cache Size | `_stmt_cache_size` | `int` | Maximum number of prepared statements cached per connection; default is 0 (disabled). Note that `sql.DB` is a connection pool, so each connection maintains its own independent cache. |
## DSN Examples
@@ -181,6 +191,7 @@ go build -tags "icu json1 fts5 secure_delete"
| Tracing / Debug | sqlite_trace | Activate trace functions |
| User Authentication | sqlite_userauth | SQLite User Authentication see [User Authentication](#user-authentication) for more information. |
| Virtual Tables | sqlite_vtable | SQLite Virtual Tables see [SQLite Official VTABLE Documentation](https://www.sqlite.org/vtab.html) for more information, and a [full example here](https://github.com/mattn/go-sqlite3/tree/master/_example/vtable) |
| The DBSTAT Virtual Table | sqlite_dbstat | The DBSTAT virtual table is a read-only virtual table that returns information about the amount of disk space used to store the content of an SQLite database. See [SQLite Official Documentation](https://www.sqlite.org/dbstat.html) for more information. |
# Compilation
+33
View File
@@ -0,0 +1,33 @@
# Security Policy
## Supported Versions
Only the latest release on the `v1.14.x` line receives security fixes.
| Version | Supported |
| -------- | ------------------ |
| 1.14.x | :white_check_mark: |
| < 1.14 | :x: |
## Scope
`go-sqlite3` is a CGo binding that bundles the SQLite amalgamation
(`sqlite3-binding.c` / `sqlite3-binding.h`). Please report issues to the
appropriate project:
- Bugs in the Go binding layer, CGo glue, build tags, or this repository's
own code: report here.
- Vulnerabilities in SQLite itself: please report them upstream to the
SQLite developers at <https://www.sqlite.org/>. Once a fix is released
upstream, this repository will update the bundled amalgamation.
## Reporting a Vulnerability
Please **do not** open a public GitHub issue for security problems.
Use GitHub's private vulnerability reporting:
<https://github.com/mattn/go-sqlite3/security/advisories/new>
This project is maintained on a best-effort basis by volunteers, so please
allow reasonable time for investigation and a fix before any public
d
+103 -39
View File
@@ -18,7 +18,7 @@ package sqlite3
#endif
#include <stdlib.h>
void _sqlite3_result_text(sqlite3_context* ctx, const char* s);
void _sqlite3_result_text(sqlite3_context* ctx, const char* s, int n);
void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l);
*/
import "C"
@@ -29,12 +29,13 @@ import (
"math"
"reflect"
"sync"
"sync/atomic"
"unsafe"
)
//export callbackTrampoline
func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) {
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
func callbackTrampoline(ctx *C.sqlite3_context, argc C.int, argv **C.sqlite3_value) {
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:int(argc):int(argc)]
fi := lookupHandle(C.sqlite3_user_data(ctx)).(*functionInfo)
fi.Call(ctx, args)
}
@@ -59,9 +60,9 @@ func compareTrampoline(handlePtr unsafe.Pointer, la C.int, a *C.char, lb C.int,
}
//export commitHookTrampoline
func commitHookTrampoline(handle unsafe.Pointer) int {
func commitHookTrampoline(handle unsafe.Pointer) C.int {
callback := lookupHandle(handle).(func() int)
return callback()
return C.int(callback())
}
//export rollbackHookTrampoline
@@ -71,23 +72,23 @@ func rollbackHookTrampoline(handle unsafe.Pointer) {
}
//export updateHookTrampoline
func updateHookTrampoline(handle unsafe.Pointer, op int, db *C.char, table *C.char, rowid int64) {
func updateHookTrampoline(handle unsafe.Pointer, op C.int, db *C.char, table *C.char, rowid int64) {
callback := lookupHandle(handle).(func(int, string, string, int64))
callback(op, C.GoString(db), C.GoString(table), rowid)
callback(int(op), C.GoString(db), C.GoString(table), rowid)
}
//export authorizerTrampoline
func authorizerTrampoline(handle unsafe.Pointer, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
func authorizerTrampoline(handle unsafe.Pointer, op C.int, arg1 *C.char, arg2 *C.char, arg3 *C.char) C.int {
callback := lookupHandle(handle).(func(int, string, string, string) int)
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
return C.int(callback(int(op), C.GoString(arg1), C.GoString(arg2), C.GoString(arg3)))
}
//export preUpdateHookTrampoline
func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) {
func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op C.int, db *C.char, table *C.char, oldrowid int64, newrowid int64) {
hval := lookupHandleVal(handle)
data := SQLitePreUpdateData{
Conn: hval.db,
Op: op,
Op: int(op),
DatabaseName: C.GoString(db),
TableName: C.GoString(table),
OldRowID: oldrowid,
@@ -104,39 +105,84 @@ type handleVal struct {
}
var handleLock sync.Mutex
var handleVals = make(map[unsafe.Pointer]handleVal)
var handleVals atomic.Value // stores map[unsafe.Pointer]handleVal
func newHandle(db *SQLiteConn, v any) unsafe.Pointer {
handleLock.Lock()
defer handleLock.Unlock()
val := handleVal{db: db, val: v}
var p unsafe.Pointer = C.malloc(C.size_t(1))
if p == nil {
panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil")
}
handleVals[p] = val
handleLock.Lock()
defer handleLock.Unlock()
next := cloneHandleVals(len(loadHandleVals()) + 1)
next[p] = val
handleVals.Store(next)
return p
}
func lookupHandleVal(handle unsafe.Pointer) handleVal {
handleLock.Lock()
defer handleLock.Unlock()
return handleVals[handle]
return loadHandleVals()[handle]
}
func lookupHandle(handle unsafe.Pointer) any {
return lookupHandleVal(handle).val
}
// deleteHandle releases a single handle created by newHandle. It is a no-op
// if the handle is unknown (e.g. already released).
func deleteHandle(handle unsafe.Pointer) {
handleLock.Lock()
defer handleLock.Unlock()
current := loadHandleVals()
if _, ok := current[handle]; !ok {
return
}
next := make(map[unsafe.Pointer]handleVal, len(current)-1)
for h, v := range current {
if h == handle {
continue
}
next[h] = v
}
handleVals.Store(next)
C.free(handle)
}
func deleteHandles(db *SQLiteConn) {
handleLock.Lock()
defer handleLock.Unlock()
for handle, val := range handleVals {
if val.db == db {
delete(handleVals, handle)
C.free(handle)
}
current := loadHandleVals()
if len(current) == 0 {
return
}
next := make(map[unsafe.Pointer]handleVal, len(current))
for handle, val := range current {
if val.db == db {
C.free(handle)
continue
}
next[handle] = val
}
handleVals.Store(next)
}
func loadHandleVals() map[unsafe.Pointer]handleVal {
m, _ := handleVals.Load().(map[unsafe.Pointer]handleVal)
return m
}
func cloneHandleVals(size int) map[unsafe.Pointer]handleVal {
next := make(map[unsafe.Pointer]handleVal, size)
for handle, val := range loadHandleVals() {
next[handle] = val
}
return next
}
// This is only here so that tests can refer to it.
@@ -204,12 +250,13 @@ func callbackArgBytes(v *C.sqlite3_value) (reflect.Value, error) {
func callbackArgString(v *C.sqlite3_value) (reflect.Value, error) {
switch C.sqlite3_value_type(v) {
case C.SQLITE_BLOB:
l := C.sqlite3_value_bytes(v)
p := (*C.char)(C.sqlite3_value_blob(v))
l := C.sqlite3_value_bytes(v)
return reflect.ValueOf(C.GoStringN(p, l)), nil
case C.SQLITE_TEXT:
c := (*C.char)(unsafe.Pointer(C.sqlite3_value_text(v)))
return reflect.ValueOf(C.GoString(c)), nil
l := C.sqlite3_value_bytes(v)
return reflect.ValueOf(C.GoStringN(c, l)), nil
default:
return reflect.Value{}, fmt.Errorf("argument must be BLOB or TEXT")
}
@@ -234,6 +281,16 @@ func callbackArgGeneric(v *C.sqlite3_value) (reflect.Value, error) {
}
}
// callbackArgConvert returns conv as-is when the parameter type is the
// canonical type conv produces, and wraps it with a cast for named types
// (e.g. time.Duration), which reflect.Call would otherwise panic on.
func callbackArgConvert(conv callbackArgConverter, typ, canonical reflect.Type) callbackArgConverter {
if typ == canonical {
return conv
}
return callbackArgCast{conv, typ}.Run
}
func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
switch typ.Kind() {
case reflect.Interface:
@@ -245,18 +302,18 @@ func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
if typ.Elem().Kind() != reflect.Uint8 {
return nil, errors.New("the only supported slice type is []byte")
}
return callbackArgBytes, nil
return callbackArgConvert(callbackArgBytes, typ, reflect.TypeOf([]byte(nil))), nil
case reflect.String:
return callbackArgString, nil
return callbackArgConvert(callbackArgString, typ, reflect.TypeOf("")), nil
case reflect.Bool:
return callbackArgBool, nil
return callbackArgConvert(callbackArgBool, typ, reflect.TypeOf(false)), nil
case reflect.Int64:
return callbackArgInt64, nil
return callbackArgConvert(callbackArgInt64, typ, reflect.TypeOf(int64(0))), nil
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint:
c := callbackArgCast{callbackArgInt64, typ}
return c.Run, nil
case reflect.Float64:
return callbackArgFloat64, nil
return callbackArgConvert(callbackArgFloat64, typ, reflect.TypeOf(float64(0))), nil
case reflect.Float32:
c := callbackArgCast{callbackArgFloat64, typ}
return c.Run, nil
@@ -300,8 +357,7 @@ func callbackRetInteger(ctx *C.sqlite3_context, v reflect.Value) error {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint:
v = v.Convert(reflect.TypeOf(int64(0)))
case reflect.Bool:
b := v.Interface().(bool)
if b {
if v.Bool() {
v = reflect.ValueOf(int64(1))
} else {
v = reflect.ValueOf(int64(0))
@@ -310,7 +366,7 @@ func callbackRetInteger(ctx *C.sqlite3_context, v reflect.Value) error {
return fmt.Errorf("cannot convert %s to INTEGER", v.Type())
}
C.sqlite3_result_int64(ctx, C.sqlite3_int64(v.Interface().(int64)))
C.sqlite3_result_int64(ctx, C.sqlite3_int64(v.Int()))
return nil
}
@@ -323,7 +379,7 @@ func callbackRetFloat(ctx *C.sqlite3_context, v reflect.Value) error {
return fmt.Errorf("cannot convert %s to FLOAT", v.Type())
}
C.sqlite3_result_double(ctx, C.double(v.Interface().(float64)))
C.sqlite3_result_double(ctx, C.double(v.Float()))
return nil
}
@@ -331,11 +387,14 @@ func callbackRetBlob(ctx *C.sqlite3_context, v reflect.Value) error {
if v.Type().Kind() != reflect.Slice || v.Type().Elem().Kind() != reflect.Uint8 {
return fmt.Errorf("cannot convert %s to BLOB", v.Type())
}
i := v.Interface()
if i == nil || len(i.([]byte)) == 0 {
bs := v.Bytes()
if len(bs) == 0 {
C.sqlite3_result_null(ctx)
} else {
bs := i.([]byte)
if i64 && len(bs) > math.MaxInt32 {
C.sqlite3_result_error_toobig(ctx)
return nil
}
C._sqlite3_result_blob(ctx, unsafe.Pointer(&bs[0]), C.int(len(bs)))
}
return nil
@@ -345,8 +404,13 @@ func callbackRetText(ctx *C.sqlite3_context, v reflect.Value) error {
if v.Type().Kind() != reflect.String {
return fmt.Errorf("cannot convert %s to TEXT", v.Type())
}
cstr := C.CString(v.Interface().(string))
C._sqlite3_result_text(ctx, cstr)
s := v.String()
if i64 && len(s) > math.MaxInt32 {
C.sqlite3_result_error_toobig(ctx)
return nil
}
cstr := C.CString(s)
C._sqlite3_result_text(ctx, cstr, C.int(len(s)))
return nil
}
+8257 -4585
View File
File diff suppressed because it is too large. Load diff
+485 -104
View File
@@ -147,12 +147,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.51.3"
#define SQLITE_VERSION_NUMBER 3051003
#define SQLITE_SOURCE_ID "2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618"
#define SQLITE_SCM_BRANCH "branch-3.51"
#define SQLITE_SCM_TAGS "release version-3.51.3"
#define SQLITE_SCM_DATETIME "2026-03-13T10:38:09.694Z"
#define SQLITE_VERSION "3.53.4"
#define SQLITE_VERSION_NUMBER 3053004
#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc"
#define SQLITE_SCM_BRANCH "branch-3.53"
#define SQLITE_SCM_TAGS "release version-3.53.4"
#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -579,7 +579,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */
/*
** CAPI3REF: Flags For File Open Operations
@@ -1291,6 +1291,12 @@ struct sqlite3_io_methods {
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
/* reserved file-control numbers:
** 101
** 102
** 103
*/
/*
** CAPI3REF: Mutex Handle
@@ -1491,7 +1497,7 @@ typedef const char *sqlite3_filename;
** greater and the function pointer is not NULL) and will fall back
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
**
** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces
** are not used by the SQLite core. These optional interfaces are provided
** by some VFSes to facilitate testing of the VFS code. By overriding
** system calls with functions under its control, a test program can
@@ -1712,7 +1718,8 @@ SQLITE_API int sqlite3_os_end(void);
** are called "anytime configuration options".
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
** [sqlite3_shutdown()] with a first argument that is not an anytime
** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.
** configuration option, then the sqlite3_config() call will
** return SQLITE_MISUSE.
** Note, however, that ^sqlite3_config() can be called as part of the
** implementation of an application-defined [sqlite3_os_init()].
**
@@ -2278,9 +2285,10 @@ struct sqlite3_mem_methods {
** is less than 8. The "sz" argument should be a multiple of 8 less than
** 65536. If "sz" does not meet this constraint, it is reduced in size until
** it does.
** <li><p>The third argument ("cnt") is the number of slots. Lookaside is disabled
** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** <li><p>The third argument ("cnt") is the number of slots.
** Lookaside is disabled if "cnt"is less than 1.
* The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** parameter is usually chosen so that the product of "sz" and "cnt" is less
** than 1,000,000.
** </ol>
@@ -2568,12 +2576,15 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
** statistics. For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is prepared and when it
** is stepped. The flag is set (collection of statistics is enabled)
** by default. <p>This option takes two arguments: an integer and a pointer to
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
** a flag that enables collection of run-time performance statistics
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
** columns of the [bytecode virtual table].
** For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
** The flag is set (collection of statistics is enabled) by default.
** <p>This option takes two arguments: an integer and a pointer to
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
** leave unchanged the statement scanstatus option. If the second argument
** is not NULL, then the value of the statement scanstatus setting after
@@ -2646,16 +2657,34 @@ struct sqlite3_mem_methods {
** comments are allowed in SQL text after processing the first argument.
** </dd>
**
** [[SQLITE_DBCONFIG_FP_DIGITS]]
** <dt>SQLITE_DBCONFIG_FP_DIGITS</dt>
** <dd>The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines
** the number of significant digits that SQLite will attempt to preserve when
** converting floating point numbers (IEEE 754 "doubles") into text. The
** default value 17, as of SQLite version 3.52.0. The value was 15 in all
** prior versions.<p>
** This option takes two arguments which are an integer and a pointer
** to an integer. The first argument is a small integer, between 3 and 23, or
** zero. The FP_DIGITS setting is changed to that small integer, or left
** unaltered if the first argument is zero or out of range. The second argument
** is a pointer to an integer. If the pointer is not NULL, then the value of
** the FP_DIGITS setting, after possibly being modified by the first
** arguments, is written into the integer to which the second argument points.
** </dd>
**
** </dl>
**
** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3>
**
** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the
** overall call to [sqlite3_db_config()] has a total of four parameters.
** The first argument (the third parameter to sqlite3_db_config()) is an integer.
** The second argument is a pointer to an integer. If the first argument is 1,
** then the option becomes enabled. If the first integer argument is 0, then the
** option is disabled. If the first argument is -1, then the option setting
** The first argument (the third parameter to sqlite3_db_config()) is
** an integer.
** The second argument is a pointer to an integer. If the first argument is 1,
** then the option becomes enabled. If the first integer argument is 0,
** then the option is disabled.
** If the first argument is -1, then the option setting
** is unchanged. The second argument, the pointer to an integer, may be NULL.
** If the second argument is not NULL, then a value of 0 or 1 is written into
** the integer to which the second argument points, depending on whether the
@@ -2663,9 +2692,10 @@ struct sqlite3_mem_methods {
** the first argument.
**
** <p>While most SQLITE_DBCONFIG options use the argument format
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME]
** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the
** documentation of those exceptional options for details.
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME],
** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options
** are different. See the documentation of those exceptional options for
** details.
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2690,7 +2720,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */
#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */
#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -4172,6 +4203,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename);
** <li> sqlite3_errmsg()
** <li> sqlite3_errmsg16()
** <li> sqlite3_error_offset()
** <li> sqlite3_db_handle()
** </ul>
**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
@@ -4218,7 +4250,7 @@ SQLITE_API const char *sqlite3_errstr(int);
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
/*
** CAPI3REF: Set Error Codes And Message
** CAPI3REF: Set Error Code And Message
** METHOD: sqlite3
**
** Set the error code of the database handle passed as the first argument
@@ -4335,7 +4367,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** or in an ORDER BY or GROUP BY clause.</dd>)^
**
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
** <dd>The maximum depth of the parse tree on any expression and
** the maximum nesting depth for subqueries and VIEWs</dd>)^
**
** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
** <dd>The maximum depth of the LALR(1) parser stack used to analyze
** input SQL statements.</dd>)^
**
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
@@ -4362,7 +4399,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** <dd>The maximum index number of any [parameter] in an SQL statement.)^
**
** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
** <dd>The maximum depth of recursion for triggers.</dd>)^
** <dd>The maximum depth of recursion for triggers, and the maximum
** nesting depth for separate triggers.</dd>)^
**
** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
** <dd>The maximum number of auxiliary worker threads that a single
@@ -4381,6 +4419,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
#define SQLITE_LIMIT_PARSER_DEPTH 12
/*
** CAPI3REF: Prepare Flags
@@ -4425,12 +4464,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** fails, the sqlite3_prepare_v3() call returns the same error indications
** with or without this flag; it just omits the call to [sqlite3_log()] that
** logs the error.
**
** [[SQLITE_PREPARE_FROM_DDL]] <dt>SQLITE_PREPARE_FROM_DDL</dt>
** <dd>The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce
** security constraints that would otherwise only be enforced when parsing
** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag
** causes the SQL compiler to treat the SQL statement being prepared as if
** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and
** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called
** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only
** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice
** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that
** is derived from parts of the database schema. In particular, virtual
** table implementations that run SQL statements that are derived from
** arguments to their CREATE VIRTUAL TABLE statement should always use
** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to
** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
#define SQLITE_PREPARE_NO_VTAB 0x04
#define SQLITE_PREPARE_DONT_LOG 0x10
#define SQLITE_PREPARE_FROM_DDL 0x20
/*
** CAPI3REF: Compiling An SQL Statement
@@ -4444,8 +4500,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** The preferred routine to use is [sqlite3_prepare_v2()]. The
** [sqlite3_prepare()] interface is legacy and should be avoided.
** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
** for special purposes.
** [sqlite3_prepare_v3()] has an extra
** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes
** needed for special purpose or to pass along security restrictions.
**
** The use of the UTF-8 interfaces is preferred, as SQLite currently
** does all parsing using UTF-8. The UTF-16 interfaces are provided
@@ -4850,8 +4907,8 @@ typedef struct sqlite3_context sqlite3_context;
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
** otherwise.
** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT,
** or UTF16 otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
@@ -4897,10 +4954,15 @@ typedef struct sqlite3_context sqlite3_context;
** object and pointer to it must remain valid until then. ^SQLite will then
** manage the lifetime of its private copy.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter. If
** the sixth argument to sqlite3_bind_text64() is not one of the
** ^The sixth argument (the E argument)
** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of
** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE] to specify the encoding of the text in the
** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the
** string argument is both UTF-8 encoded and is zero-terminated. In other
** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at
** least N+1 bytes and that the Z&#91;N&#93; byte is zero. If
** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
@@ -5767,6 +5829,52 @@ SQLITE_API int sqlite3_create_window_function(
**
** These constants define integer codes that represent the various
** text encodings supported by SQLite.
**
** <dl>
** [[SQLITE_UTF8]] <dt>SQLITE_UTF8</dt><dd>Text is encoding as UTF-8</dd>
**
** [[SQLITE_UTF16LE]] <dt>SQLITE_UTF16LE</dt><dd>Text is encoding as UTF-16
** with each code point being expressed "little endian" - the least significant
** byte first. This is the usual encoding, for example on Windows.</dd>
**
** [[SQLITE_UTF16BE]] <dt>SQLITE_UTF16BE</dt><dd>Text is encoding as UTF-16
** with each code point being expressed "big endian" - the most significant
** byte first. This encoding is less common, but is still sometimes seen,
** specially on older systems.
**
** [[SQLITE_UTF16]] <dt>SQLITE_UTF16</dt><dd>Text is encoding as UTF-16
** with each code point being expressed either little endian or as big
** endian, according to the native endianness of the host computer.
**
** [[SQLITE_ANY]] <dt>SQLITE_ANY</dt><dd>This encoding value may only be used
** to declare the preferred text for [application-defined SQL functions]
** created using [sqlite3_create_function()] and similar. If the preferred
** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep
** parameter) is SQLITE_ANY, that indicates that the function does not have
** a preference regarding the text encoding of its parameters and can take
** any text encoding that the SQLite core find convenient to supply. This
** option is deprecated. Please do not use it in new applications.
**
** [[SQLITE_UTF16_ALIGNED]] <dt>SQLITE_UTF16_ALIGNED</dt><dd>This encoding
** value may be used as the 3rd parameter (the eTextRep parameter) to
** [sqlite3_create_collation()] and similar. This encoding value means
** that the application-defined collating sequence created expects its
** input strings to be in UTF16 in native byte order, and that the start
** of the strings must be aligned to a 2-byte boundary.
**
** [[SQLITE_UTF8_ZT]] <dt>SQLITE_UTF8_ZT</dt><dd>This option can only be
** used to specify the text encoding to strings input to
** [sqlite3_result_text64()] and [sqlite3_bind_text64()].
** The SQLITE_UTF8_ZT encoding means that the input string (call it "z")
** is UTF-8 encoded and that it is zero-terminated. If the length parameter
** (call it "n") is non-negative, this encoding option means that the caller
** guarantees that z array contains at least n+1 bytes and that the z&#91;n&#93;
** byte has a value of zero.
** This option gives the same output as SQLITE_UTF8, but can be more efficient
** by avoiding the need to make a copy of the input string, in some cases.
** However, if z is allocated to hold fewer than n+1 bytes or if the
** z&#91;n&#93; byte is not zero, undefined behavior may result.
** </dl>
*/
#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */
#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */
@@ -5774,6 +5882,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */
/*
** CAPI3REF: Function Flags
@@ -6008,26 +6117,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** the SQL function that supplied the [sqlite3_value*] parameters.
**
** As long as the input parameter is correct, these routines can only
** fail if an out-of-memory error occurs during a format conversion.
** Only the following subset of interfaces are subject to out-of-memory
** errors:
**
** <ul>
** <li> sqlite3_value_blob()
** <li> sqlite3_value_text()
** <li> sqlite3_value_text16()
** <li> sqlite3_value_text16le()
** <li> sqlite3_value_text16be()
** <li> sqlite3_value_bytes()
** <li> sqlite3_value_bytes16()
** </ul>
**
** fail if an out-of-memory error occurs while trying to do a
** UTF8&rarr;UTF16 or UTF16&rarr;UTF8 conversion.
** If an out-of-memory error occurs, then the return value from these
** routines is the same as if the column had contained an SQL NULL value.
** Valid SQL NULL returns can be distinguished from out-of-memory errors
** by invoking the [sqlite3_errcode()] immediately after the suspect
** If the input sqlite3_value was not obtained from [sqlite3_value_dup()],
** then valid SQL NULL returns can also be distinguished from
** out-of-memory errors after extracting the value
** by invoking the [sqlite3_errcode()] immediately after the suspicious
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
** If the input sqlite3_value was obtained from sqlite3_value_dup() then
** it is disconnected from the database connection and so sqlite3_errcode()
** will not work.
** In that case, the only way to distinguish an out-of-memory
** condition from a true SQL NULL is to invoke sqlite3_value_type() on the
** input to see if it is NULL prior to trying to extract the value.
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API double sqlite3_value_double(sqlite3_value*);
@@ -6054,7 +6159,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
** returns something other than SQLITE_TEXT, then the return value from
** sqlite3_value_encoding(X) is meaningless. ^Calls to
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)],
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)],
** [sqlite3_value_text16be(X)],
** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or
** [sqlite3_value_bytes16(X)] might change the encoding of the value X and
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
@@ -6185,17 +6291,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** query execution, under some circumstances the associated auxiliary data
** might be preserved. An example of where this might be useful is in a
** regular-expression matching function. The compiled version of the regular
** expression can be stored as auxiliary data associated with the pattern string.
** Then as long as the pattern string remains the same,
** expression can be stored as auxiliary data associated with the pattern
** string. Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
** value to the application-defined function. ^N is zero for the left-most
** function argument. ^If there is no auxiliary data
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary
** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the
** Nth argument value to the application-defined function. ^N is zero
** for the left-most function argument. ^If there is no auxiliary data
** associated with the function argument, the sqlite3_get_auxdata(C,N)
** interface returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the
** N-th argument of the application-defined function. ^Subsequent
@@ -6279,10 +6385,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
**
** There is no limit (other than available memory) on the number of different
** client data pointers (with different names) that can be attached to a
** single database connection. However, the implementation is optimized
** for the case of having only one or two different client data names.
** Applications and wrapper libraries are discouraged from using more than
** one client data name each.
** single database connection. However, the current implementation stores
** the content on a linked list. Insert and retrieval performance will
** be proportional to the number of entries. The design use case, and
** the use case for which the implementation is optimized, is
** that an application will store only small number of client data names,
** typically just one or two. This interface is not intended to be a
** generalized key/value store for thousands or millions of keys. It
** will work for that, but performance might be disappointing.
**
** There is no way to enumerate the client data pointers
** associated with a database connection. The N parameter can be thought
@@ -6390,10 +6500,14 @@ typedef void (*sqlite3_destructor_type)(void*);
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
** specified the E parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that
** the result text is both UTF-8 and zero-terminated. In other words,
** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that
** the Z&#91;N&#93; is zero.
** ^SQLite takes the text result from the application from
** the 2nd parameter of the sqlite3_result_text* interfaces.
** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces
@@ -6480,7 +6594,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
SQLITE_API void sqlite3_result_null(sqlite3_context*);
SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n,
void(*)(void*), unsigned char encoding);
SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
@@ -7419,7 +7533,7 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The sqlite3_load_extension() interface attempts to load an
** [SQLite extension] library contained in the file zFile. If
** the file cannot be loaded directly, attempts are made to load
** with various operating-system specific extensions added.
** with various operating-system specific filename extensions added.
** So for example, if "samplelib" cannot be loaded, then names like
** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
** be tried also.
@@ -7427,10 +7541,10 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The entry point is zProc.
** ^(zProc may be 0, in which case SQLite will try to come up with an
** entry point name on its own. It first tries "sqlite3_extension_init".
** If that does not work, it constructs a name "sqlite3_X_init" where
** X consists of the lower-case equivalent of all ASCII alphabetic
** characters in the filename from the last "/" to the first following
** "." and omitting any initial "lib".)^
** If that does not work, it tries names of the form "sqlite3_X_init"
** where X consists of the lower-case equivalent of all ASCII alphabetic
** characters or all ASCII alphanumeric characters in the filename from
** the last "/" to the first following "." and omitting any initial "lib".)^
** ^The sqlite3_load_extension() interface returns
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
** ^If an error occurs and pzErrMsg is not 0, then the
@@ -7504,7 +7618,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** <blockquote><pre>
** &nbsp; int xEntryPoint(
** &nbsp; sqlite3 *db,
** &nbsp; const char **pzErrMsg,
** &nbsp; char **pzErrMsg,
** &nbsp; const struct sqlite3_api_routines *pThunk
** &nbsp; );
** </pre></blockquote>)^
@@ -8254,13 +8368,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
@@ -8615,6 +8722,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */
#define SQLITE_TESTCTRL_ATOF 34
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
@@ -8723,17 +8831,22 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
** errors were encountered during construction of the string. ^The
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the
** string in [sqlite3_str] object X is zero bytes long.
**
** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
** X and the string content it contains. Calling sqlite3_str_free(X) is
** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
*/
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
SQLITE_API void sqlite3_str_free(sqlite3_str*);
/*
** CAPI3REF: Add Content To A Dynamic String
** METHOD: sqlite3_str
**
** These interfaces add content to an sqlite3_str object previously obtained
** from [sqlite3_str_new()].
** These interfaces add or remove content to an sqlite3_str object
** previously obtained from [sqlite3_str_new()].
**
** ^The [sqlite3_str_appendf(X,F,...)] and
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
@@ -8756,6 +8869,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
** ^The [sqlite3_str_reset(X)] method resets the string under construction
** inside [sqlite3_str] object X back to zero bytes in length.
**
** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
** under construction to be N bytes or less. This routine is a no-op if
** N is negative or if the string is already N bytes or smaller in size.
**
** These methods do not return a result code. ^If an error occurs, that fact
** is recorded in the [sqlite3_str] object and can be recovered by a
** subsequent call to [sqlite3_str_errcode(X)].
@@ -8766,6 +8883,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
SQLITE_API void sqlite3_str_reset(sqlite3_str*);
SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
/*
** CAPI3REF: Status Of A Dynamic String
@@ -10296,7 +10414,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** <tr>
** <td valign="top">sqlite3_vtab_distinct() return value
** <td valign="top">Rows are returned in aOrderBy order
** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent
** <td valign="top">Rows with the same value in all aOrderBy columns are
** adjacent
** <td valign="top">Duplicates over all colUsed columns may be omitted
** <tr><td>0<td>yes<td>yes<td>no
** <tr><td>1<td>no<td>yes<td>no
@@ -10305,8 +10424,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** </table>
**
** ^For the purposes of comparing virtual table output values to see if the
** values are the same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
** values are the same value for sorting purposes, two NULL values are
** considered to be the same. In other words, the comparison operator is "IS"
** (or "IS NOT DISTINCT FROM") and not "==".
**
** If a virtual table implementation is unable to meet the requirements
@@ -10599,9 +10718,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** a variable pointed to by the "pOut" parameter.
**
** The "flags" parameter must be passed a mask of flags. At present only
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
** is specified, then status information is available for all elements
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
** the EXPLAIN QUERY PLAN output) are available. Invoking API
@@ -10615,7 +10734,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** elements used to implement the statement - a non-zero value is returned and
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
** See also: [sqlite3_stmt_scanstatus_reset()] and the
** [nexec and ncycle] columns of the [bytecode virtual table].
*/
SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
@@ -11157,19 +11277,42 @@ SQLITE_API int sqlite3_deserialize(
/*
** CAPI3REF: Bind array values to the CARRAY table-valued function
**
** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to
** one of the first argument of the [carray() table-valued function]. The
** S parameter is a pointer to the [prepared statement] that uses the carray()
** functions. I is the parameter index to be bound. P is a pointer to the
** array to be bound, and N is the number of eements in the array. The
** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
** indicate the datatype of the array being bound. The X argument is not a
** NULL pointer, then SQLite will invoke the function X on the P parameter
** after it has finished using P, even if the call to
** sqlite3_carray_bind() fails. The special-case finalizer
** SQLITE_TRANSIENT has no effect here.
** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to
** parameter that is the first argument of the [carray() table-valued function].
** The S parameter is a pointer to the [prepared statement] that uses the
** carray() functions. I is the parameter index to be bound. I must be the
** index of the parameter that is the first argument to the carray()
** table-valued function. P is a pointer to the array to be bound, and N
** is the number of elements in the array. The F argument is one of
** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT],
** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P.
**
** If the X argument is not a NULL pointer or one of the special
** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke
** the function X with argument D when it is finished using the data in P.
** The call to X(D) is a destructor for the array P. The destructor X(D)
** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X
** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes
** that the data static and the destructor is never invoked. If the X
** parameter is the special-case value [SQLITE_TRANSIENT], then
** sqlite3_carray_bind_v2() makes its own private copy of the data prior
** to returning and never invokes the destructor X.
**
** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2()
** with a D parameter set to P. In other words,
** sqlite3_carray_bind(S,I,P,N,F,X) is same as
** sqlite3_carray_bind_v2(S,I,P,N,F,X,P).
*/
SQLITE_API int sqlite3_carray_bind_v2(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
void *aData, /* Pointer to array data */
int nData, /* Number of data elements */
int mFlags, /* CARRAY flags */
void (*xDel)(void*), /* Destructor for aData */
void *pDel /* Optional argument to xDel() */
);
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
@@ -12713,11 +12856,23 @@ SQLITE_API int sqlite3changeset_apply_v3(
** database behave as if they were declared with "ON UPDATE NO ACTION ON
** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL
** or SET DEFAULT.
**
** <dt>SQLITE_CHANGESETAPPLY_NOUPDATELOOP <dd>
** Sometimes, a changeset contains two or more update statements such that
** although after applying all updates the database will contain no
** constraint violations, no single update can be applied before the others.
** The simplest example of this is a pair of UPDATEs that have "swapped"
** two column values with a UNIQUE constraint.
** <p>
** Usually, sqlite3changeset_apply() and similar functions work hard to try
** to find a way to apply such a changeset. However, if this flag is set,
** then all such updates are considered CONSTRAINT conflicts.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -13200,6 +13355,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg);
*/
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** CAPI3REF: Configure a changegroup object
**
** Configure the changegroup object passed as the first argument.
** At present the only valid value for the second parameter is
** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET].
*/
SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg);
/*
** CAPI3REF: Options for sqlite3changegroup_config().
**
** The following values may be passed as the 2nd parameter to
** sqlite3changegroup_config().
**
** <dt>SQLITE_CHANGEGROUP_CONFIG_PATCHSET <dd>
** A changegroup object generates either a changeset or patchset. Usually,
** this is determined by whether the first call to sqlite3changegroup_add()
** is passed a changeset or a patchset. Or, if the first changes are added
** to the changegroup object using the sqlite3changegroup_change_xxx()
** APIs, then this option may be used to configure whether the changegroup
** object generates a changeset or patchset.
**
** When this option is invoked, parameter pArg must point to a value of
** type int. If the changegroup currently contains zero changes, and the
** value of the int variable is zero or greater than zero, then the
** changegroup is configured to generate a changeset or patchset,
** respectively. It is a no-op, not an error, if the changegroup is not
** configured because it has already started accumulating changes.
**
** Before returning, the int variable is set to 0 if the changegroup is
** configured to generate a changeset, or 1 if it is configured to generate
** a patchset.
*/
#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1
/*
** CAPI3REF: Begin adding a change to a changegroup
**
** This API is used, in concert with other sqlite3changegroup_change_xxx()
** APIs, to add changes to a changegroup object one at a time. To add a
** single change, the caller must:
**
** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of
** change (INSERT, UPDATE or DELETE), the affected table and whether
** or not the change should be marked as indirect.
**
** 2. Invoke sqlite3changegroup_change_int64() or one of the other four
** value functions - _null(), _double(), _text() or _blob() - one or
** more times to specify old.* and new.* values for the change being
** constructed.
**
** 3. Invoke sqlite3changegroup_change_finish() to either finish adding
** the change to the group, or to discard the change altogether.
**
** The first argument to this function must be a pointer to the existing
** changegroup object that the change will be added to. The second argument
** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the
** name of the table that the change affects, and the fourth is a boolean
** flag specifying whether the change should be marked as "indirect" (if
** bIndirect is non-zero) or not indirect (if bIndirect is zero).
**
** Following a successful call to this function, this function may not be
** called again on the same changegroup object until after
** sqlite3changegroup_change_finish() has been called. Doing so is an
** SQLITE_MISUSE error.
**
** The changegroup object passed as the first argument must be already
** configured with schema data for the specified table. It may be configured
** either by calling sqlite3changegroup_schema() with a database that contains
** the table, or sqlite3changegroup_add() with a changeset that contains the
** table. If the changegroup object has not been configured with a schema for
** the specified table when this function is called, SQLITE_ERROR is returned.
**
** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an
** SQLite error code is returned. In this case, if argument pzErr is non-NULL,
** then (*pzErr) may be set to point to a buffer containing a utf-8 formated,
** nul-terminated, English language error message. It is the responsibility
** of the caller to eventually free this buffer using sqlite3_free().
*/
SQLITE_API int sqlite3changegroup_change_begin(
sqlite3_changegroup*,
int eOp,
const char *zTab,
int bIndirect,
char **pzErr
);
/*
** CAPI3REF: Add a 64-bit integer to a changegroup
**
** This function may only be called between a successful call to
** sqlite3changegroup_change_begin() and its matching
** sqlite3changegroup_change_finish() call. If it is called at any
** other time, it is an SQLITE_MISUSE error. Calling this function
** specifies a 64-bit integer value to be used in the change currently being
** added to the changegroup object passed as the first argument.
**
** The second parameter, bNew, specifies whether the value is to be part of
** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of
** the change under construction. If this does not match the type of change
** specified by the preceding call to sqlite3changegroup_change_begin() (i.e.
** an old.* value for an SQLITE_INSERT change, or a new.* value for an
** SQLITE_DELETE), then SQLITE_ERROR is returned.
**
** The third parameter specifies the column of the old.* or new.* record that
** the value will be a part of. If the specified table has an explicit primary
** key, then this is the index of the table column, numbered from 0 in the order
** specified within the CREATE TABLE statement. Or, if the table uses an
** implicit rowid key, then the column 0 is the rowid and the explicit columns
** are numbered starting from 1. If the iCol parameter is less than 0 or greater
** than the index of the last column in the table, SQLITE_RANGE is returned.
**
** The fourth parameter is the integer value to use as part of the old.* or
** new.* record.
**
** If this call is successful, SQLITE_OK is returned. Otherwise, if an
** error occurs, an SQLite error code is returned.
*/
SQLITE_API int sqlite3changegroup_change_int64(
sqlite3_changegroup*,
int bNew,
int iCol,
sqlite3_int64 iVal
);
/*
** CAPI3REF: Add a NULL to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). Except that
** it configures the change currently under construction with a NULL value
** instead of a 64-bit integer.
*/
SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int);
/*
** CAPI3REF: Add an double to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). Except that
** it configures the change currently being constructed with a real value
** instead of a 64-bit integer.
*/
SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double);
/*
** CAPI3REF: Add a text value to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). It configures
** the currently accumulated change with a text value instead of a 64-bit
** integer. Parameter pVal points to a buffer containing the text encoded using
** utf-8. Parameter nVal may either be the size of the text value in bytes, or
** else a negative value, in which case the buffer pVal points to is assumed to
** be nul-terminated.
*/
SQLITE_API int sqlite3changegroup_change_text(
sqlite3_changegroup*, int, int, const char *pVal, int nVal
);
/*
** CAPI3REF: Add a blob to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). It configures
** the currently accumulated change with a blob value instead of a 64-bit
** integer. Parameter pVal points to a buffer containing the blob. Parameter
** nVal is the size of the blob in bytes.
*/
SQLITE_API int sqlite3changegroup_change_blob(
sqlite3_changegroup*, int, int, const void *pVal, int nVal
);
/*
** CAPI3REF: Finish adding one-at-at-time changes to a changegroup
**
** This function may only be called following a successful call to
** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error.
**
** If parameter bDiscard is non-zero, then the current change is simply
** discarded. In this case this function is always successful and SQLITE_OK
** returned.
**
** If parameter bDiscard is zero, then an attempt is made to add the current
** change to the changegroup. Assuming the changegroup is configured to
** produce a changeset (not a patchset), this requires that:
**
** * If the change is an INSERT or DELETE, then a value must be specified
** for all columns of the new.* or old.* record, respectively.
**
** * If the change is an UPDATE record, then values must be provided for
** the PRIMARY KEY columns of the old.* record, but must not be provided
** for PRIMARY KEY columns of the new.* record.
**
** * If the change is an UPDATE record, then for each non-PRIMARY KEY
** column in the old.* record for which a value has been provided, a
** value must also be provided for the same column in the new.* record.
** Similarly, for each non-PK column in the old.* record for which
** a value is not provided, a value must not be provided for the same
** column in the new.* record.
**
** * All values specified for PRIMARY KEY columns must be non-NULL.
**
** Otherwise, it is an error.
**
** If the changegroup already contains a change for the same row (identified
** by PRIMARY KEY columns), then the current change is combined with the
** existing change in the same way as for sqlite3changegroup_add().
**
** For a patchset, all of the above rules apply except that it doesn't matter
** whether or not values are provided for the non-PK old.* record columns
** for an UPDATE or DELETE change. This means that code used to produce
** a changeset using the sqlite3changegroup_change_xxx() APIs may also
** be used to produce patchsets.
**
** If the call is successful, SQLITE_OK is returned. Otherwise, if an error
** occurs, an SQLite error code is returned. If an error is returned and
** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer
** containing a nul-terminated, utf-8 encoded, English language error message.
** It is the responsibility of the caller to eventually free any such error
** message buffer using sqlite3_free().
*/
SQLITE_API int sqlite3changegroup_change_finish(
sqlite3_changegroup*,
int bDiscard,
char **pzErr
);
/*
** Make sure we can call this stuff from C++.
*/
+235 -130
View File
@@ -69,13 +69,13 @@ _sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zV
}
static int
_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, sqlite3_uint64 np) {
return sqlite3_bind_text64(stmt, n, p, np, SQLITE_TRANSIENT, SQLITE_UTF8);
}
static int
_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, sqlite3_uint64 np) {
return sqlite3_bind_blob64(stmt, n, p, np, SQLITE_TRANSIENT);
}
typedef struct {
@@ -220,8 +220,8 @@ _sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_
}
#endif
void _sqlite3_result_text(sqlite3_context* ctx, const char* s) {
sqlite3_result_text(ctx, s, -1, &free);
void _sqlite3_result_text(sqlite3_context* ctx, const char* s, int n) {
sqlite3_result_text(ctx, s, n, &free);
}
void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l) {
@@ -445,15 +445,20 @@ type SQLiteDriver struct {
// SQLiteConn implements driver.Conn.
type SQLiteConn struct {
mu sync.Mutex
db *C.sqlite3
loc *time.Location
txlock string
funcs []*functionInfo
aggregators []*aggInfo
stmtCache map[string][]*SQLiteStmt
stmtCacheSize int
stmtCacheCount int
mu sync.Mutex
db *C.sqlite3
loc *time.Location
txlock string
funcs []*functionInfo
aggregators []*aggInfo
// Prepared-statement cache. The slice is allocated at Open with a
// fixed capacity equal to the configured cache size; cap bounds the
// cache, len is the live count, and entries are ordered LRU-first
// (index 0 is the oldest, the tail is most recently put). Access
// requires mu; stmtCacheEnabled is immutable after Open and is the
// only field safe to read without the lock.
stmtCache []*SQLiteStmt
stmtCacheEnabled bool
}
// SQLiteTx implements driver.Tx.
@@ -471,6 +476,12 @@ type SQLiteStmt struct {
cls bool // True if the statement was created by SQLiteConn.Query
namedParams map[string][3]int
cacheKey string
metadata *sqliteStmtMetadata
}
type sqliteStmtMetadata struct {
cols []string
decltype []string
}
// SQLiteResult implements sql.Result.
@@ -1017,25 +1028,37 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.Name
if err != nil {
return nil, err
}
s.(*SQLiteStmt).cls = true
ss := s.(*SQLiteStmt)
ss.cls = true
// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle
// when the input is empty or contains only whitespace/comments.
if ss.s == nil {
tail := ss.t
ss.Close()
if tail == "" {
return &SQLiteRows{cls: true, ctx: ctx}, nil
}
query = tail
continue
}
na := s.NumInput()
if len(args)-start < na {
s.Close()
ss.Close()
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
}
stmtArgs := stmtArgs(args, start, na)
rows, err := s.(*SQLiteStmt).query(ctx, stmtArgs)
rows, err := ss.query(ctx, stmtArgs)
if err != nil && err != driver.ErrSkip {
s.Close()
ss.Close()
return rows, err
}
start += na
tail := s.(*SQLiteStmt).t
tail := ss.t
if tail == "" {
return rows, nil
}
rows.Close()
s.Close()
ss.Close()
query = tail
}
}
@@ -1572,6 +1595,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
return nil, errors.New("sqlite succeeded without returning a database")
}
// Create connection to SQLite
conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
if stmtCacheSize > 0 {
conn.stmtCache = make([]*SQLiteStmt, 0, stmtCacheSize)
conn.stmtCacheEnabled = true
}
// fail closes the connection so no error path leaks the database
// handle or any callback handles registered on it.
fail := func(err error) (driver.Conn, error) {
conn.Close()
return nil, err
}
exec := func(s string) error {
cs := C.CString(s)
rv := C.sqlite3_exec(db, cs, nil, nil, nil)
@@ -1584,8 +1621,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// Busy timeout
if err := exec(fmt.Sprintf("PRAGMA busy_timeout = %d;", busyTimeout)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
// USER AUTHENTICATION
@@ -1610,65 +1646,59 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// NO => Continue
//
// Create connection to SQLite
conn := &SQLiteConn{db: db, loc: loc, txlock: txlock, stmtCacheSize: stmtCacheSize}
if stmtCacheSize > 0 {
conn.stmtCache = make(map[string][]*SQLiteStmt)
}
// Password Cipher has to be registered before authentication
if len(authCrypt) > 0 {
switch strings.ToUpper(authCrypt) {
case "SHA1":
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSHA1, true); err != nil {
return nil, fmt.Errorf("CryptEncoderSHA1: %s", err)
return fail(fmt.Errorf("CryptEncoderSHA1: %s", err))
}
case "SSHA1":
if len(authSalt) == 0 {
return nil, fmt.Errorf("_auth_crypt=ssha1, requires _auth_salt")
return fail(fmt.Errorf("_auth_crypt=ssha1, requires _auth_salt"))
}
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSSHA1(authSalt), true); err != nil {
return nil, fmt.Errorf("CryptEncoderSSHA1: %s", err)
return fail(fmt.Errorf("CryptEncoderSSHA1: %s", err))
}
case "SHA256":
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSHA256, true); err != nil {
return nil, fmt.Errorf("CryptEncoderSHA256: %s", err)
return fail(fmt.Errorf("CryptEncoderSHA256: %s", err))
}
case "SSHA256":
if len(authSalt) == 0 {
return nil, fmt.Errorf("_auth_crypt=ssha256, requires _auth_salt")
return fail(fmt.Errorf("_auth_crypt=ssha256, requires _auth_salt"))
}
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSSHA256(authSalt), true); err != nil {
return nil, fmt.Errorf("CryptEncoderSSHA256: %s", err)
return fail(fmt.Errorf("CryptEncoderSSHA256: %s", err))
}
case "SHA384":
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSHA384, true); err != nil {
return nil, fmt.Errorf("CryptEncoderSHA384: %s", err)
return fail(fmt.Errorf("CryptEncoderSHA384: %s", err))
}
case "SSHA384":
if len(authSalt) == 0 {
return nil, fmt.Errorf("_auth_crypt=ssha384, requires _auth_salt")
return fail(fmt.Errorf("_auth_crypt=ssha384, requires _auth_salt"))
}
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSSHA384(authSalt), true); err != nil {
return nil, fmt.Errorf("CryptEncoderSSHA384: %s", err)
return fail(fmt.Errorf("CryptEncoderSSHA384: %s", err))
}
case "SHA512":
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSHA512, true); err != nil {
return nil, fmt.Errorf("CryptEncoderSHA512: %s", err)
return fail(fmt.Errorf("CryptEncoderSHA512: %s", err))
}
case "SSHA512":
if len(authSalt) == 0 {
return nil, fmt.Errorf("_auth_crypt=ssha512, requires _auth_salt")
return fail(fmt.Errorf("_auth_crypt=ssha512, requires _auth_salt"))
}
if err := conn.RegisterFunc("sqlite_crypt", CryptEncoderSSHA512(authSalt), true); err != nil {
return nil, fmt.Errorf("CryptEncoderSSHA512: %s", err)
return fail(fmt.Errorf("CryptEncoderSSHA512: %s", err))
}
}
}
// Preform Authentication
if err := conn.Authenticate(authUser, authPass); err != nil {
return nil, err
return fail(err)
}
// Register: authenticate
@@ -1686,7 +1716,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK.
if err := conn.RegisterFunc("authenticate", conn.authenticate, true); err != nil {
return nil, err
return fail(err)
}
//
// Register: auth_user_add
@@ -1699,7 +1729,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
// non-admin user results in an error.
if err := conn.RegisterFunc("auth_user_add", conn.authUserAdd, true); err != nil {
return nil, err
return fail(err)
}
//
// Register: auth_user_change
@@ -1709,7 +1739,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// credentials or admin privilege setting. No user may change their own
// admin privilege setting.
if err := conn.RegisterFunc("auth_user_change", conn.authUserChange, true); err != nil {
return nil, err
return fail(err)
}
//
// Register: auth_user_delete
@@ -1719,13 +1749,13 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// the database cannot be converted into a no-authentication-required
// database.
if err := conn.RegisterFunc("auth_user_delete", conn.authUserDelete, true); err != nil {
return nil, err
return fail(err)
}
// Register: auth_enabled
// auth_enabled can be used to check if user authentication is enabled
if err := conn.RegisterFunc("auth_enabled", conn.authEnabled, true); err != nil {
return nil, err
return fail(err)
}
// Auto Vacuum
@@ -1736,8 +1766,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// and activating user authentication creates the internal table `sqlite_user`.
if autoVacuum > -1 {
if err := exec(fmt.Sprintf("PRAGMA auto_vacuum = %d;", autoVacuum)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
@@ -1747,17 +1776,17 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// has provided an username and password within the DSN.
// We are not allowed to continue.
if len(authUser) == 0 {
return nil, fmt.Errorf("Missing '_auth_user' while user authentication was requested with '_auth'")
return fail(fmt.Errorf("Missing '_auth_user' while user authentication was requested with '_auth'"))
}
if len(authPass) == 0 {
return nil, fmt.Errorf("Missing '_auth_pass' while user authentication was requested with '_auth'")
return fail(fmt.Errorf("Missing '_auth_pass' while user authentication was requested with '_auth'"))
}
// Check if User Authentication is Enabled
authExists := conn.AuthEnabled()
if !authExists {
if err := conn.AuthUserAdd(authUser, authPass, true); err != nil {
return nil, err
return fail(err)
}
}
}
@@ -1765,40 +1794,35 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// Case Sensitive LIKE
if caseSensitiveLike > -1 {
if err := exec(fmt.Sprintf("PRAGMA case_sensitive_like = %d;", caseSensitiveLike)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Defer Foreign Keys
if deferForeignKeys > -1 {
if err := exec(fmt.Sprintf("PRAGMA defer_foreign_keys = %d;", deferForeignKeys)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Foreign Keys
if foreignKeys > -1 {
if err := exec(fmt.Sprintf("PRAGMA foreign_keys = %d;", foreignKeys)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Ignore CHECK Constraints
if ignoreCheckConstraints > -1 {
if err := exec(fmt.Sprintf("PRAGMA ignore_check_constraints = %d;", ignoreCheckConstraints)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Journal Mode
if journalMode != "" {
if err := exec(fmt.Sprintf("PRAGMA journal_mode = %s;", journalMode)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
@@ -1806,23 +1830,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// Because the default is NORMAL and this is not changed in this package
// by using the compile time SQLITE_DEFAULT_LOCKING_MODE this PRAGMA can always be executed
if err := exec(fmt.Sprintf("PRAGMA locking_mode = %s;", lockingMode)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
// Query Only
if queryOnly > -1 {
if err := exec(fmt.Sprintf("PRAGMA query_only = %d;", queryOnly)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Recursive Triggers
if recursiveTriggers > -1 {
if err := exec(fmt.Sprintf("PRAGMA recursive_triggers = %d;", recursiveTriggers)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
@@ -1833,8 +1854,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// you can compile with secure_delete 'ON' and disable it for a specific database connection.
if secureDelete != "DEFAULT" {
if err := exec(fmt.Sprintf("PRAGMA secure_delete = %s;", secureDelete)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
@@ -1842,37 +1862,32 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
//
// Because default is NORMAL this statement is always executed
if err := exec(fmt.Sprintf("PRAGMA synchronous = %s;", synchronousMode)); err != nil {
conn.Close()
return nil, err
return fail(err)
}
// Writable Schema
if writableSchema > -1 {
if err := exec(fmt.Sprintf("PRAGMA writable_schema = %d;", writableSchema)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
// Cache Size
if cacheSize != nil {
if err := exec(fmt.Sprintf("PRAGMA cache_size = %d;", *cacheSize)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
return fail(err)
}
}
if len(d.Extensions) > 0 {
if err := conn.loadExtensions(d.Extensions); err != nil {
conn.Close()
return nil, err
return fail(err)
}
}
if d.ConnectHook != nil {
if err := d.ConnectHook(conn); err != nil {
conn.Close()
return nil, err
return fail(err)
}
}
runtime.SetFinalizer(conn, (*SQLiteConn).Close)
@@ -1907,7 +1922,7 @@ func (c *SQLiteConn) dbConnOpen() bool {
}
func (c *SQLiteConn) takeCachedStmt(query string) *SQLiteStmt {
if c == nil || query == "" || c.stmtCacheSize <= 0 {
if c == nil || query == "" || !c.stmtCacheEnabled {
return nil
}
@@ -1917,21 +1932,25 @@ func (c *SQLiteConn) takeCachedStmt(query string) *SQLiteStmt {
if c.db == nil {
return nil
}
stmts := c.stmtCache[query]
if len(stmts) == 0 {
return nil
// Scan from the MRU end (tail) so that a stmt put just before is
// found immediately.
for i := len(c.stmtCache) - 1; i >= 0; i-- {
s := c.stmtCache[i]
if s.cacheKey != query {
continue
}
n := len(c.stmtCache)
copy(c.stmtCache[i:n-1], c.stmtCache[i+1:n])
c.stmtCache[n-1] = nil
c.stmtCache = c.stmtCache[:n-1]
// The stmt was marked closed by Close before being cached, and
// cls may have been set if Query opened it; reset both so the
// caller gets a stmt equivalent to a fresh Prepare.
s.closed = false
s.cls = false
return s
}
s := stmts[len(stmts)-1]
if len(stmts) == 1 {
delete(c.stmtCache, query)
} else {
c.stmtCache[query] = stmts[:len(stmts)-1]
}
c.stmtCacheCount--
s.closed = false
s.cls = false
s.t = ""
return s
return nil
}
func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
@@ -1942,32 +1961,50 @@ func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
c.mu.Lock()
defer c.mu.Unlock()
if c.db == nil || c.stmtCacheCount >= c.stmtCacheSize {
return c.putCachedStmtLocked(s)
}
func (c *SQLiteConn) putCachedStmtLocked(s *SQLiteStmt) bool {
if c.db == nil {
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++
// If full, finalize the LRU entry at index 0 and shift left; the
// freed tail slot is immediately reused by the append below.
if len(c.stmtCache) == cap(c.stmtCache) {
finalizeCachedStmt(c.stmtCache[0])
copy(c.stmtCache, c.stmtCache[1:])
c.stmtCache = c.stmtCache[:len(c.stmtCache)-1]
}
c.stmtCache = append(c.stmtCache, s)
return true
}
func (c *SQLiteConn) closeCachedStmtsLocked() {
for key, stmts := range c.stmtCache {
for _, s := range stmts {
if s == nil || s.s == nil {
continue
}
runtime.SetFinalizer(s, nil)
C.sqlite3_finalize(s.s)
s.s = nil
s.c = nil
}
delete(c.stmtCache, key)
for i, s := range c.stmtCache {
c.stmtCache[i] = nil
finalizeCachedStmt(s)
}
c.stmtCacheCount = 0
c.stmtCache = c.stmtCache[:0]
}
// finalizeCachedStmt tears down a stmt that was sitting in the connection's
// stmt cache. The caller must hold c.mu. It is safe to pass a nil stmt or a
// stmt whose handle has already been released.
func finalizeCachedStmt(s *SQLiteStmt) {
if s == nil {
return
}
runtime.SetFinalizer(s, nil)
if s.s != nil {
C.sqlite3_finalize(s.s)
s.s = nil
}
s.c = nil
s.closed = true
}
// Prepare the query string. Return a new statement.
@@ -2002,7 +2039,7 @@ func (c *SQLiteConn) prepareWithCache(ctx context.Context, query string) (driver
return nil, err
}
ss := stmt.(*SQLiteStmt)
if ss.t == "" {
if ss.t == "" && c.stmtCacheEnabled {
ss.cacheKey = query
}
return ss, nil
@@ -2033,7 +2070,9 @@ func (c *SQLiteConn) GetFilename(schemaName string) string {
if schemaName == "" {
schemaName = "main"
}
return C.GoString(C.sqlite3_db_filename(c.db, C.CString(schemaName)))
cSchema := C.CString(schemaName)
defer C.free(unsafe.Pointer(cSchema))
return C.GoString(C.sqlite3_db_filename(c.db, cSchema))
}
// GetLimit returns the current value of a run-time limit.
@@ -2120,12 +2159,20 @@ func (s *SQLiteStmt) Close() error {
s.c = nil
return nil
}
if !conn.dbConnOpen() {
if s.cacheKey != "" {
conn.mu.Lock()
if conn.db == nil {
conn.mu.Unlock()
return errors.New("sqlite statement with already closed database connection")
}
if conn.putCachedStmtLocked(s) {
conn.mu.Unlock()
return nil
}
conn.mu.Unlock()
} else if !conn.dbConnOpen() {
return errors.New("sqlite statement with already closed database connection")
}
if s.cacheKey != "" && conn.putCachedStmt(s) {
return nil
}
s.s = nil
s.c = nil
rv := C.sqlite3_finalize(stmt)
@@ -2144,9 +2191,9 @@ var placeHolder = []byte{0}
func bindText(s *C.sqlite3_stmt, n C.int, v string) C.int {
if len(v) == 0 {
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0))
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.sqlite3_uint64(0))
}
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(unsafe.StringData(v))), C.int(len(v)))
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(unsafe.StringData(v))), C.sqlite3_uint64(len(v)))
}
func bindValue(s *C.sqlite3_stmt, n C.int, value driver.Value) C.int {
@@ -2172,14 +2219,14 @@ func bindValue(s *C.sqlite3_stmt, n C.int, value driver.Value) C.int {
if ln == 0 {
v = placeHolder
}
return C._sqlite3_bind_blob(s, n, unsafe.Pointer(&v[0]), C.int(ln))
return C._sqlite3_bind_blob(s, n, unsafe.Pointer(&v[0]), C.sqlite3_uint64(ln))
case time.Time:
var buf [64]byte
b := v.AppendFormat(buf[:0], SQLiteTimestampFormats[0])
if len(b) == 0 {
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0))
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.sqlite3_uint64(0))
}
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&b[0])), C.sqlite3_uint64(len(b)))
default:
return C.SQLITE_MISUSE
}
@@ -2238,6 +2285,17 @@ func stmtArgs(args []driver.NamedValue, start, na int) []driver.NamedValue {
return stmtArgs
}
// bindError converts a non-OK return code from bindValue into an error.
// The synthetic SQLITE_MISUSE returned for unsupported Go types is never
// recorded in the database handle, so lastError may report no error; fall
// back to an explicit message instead of silently ignoring the failure.
func (s *SQLiteStmt) bindError(v driver.Value) error {
if err := s.c.lastError(); err != nil {
return err
}
return fmt.Errorf("sqlite3: unsupported bind type %T", v)
}
func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
rv := C._sqlite3_reset_clear(s.s)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
@@ -2257,7 +2315,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
n := C.int(arg.Ordinal)
rv = bindValue(s.s, n, arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
return s.bindError(arg.Value)
}
}
return nil
@@ -2267,7 +2325,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
if arg.Name == "" {
rv = bindValue(s.s, C.int(arg.Ordinal), arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
return s.bindError(arg.Value)
}
continue
}
@@ -2278,7 +2336,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
}
rv = bindValue(s.s, C.int(idx), arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
return s.bindError(arg.Value)
}
}
}
@@ -2439,14 +2497,51 @@ func (rc *SQLiteRows) Close() error {
return nil
}
func (s *SQLiteStmt) cacheMetadata() bool {
return !s.cls || s.cacheKey != ""
}
func (s *SQLiteStmt) columnNamesLocked(n int) []string {
if s.metadata == nil {
s.metadata = &sqliteStmtMetadata{}
}
if len(s.metadata.cols) != n {
s.metadata.cols = make([]string, n)
for i := range s.metadata.cols {
s.metadata.cols[i] = C.GoString(C.sqlite3_column_name(s.s, C.int(i)))
}
}
return s.metadata.cols
}
func (s *SQLiteStmt) declTypesLocked(n int) []string {
if s.metadata == nil {
s.metadata = &sqliteStmtMetadata{}
}
if len(s.metadata.decltype) != n {
s.metadata.decltype = make([]string, n)
for i := range s.metadata.decltype {
s.metadata.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(s.s, C.int(i))))
}
}
return s.metadata.decltype
}
// Columns return column names.
func (rc *SQLiteRows) Columns() []string {
if rc.s == nil {
return rc.cols
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
rc.cols = make([]string, rc.nc)
for i := range rc.cols {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
if rc.s.cacheMetadata() {
rc.cols = rc.s.columnNamesLocked(int(rc.nc))
} else {
rc.cols = make([]string, rc.nc)
for i := range rc.cols {
rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i)))
}
}
}
return rc.cols
@@ -2454,9 +2549,13 @@ func (rc *SQLiteRows) Columns() []string {
func (rc *SQLiteRows) declTypes() []string {
if rc.s.s != nil && rc.decltype == nil {
rc.decltype = make([]string, rc.nc)
for i := range rc.decltype {
rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
if rc.s.cacheMetadata() {
rc.decltype = rc.s.declTypesLocked(int(rc.nc))
} else {
rc.decltype = make([]string, rc.nc)
for i := range rc.decltype {
rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))))
}
}
}
return rc.decltype
@@ -2464,6 +2563,9 @@ func (rc *SQLiteRows) declTypes() []string {
// DeclTypes return column types.
func (rc *SQLiteRows) DeclTypes() []string {
if rc.s == nil {
return rc.decltype
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
return rc.declTypes()
@@ -2471,6 +2573,9 @@ func (rc *SQLiteRows) DeclTypes() []string {
// Next move cursor to next. Attempts to honor context timeout from QueryContext call.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
if rc.s == nil {
return io.EOF
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
+9 -4
View File
@@ -28,7 +28,6 @@ import "C"
import (
"math"
"reflect"
"unsafe"
)
@@ -91,9 +90,15 @@ func (c *SQLiteContext) ResultNull() {
// ResultText sets the result of an SQL function.
// See: sqlite3_result_text, http://sqlite.org/c3ref/result_blob.html
func (c *SQLiteContext) ResultText(s string) {
h := (*reflect.StringHeader)(unsafe.Pointer(&s))
cs, l := (*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len)
C.my_result_text((*C.sqlite3_context)(c), cs, l)
if i64 && len(s) > math.MaxInt32 {
C.sqlite3_result_error_toobig((*C.sqlite3_context)(c))
return
}
if len(s) == 0 {
C.my_result_text((*C.sqlite3_context)(c), (*C.char)(unsafe.Pointer(&placeHolder[0])), 0)
return
}
C.my_result_text((*C.sqlite3_context)(c), (*C.char)(unsafe.Pointer(unsafe.StringData(s))), C.int(len(s)))
}
// ResultZeroblob sets the result of an SQL function.
+3 -3
View File
@@ -74,11 +74,11 @@ func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
}
var errMsg *C.char
defer C.sqlite3_free(unsafe.Pointer(errMsg))
rv := C.sqlite3_load_extension(c.db, clib, centry, &errMsg)
if rv != C.SQLITE_OK {
return errors.New(C.GoString(errMsg))
err := errors.New(C.GoString(errMsg))
C.sqlite3_free(unsafe.Pointer(errMsg))
return err
}
return nil
+15
View File
@@ -0,0 +1,15 @@
// Copyright (C) 2025 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
// Copyright (C) 2025 Jakob Borg <jakob@kastelo.net>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build sqlite_dbstat
// +build sqlite_dbstat
package sqlite3
/*
#cgo CFLAGS: -DSQLITE_ENABLE_DBSTAT_VTAB
*/
import "C"
+6 -2
View File
@@ -59,13 +59,17 @@ func (d *SQLitePreUpdateData) row(dest []any, new bool) error {
for i := 0; i < d.Count() && i < len(dest); i++ {
var val *C.sqlite3_value
var src any
var rc C.int
// Initially I tried making this just a function pointer argument, but
// it's absurdly complicated to pass C function pointers.
if new {
C.sqlite3_preupdate_new(d.Conn.db, C.int(i), &val)
rc = C.sqlite3_preupdate_new(d.Conn.db, C.int(i), &val)
} else {
C.sqlite3_preupdate_old(d.Conn.db, C.int(i), &val)
rc = C.sqlite3_preupdate_old(d.Conn.db, C.int(i), &val)
}
if rc != C.SQLITE_OK {
return Error{Code: ErrNo(rc)}
}
switch C.sqlite3_value_type(val) {
+3
View File
@@ -60,6 +60,9 @@ func (c *SQLiteConn) Deserialize(b []byte, schema string) error {
defer C.free(unsafe.Pointer(zSchema))
tmpBuf := (*C.uchar)(C.sqlite3_malloc64(C.sqlite3_uint64(len(b))))
if tmpBuf == nil && len(b) > 0 {
return fmt.Errorf("deserialize failed: out of memory")
}
copy(unsafe.Slice((*byte)(unsafe.Pointer(tmpBuf)), len(b)), b)
rc := C.sqlite3_deserialize(c.db, zSchema, tmpBuf, C.sqlite3_int64(len(b)),
+2 -1
View File
@@ -21,6 +21,7 @@ package sqlite3
extern void unlock_notify_callback(void *arg, int argc);
*/
import "C"
import (
"fmt"
"math"
@@ -82,7 +83,7 @@ func unlock_notify_wait(db *C.sqlite3) C.int {
h := unt.add(c)
defer unt.remove(h)
pargv := C.malloc(C.sizeof_uint)
pargv := C.malloc(C.size_t(unsafe.Sizeof(uint(0))))
defer C.free(pargv)
argv := (*[1]uint)(pargv)
+58 -31
View File
@@ -113,6 +113,9 @@ uintptr_t goVOpen(void *pVTab, char **pzErr);
static int cXOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
void *vTabCursor = (void *)goVOpen(((goVTab*)pVTab)->vTab, &(pVTab->zErrMsg));
if (!vTabCursor) {
return SQLITE_ERROR;
}
goVTabCursor *pCursor = (goVTabCursor *)sqlite3_malloc(sizeof(goVTabCursor));
if (!pCursor) {
return SQLITE_NOMEM;
@@ -270,7 +273,6 @@ import "C"
import (
"fmt"
"math"
"reflect"
"unsafe"
)
@@ -329,11 +331,7 @@ type InfoOrderBy struct {
}
func constraints(info *C.sqlite3_index_info) []InfoConstraint {
slice := *(*[]C.struct_sqlite3_index_constraint)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aConstraint)),
Len: int(info.nConstraint),
Cap: int(info.nConstraint),
}))
slice := unsafe.Slice(info.aConstraint, int(info.nConstraint))
cst := make([]InfoConstraint, 0, len(slice))
for _, c := range slice {
@@ -351,11 +349,7 @@ func constraints(info *C.sqlite3_index_info) []InfoConstraint {
}
func orderBys(info *C.sqlite3_index_info) []InfoOrderBy {
slice := *(*[]C.struct_sqlite3_index_orderby)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aOrderBy)),
Len: int(info.nOrderBy),
Cap: int(info.nOrderBy),
}))
slice := unsafe.Slice(info.aOrderBy, int(info.nOrderBy))
ob := make([]InfoOrderBy, 0, len(slice))
for _, c := range slice {
@@ -400,10 +394,7 @@ func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **
return 0
}
args := make([]string, argc)
var A []*C.char
slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: int(argc), Cap: int(argc)}
a := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&slice)).Elem().Interface()
for i, s := range a.([]*C.char) {
for i, s := range unsafe.Slice(argv, int(argc)) {
args[i] = C.GoString(s)
}
var vTab VTab
@@ -432,6 +423,9 @@ func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char {
} else {
err = vt.vTab.Disconnect()
}
// The vtab is gone as far as SQLite is concerned regardless of the
// callback result, so release the handle either way.
deleteHandle(pVTab)
if err != nil {
return mPrintf("%s", err.Error())
}
@@ -460,20 +454,23 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
if err != nil {
return mPrintf("%s", err.Error())
}
if res == nil {
return mPrintf("%s", "BestIndex returned a nil IndexResult")
}
if len(res.Used) != len(csts) {
return mPrintf("Result.Used != expected value", "")
}
// Get a pointer to constraint_usage struct so we can update in place.
slice := *(*[]C.struct_sqlite3_index_constraint_usage)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aConstraintUsage)),
Len: int(info.nConstraint),
Cap: int(info.nConstraint),
}))
slice := unsafe.Slice(info.aConstraintUsage, int(info.nConstraint))
index := 1
for i := range slice {
if res.Used[i] {
// SQLite returns "xBestIndex malfunction" when an argvIndex is
// assigned to a constraint it marked as not usable, so ignore
// Used for those; they may become usable on a later xBestIndex
// invocation for a different plan.
if res.Used[i] && csts[i].Usable {
slice[i].argvIndex = C.int(index)
slice[i].omit = C.uchar(1)
index++
@@ -488,19 +485,30 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
}
info.needToFreeIdxStr = C.int(1)
idxStr := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.idxStr)),
Len: len(res.IdxStr) + 1,
Cap: len(res.IdxStr) + 1,
}))
idxStr := unsafe.Slice((*byte)(unsafe.Pointer(info.idxStr)), len(res.IdxStr)+1)
copy(idxStr, res.IdxStr)
idxStr[len(idxStr)-1] = 0 // null-terminated string
if res.AlreadyOrdered {
info.orderByConsumed = C.int(1)
}
info.estimatedCost = C.double(res.EstimatedCost)
info.estimatedRows = C.sqlite3_int64(res.EstimatedRows)
// SQLite pre-initializes estimatedCost and estimatedRows with sensible
// defaults; overwriting them with the Go zero value would make every
// candidate plan look free and break query planning, so only pass
// values the implementation actually set.
if res.EstimatedCost > 0 {
info.estimatedCost = C.double(res.EstimatedCost)
}
if res.EstimatedRows > 0 {
var rows int64
if res.EstimatedRows >= float64(math.MaxInt64) {
rows = math.MaxInt64
} else if rows = int64(res.EstimatedRows); rows < 1 {
// A positive fractional estimate must not truncate to 0.
rows = 1
}
info.estimatedRows = C.sqlite3_int64(rows)
}
return nil
}
@@ -509,6 +517,9 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
func goVClose(pCursor unsafe.Pointer) *C.char {
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
err := vtc.vTabCursor.Close()
// The cursor is gone as far as SQLite is concerned regardless of the
// callback result, so release the handle either way.
deleteHandle(pCursor)
if err != nil {
return mPrintf("%s", err.Error())
}
@@ -519,6 +530,7 @@ func goVClose(pCursor unsafe.Pointer) *C.char {
func goMDestroy(pClientData unsafe.Pointer) {
m := lookupHandle(pClientData).(*sqliteModule)
m.module.DestroyModule()
deleteHandle(pClientData)
}
//export goVFilter
@@ -531,7 +543,14 @@ func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int
if err != nil {
return mPrintf("%s", err.Error())
}
vals = append(vals, conv.Interface())
// work around for SQLITE_NULL
x := conv.Interface()
if z, ok := x.([]byte); ok && z == nil {
x = nil
}
vals = append(vals, x)
}
err := vtc.vTabCursor.Filter(int(idxNum), C.GoString(idxName), vals)
if err != nil {
@@ -625,7 +644,15 @@ func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid
}
case argc > 1:
err = v.Update(vals[1], vals[2:])
// Per the xUpdate contract argv[0] identifies the row being
// updated while argv[1] is its new rowid. VTabUpdater has no
// way to convey a rowid change, so reject it instead of
// silently updating values under the old rowid.
if vals[0] != vals[1] {
err = fmt.Errorf("virtual %s table %sdoes not support changing the rowid", vt.module.name, tname)
} else {
err = v.Update(vals[0], vals[2:])
}
}
}
@@ -725,5 +752,5 @@ func (c *SQLiteConn) CreateModule(moduleName string, module Module) error {
}
return nil
}
return nil
return fmt.Errorf("sqlite3: CreateModule requires a non-nil module")
}
+10 -1
View File
@@ -376,7 +376,11 @@ struct sqlite3_api_routines {
/* Version 3.51.0 and later */
int (*set_errmsg)(sqlite3*,int,const char*);
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
/* Version 3.52.0 and later */
void (*str_truncate)(sqlite3_str*,int);
void (*str_free)(sqlite3_str*);
int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
};
/*
@@ -715,6 +719,11 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.51.0 and later */
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
#define sqlite3_db_status64 sqlite3_api->db_status64
/* Version 3.52.0 and later */
#define sqlite3_str_truncate sqlite3_api->str_truncate
#define sqlite3_str_free sqlite3_api->str_free
#define sqlite3_carray_bind sqlite3_api->carray_bind
#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+3 -3
View File
@@ -27,15 +27,15 @@ func NewNatsKeyValue(c Config, log *zerolog.Logger) (jetstream.KeyValue, error)
}
opts := []nats.Option{
nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
log.Error().Err(err).Msg("Disconnected from NATS. Trying to reconnect...")
log.Error().Err(err).Str("database", c.Database).Msg("Disconnected from NATS. Trying to reconnect...")
}),
nats.ReconnectHandler(func(nc *nats.Conn) {
log.Error().Msgf("Successfully reconnected to NATS at: %s", nc.ConnectedUrl())
log.Error().Str("database", c.Database).Msgf("Successfully reconnected to NATS at: %s", nc.ConnectedUrl())
}),
nats.ClosedHandler(func(nc *nats.Conn) {
// Alright, it's time to give up. Send ourselves a SIGTERM to trigger a graceful
// shutdown of the service.
log.Error().Msg("NATS connection closed permanently. Shutting down...")
log.Error().Str("database", c.Database).Msg("NATS connection closed permanently. Shutting down...")
pid := os.Getpid()
process, err := os.FindProcess(pid)
@@ -500,9 +500,21 @@ func (b HybridBackend) Lock(n MetadataNode) (UnlockFunc, error) {
mlock, err := lockedfile.OpenFile(metaLockPath, os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
// create the parent directory
err = os.MkdirAll(filepath.Dir(metaLockPath), 0700)
if err != nil {
// The lock file's parent directories don't exist yet (or anymore).
// We may only create the space's metadata directories, never the
// space's base directory itself: locking a node (i.e. the space
// root) whose space has been removed (or has not been created yet)
// must not resurrect the spaca.
base := b.metadataPathFunc(n)
if base == "" {
return nil, err
}
// base is the space's metadata directory (e.g. <spaceRoot>/.oc-nodes),
// so its parent is the space's base directory.
if _, statErr := os.Stat(filepath.Dir(base)); statErr != nil {
return nil, statErr
}
if err = os.MkdirAll(filepath.Dir(metaLockPath), 0700); err != nil {
return nil, err
}
mlock, err = lockedfile.OpenFile(metaLockPath, os.O_RDWR|os.O_CREATE, 0600)
@@ -282,8 +282,10 @@ func (p AsyncPropagator) propagate(ctx context.Context, spaceID, nodeID string,
attrs := node.Attributes{}
// lock parent before reading treesize or tree time
// we deliberately allow reading disabled spaces so that the metadata is always consistent (see https://github.com/opencloud-eu/reva/issues/747)
_, subspan = tracer.Start(ctx, "node.LockAndReadNode")
n, unlock, err := node.LockAndReadNode(ctx, p.lookup, spaceID, nodeID, "", false, nil, false)
n, unlock, err := node.LockAndReadNode(ctx, p.lookup, spaceID, nodeID, "", true, nil, false)
subspan.End()
if err != nil {
if n != nil && !n.Exists {
@@ -92,7 +92,8 @@ func (p SyncPropagator) propagateItem(ctx context.Context, n *node.Node, sTime t
attrs := node.Attributes{}
// lock parent before reading treesize or tree time
n, unlock, err := node.LockAndReadNode(ctx, p.lookup, n.SpaceID, n.ParentID, "", false, n.SpaceRoot, false)
// we deliberately allow reading disabled spaces so that the metadata is always consistent (see https://github.com/opencloud-eu/reva/issues/747)
n, unlock, err := node.LockAndReadNode(ctx, p.lookup, n.SpaceID, n.ParentID, "", true, n.SpaceRoot, false)
if err != nil {
return nil, true, err
}
+6
View File
@@ -252,6 +252,12 @@ func IsSpaceRoot(ri *storageprovider.ResourceInfo) bool {
return f.GetOpaqueId() == s.GetOpaqueId() && f.GetSpaceId() == s.GetSpaceId()
}
// IsProcessing checks if the given resource info is still being processed
// (e.g. postprocessing after an upload has not finished yet).
func IsProcessing(ri *storageprovider.ResourceInfo) bool {
return ReadPlainFromOpaque(ri.GetOpaque(), "status") == "processing"
}
func checkStatusCode(reason, message string, code rpc.Code) error {
if code == rpc.Code_CODE_OK {
return nil
+9 -3
View File
@@ -4,10 +4,12 @@ import (
"crypto/rand"
"fmt"
"io"
"math"
"math/big"
)
// ErrNumWordsNegative is returned when a negative number of words is requested.
var ErrNumWordsNegative = fmt.Errorf("number of words cannot be negative")
// sides is the number of sides on a die.
var sides = big.NewInt(6)
@@ -68,6 +70,10 @@ func NewGenerator(i *GeneratorInput) (*Generator, error) {
// non-overlapping words, use a single invocation of the function and split the
// resulting string list.
func (g *Generator) Generate(numWords int) ([]string, error) {
if numWords < 0 {
return nil, ErrNumWordsNegative
}
if typ, ok := g.wordList.(WordListNumWordser); ok {
if l := typ.NumWords(); numWords > l {
return nil, fmt.Errorf("number of requested words (%d) cannot exceed the size of the wordlist (%d)",
@@ -182,13 +188,13 @@ func (g *Generator) RollDie() (int, error) {
func (g *Generator) RollWord(d int) (int, error) {
var final int
for i := d; i > 0; i-- {
for range d {
res, err := g.RollDie()
if err != nil {
return 0, err
}
final += res * int(math.Pow(10, float64(i-1)))
final = final*10 + res
}
return final, nil
+13 -6
View File
@@ -5,14 +5,13 @@
// if err != nil {
// log.Fatal(err)
// }
// log.Printf(res)
// log.Print(res)
//
// Most functions are safe for concurrent use.
package password
import (
"crypto/rand"
"errors"
"fmt"
"io"
"math/big"
@@ -47,19 +46,23 @@ const (
var (
// ErrExceedsTotalLength is the error returned with the number of digits and
// symbols is greater than the total length.
ErrExceedsTotalLength = errors.New("number of digits and symbols must be less than total length")
ErrExceedsTotalLength = fmt.Errorf("number of digits and symbols must be less than total length")
// ErrLettersExceedsAvailable is the error returned with the number of letters
// exceeds the number of available letters and repeats are not allowed.
ErrLettersExceedsAvailable = errors.New("number of letters exceeds available letters and repeats are not allowed")
ErrLettersExceedsAvailable = fmt.Errorf("number of letters exceeds available letters and repeats are not allowed")
// ErrDigitsExceedsAvailable is the error returned with the number of digits
// exceeds the number of available digits and repeats are not allowed.
ErrDigitsExceedsAvailable = errors.New("number of digits exceeds available digits and repeats are not allowed")
ErrDigitsExceedsAvailable = fmt.Errorf("number of digits exceeds available digits and repeats are not allowed")
// ErrSymbolsExceedsAvailable is the error returned with the number of symbols
// exceeds the number of available symbols and repeats are not allowed.
ErrSymbolsExceedsAvailable = errors.New("number of symbols exceeds available symbols and repeats are not allowed")
ErrSymbolsExceedsAvailable = fmt.Errorf("number of symbols exceeds available symbols and repeats are not allowed")
// ErrNegativeInput is the error returned when the number of digits or symbols
// is negative.
ErrNegativeInput = fmt.Errorf("number of digits and symbols must not be negative")
)
// Generator is the stateful generator which can be used to customize the list
@@ -129,6 +132,10 @@ func NewGenerator(i *GeneratorInput) (*Generator, error) {
// The algorithm is fast, but it's not designed to be performant; it favors
// entropy over speed. This function is safe for concurrent use.
func (g *Generator) Generate(length, numDigits, numSymbols int, noUpper, allowRepeat bool) (string, error) {
if numDigits < 0 || numSymbols < 0 {
return "", ErrNegativeInput
}
letters := g.lowerLetters
if !noUpper {
letters += g.upperLetters
+12 -12
View File
@@ -93,7 +93,7 @@ github.com/alexedwards/argon2id
# github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964
## explicit
github.com/amoghe/go-crypt
# github.com/antithesishq/antithesis-sdk-go v0.7.2-default-no-op
# github.com/antithesishq/antithesis-sdk-go v0.7.2
## explicit; go 1.24.0
github.com/antithesishq/antithesis-sdk-go/assert
github.com/antithesishq/antithesis-sdk-go/internal
@@ -1013,16 +1013,16 @@ github.com/magiconair/properties
# github.com/mattermost/xml-roundtrip-validator v0.1.0
## explicit; go 1.14
github.com/mattermost/xml-roundtrip-validator
# github.com/mattn/go-colorable v0.1.14
# github.com/mattn/go-colorable v0.1.15
## explicit; go 1.18
github.com/mattn/go-colorable
# github.com/mattn/go-isatty v0.0.20
## explicit; go 1.15
# github.com/mattn/go-isatty v0.0.22
## explicit; go 1.21
github.com/mattn/go-isatty
# github.com/mattn/go-runewidth v0.0.23
# github.com/mattn/go-runewidth v0.0.24
## explicit; go 1.20
github.com/mattn/go-runewidth
# github.com/mattn/go-sqlite3 v1.14.42
# github.com/mattn/go-sqlite3 v1.14.49
## explicit; go 1.21
github.com/mattn/go-sqlite3
# github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b
@@ -1364,7 +1364,7 @@ github.com/opencloud-eu/icap-client
# github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
## explicit; go 1.18
github.com/opencloud-eu/libre-graph-api-go
# github.com/opencloud-eu/reva/v2 v2.47.0
# github.com/opencloud-eu/reva/v2 v2.48.0
## explicit; go 1.25.8
github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace
github.com/opencloud-eu/reva/v2/cmd/revad/runtime
@@ -1979,11 +1979,11 @@ github.com/sercand/kuberesolver/v5
# github.com/sergi/go-diff v1.4.0
## explicit; go 1.13
github.com/sergi/go-diff/diffmatchpatch
# github.com/sethvargo/go-diceware v0.5.0
## explicit; go 1.22
# github.com/sethvargo/go-diceware v0.6.0
## explicit; go 1.25
github.com/sethvargo/go-diceware/diceware
# github.com/sethvargo/go-password v0.3.1
## explicit; go 1.21
# github.com/sethvargo/go-password v0.4.0
## explicit; go 1.25
github.com/sethvargo/go-password/password
# github.com/shamaton/msgpack/v2 v2.4.1
## explicit; go 1.20
@@ -2572,7 +2572,7 @@ google.golang.org/genproto/protobuf/field_mask
google.golang.org/genproto/googleapis/api
google.golang.org/genproto/googleapis/api/annotations
google.golang.org/genproto/googleapis/api/httpbody
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0
## explicit; go 1.25.0
google.golang.org/genproto/googleapis/rpc/errdetails
google.golang.org/genproto/googleapis/rpc/status