vendor: Mega update all dependencies

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4080
This commit is contained in:
Jakob Borg
2017-04-05 14:34:41 +00:00
parent 49c1527724
commit a1bcc15458
1354 changed files with 55066 additions and 797850 deletions

View File

@@ -126,11 +126,11 @@ func builtinAvg(arg []interface{}, ctx map[interface{}]interface{}) (v interface
case complex64:
return complex64(complex128(x) / complex(float64(data.n), 0)), nil
case complex128:
return complex64(complex128(x) / complex(float64(data.n), 0)), nil
return complex64(x / complex(float64(data.n), 0)), nil
case float32:
return float32(float64(x) / float64(data.n)), nil
case float64:
return float64(x) / float64(data.n), nil
return x / float64(data.n), nil
case int8:
return int8(int64(x) / int64(data.n)), nil
case int16:
@@ -138,7 +138,7 @@ func builtinAvg(arg []interface{}, ctx map[interface{}]interface{}) (v interface
case int32:
return int32(int64(x) / int64(data.n)), nil
case int64:
return int64(int64(x) / int64(data.n)), nil
return x / int64(data.n), nil
case uint8:
return uint8(uint64(x) / data.n), nil
case uint16:
@@ -146,7 +146,7 @@ func builtinAvg(arg []interface{}, ctx map[interface{}]interface{}) (v interface
case uint32:
return uint32(uint64(x) / data.n), nil
case uint64:
return uint64(uint64(x) / data.n), nil
return x / data.n, nil
}
}
@@ -216,9 +216,9 @@ func builtinComplex(arg []interface{}, _ map[interface{}]interface{}) (v interfa
case idealUint:
return idealComplex(complex(float64(re), float64(im.(idealUint)))), nil
case float32:
return complex(float32(re), im.(float32)), nil
return complex(re, im.(float32)), nil
case float64:
return complex(float64(re), im.(float64)), nil
return complex(re, im.(float64)), nil
case int8:
return complex(float64(re), float64(im.(int8))), nil
case int16:

26
vendor/github.com/cznic/ql/coerce.go generated vendored
View File

@@ -93,13 +93,13 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
//case idealUint:
//case bool:
case complex64:
return complex64(complex(float32(x), 0))
return complex(float32(x), 0)
case complex128:
return complex128(complex(float64(x), 0))
return complex(float64(x), 0)
case float32:
return float32(float64(x))
case float64:
return float64(float64(x))
return float64(x)
//case int8:
//case int16:
//case int32:
@@ -130,9 +130,9 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
}
//case bool:
case complex64:
return complex64(complex(float32(x), 0))
return complex(float32(x), 0)
case complex128:
return complex128(complex(float64(x), 0))
return complex(float64(x), 0)
case float32:
return float32(int64(x))
case float64:
@@ -150,7 +150,7 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
return int32(int64(x))
}
case int64:
return int64(int64(x))
return int64(x)
//case string:
case uint8:
if x >= 0 && x <= math.MaxUint8 {
@@ -190,9 +190,9 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
return idealUint(int64(x))
//case bool:
case complex64:
return complex64(complex(float32(x), 0))
return complex(float32(x), 0)
case complex128:
return complex128(complex(float64(x), 0))
return complex(float64(x), 0)
case float32:
return float32(int64(x))
case float64:
@@ -204,7 +204,7 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
case int32:
return int32(int64(x))
case int64:
return int64(int64(x))
return int64(x)
//case string:
case uint8:
return uint8(int64(x))
@@ -237,9 +237,9 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
return idealUint(uint64(x))
//case bool:
case complex64:
return complex64(complex(float32(x), 0))
return complex(float32(x), 0)
case complex128:
return complex128(complex(float64(x), 0))
return complex(float64(x), 0)
case float32:
return float32(uint64(x))
case float64:
@@ -258,7 +258,7 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
}
case int64:
if x <= math.MaxInt64 {
return int64(int64(x))
return int64(x)
}
//case string:
case uint8:
@@ -274,7 +274,7 @@ func coerce1(inVal, otherVal interface{}) (coercedInVal interface{}) {
return uint32(int64(x))
}
case uint64:
return uint64(uint64(x))
return uint64(x)
case *big.Int:
return big.NewInt(0).SetUint64(uint64(x))
case *big.Rat:

34
vendor/github.com/cznic/ql/doc.go generated vendored
View File

@@ -14,8 +14,13 @@
//
// Change list
//
// 2017-01-10: Release v1.1.0 fixes some bugs and adds a configurable WAL
// headroom.
//
// https://github.com/cznic/ql/issues/140
//
// 2016-07-29: Release v1.0.6 enables alternatively using = instead of == for
// equality oparation.
// equality operation.
//
// https://github.com/cznic/ql/issues/131
//
@@ -279,18 +284,21 @@
//
// The following keywords are reserved and may not be used as identifiers.
//
// ADD COLUMN false int32 ORDER uint16
// ALTER complex128 float int64 OUTER uint32
// AND complex64 float32 int8 RIGHT uint64
// AS CREATE float64 INTO SELECT uint8
// ASC DEFAULT FROM JOIN SET UNIQUE
// BETWEEN DELETE GROUP LEFT string UPDATE
// bigint DESC IF LIMIT TABLE VALUES
// bigrat DISTINCT IN LIKE time WHERE
// blob DROP INDEX NOT true
// bool duration INSERT NULL OR
// BY EXISTS int OFFSET TRUNCATE
// byte EXPLAIN int16 ON uint
// ADD complex128 FROM LEFT string
// ALTER complex64 FULL LIKE TABLE
// AND CREATE GROUP LIMIT time
// AS DEFAULT IF NOT TRANSACTION
// ASC DELETE IN NULL true
// BEGIN DESC INDEX OFFSET TRUNCATE
// BETWEEN DISTINCT INSERT ON uint
// bigint DROP int OR uint16
// bigrat duration int16 ORDER uint32
// blob EXISTS int32 OUTER uint64
// bool EXPLAIN int64 RIGHT uint8
// BY false int8 ROLLBACK UNIQUE
// byte float INTO rune UPDATE
// COLUMN float32 IS SELECT VALUES
// COMMIT float64 JOIN SET WHERE
//
// Keywords are not case sensitive.
//

50
vendor/github.com/cznic/ql/driver.go generated vendored
View File

@@ -14,8 +14,10 @@ import (
"fmt"
"io"
"math/big"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
@@ -144,23 +146,51 @@ func (d *sqlDriver) lock() func() {
// efficient re-use.
//
// The returned connection is only used by one goroutine at a time.
//
// The name supported URL parameters:
//
// headroom Size of the WAL headroom. See https://github.com/cznic/ql/issues/140.
func (d *sqlDriver) Open(name string) (driver.Conn, error) {
if d != fileDriver && d != memDriver {
switch {
case d == fileDriver:
if !strings.Contains(name, "://") && !strings.HasPrefix(name, "file") {
name = "file://" + name
}
case d == memDriver:
if !strings.Contains(name, "://") && !strings.HasPrefix(name, "memory") {
name = "memory://" + name
}
default:
return nil, fmt.Errorf("open: unexpected/unsupported instance of driver.Driver: %p", d)
}
switch {
case d == fileDriver && strings.HasPrefix(name, "file://"):
name = name[len("file://"):]
case d == fileDriver && strings.HasPrefix(name, "memory://"):
d = memDriver
name = name[len("memory://"):]
name = filepath.ToSlash(name) // Ensure / separated URLs on Windows
uri, err := url.Parse(name)
if err != nil {
return nil, err
}
name = filepath.Clean(name)
if name == "" || name == "." || name == string(os.PathSeparator) {
switch uri.Scheme {
case "file":
// ok
case "memory":
d = memDriver
default:
return nil, fmt.Errorf("open: unexpected/unsupported scheme: %s", uri.Scheme)
}
name = filepath.Clean(filepath.Join(uri.Host, uri.Path))
if d == fileDriver && (name == "" || name == "." || name == string(os.PathSeparator)) {
return nil, fmt.Errorf("invalid DB name %q", name)
}
var headroom int64
if a := uri.Query()["headroom"]; len(a) != 0 {
if headroom, err = strconv.ParseInt(a[0], 10, 64); err != nil {
return nil, err
}
}
defer d.lock()()
db := d.dbs[name]
if db == nil {
@@ -170,7 +200,7 @@ func (d *sqlDriver) Open(name string) (driver.Conn, error) {
case true:
db0, err = OpenMem()
default:
db0, err = OpenFile(name, &Options{CanCreate: true})
db0, err = OpenFile(name, &Options{CanCreate: true, Headroom: headroom})
}
if err != nil {
return nil, err

78
vendor/github.com/cznic/ql/etc.go generated vendored
View File

@@ -145,7 +145,7 @@ func intExpr(x interface{}) (i int64, err error) {
return 0, invNegLO(x)
}
return int64(x), nil
return x, nil
case uint8:
return int64(x), nil
case uint16:
@@ -210,7 +210,7 @@ func limOffExpr(x interface{}) (i uint64, err error) {
case uint32:
return uint64(x), nil
case uint64:
return uint64(x), nil
return x, nil
default:
return 0, fmt.Errorf("non-integer used in LIMIT or OFFSET: %v (value of type %T)", x, x)
}
@@ -318,10 +318,10 @@ func indexExpr(s *string, x interface{}) (i uint64, err error) {
return uint64(x), nil
case uint64:
if s != nil && x >= uint64(len(*s)) {
return 0, invBoundX(*s, uint64(x))
return 0, invBoundX(*s, x)
}
return uint64(x), nil
return x, nil
default:
return 0, fmt.Errorf("non-integer string index %v (value of type %T)", x, x)
}
@@ -429,10 +429,10 @@ func sliceExpr(s *string, x interface{}, mod int) (i uint64, err error) {
return uint64(x), nil
case uint64:
if s != nil && x >= uint64(len(*s)+mod) {
return 0, invSliceBoundX(*s, uint64(x))
return 0, invSliceBoundX(*s, x)
}
return uint64(x), nil
return x, nil
default:
return 0, fmt.Errorf("invalid slice index %s (type %T)", x, x)
}
@@ -529,7 +529,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
//case idealRune:
//case idealUint:
case bool:
return bool(x), nil
return x, nil
//case complex64:
//case complex128:
//case float32:
@@ -561,7 +561,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
return complex(float32(x), 0), nil
//case bool:
case complex64:
return complex64(x), nil
return x, nil
case complex128:
return complex64(x), nil
//case float32:
@@ -595,7 +595,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case complex64:
return complex128(x), nil
case complex128:
return complex128(x), nil
return x, nil
//case float32:
//case float64:
//case int8:
@@ -626,7 +626,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
//case complex64:
//case complex128:
case float32:
return float32(x), nil
return x, nil
case float64:
return float32(x), nil
case int8:
@@ -675,7 +675,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case float32:
return float64(x), nil
case float64:
return float64(x), nil
return x, nil
case int8:
return float64(x), nil
case int16:
@@ -728,7 +728,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case float64:
return int8(x), nil
case int8:
return int8(x), nil
return x, nil
case int16:
return int8(x), nil
case int32:
@@ -777,7 +777,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case int8:
return int16(x), nil
case int16:
return int16(x), nil
return x, nil
case int32:
return int16(x), nil
case int64:
@@ -826,7 +826,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case int16:
return int32(x), nil
case int32:
return int32(x), nil
return x, nil
case int64:
return int32(x), nil
//case string:
@@ -875,7 +875,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case int32:
return int64(x), nil
case int64:
return int64(x), nil
return x, nil
//case string:
case uint8:
return int64(x), nil
@@ -917,7 +917,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case int64:
return string(x), nil
case string:
return string(x), nil
return x, nil
case uint8:
return string(x), nil
case uint16:
@@ -970,7 +970,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
return uint8(x), nil
//case string:
case uint8:
return uint8(x), nil
return x, nil
case uint16:
return uint8(x), nil
case uint32:
@@ -1019,7 +1019,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case uint8:
return uint16(x), nil
case uint16:
return uint16(x), nil
return x, nil
case uint32:
return uint16(x), nil
case uint64:
@@ -1068,7 +1068,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case uint16:
return uint32(x), nil
case uint32:
return uint32(x), nil
return x, nil
case uint64:
return uint32(x), nil
case *big.Int:
@@ -1117,7 +1117,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
case uint32:
return uint64(x), nil
case uint64:
return uint64(x), nil
return x, nil
case *big.Int:
return x.Uint64(), nil
case time.Duration:
@@ -1162,7 +1162,7 @@ func convert(val interface{}, typ int) (v interface{}, err error) { //NTYPE
ii.Quo(ii, rr.Denom())
return ii, nil
case float64:
rr := big.NewRat(1, 1).SetFloat64(float64(x))
rr := big.NewRat(1, 1).SetFloat64(x)
ii := big.NewInt(0).Set(rr.Num())
ii.Quo(ii, rr.Denom())
return ii, nil
@@ -1365,7 +1365,7 @@ func typeCheck(rec []interface{}, cols []*col) (err error) {
rec[i] = complex64(y)
continue
case qComplex128:
rec[i] = complex128(y)
rec[i] = y
continue
case qFloat32, qFloat64, qInt8, qInt16, qInt32, qInt64, qUint8, qUint16, qUint32, qUint64:
return fmt.Errorf("constant %v truncated to real", y)
@@ -1378,13 +1378,13 @@ func typeCheck(rec []interface{}, cols []*col) (err error) {
rec[i] = complex(float32(y), 0)
continue
case qComplex128:
rec[i] = complex(float64(y), 0)
rec[i] = complex(y, 0)
continue
case qFloat32:
rec[i] = float32(y)
continue
case qFloat64:
rec[i] = float64(y)
rec[i] = y
continue
case qInt8:
if math.Floor(y) != y {
@@ -1532,7 +1532,7 @@ func typeCheck(rec []interface{}, cols []*col) (err error) {
return overflow(y, c.typ)
}
rec[i] = int64(y)
rec[i] = y
continue
case qString:
case qUint8:
@@ -1612,7 +1612,7 @@ func typeCheck(rec []interface{}, cols []*col) (err error) {
return overflow(y, c.typ)
}
rec[i] = int64(y)
rec[i] = y
continue
case qString:
case qUint8:
@@ -1719,7 +1719,7 @@ func typeCheck(rec []interface{}, cols []*col) (err error) {
rec[i] = uint32(y)
continue
case qUint64:
rec[i] = uint64(y)
rec[i] = y
continue
case qBigInt:
rec[i] = big.NewInt(0).SetUint64(y)
@@ -1788,7 +1788,7 @@ func collate1(a, b interface{}) int {
return 1
case complex64:
{
x, y := complex64(x), complex64(y)
x, y := complex64(x), y
if x == y {
return 0
}
@@ -1886,7 +1886,7 @@ func collate1(a, b interface{}) int {
}
case uint64:
{
x, y := uint64(x), uint64(y)
x, y := uint64(x), y
if x < y {
return -1
}
@@ -1968,7 +1968,7 @@ func collate1(a, b interface{}) int {
}
case int64:
{
x, y := int64(x), int64(y)
x, y := int64(x), y
if x < y {
return -1
}
@@ -2050,7 +2050,7 @@ func collate1(a, b interface{}) int {
}
case int64:
{
x, y := int64(x), int64(y)
x, y := int64(x), y
if x < y {
return -1
}
@@ -2106,7 +2106,7 @@ func collate1(a, b interface{}) int {
}
case float64:
{
x, y := float64(x), float64(y)
x, y := float64(x), y
if x < y {
return -1
}
@@ -2144,7 +2144,7 @@ func collate1(a, b interface{}) int {
return 1
case idealComplex:
{
x, y := complex64(x), complex64(y)
x, y := x, complex64(y)
if x == y {
return 0
}
@@ -2190,7 +2190,7 @@ func collate1(a, b interface{}) int {
return 1
case idealComplex:
{
x, y := complex128(x), complex128(y)
x, y := x, complex128(y)
if x == y {
return 0
}
@@ -2228,7 +2228,7 @@ func collate1(a, b interface{}) int {
return 1
case idealFloat:
{
x, y := float32(x), float32(y)
x, y := x, float32(y)
if x < y {
return -1
}
@@ -2258,7 +2258,7 @@ func collate1(a, b interface{}) int {
return 1
case idealFloat:
{
x, y := float64(x), float64(y)
x, y := x, float64(y)
if x < y {
return -1
}
@@ -2378,7 +2378,7 @@ func collate1(a, b interface{}) int {
return 1
case idealInt:
{
x, y := int64(x), int64(y)
x, y := x, int64(y)
if x < y {
return -1
}
@@ -2537,7 +2537,7 @@ func collate1(a, b interface{}) int {
return 1
case idealInt:
{
x, y := uint64(x), uint64(y)
x, y := x, uint64(y)
if x < y {
return -1
}
@@ -2550,7 +2550,7 @@ func collate1(a, b interface{}) int {
}
case idealUint:
{
x, y := uint64(x), uint64(y)
x, y := x, uint64(y)
if x < y {
return -1
}

4
vendor/github.com/cznic/ql/expr.go generated vendored
View File

@@ -1958,7 +1958,7 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
case uint32:
cnt = uint64(y)
case uint64:
cnt = uint64(y)
cnt = y
default:
return invOp2(a, b, op)
}
@@ -2057,7 +2057,7 @@ func (o *binaryOperation) eval(execCtx *execCtx, ctx map[interface{}]interface{}
case uint32:
cnt = uint64(y)
case uint64:
cnt = uint64(y)
cnt = y
default:
return invOp2(a, b, op)
}

72
vendor/github.com/cznic/ql/file.go generated vendored
View File

@@ -89,7 +89,7 @@ func OpenFile(name string, opt *Options) (db *DB, err error) {
}
}
fi, err := newFileFromOSFile(f) // always ACID
fi, err := newFileFromOSFile(f, opt.Headroom) // always ACID
if err != nil {
return
}
@@ -101,6 +101,8 @@ func OpenFile(name string, opt *Options) (db *DB, err error) {
}
}
fi.removeEmptyWAL = opt.RemoveEmptyWAL
return newDB(fi)
}
@@ -126,10 +128,25 @@ func OpenFile(name string, opt *Options) (db *DB, err error) {
// interface.
//
// If TempFile is nil it defaults to ioutil.TempFile.
//
// Headroom
//
// Headroom selects the minimum size a WAL file will have. The "extra"
// allocated file space serves as a headroom. Commits that fit into the
// headroom should not fail due to 'not enough space on the volume' errors. The
// headroom parameter is first rounded-up to a non negative multiple of the
// size of the lldb.Allocator atom.
//
// RemoveEmptyWAL
//
// RemoveEmptyWAL controls whether empty WAL files should be deleted on
// clean exit.
type Options struct {
CanCreate bool
OSFile lldb.OSFile
TempFile func(dir, prefix string) (f lldb.OSFile, err error)
CanCreate bool
OSFile lldb.OSFile
TempFile func(dir, prefix string) (f lldb.OSFile, err error)
Headroom int64
RemoveEmptyWAL bool
}
type fileBTreeIterator struct {
@@ -258,7 +275,7 @@ func infer(from []interface{}, to *[]*col) {
case time.Duration:
c.typ = qDuration
case chunk:
vals, err := lldb.DecodeScalars([]byte(x.b))
vals, err := lldb.DecodeScalars(x.b)
if err != nil {
panic(err)
}
@@ -374,19 +391,20 @@ func (t *fileTemp) Set(k, v []interface{}) (err error) {
}
type file struct {
a *lldb.Allocator
codec *gobCoder
f lldb.Filer
f0 lldb.OSFile
id int64
lck io.Closer
mu sync.Mutex
name string
tempFile func(dir, prefix string) (f lldb.OSFile, err error)
wal *os.File
a *lldb.Allocator
codec *gobCoder
f lldb.Filer
f0 lldb.OSFile
id int64
lck io.Closer
mu sync.Mutex
name string
tempFile func(dir, prefix string) (f lldb.OSFile, err error)
wal *os.File
removeEmptyWAL bool // Whether empty WAL files should be removed on close
}
func newFileFromOSFile(f lldb.OSFile) (fi *file, err error) {
func newFileFromOSFile(f lldb.OSFile, headroom int64) (fi *file, err error) {
nm := lockName(f.Name())
lck, err := lock.Lock(nm)
if err != nil {
@@ -434,9 +452,7 @@ func newFileFromOSFile(f lldb.OSFile) (fi *file, err error) {
return nil, err
}
if st.Size() != 0 {
return nil, fmt.Errorf("(file-001) non empty WAL file %s exists", wn)
}
closew = st.Size() == 0
}
info, err := f.Stat()
@@ -454,7 +470,7 @@ func newFileFromOSFile(f lldb.OSFile) (fi *file, err error) {
filer := lldb.Filer(lldb.NewOSFiler(f))
filer = lldb.NewInnerFiler(filer, 16)
if filer, err = lldb.NewACIDFiler(filer, w); err != nil {
if filer, err = lldb.NewACIDFiler(filer, w, lldb.MinWAL(headroom)); err != nil {
return nil, err
}
@@ -508,7 +524,7 @@ func newFileFromOSFile(f lldb.OSFile) (fi *file, err error) {
filer := lldb.Filer(lldb.NewOSFiler(f))
filer = lldb.NewInnerFiler(filer, 16)
if filer, err = lldb.NewACIDFiler(filer, w); err != nil {
if filer, err = lldb.NewACIDFiler(filer, w, lldb.MinWAL(headroom)); err != nil {
return nil, err
}
@@ -589,12 +605,22 @@ func (s *file) Close() (err error) {
es := s.f0.Sync()
ef := s.f0.Close()
var ew error
var ew, estat, eremove error
if s.wal != nil {
remove := false
wn := s.wal.Name()
if s.removeEmptyWAL {
var stat os.FileInfo
stat, estat = s.wal.Stat()
remove = stat.Size() == 0
}
ew = s.wal.Close()
if remove {
eremove = os.Remove(wn)
}
}
el := s.lck.Close()
return errSet(&err, es, ef, ew, el)
return errSet(&err, es, ef, ew, el, estat, eremove)
}
func (s *file) Name() string { return s.name }

56
vendor/github.com/cznic/ql/ql.go generated vendored
View File

@@ -771,16 +771,17 @@ func cols2meta(f []*col) (s string) {
// DB represent the database capable of executing QL statements.
type DB struct {
cc *TCtx // Current transaction context
exprCache map[string]expression
exprCacheMu sync.Mutex
hasIndex2 int // 0: nope, 1: in progress, 2: yes.
isMem bool
mu sync.Mutex
queue []chan struct{}
root *root
rw bool // DB FSM
rwmu sync.RWMutex
store storage
tnl int // Transaction nesting level
exprCache map[string]expression
exprCacheMu sync.Mutex
hasIndex2 int // 0: nope, 1: in progress, 2: yes.
}
var selIndex2Expr = MustCompile("select Expr from __Index2_Expr where Index2_ID == $1")
@@ -1086,7 +1087,7 @@ func mustCompile(src string) List {
return list
}
// Execute executes statements in a list while substituting QL paramaters from
// Execute executes statements in a list while substituting QL parameters from
// arg.
//
// The resulting []Recordset corresponds to the SELECT FROM statements in the
@@ -1214,6 +1215,15 @@ func (db *DB) Execute(ctx *TCtx, l List, arg ...interface{}) (rs []Recordset, in
return
}
func (db *DB) muUnlock() {
if n := len(db.queue); n != 0 {
db.queue[0] <- struct{}{}
copy(db.queue, db.queue[1:])
db.queue = db.queue[:n-1]
}
db.mu.Unlock()
}
func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tnlb int, err error) {
db.mu.Lock()
tnla = db.tnl
@@ -1222,7 +1232,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
case false:
switch s.(type) {
case beginTransactionStmt:
defer db.mu.Unlock()
defer db.muUnlock()
if pc == nil {
return nil, tnla, tnlb, errors.New("BEGIN TRANSACTION: cannot start a transaction in nil TransactionCtx")
}
@@ -1239,19 +1249,19 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
db.rw = true
return
case commitStmt:
defer db.mu.Unlock()
defer db.muUnlock()
return nil, tnla, tnlb, errCommitNotInTransaction
case rollbackStmt:
defer db.mu.Unlock()
defer db.muUnlock()
return nil, tnla, tnlb, errRollbackNotInTransaction
default:
if s.isUpdating() {
db.mu.Unlock()
db.muUnlock()
return nil, tnla, tnlb, fmt.Errorf("attempt to update the DB outside of a transaction")
}
db.rwmu.RLock() // can safely grab before Unlock
db.mu.Unlock()
db.muUnlock()
defer db.rwmu.RUnlock()
rs, err = s.exec(&execCtx{db, arg}) // R/O tctx
return rs, tnla, tnlb, err
@@ -1259,7 +1269,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
default: // case true:
switch s.(type) {
case beginTransactionStmt:
defer db.mu.Unlock()
defer db.muUnlock()
if pc == nil {
return nil, tnla, tnlb, errBeginTransNoCtx
@@ -1267,12 +1277,16 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
if pc != db.cc {
for db.rw {
db.mu.Unlock() // Transaction isolation
ch := make(chan struct{}, 1)
db.queue = append(db.queue, ch)
db.mu.Unlock()
<-ch
db.mu.Lock()
}
db.rw = true
db.rwmu.Lock()
}
if err = db.store.BeginTransaction(); err != nil {
@@ -1285,7 +1299,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
tnlb = db.tnl
return
case commitStmt:
defer db.mu.Unlock()
defer db.muUnlock()
if pc != db.cc {
return nil, tnla, tnlb, fmt.Errorf("invalid passed transaction context")
}
@@ -1303,7 +1317,7 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
db.rwmu.Unlock()
return
case rollbackStmt:
defer db.mu.Unlock()
defer db.muUnlock()
defer func() { pc.LastInsertID = db.root.lastInsertID }()
if pc != db.cc {
return nil, tnla, tnlb, fmt.Errorf("invalid passed transaction context")
@@ -1324,18 +1338,18 @@ func (db *DB) run1(pc *TCtx, s stmt, arg ...interface{}) (rs Recordset, tnla, tn
default:
if pc == nil {
if s.isUpdating() {
db.mu.Unlock()
db.muUnlock()
return nil, tnla, tnlb, fmt.Errorf("attempt to update the DB outside of a transaction")
}
db.mu.Unlock() // must Unlock before RLock
db.muUnlock() // must Unlock before RLock
db.rwmu.RLock()
defer db.rwmu.RUnlock()
rs, err = s.exec(&execCtx{db, arg})
return rs, tnla, tnlb, err
}
defer db.mu.Unlock()
defer db.muUnlock()
defer func() { pc.LastInsertID = db.root.lastInsertID }()
if pc != db.cc {
return nil, tnla, tnlb, fmt.Errorf("invalid passed transaction context")
@@ -1361,7 +1375,7 @@ func (db *DB) Flush() (err error) {
// Close will close the DB. Successful Close is idempotent.
func (db *DB) Close() error {
db.mu.Lock()
defer db.mu.Unlock()
defer db.muUnlock()
if db.store == nil {
return nil
}
@@ -1380,17 +1394,17 @@ func (db *DB) do(r recordset, f func(data []interface{}) (bool, error)) (err err
switch db.rw {
case false:
db.rwmu.RLock() // can safely grab before Unlock
db.mu.Unlock()
db.muUnlock()
defer db.rwmu.RUnlock()
default: // case true:
if r.tx == nil {
db.mu.Unlock() // must Unlock before RLock
db.muUnlock() // must Unlock before RLock
db.rwmu.RLock()
defer db.rwmu.RUnlock()
break
}
defer db.mu.Unlock()
defer db.muUnlock()
if r.tx != db.cc {
return fmt.Errorf("invalid passed transaction context")
}
@@ -1569,7 +1583,7 @@ func (db *DB) info() (r *DbInfo, err error) {
// to obtain the result.
func (db *DB) Info() (r *DbInfo, err error) {
db.mu.Lock()
defer db.mu.Unlock()
defer db.muUnlock()
return db.info()
}