Update dependencies
This commit is contained in:
81
vendor/modernc.org/sqlite/sqlite.go
generated
vendored
81
vendor/modernc.org/sqlite/sqlite.go
generated
vendored
@ -11,12 +11,16 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@ -471,14 +475,14 @@ func toNamedValues(vals []driver.Value) (r []driver.NamedValue) {
|
||||
|
||||
func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Result, err error) {
|
||||
var pstmt uintptr
|
||||
done := false
|
||||
var done int32
|
||||
if ctx != nil && ctx.Done() != nil {
|
||||
donech := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
atomic.AddInt32(&done, 1)
|
||||
s.c.interrupt(s.c.db)
|
||||
case <-donech:
|
||||
}
|
||||
@ -489,7 +493,7 @@ func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Res
|
||||
}()
|
||||
}
|
||||
|
||||
for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && !done; {
|
||||
for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && atomic.LoadInt32(&done) == 0; {
|
||||
if pstmt, err = s.c.prepareV2(&psql); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -568,15 +572,14 @@ func (s *stmt) Query(args []driver.Value) (driver.Rows, error) { //TODO StmtQuer
|
||||
|
||||
func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Rows, err error) {
|
||||
var pstmt uintptr
|
||||
|
||||
done := false
|
||||
var done int32
|
||||
if ctx != nil && ctx.Done() != nil {
|
||||
donech := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
done = true
|
||||
atomic.AddInt32(&done, 1)
|
||||
s.c.interrupt(s.c.db)
|
||||
case <-donech:
|
||||
}
|
||||
@ -588,7 +591,7 @@ func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Ro
|
||||
}
|
||||
|
||||
var allocs []uintptr
|
||||
for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && !done; {
|
||||
for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && atomic.LoadInt32(&done) == 0; {
|
||||
if pstmt, err = s.c.prepareV2(&psql); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -720,12 +723,29 @@ func (t *tx) exec(ctx context.Context, sql string) (err error) {
|
||||
type conn struct {
|
||||
db uintptr // *sqlite3.Xsqlite3
|
||||
tls *libc.TLS
|
||||
|
||||
// Context handling can cause conn.Close and conn.interrupt to be invoked
|
||||
// concurrently.
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func newConn(name string) (*conn, error) {
|
||||
func newConn(dsn string) (*conn, error) {
|
||||
var query string
|
||||
|
||||
// Parse the query parameters from the dsn and them from the dsn if not prefixed by file:
|
||||
// https://github.com/mattn/go-sqlite3/blob/3392062c729d77820afc1f5cae3427f0de39e954/sqlite3.go#L1046
|
||||
// https://github.com/mattn/go-sqlite3/blob/3392062c729d77820afc1f5cae3427f0de39e954/sqlite3.go#L1383
|
||||
pos := strings.IndexRune(dsn, '?')
|
||||
if pos >= 1 {
|
||||
query = dsn[pos+1:]
|
||||
if !strings.HasPrefix(dsn, "file:") {
|
||||
dsn = dsn[:pos]
|
||||
}
|
||||
}
|
||||
|
||||
c := &conn{tls: libc.NewTLS()}
|
||||
db, err := c.openV2(
|
||||
name,
|
||||
dsn,
|
||||
sqlite3.SQLITE_OPEN_READWRITE|sqlite3.SQLITE_OPEN_CREATE|
|
||||
sqlite3.SQLITE_OPEN_FULLMUTEX|
|
||||
sqlite3.SQLITE_OPEN_URI,
|
||||
@ -740,9 +760,29 @@ func newConn(name string) (*conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = applyPragmas(c, query); err != nil {
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func applyPragmas(c *conn, query string) error {
|
||||
q, err := url.ParseQuery(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range q["_pragma"] {
|
||||
cmd := "pragma " + v
|
||||
_, err := c.exec(context.Background(), cmd, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
|
||||
func (c *conn) columnBlob(pstmt uintptr, iCol int) (v []byte, err error) {
|
||||
p := sqlite3.Xsqlite3_column_blob(c.tls, pstmt, int32(iCol))
|
||||
@ -833,12 +873,17 @@ func (c *conn) changes() (int, error) {
|
||||
func (c *conn) step(pstmt uintptr) (int, error) {
|
||||
for {
|
||||
switch rc := sqlite3.Xsqlite3_step(c.tls, pstmt); rc {
|
||||
case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
|
||||
case sqliteLockedSharedcache:
|
||||
if err := c.retry(pstmt); err != nil {
|
||||
return sqlite3.SQLITE_LOCKED, err
|
||||
}
|
||||
default:
|
||||
case
|
||||
sqlite3.SQLITE_DONE,
|
||||
sqlite3.SQLITE_ROW:
|
||||
|
||||
return int(rc), nil
|
||||
default:
|
||||
return int(rc), errors.New(ErrorCodeString[int(rc)])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1096,7 +1141,7 @@ func (c *conn) prepareV2(zSQL *uintptr) (pstmt uintptr, err error) {
|
||||
case sqlite3.SQLITE_OK:
|
||||
*zSQL = *(*uintptr)(unsafe.Pointer(pptail))
|
||||
return *(*uintptr)(unsafe.Pointer(ppstmt)), nil
|
||||
case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
|
||||
case sqliteLockedSharedcache:
|
||||
if err := c.retry(0); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -1108,7 +1153,13 @@ func (c *conn) prepareV2(zSQL *uintptr) (pstmt uintptr, err error) {
|
||||
|
||||
// void sqlite3_interrupt(sqlite3*);
|
||||
func (c *conn) interrupt(pdb uintptr) (err error) {
|
||||
sqlite3.Xsqlite3_interrupt(c.tls, pdb)
|
||||
c.Lock() // Defend against race with .Close invoked by context handling.
|
||||
|
||||
defer c.Unlock()
|
||||
|
||||
if c.tls != nil {
|
||||
sqlite3.Xsqlite3_interrupt(c.tls, pdb)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1200,6 +1251,10 @@ func (c *conn) begin(ctx context.Context, opts driver.TxOptions) (t driver.Tx, e
|
||||
// Close when there's a surplus of idle connections, it shouldn't be necessary
|
||||
// for drivers to do their own connection caching.
|
||||
func (c *conn) Close() error {
|
||||
c.Lock() // Defend against race with .interrupt invoked by context handling.
|
||||
|
||||
defer c.Unlock()
|
||||
|
||||
if c.db != 0 {
|
||||
if err := c.closeV2(c.db); err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user