mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Update go-sqlite3 to 1.14.6 (#1209)
This commit is contained in:
2
go.mod
2
go.mod
@@ -18,7 +18,7 @@ require (
|
||||
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/json-iterator/go v1.1.9
|
||||
github.com/mattn/go-sqlite3 v1.13.0
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/natefinch/pie v0.0.0-20170715172608-9a0d72014007
|
||||
github.com/remeh/sizedwaitgroup v1.0.0
|
||||
github.com/rs/cors v1.6.0
|
||||
|
||||
2
go.sum
2
go.sum
@@ -540,6 +540,8 @@ github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK86
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c=
|
||||
github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
|
||||
4
vendor/github.com/mattn/go-sqlite3/.codecov.yml
generated
vendored
Normal file
4
vendor/github.com/mattn/go-sqlite3/.codecov.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
coverage:
|
||||
status:
|
||||
project: off
|
||||
patch: off
|
||||
33
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
33
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
@@ -1,33 +0,0 @@
|
||||
language: go
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- master
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew update
|
||||
fi
|
||||
- go get github.com/smartystreets/goconvey
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
|
||||
script:
|
||||
- $HOME/gopath/bin/goveralls -repotoken 3qJVUE0iQwqnCbmNcDsjYu1nh4J4KIFXx
|
||||
- go test -race -v . -tags ""
|
||||
- go test -race -v . -tags "libsqlite3"
|
||||
- go test -race -v . -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_preupdate_hook sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
|
||||
- go test -race -v . -tags "sqlite_vacuum_full"
|
||||
34
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
34
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
@@ -2,16 +2,20 @@ go-sqlite3
|
||||
==========
|
||||
|
||||
[](http://godoc.org/github.com/mattn/go-sqlite3)
|
||||
[](https://travis-ci.org/mattn/go-sqlite3)
|
||||
[](https://github.com/mattn/go-sqlite3/actions?query=workflow%3AGo)
|
||||
[](https://opencollective.com/mattn-go-sqlite3)
|
||||
[](https://coveralls.io/r/mattn/go-sqlite3?branch=master)
|
||||
[](https://codecov.io/gh/mattn/go-sqlite3)
|
||||
[](https://goreportcard.com/report/github.com/mattn/go-sqlite3)
|
||||
|
||||
Latest stable version is v1.14 or later not v2.
|
||||
|
||||
~~**NOTE:** The increase to v2 was an accident. There were no major changes or features.~~
|
||||
|
||||
# Description
|
||||
|
||||
sqlite3 driver conforming to the built-in database/sql interface
|
||||
|
||||
Supported Golang version: See .travis.yml
|
||||
Supported Golang version: See [.github/workflows/go.yaml](./.github/workflows/go.yaml)
|
||||
|
||||
[This package follows the official Golang Release Policy.](https://golang.org/doc/devel/release.html#policy)
|
||||
|
||||
@@ -121,6 +125,8 @@ Boolean values can be one of:
|
||||
| Time Zone Location | `_loc` | auto | Specify location of time format. |
|
||||
| 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) |
|
||||
|
||||
|
||||
## DSN Examples
|
||||
|
||||
@@ -210,9 +216,15 @@ This library can be cross-compiled.
|
||||
|
||||
In some cases you are required to the `CC` environment variable with the cross compiler.
|
||||
|
||||
Additional information:
|
||||
- [#491](https://github.com/mattn/go-sqlite3/issues/491)
|
||||
- [#560](https://github.com/mattn/go-sqlite3/issues/560)
|
||||
## Cross Compiling from MAC OSX
|
||||
The simplest way to cross compile from OSX is to use [xgo](https://github.com/karalabe/xgo).
|
||||
|
||||
Steps:
|
||||
- Install [xgo](https://github.com/karalabe/xgo) (`go get github.com/karalabe/xgo`).
|
||||
- Ensure that your project is within your `GOPATH`.
|
||||
- Run `xgo local/path/to/project`.
|
||||
|
||||
Please refer to the project's [README](https://github.com/karalabe/xgo/blob/master/README.md) for further information.
|
||||
|
||||
# Google Cloud Platform
|
||||
|
||||
@@ -451,6 +463,16 @@ If you want your own extension to be listed here or you want to add a reference
|
||||
Spatialite is available as an extension to SQLite, and can be used in combination with this repository.
|
||||
For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatialite).
|
||||
|
||||
## extension-functions.c from SQLite3 Contrib
|
||||
|
||||
extension-functions.c is available as an extension to SQLite, and provides the following functions:
|
||||
|
||||
- Math: acos, asin, atan, atn2, atan2, acosh, asinh, atanh, difference, degrees, radians, cos, sin, tan, cot, cosh, sinh, tanh, coth, exp, log, log10, power, sign, sqrt, square, ceil, floor, pi.
|
||||
- String: replicate, charindex, leftstr, rightstr, ltrim, rtrim, trim, replace, reverse, proper, padl, padr, padc, strfilter.
|
||||
- Aggregate: stdev, variance, mode, median, lower_quartile, upper_quartile
|
||||
|
||||
For an example see [dinedal/go-sqlite3-extension-functions](https://github.com/dinedal/go-sqlite3-extension-functions).
|
||||
|
||||
# FAQ
|
||||
|
||||
- Getting insert error while query is opened.
|
||||
|
||||
56
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
56
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
@@ -35,56 +35,55 @@ import (
|
||||
//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]
|
||||
fi := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*functionInfo)
|
||||
fi := lookupHandle(C.sqlite3_user_data(ctx)).(*functionInfo)
|
||||
fi.Call(ctx, args)
|
||||
}
|
||||
|
||||
//export stepTrampoline
|
||||
func stepTrampoline(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)]
|
||||
ai := lookupHandle(uintptr(C.sqlite3_user_data(ctx))).(*aggInfo)
|
||||
ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo)
|
||||
ai.Step(ctx, args)
|
||||
}
|
||||
|
||||
//export doneTrampoline
|
||||
func doneTrampoline(ctx *C.sqlite3_context) {
|
||||
handle := uintptr(C.sqlite3_user_data(ctx))
|
||||
ai := lookupHandle(handle).(*aggInfo)
|
||||
ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo)
|
||||
ai.Done(ctx)
|
||||
}
|
||||
|
||||
//export compareTrampoline
|
||||
func compareTrampoline(handlePtr uintptr, la C.int, a *C.char, lb C.int, b *C.char) C.int {
|
||||
func compareTrampoline(handlePtr unsafe.Pointer, la C.int, a *C.char, lb C.int, b *C.char) C.int {
|
||||
cmp := lookupHandle(handlePtr).(func(string, string) int)
|
||||
return C.int(cmp(C.GoStringN(a, la), C.GoStringN(b, lb)))
|
||||
}
|
||||
|
||||
//export commitHookTrampoline
|
||||
func commitHookTrampoline(handle uintptr) int {
|
||||
func commitHookTrampoline(handle unsafe.Pointer) int {
|
||||
callback := lookupHandle(handle).(func() int)
|
||||
return callback()
|
||||
}
|
||||
|
||||
//export rollbackHookTrampoline
|
||||
func rollbackHookTrampoline(handle uintptr) {
|
||||
func rollbackHookTrampoline(handle unsafe.Pointer) {
|
||||
callback := lookupHandle(handle).(func())
|
||||
callback()
|
||||
}
|
||||
|
||||
//export updateHookTrampoline
|
||||
func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, rowid int64) {
|
||||
func updateHookTrampoline(handle unsafe.Pointer, op 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)
|
||||
}
|
||||
|
||||
//export authorizerTrampoline
|
||||
func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
|
||||
func authorizerTrampoline(handle unsafe.Pointer, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
|
||||
callback := lookupHandle(handle).(func(int, string, string, string) int)
|
||||
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
|
||||
}
|
||||
|
||||
//export preUpdateHookTrampoline
|
||||
func preUpdateHookTrampoline(handle uintptr, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) {
|
||||
func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) {
|
||||
hval := lookupHandleVal(handle)
|
||||
data := SQLitePreUpdateData{
|
||||
Conn: hval.db,
|
||||
@@ -105,33 +104,27 @@ type handleVal struct {
|
||||
}
|
||||
|
||||
var handleLock sync.Mutex
|
||||
var handleVals = make(map[uintptr]handleVal)
|
||||
var handleIndex uintptr = 100
|
||||
var handleVals = make(map[unsafe.Pointer]handleVal)
|
||||
|
||||
func newHandle(db *SQLiteConn, v interface{}) uintptr {
|
||||
func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer {
|
||||
handleLock.Lock()
|
||||
defer handleLock.Unlock()
|
||||
i := handleIndex
|
||||
handleIndex++
|
||||
handleVals[i] = handleVal{db, v}
|
||||
return i
|
||||
}
|
||||
|
||||
func lookupHandleVal(handle uintptr) handleVal {
|
||||
handleLock.Lock()
|
||||
defer handleLock.Unlock()
|
||||
r, ok := handleVals[handle]
|
||||
if !ok {
|
||||
if handle >= 100 && handle < handleIndex {
|
||||
panic("deleted handle")
|
||||
} else {
|
||||
panic("invalid handle")
|
||||
}
|
||||
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")
|
||||
}
|
||||
return r
|
||||
handleVals[p] = val
|
||||
return p
|
||||
}
|
||||
|
||||
func lookupHandle(handle uintptr) interface{} {
|
||||
func lookupHandleVal(handle unsafe.Pointer) handleVal {
|
||||
handleLock.Lock()
|
||||
defer handleLock.Unlock()
|
||||
return handleVals[handle]
|
||||
}
|
||||
|
||||
func lookupHandle(handle unsafe.Pointer) interface{} {
|
||||
return lookupHandleVal(handle).val
|
||||
}
|
||||
|
||||
@@ -141,6 +134,7 @@ func deleteHandles(db *SQLiteConn) {
|
||||
for handle, val := range handleVals {
|
||||
if val.db == db {
|
||||
delete(handleVals, handle)
|
||||
C.free(handle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
vendor/github.com/mattn/go-sqlite3/doc.go
generated
vendored
35
vendor/github.com/mattn/go-sqlite3/doc.go
generated
vendored
@@ -79,9 +79,8 @@ Then, you can use this extension.
|
||||
|
||||
Connection Hook
|
||||
|
||||
You can hook and inject your code when the connection is established. database/sql
|
||||
doesn't provide a way to get native go-sqlite3 interfaces. So if you want,
|
||||
you need to set ConnectHook and get the SQLiteConn.
|
||||
You can hook and inject your code when the connection is established by setting
|
||||
ConnectHook to get the SQLiteConn.
|
||||
|
||||
sql.Register("sqlite3_with_hook_example",
|
||||
&sqlite3.SQLiteDriver{
|
||||
@@ -91,21 +90,45 @@ you need to set ConnectHook and get the SQLiteConn.
|
||||
},
|
||||
})
|
||||
|
||||
You can also use database/sql.Conn.Raw (Go >= 1.13):
|
||||
|
||||
conn, err := db.Conn(context.Background())
|
||||
// if err != nil { ... }
|
||||
defer conn.Close()
|
||||
err = conn.Raw(func (driverConn interface{}) error {
|
||||
sqliteConn := driverConn.(*sqlite3.SQLiteConn)
|
||||
// ... use sqliteConn
|
||||
})
|
||||
// if err != nil { ... }
|
||||
|
||||
Go SQlite3 Extensions
|
||||
|
||||
If you want to register Go functions as SQLite extension functions,
|
||||
call RegisterFunction from ConnectHook.
|
||||
If you want to register Go functions as SQLite extension functions
|
||||
you can make a custom driver by calling RegisterFunction from
|
||||
ConnectHook.
|
||||
|
||||
regex = func(re, s string) (bool, error) {
|
||||
return regexp.MatchString(re, s)
|
||||
}
|
||||
sql.Register("sqlite3_with_go_func",
|
||||
sql.Register("sqlite3_extended",
|
||||
&sqlite3.SQLiteDriver{
|
||||
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
||||
return conn.RegisterFunc("regexp", regex, true)
|
||||
},
|
||||
})
|
||||
|
||||
You can then use the custom driver by passing its name to sql.Open.
|
||||
|
||||
var i int
|
||||
conn, err := sql.Open("sqlite3_extended", "./foo.db")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = db.QueryRow(`SELECT regexp("foo.*", "seafood")`).Scan(&i)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
See the documentation of RegisterFunc for more details.
|
||||
|
||||
*/
|
||||
|
||||
19
vendor/github.com/mattn/go-sqlite3/error.go
generated
vendored
19
vendor/github.com/mattn/go-sqlite3/error.go
generated
vendored
@@ -5,7 +5,15 @@
|
||||
|
||||
package sqlite3
|
||||
|
||||
/*
|
||||
#ifndef USE_LIBSQLITE3
|
||||
#include <sqlite3-binding.h>
|
||||
#else
|
||||
#include <sqlite3.h>
|
||||
#endif
|
||||
*/
|
||||
import "C"
|
||||
import "syscall"
|
||||
|
||||
// ErrNo inherit errno.
|
||||
type ErrNo int
|
||||
@@ -20,6 +28,7 @@ type ErrNoExtended int
|
||||
type Error struct {
|
||||
Code ErrNo /* The error code returned by SQLite */
|
||||
ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */
|
||||
SystemErrno syscall.Errno /* The system errno returned by the OS through SQLite, if applicable */
|
||||
err string /* The error string returned by sqlite3_errmsg(),
|
||||
this usually contains more specific details. */
|
||||
}
|
||||
@@ -72,10 +81,16 @@ func (err ErrNoExtended) Error() string {
|
||||
}
|
||||
|
||||
func (err Error) Error() string {
|
||||
var str string
|
||||
if err.err != "" {
|
||||
return err.err
|
||||
str = err.err
|
||||
} else {
|
||||
str = C.GoString(C.sqlite3_errstr(C.int(err.Code)))
|
||||
}
|
||||
return errorString(err)
|
||||
if err.SystemErrno != 0 {
|
||||
str += ": " + err.SystemErrno.Error()
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// result codes from http://www.sqlite.org/c3ref/c_abort_rollback.html
|
||||
|
||||
3
vendor/github.com/mattn/go-sqlite3/go.mod
generated
vendored
Normal file
3
vendor/github.com/mattn/go-sqlite3/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/mattn/go-sqlite3
|
||||
|
||||
go 1.12
|
||||
0
vendor/github.com/mattn/go-sqlite3/go.sum
generated
vendored
Normal file
0
vendor/github.com/mattn/go-sqlite3/go.sum
generated
vendored
Normal file
24368
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
24368
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
File diff suppressed because it is too large
Load Diff
866
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
866
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
File diff suppressed because it is too large
Load Diff
241
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
241
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
@@ -15,10 +15,8 @@ package sqlite3
|
||||
#cgo CFLAGS: -DHAVE_USLEEP=1
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_FTS3
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_FTS4_UNICODE61
|
||||
#cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15
|
||||
#cgo CFLAGS: -DSQLITE_OMIT_DEPRECATED
|
||||
#cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC
|
||||
#cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT
|
||||
#cgo CFLAGS: -Wno-deprecated-declarations
|
||||
@@ -183,6 +181,12 @@ static int _sqlite3_limit(sqlite3* db, int limitId, int newLimit) {
|
||||
return sqlite3_limit(db, limitId, newLimit);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SQLITE_VERSION_NUMBER < 3012000
|
||||
static int sqlite3_system_errno(sqlite3 *db) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
@@ -198,6 +202,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -466,7 +471,7 @@ func (c *SQLiteConn) RegisterCollation(name string, cmp func(string, string) int
|
||||
handle := newHandle(c, cmp)
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
rv := C.sqlite3_create_collation(c.db, cname, C.SQLITE_UTF8, unsafe.Pointer(handle), (*[0]byte)(unsafe.Pointer(C.compareTrampoline)))
|
||||
rv := C.sqlite3_create_collation(c.db, cname, C.SQLITE_UTF8, handle, (*[0]byte)(unsafe.Pointer(C.compareTrampoline)))
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
}
|
||||
@@ -484,7 +489,7 @@ func (c *SQLiteConn) RegisterCommitHook(callback func() int) {
|
||||
if callback == nil {
|
||||
C.sqlite3_commit_hook(c.db, nil, nil)
|
||||
} else {
|
||||
C.sqlite3_commit_hook(c.db, (*[0]byte)(C.commitHookTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||
C.sqlite3_commit_hook(c.db, (*[0]byte)(C.commitHookTrampoline), newHandle(c, callback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,7 +502,7 @@ func (c *SQLiteConn) RegisterRollbackHook(callback func()) {
|
||||
if callback == nil {
|
||||
C.sqlite3_rollback_hook(c.db, nil, nil)
|
||||
} else {
|
||||
C.sqlite3_rollback_hook(c.db, (*[0]byte)(C.rollbackHookTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||
C.sqlite3_rollback_hook(c.db, (*[0]byte)(C.rollbackHookTrampoline), newHandle(c, callback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +519,7 @@ func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64
|
||||
if callback == nil {
|
||||
C.sqlite3_update_hook(c.db, nil, nil)
|
||||
} else {
|
||||
C.sqlite3_update_hook(c.db, (*[0]byte)(C.updateHookTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||
C.sqlite3_update_hook(c.db, (*[0]byte)(C.updateHookTrampoline), newHandle(c, callback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +533,7 @@ func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, strin
|
||||
if callback == nil {
|
||||
C.sqlite3_set_authorizer(c.db, nil, nil)
|
||||
} else {
|
||||
C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||
C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), newHandle(c, callback))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,8 +614,8 @@ func (c *SQLiteConn) RegisterFunc(name string, impl interface{}, pure bool) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTextRep C.int, pApp uintptr, xFunc unsafe.Pointer, xStep unsafe.Pointer, xFinal unsafe.Pointer) C.int {
|
||||
return C._sqlite3_create_function(db, zFunctionName, nArg, eTextRep, C.uintptr_t(pApp), (*[0]byte)(xFunc), (*[0]byte)(xStep), (*[0]byte)(xFinal))
|
||||
func sqlite3CreateFunction(db *C.sqlite3, zFunctionName *C.char, nArg C.int, eTextRep C.int, pApp unsafe.Pointer, xFunc unsafe.Pointer, xStep unsafe.Pointer, xFinal unsafe.Pointer) C.int {
|
||||
return C._sqlite3_create_function(db, zFunctionName, nArg, eTextRep, C.uintptr_t(uintptr(pApp)), (*[0]byte)(xFunc), (*[0]byte)(xStep), (*[0]byte)(xFinal))
|
||||
}
|
||||
|
||||
// RegisterAggregator makes a Go type available as a SQLite aggregation function.
|
||||
@@ -749,15 +754,28 @@ func (c *SQLiteConn) lastError() error {
|
||||
return lastError(c.db)
|
||||
}
|
||||
|
||||
// Note: may be called with db == nil
|
||||
func lastError(db *C.sqlite3) error {
|
||||
rv := C.sqlite3_errcode(db)
|
||||
rv := C.sqlite3_errcode(db) // returns SQLITE_NOMEM if db == nil
|
||||
if rv == C.SQLITE_OK {
|
||||
return nil
|
||||
}
|
||||
extrv := C.sqlite3_extended_errcode(db) // returns SQLITE_NOMEM if db == nil
|
||||
errStr := C.GoString(C.sqlite3_errmsg(db)) // returns "out of memory" if db == nil
|
||||
|
||||
// https://www.sqlite.org/c3ref/system_errno.html
|
||||
// sqlite3_system_errno is only meaningful if the error code was SQLITE_CANTOPEN,
|
||||
// or it was SQLITE_IOERR and the extended code was not SQLITE_IOERR_NOMEM
|
||||
var systemErrno syscall.Errno
|
||||
if rv == C.SQLITE_CANTOPEN || (rv == C.SQLITE_IOERR && extrv != C.SQLITE_IOERR_NOMEM) {
|
||||
systemErrno = syscall.Errno(C.sqlite3_system_errno(db))
|
||||
}
|
||||
|
||||
return Error{
|
||||
Code: ErrNo(rv),
|
||||
ExtendedCode: ErrNoExtended(C.sqlite3_extended_errcode(db)),
|
||||
err: C.GoString(C.sqlite3_errmsg(db)),
|
||||
ExtendedCode: ErrNoExtended(extrv),
|
||||
SystemErrno: systemErrno,
|
||||
err: errStr,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,20 +800,29 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []namedValue)
|
||||
}
|
||||
var res driver.Result
|
||||
if s.(*SQLiteStmt).s != nil {
|
||||
stmtArgs := make([]namedValue, 0, len(args))
|
||||
na := s.NumInput()
|
||||
if len(args) < na {
|
||||
if len(args)-start < na {
|
||||
s.Close()
|
||||
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args))
|
||||
}
|
||||
for i := 0; i < na; i++ {
|
||||
args[i].Ordinal -= start
|
||||
// consume the number of arguments used in the current
|
||||
// statement and append all named arguments not
|
||||
// contained therein
|
||||
stmtArgs = append(stmtArgs, args[start:start+na]...)
|
||||
for i := range args {
|
||||
if (i < start || i >= na) && args[i].Name != "" {
|
||||
stmtArgs = append(stmtArgs, args[i])
|
||||
}
|
||||
}
|
||||
res, err = s.(*SQLiteStmt).exec(ctx, args[:na])
|
||||
for i := range stmtArgs {
|
||||
stmtArgs[i].Ordinal = i + 1
|
||||
}
|
||||
res, err = s.(*SQLiteStmt).exec(ctx, stmtArgs)
|
||||
if err != nil && err != driver.ErrSkip {
|
||||
s.Close()
|
||||
return nil, err
|
||||
}
|
||||
args = args[na:]
|
||||
start += na
|
||||
}
|
||||
tail := s.(*SQLiteStmt).t
|
||||
@@ -828,24 +855,33 @@ func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
||||
func (c *SQLiteConn) query(ctx context.Context, query string, args []namedValue) (driver.Rows, error) {
|
||||
start := 0
|
||||
for {
|
||||
stmtArgs := make([]namedValue, 0, len(args))
|
||||
s, err := c.prepare(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.(*SQLiteStmt).cls = true
|
||||
na := s.NumInput()
|
||||
if len(args) < na {
|
||||
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args))
|
||||
if len(args)-start < na {
|
||||
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
|
||||
}
|
||||
for i := 0; i < na; i++ {
|
||||
args[i].Ordinal -= start
|
||||
// consume the number of arguments used in the current
|
||||
// statement and append all named arguments not contained
|
||||
// therein
|
||||
stmtArgs = append(stmtArgs, args[start:start+na]...)
|
||||
for i := range args {
|
||||
if (i < start || i >= na) && args[i].Name != "" {
|
||||
stmtArgs = append(stmtArgs, args[i])
|
||||
}
|
||||
}
|
||||
rows, err := s.(*SQLiteStmt).query(ctx, args[:na])
|
||||
for i := range stmtArgs {
|
||||
stmtArgs[i].Ordinal = i + 1
|
||||
}
|
||||
rows, err := s.(*SQLiteStmt).query(ctx, stmtArgs)
|
||||
if err != nil && err != driver.ErrSkip {
|
||||
s.Close()
|
||||
return rows, err
|
||||
}
|
||||
args = args[na:]
|
||||
start += na
|
||||
tail := s.(*SQLiteStmt).t
|
||||
if tail == "" {
|
||||
@@ -869,10 +905,6 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
|
||||
return &SQLiteTx{c}, nil
|
||||
}
|
||||
|
||||
func errorString(err Error) string {
|
||||
return C.GoString(C.sqlite3_errstr(C.int(err.Code)))
|
||||
}
|
||||
|
||||
// Open database and return a new connection.
|
||||
//
|
||||
// A pragma can take either zero or one argument.
|
||||
@@ -897,7 +929,7 @@ func errorString(err Error) string {
|
||||
// - rwc
|
||||
// - memory
|
||||
//
|
||||
// shared
|
||||
// cache
|
||||
// SQLite Shared-Cache Mode
|
||||
// https://www.sqlite.org/sharedcache.html
|
||||
// Values:
|
||||
@@ -1007,6 +1039,8 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
secureDelete := "DEFAULT"
|
||||
synchronousMode := "NORMAL"
|
||||
writableSchema := -1
|
||||
vfsName := ""
|
||||
var cacheSize *int64
|
||||
|
||||
pos := strings.IndexRune(dsn, '?')
|
||||
if pos >= 1 {
|
||||
@@ -1330,6 +1364,22 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Cache size (_cache_size)
|
||||
//
|
||||
// https://sqlite.org/pragma.html#pragma_cache_size
|
||||
//
|
||||
if val := params.Get("_cache_size"); val != "" {
|
||||
iv, err := strconv.ParseInt(val, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Invalid _cache_size: %v: %v", val, err)
|
||||
}
|
||||
cacheSize = &iv
|
||||
}
|
||||
|
||||
if val := params.Get("vfs"); val != "" {
|
||||
vfsName = val
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(dsn, "file:") {
|
||||
dsn = dsn[:pos]
|
||||
}
|
||||
@@ -1338,14 +1388,22 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
var db *C.sqlite3
|
||||
name := C.CString(dsn)
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
var vfs *C.char
|
||||
if vfsName != "" {
|
||||
vfs = C.CString(vfsName)
|
||||
defer C.free(unsafe.Pointer(vfs))
|
||||
}
|
||||
rv := C._sqlite3_open_v2(name, &db,
|
||||
mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE,
|
||||
nil)
|
||||
vfs)
|
||||
if rv != 0 {
|
||||
// Save off the error _before_ closing the database.
|
||||
// This is safe even if db is nil.
|
||||
err := lastError(db)
|
||||
if db != nil {
|
||||
C.sqlite3_close_v2(db)
|
||||
}
|
||||
return nil, Error{Code: ErrNo(rv)}
|
||||
return nil, err
|
||||
}
|
||||
if db == nil {
|
||||
return nil, errors.New("sqlite succeeded without returning a database")
|
||||
@@ -1630,6 +1688,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
if len(d.Extensions) > 0 {
|
||||
if err := conn.loadExtensions(d.Extensions); err != nil {
|
||||
conn.Close()
|
||||
@@ -1759,11 +1825,6 @@ func (s *SQLiteStmt) NumInput() int {
|
||||
return int(C.sqlite3_bind_parameter_count(s.s))
|
||||
}
|
||||
|
||||
type bindArg struct {
|
||||
n int
|
||||
v driver.Value
|
||||
}
|
||||
|
||||
var placeHolder = []byte{0}
|
||||
|
||||
func (s *SQLiteStmt) bind(args []namedValue) error {
|
||||
@@ -1772,52 +1833,63 @@ func (s *SQLiteStmt) bind(args []namedValue) error {
|
||||
return s.c.lastError()
|
||||
}
|
||||
|
||||
bindIndices := make([][3]int, len(args))
|
||||
prefixes := []string{":", "@", "$"}
|
||||
for i, v := range args {
|
||||
bindIndices[i][0] = args[i].Ordinal
|
||||
if v.Name != "" {
|
||||
cname := C.CString(":" + v.Name)
|
||||
args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s.s, cname))
|
||||
C.free(unsafe.Pointer(cname))
|
||||
for j := range prefixes {
|
||||
cname := C.CString(prefixes[j] + v.Name)
|
||||
bindIndices[i][j] = int(C.sqlite3_bind_parameter_index(s.s, cname))
|
||||
C.free(unsafe.Pointer(cname))
|
||||
}
|
||||
args[i].Ordinal = bindIndices[i][0]
|
||||
}
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
n := C.int(arg.Ordinal)
|
||||
switch v := arg.Value.(type) {
|
||||
case nil:
|
||||
rv = C.sqlite3_bind_null(s.s, n)
|
||||
case string:
|
||||
if len(v) == 0 {
|
||||
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0))
|
||||
} else {
|
||||
b := []byte(v)
|
||||
for i, arg := range args {
|
||||
for j := range bindIndices[i] {
|
||||
if bindIndices[i][j] == 0 {
|
||||
continue
|
||||
}
|
||||
n := C.int(bindIndices[i][j])
|
||||
switch v := arg.Value.(type) {
|
||||
case nil:
|
||||
rv = C.sqlite3_bind_null(s.s, n)
|
||||
case string:
|
||||
if len(v) == 0 {
|
||||
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0))
|
||||
} else {
|
||||
b := []byte(v)
|
||||
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
|
||||
}
|
||||
case int64:
|
||||
rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v))
|
||||
case bool:
|
||||
if v {
|
||||
rv = C.sqlite3_bind_int(s.s, n, 1)
|
||||
} else {
|
||||
rv = C.sqlite3_bind_int(s.s, n, 0)
|
||||
}
|
||||
case float64:
|
||||
rv = C.sqlite3_bind_double(s.s, n, C.double(v))
|
||||
case []byte:
|
||||
if v == nil {
|
||||
rv = C.sqlite3_bind_null(s.s, n)
|
||||
} else {
|
||||
ln := len(v)
|
||||
if ln == 0 {
|
||||
v = placeHolder
|
||||
}
|
||||
rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(ln))
|
||||
}
|
||||
case time.Time:
|
||||
b := []byte(v.Format(SQLiteTimestampFormats[0]))
|
||||
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
|
||||
}
|
||||
case int64:
|
||||
rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v))
|
||||
case bool:
|
||||
if v {
|
||||
rv = C.sqlite3_bind_int(s.s, n, 1)
|
||||
} else {
|
||||
rv = C.sqlite3_bind_int(s.s, n, 0)
|
||||
if rv != C.SQLITE_OK {
|
||||
return s.c.lastError()
|
||||
}
|
||||
case float64:
|
||||
rv = C.sqlite3_bind_double(s.s, n, C.double(v))
|
||||
case []byte:
|
||||
if v == nil {
|
||||
rv = C.sqlite3_bind_null(s.s, n)
|
||||
} else {
|
||||
ln := len(v)
|
||||
if ln == 0 {
|
||||
v = placeHolder
|
||||
}
|
||||
rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(ln))
|
||||
}
|
||||
case time.Time:
|
||||
b := []byte(v.Format(SQLiteTimestampFormats[0]))
|
||||
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
|
||||
}
|
||||
if rv != C.SQLITE_OK {
|
||||
return s.c.lastError()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1875,6 +1947,14 @@ func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
return s.exec(context.Background(), list)
|
||||
}
|
||||
|
||||
func isInterruptErr(err error) bool {
|
||||
sqliteErr, ok := err.(Error)
|
||||
if ok {
|
||||
return sqliteErr.Code == ErrInterrupt
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// exec executes a query that doesn't return rows. Attempts to honor context timeout.
|
||||
func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result, error) {
|
||||
if ctx.Done() == nil {
|
||||
@@ -1890,19 +1970,22 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
|
||||
r, err := s.execSync(args)
|
||||
resultCh <- result{r, err}
|
||||
}()
|
||||
var rv result
|
||||
select {
|
||||
case rv := <- resultCh:
|
||||
return rv.r, rv.err
|
||||
case rv = <-resultCh:
|
||||
case <-ctx.Done():
|
||||
select {
|
||||
case <-resultCh: // no need to interrupt
|
||||
case rv = <-resultCh: // no need to interrupt, operation completed in db
|
||||
default:
|
||||
// this is still racy and can be no-op if executed between sqlite3_* calls in execSync.
|
||||
C.sqlite3_interrupt(s.c.db)
|
||||
<-resultCh // ensure goroutine completed
|
||||
rv = <-resultCh // wait for goroutine completed
|
||||
if isInterruptErr(rv.err) {
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
}
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
return rv.r, rv.err
|
||||
}
|
||||
|
||||
func (s *SQLiteStmt) execSync(args []namedValue) (driver.Result, error) {
|
||||
@@ -1992,7 +2075,7 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||
resultCh <- rc.nextSyncLocked(dest)
|
||||
}()
|
||||
select {
|
||||
case err := <- resultCh:
|
||||
case err := <-resultCh:
|
||||
return err
|
||||
case <-rc.ctx.Done():
|
||||
select {
|
||||
|
||||
1
vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
generated
vendored
1
vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
generated
vendored
@@ -14,5 +14,6 @@ package sqlite3
|
||||
#cgo darwin CFLAGS: -I/usr/local/opt/sqlite/include
|
||||
#cgo openbsd LDFLAGS: -lsqlite3
|
||||
#cgo solaris LDFLAGS: -lsqlite3
|
||||
#cgo windows LDFLAGS: -lsqlite3
|
||||
*/
|
||||
import "C"
|
||||
|
||||
40
vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
generated
vendored
40
vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
generated
vendored
@@ -28,12 +28,9 @@ func (c *SQLiteConn) loadExtensions(extensions []string) error {
|
||||
}
|
||||
|
||||
for _, extension := range extensions {
|
||||
cext := C.CString(extension)
|
||||
defer C.free(unsafe.Pointer(cext))
|
||||
rv = C.sqlite3_load_extension(c.db, cext, nil, nil)
|
||||
if rv != C.SQLITE_OK {
|
||||
if err := c.loadExtension(extension, nil); err != nil {
|
||||
C.sqlite3_enable_load_extension(c.db, 0)
|
||||
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +38,7 @@ func (c *SQLiteConn) loadExtensions(extensions []string) error {
|
||||
if rv != C.SQLITE_OK {
|
||||
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -51,14 +49,9 @@ func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
|
||||
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
}
|
||||
|
||||
clib := C.CString(lib)
|
||||
defer C.free(unsafe.Pointer(clib))
|
||||
centry := C.CString(entry)
|
||||
defer C.free(unsafe.Pointer(centry))
|
||||
|
||||
rv = C.sqlite3_load_extension(c.db, clib, centry, nil)
|
||||
if rv != C.SQLITE_OK {
|
||||
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
|
||||
if err := c.loadExtension(lib, &entry); err != nil {
|
||||
C.sqlite3_enable_load_extension(c.db, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
rv = C.sqlite3_enable_load_extension(c.db, 0)
|
||||
@@ -68,3 +61,24 @@ func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
|
||||
clib := C.CString(lib)
|
||||
defer C.free(unsafe.Pointer(clib))
|
||||
|
||||
var centry *C.char
|
||||
if entry != nil {
|
||||
centry = C.CString(*entry)
|
||||
defer C.free(unsafe.Pointer(centry))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
115
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go
generated
vendored
115
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go
generated
vendored
@@ -226,11 +226,43 @@ static sqlite3_module goModule = {
|
||||
0 // xRollbackTo
|
||||
};
|
||||
|
||||
// See https://sqlite.org/vtab.html#eponymous_only_virtual_tables
|
||||
static sqlite3_module goModuleEponymousOnly = {
|
||||
0, // iVersion
|
||||
0, // xCreate - create a table, which here is null
|
||||
cXConnect, // xConnect - connect to an existing table
|
||||
cXBestIndex, // xBestIndex - Determine search strategy
|
||||
cXDisconnect, // xDisconnect - Disconnect from a table
|
||||
cXDestroy, // xDestroy - Drop a table
|
||||
cXOpen, // xOpen - open a cursor
|
||||
cXClose, // xClose - close a cursor
|
||||
cXFilter, // xFilter - configure scan constraints
|
||||
cXNext, // xNext - advance a cursor
|
||||
cXEof, // xEof
|
||||
cXColumn, // xColumn - read data
|
||||
cXRowid, // xRowid - read data
|
||||
cXUpdate, // xUpdate - write data
|
||||
// Not implemented
|
||||
0, // xBegin - begin transaction
|
||||
0, // xSync - sync transaction
|
||||
0, // xCommit - commit transaction
|
||||
0, // xRollback - rollback transaction
|
||||
0, // xFindFunction - function overloading
|
||||
0, // xRename - rename the table
|
||||
0, // xSavepoint
|
||||
0, // xRelease
|
||||
0 // xRollbackTo
|
||||
};
|
||||
|
||||
void goMDestroy(void*);
|
||||
|
||||
static int _sqlite3_create_module(sqlite3 *db, const char *zName, uintptr_t pClientData) {
|
||||
return sqlite3_create_module_v2(db, zName, &goModule, (void*) pClientData, goMDestroy);
|
||||
}
|
||||
|
||||
static int _sqlite3_create_module_eponymous_only(sqlite3 *db, const char *zName, uintptr_t pClientData) {
|
||||
return sqlite3_create_module_v2(db, zName, &goModuleEponymousOnly, (void*) pClientData, goMDestroy);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@@ -288,10 +320,13 @@ type InfoOrderBy struct {
|
||||
}
|
||||
|
||||
func constraints(info *C.sqlite3_index_info) []InfoConstraint {
|
||||
l := info.nConstraint
|
||||
slice := (*[1 << 30]C.struct_sqlite3_index_constraint)(unsafe.Pointer(info.aConstraint))[:l:l]
|
||||
slice := *(*[]C.struct_sqlite3_index_constraint)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(info.aConstraint)),
|
||||
Len: int(info.nConstraint),
|
||||
Cap: int(info.nConstraint),
|
||||
}))
|
||||
|
||||
cst := make([]InfoConstraint, 0, l)
|
||||
cst := make([]InfoConstraint, 0, len(slice))
|
||||
for _, c := range slice {
|
||||
var usable bool
|
||||
if c.usable > 0 {
|
||||
@@ -307,10 +342,13 @@ func constraints(info *C.sqlite3_index_info) []InfoConstraint {
|
||||
}
|
||||
|
||||
func orderBys(info *C.sqlite3_index_info) []InfoOrderBy {
|
||||
l := info.nOrderBy
|
||||
slice := (*[1 << 30]C.struct_sqlite3_index_orderby)(unsafe.Pointer(info.aOrderBy))[:l:l]
|
||||
slice := *(*[]C.struct_sqlite3_index_orderby)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(info.aOrderBy)),
|
||||
Len: int(info.nOrderBy),
|
||||
Cap: int(info.nOrderBy),
|
||||
}))
|
||||
|
||||
ob := make([]InfoOrderBy, 0, l)
|
||||
ob := make([]InfoOrderBy, 0, len(slice))
|
||||
for _, c := range slice {
|
||||
var desc bool
|
||||
if c.desc > 0 {
|
||||
@@ -347,7 +385,7 @@ func mPrintf(format, arg string) *C.char {
|
||||
|
||||
//export goMInit
|
||||
func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **C.char, isCreate C.int) C.uintptr_t {
|
||||
m := lookupHandle(uintptr(pClientData)).(*sqliteModule)
|
||||
m := lookupHandle(pClientData).(*sqliteModule)
|
||||
if m.c.db != (*C.sqlite3)(db) {
|
||||
*pzErr = mPrintf("%s", "Inconsistent db handles")
|
||||
return 0
|
||||
@@ -373,12 +411,12 @@ func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **
|
||||
}
|
||||
vt := sqliteVTab{m, vTab}
|
||||
*pzErr = nil
|
||||
return C.uintptr_t(newHandle(m.c, &vt))
|
||||
return C.uintptr_t(uintptr(newHandle(m.c, &vt)))
|
||||
}
|
||||
|
||||
//export goVRelease
|
||||
func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char {
|
||||
vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab)
|
||||
vt := lookupHandle(pVTab).(*sqliteVTab)
|
||||
var err error
|
||||
if isDestroy == 1 {
|
||||
err = vt.vTab.Destroy()
|
||||
@@ -393,7 +431,7 @@ func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char {
|
||||
|
||||
//export goVOpen
|
||||
func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t {
|
||||
vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab)
|
||||
vt := lookupHandle(pVTab).(*sqliteVTab)
|
||||
vTabCursor, err := vt.vTab.Open()
|
||||
if err != nil {
|
||||
*pzErr = mPrintf("%s", err.Error())
|
||||
@@ -401,12 +439,12 @@ func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t {
|
||||
}
|
||||
vtc := sqliteVTabCursor{vt, vTabCursor}
|
||||
*pzErr = nil
|
||||
return C.uintptr_t(newHandle(vt.module.c, &vtc))
|
||||
return C.uintptr_t(uintptr(newHandle(vt.module.c, &vtc)))
|
||||
}
|
||||
|
||||
//export goVBestIndex
|
||||
func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
|
||||
vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab)
|
||||
vt := lookupHandle(pVTab).(*sqliteVTab)
|
||||
info := (*C.sqlite3_index_info)(icp)
|
||||
csts := constraints(info)
|
||||
res, err := vt.vTab.BestIndex(csts, orderBys(info))
|
||||
@@ -418,13 +456,17 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
|
||||
}
|
||||
|
||||
// Get a pointer to constraint_usage struct so we can update in place.
|
||||
l := info.nConstraint
|
||||
s := (*[1 << 30]C.struct_sqlite3_index_constraint_usage)(unsafe.Pointer(info.aConstraintUsage))[:l:l]
|
||||
|
||||
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),
|
||||
}))
|
||||
index := 1
|
||||
for i := C.int(0); i < info.nConstraint; i++ {
|
||||
for i := range slice {
|
||||
if res.Used[i] {
|
||||
s[i].argvIndex = C.int(index)
|
||||
s[i].omit = C.uchar(1)
|
||||
slice[i].argvIndex = C.int(index)
|
||||
slice[i].omit = C.uchar(1)
|
||||
index++
|
||||
}
|
||||
}
|
||||
@@ -445,7 +487,7 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
|
||||
|
||||
//export goVClose
|
||||
func goVClose(pCursor unsafe.Pointer) *C.char {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
err := vtc.vTabCursor.Close()
|
||||
if err != nil {
|
||||
return mPrintf("%s", err.Error())
|
||||
@@ -455,13 +497,13 @@ func goVClose(pCursor unsafe.Pointer) *C.char {
|
||||
|
||||
//export goMDestroy
|
||||
func goMDestroy(pClientData unsafe.Pointer) {
|
||||
m := lookupHandle(uintptr(pClientData)).(*sqliteModule)
|
||||
m := lookupHandle(pClientData).(*sqliteModule)
|
||||
m.module.DestroyModule()
|
||||
}
|
||||
|
||||
//export goVFilter
|
||||
func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
|
||||
vals := make([]interface{}, 0, argc)
|
||||
for _, v := range args {
|
||||
@@ -480,7 +522,7 @@ func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int
|
||||
|
||||
//export goVNext
|
||||
func goVNext(pCursor unsafe.Pointer) *C.char {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
err := vtc.vTabCursor.Next()
|
||||
if err != nil {
|
||||
return mPrintf("%s", err.Error())
|
||||
@@ -490,7 +532,7 @@ func goVNext(pCursor unsafe.Pointer) *C.char {
|
||||
|
||||
//export goVEof
|
||||
func goVEof(pCursor unsafe.Pointer) C.int {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
err := vtc.vTabCursor.EOF()
|
||||
if err {
|
||||
return 1
|
||||
@@ -500,7 +542,7 @@ func goVEof(pCursor unsafe.Pointer) C.int {
|
||||
|
||||
//export goVColumn
|
||||
func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
c := (*SQLiteContext)(cp)
|
||||
err := vtc.vTabCursor.Column(c, int(col))
|
||||
if err != nil {
|
||||
@@ -511,7 +553,7 @@ func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char {
|
||||
|
||||
//export goVRowid
|
||||
func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char {
|
||||
vtc := lookupHandle(uintptr(pCursor)).(*sqliteVTabCursor)
|
||||
vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
|
||||
rowid, err := vtc.vTabCursor.Rowid()
|
||||
if err != nil {
|
||||
return mPrintf("%s", err.Error())
|
||||
@@ -522,7 +564,7 @@ func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char {
|
||||
|
||||
//export goVUpdate
|
||||
func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid *C.sqlite3_int64) *C.char {
|
||||
vt := lookupHandle(uintptr(pVTab)).(*sqliteVTab)
|
||||
vt := lookupHandle(pVTab).(*sqliteVTab)
|
||||
|
||||
var tname string
|
||||
if n, ok := vt.vTab.(interface {
|
||||
@@ -585,6 +627,13 @@ type Module interface {
|
||||
DestroyModule()
|
||||
}
|
||||
|
||||
// EponymousOnlyModule is a "virtual table module" (as above), but
|
||||
// for defining "eponymous only" virtual tables See: https://sqlite.org/vtab.html#eponymous_only_virtual_tables
|
||||
type EponymousOnlyModule interface {
|
||||
Module
|
||||
EponymousOnlyModule()
|
||||
}
|
||||
|
||||
// VTab describes a particular instance of the virtual table.
|
||||
// See: http://sqlite.org/c3ref/vtab.html
|
||||
type VTab interface {
|
||||
@@ -642,9 +691,19 @@ func (c *SQLiteConn) CreateModule(moduleName string, module Module) error {
|
||||
mname := C.CString(moduleName)
|
||||
defer C.free(unsafe.Pointer(mname))
|
||||
udm := sqliteModule{c, moduleName, module}
|
||||
rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(newHandle(c, &udm)))
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
switch module.(type) {
|
||||
case EponymousOnlyModule:
|
||||
rv := C._sqlite3_create_module_eponymous_only(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm))))
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
}
|
||||
return nil
|
||||
case Module:
|
||||
rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm))))
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go
generated
vendored
2
vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go
generated
vendored
@@ -215,7 +215,6 @@ func addTraceMapping(connHandle uintptr, traceConf TraceConfig) {
|
||||
traceConf, connHandle, oldEntryCopy.config))
|
||||
}
|
||||
traceMap[connHandle] = traceMapEntry{config: traceConf}
|
||||
fmt.Printf("Added trace config %v: handle 0x%x.\n", traceConf, connHandle)
|
||||
}
|
||||
|
||||
func lookupTraceMapping(connHandle uintptr) (TraceConfig, bool) {
|
||||
@@ -234,7 +233,6 @@ func popTraceMapping(connHandle uintptr) (TraceConfig, bool) {
|
||||
entryCopy, found := traceMap[connHandle]
|
||||
if found {
|
||||
delete(traceMap, connHandle)
|
||||
fmt.Printf("Pop handle 0x%x: deleted trace config %v.\n", connHandle, entryCopy.config)
|
||||
}
|
||||
return entryCopy.config, found
|
||||
}
|
||||
|
||||
4
vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
generated
vendored
4
vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
generated
vendored
@@ -31,12 +31,12 @@ func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
|
||||
func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
|
||||
return 0, 0, false
|
||||
}
|
||||
*/
|
||||
|
||||
// ColumnTypeNullable implement RowsColumnTypeNullable.
|
||||
func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
|
||||
return true, true
|
||||
return false, false
|
||||
}
|
||||
*/
|
||||
|
||||
// ColumnTypeScanType implement RowsColumnTypeScanType.
|
||||
func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type {
|
||||
|
||||
4
vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go
generated
vendored
4
vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go
generated
vendored
@@ -15,7 +15,9 @@ package sqlite3
|
||||
// This code should improve performance on windows because
|
||||
// without the presence of usleep SQLite waits 1 second.
|
||||
//
|
||||
// Source: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
||||
// Source: https://github.com/php/php-src/blob/PHP-5.0/win32/time.c
|
||||
// License: https://github.com/php/php-src/blob/PHP-5.0/LICENSE
|
||||
// Details: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
|
||||
|
||||
/*
|
||||
#include <windows.h>
|
||||
|
||||
29
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
29
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
@@ -325,6 +325,19 @@ struct sqlite3_api_routines {
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -615,10 +628,22 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->frombind
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
27
vendor/github.com/mattn/go-sqlite3/static_mock.go
generated
vendored
27
vendor/github.com/mattn/go-sqlite3/static_mock.go
generated
vendored
@@ -13,14 +13,25 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
sql.Register("sqlite3", &SQLiteDriverMock{})
|
||||
}
|
||||
|
||||
type SQLiteDriverMock struct{}
|
||||
|
||||
var errorMsg = errors.New("Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub")
|
||||
|
||||
func (SQLiteDriverMock) Open(s string) (driver.Conn, error) {
|
||||
return nil, errorMsg
|
||||
func init() {
|
||||
sql.Register("sqlite3", &SQLiteDriver{})
|
||||
}
|
||||
|
||||
type (
|
||||
SQLiteDriver struct {
|
||||
Extensions []string
|
||||
ConnectHook func(*SQLiteConn) error
|
||||
}
|
||||
SQLiteConn struct{}
|
||||
)
|
||||
|
||||
func (SQLiteDriver) Open(s string) (driver.Conn, error) { return nil, errorMsg }
|
||||
func (c *SQLiteConn) RegisterAggregator(string, interface{}, bool) error { return errorMsg }
|
||||
func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {}
|
||||
func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg }
|
||||
func (c *SQLiteConn) RegisterCommitHook(func() int) {}
|
||||
func (c *SQLiteConn) RegisterFunc(string, interface{}, bool) error { return errorMsg }
|
||||
func (c *SQLiteConn) RegisterRollbackHook(func()) {}
|
||||
func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64)) {}
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -214,7 +214,7 @@ github.com/markbates/safe
|
||||
# github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007
|
||||
github.com/matryer/moq
|
||||
github.com/matryer/moq/pkg/moq
|
||||
# github.com/mattn/go-sqlite3 v1.13.0
|
||||
# github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mattn/go-sqlite3
|
||||
# github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/go-homedir
|
||||
|
||||
Reference in New Issue
Block a user