summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-12-16 11:37:53 +0000
committerLibravatar GitHub <noreply@github.com>2024-12-16 11:37:53 +0000
commit9697df0955095cb9be7b5fa0c4408ae4523d8b08 (patch)
tree737d826b4ea8bc22c0645cbbea7ab143428e0bda /vendor/github.com/ncruces/go-sqlite3
parentbump gruf/go-ffmpreg to v0.6.3 (#3624) (diff)
downloadgotosocial-9697df0955095cb9be7b5fa0c4408ae4523d8b08.tar.xz
bump ncruces/go-sqlite3 to v0.21.1 (#3625)
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/conn.go46
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/driver/driver.go2
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/driver/whitespace.go61
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasmbin1401614 -> 1391469 bytes
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/go.work.sum1
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasmbin17538 -> 17389 bytes
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go32
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go48
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go96
9 files changed, 164 insertions, 122 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/conn.go b/vendor/github.com/ncruces/go-sqlite3/conn.go
index 5ae0eef7c..d1ce30556 100644
--- a/vendor/github.com/ncruces/go-sqlite3/conn.go
+++ b/vendor/github.com/ncruces/go-sqlite3/conn.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math"
+ "math/rand"
"net/url"
"strings"
"time"
@@ -24,7 +25,6 @@ type Conn struct {
interrupt context.Context
pending *Stmt
stmts []*Stmt
- timer *time.Timer
busy func(context.Context, int) bool
log func(xErrorCode, string)
collation func(*Conn, string)
@@ -36,7 +36,9 @@ type Conn struct {
rollback func()
arena arena
- handle uint32
+ busy1st time.Time
+ busylst time.Time
+ handle uint32
}
// Open calls [OpenFlags] with [OPEN_READWRITE], [OPEN_CREATE] and [OPEN_URI].
@@ -389,38 +391,20 @@ func (c *Conn) BusyTimeout(timeout time.Duration) error {
}
func timeoutCallback(ctx context.Context, mod api.Module, count, tmout int32) (retry uint32) {
+ // https://fractaledmind.github.io/2024/04/15/sqlite-on-rails-the-how-and-why-of-optimal-performance/
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.interrupt.Err() == nil {
- const delays = "\x01\x02\x05\x0a\x0f\x14\x19\x19\x19\x32\x32\x64"
- const totals = "\x00\x01\x03\x08\x12\x21\x35\x4e\x67\x80\xb2\xe4"
- const ndelay = int32(len(delays) - 1)
-
- var delay, prior int32
- if count <= ndelay {
- delay = int32(delays[count])
- prior = int32(totals[count])
- } else {
- delay = int32(delays[ndelay])
- prior = int32(totals[ndelay]) + delay*(count-ndelay)
+ switch {
+ case count == 0:
+ c.busy1st = time.Now()
+ case time.Since(c.busy1st) >= time.Duration(tmout)*time.Millisecond:
+ return 0
}
-
- if delay = min(delay, tmout-prior); delay > 0 {
- delay := time.Duration(delay) * time.Millisecond
- if c.interrupt.Done() == nil {
- time.Sleep(delay)
- return 1
- }
- if c.timer == nil {
- c.timer = time.NewTimer(delay)
- } else {
- c.timer.Reset(delay)
- }
- select {
- case <-c.interrupt.Done():
- c.timer.Stop()
- case <-c.timer.C:
- return 1
- }
+ if time.Since(c.busylst) < time.Millisecond {
+ const sleepIncrement = 2*1024*1024 - 1 // power of two, ~2ms
+ time.Sleep(time.Duration(rand.Int63() & sleepIncrement))
}
+ c.busylst = time.Now()
+ return 1
}
return 0
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
index 477e9a940..b9bb03bb7 100644
--- a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
+++ b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
@@ -379,7 +379,7 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e
if err != nil {
return nil, err
}
- if tail != "" {
+ if notWhitespace(tail) {
s.Close()
return nil, util.TailErr
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/driver/whitespace.go b/vendor/github.com/ncruces/go-sqlite3/driver/whitespace.go
new file mode 100644
index 000000000..8f45706f5
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/driver/whitespace.go
@@ -0,0 +1,61 @@
+package driver
+
+func notWhitespace(sql string) bool {
+ const (
+ code = iota
+ slash
+ minus
+ ccomment
+ sqlcomment
+ endcomment
+ )
+
+ state := code
+ for _, b := range ([]byte)(sql) {
+ if b == 0 {
+ break
+ }
+
+ switch state {
+ case code:
+ switch b {
+ case '/':
+ state = slash
+ case '-':
+ state = minus
+ case ' ', ';', '\t', '\n', '\v', '\f', '\r':
+ continue
+ default:
+ return true
+ }
+ case slash:
+ if b != '*' {
+ return true
+ }
+ state = ccomment
+ case minus:
+ if b != '-' {
+ return true
+ }
+ state = sqlcomment
+ case ccomment:
+ if b == '*' {
+ state = endcomment
+ }
+ case sqlcomment:
+ if b == '\n' {
+ state = code
+ }
+ case endcomment:
+ switch b {
+ case '/':
+ state = code
+ case '*':
+ state = endcomment
+ default:
+ state = ccomment
+ }
+ }
+ }
+ return state == slash || state == minus
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm
index bf119d41d..05a6065f4 100644
--- a/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm
+++ b/vendor/github.com/ncruces/go-sqlite3/embed/sqlite3.wasm
Binary files differ
diff --git a/vendor/github.com/ncruces/go-sqlite3/go.work.sum b/vendor/github.com/ncruces/go-sqlite3/go.work.sum
index f41ac5535..ded9bda72 100644
--- a/vendor/github.com/ncruces/go-sqlite3/go.work.sum
+++ b/vendor/github.com/ncruces/go-sqlite3/go.work.sum
@@ -1,3 +1,4 @@
+github.com/ncruces/go-sqlite3 v0.21.0/go.mod h1:zxMOaSG5kFYVFK4xQa0pdwIszqxqJ0W0BxBgwdrNjuA=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
diff --git a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm
index f0b3819c8..28eab8d29 100644
--- a/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm
+++ b/vendor/github.com/ncruces/go-sqlite3/util/sql3util/parse/sql3parse_table.wasm
Binary files differ
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
index 7d809b223..07de7c3d8 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
@@ -56,16 +56,12 @@ func osAllocate(file *os.File, size int64) error {
return file.Truncate(size)
}
-func osUnlock(file *os.File, start, len int64) _ErrorCode {
- err := unix.FcntlFlock(file.Fd(), _F_OFD_SETLK, &unix.Flock_t{
- Type: unix.F_UNLCK,
- Start: start,
- Len: len,
- })
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, def _ErrorCode) _ErrorCode {
@@ -88,10 +84,14 @@ func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, d
return osLockErrorCode(err, def)
}
-func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
-}
-
-func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
+func osUnlock(file *os.File, start, len int64) _ErrorCode {
+ err := unix.FcntlFlock(file.Fd(), _F_OFD_SETLK, &unix.Flock_t{
+ Type: unix.F_UNLCK,
+ Start: start,
+ Len: len,
+ })
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
index f5841fc20..6199c7b00 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
@@ -3,7 +3,6 @@
package vfs
import (
- "math/rand"
"os"
"time"
@@ -22,16 +21,12 @@ func osAllocate(file *os.File, size int64) error {
return unix.Fallocate(int(file.Fd()), 0, 0, size)
}
-func osUnlock(file *os.File, start, len int64) _ErrorCode {
- err := unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &unix.Flock_t{
- Type: unix.F_UNLCK,
- Start: start,
- Len: len,
- })
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
+ return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, def _ErrorCode) _ErrorCode {
@@ -42,31 +37,22 @@ func osLock(file *os.File, typ int16, start, len int64, timeout time.Duration, d
}
var err error
switch {
- case timeout == 0:
- err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
case timeout < 0:
err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLKW, &lock)
default:
- before := time.Now()
- for {
- err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
- if errno, _ := err.(unix.Errno); errno != unix.EAGAIN {
- break
- }
- if time.Since(before) > timeout {
- break
- }
- const sleepIncrement = 1024*1024 - 1 // power of two, ~1ms
- time.Sleep(time.Duration(rand.Int63() & sleepIncrement))
- }
+ err = unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &lock)
}
return osLockErrorCode(err, def)
}
-func osReadLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_RDLCK, start, len, timeout, _IOERR_RDLOCK)
-}
-
-func osWriteLock(file *os.File, start, len int64, timeout time.Duration) _ErrorCode {
- return osLock(file, unix.F_WRLCK, start, len, timeout, _IOERR_LOCK)
+func osUnlock(file *os.File, start, len int64) _ErrorCode {
+ err := unix.FcntlFlock(file.Fd(), unix.F_OFD_SETLK, &unix.Flock_t{
+ Type: unix.F_UNLCK,
+ Start: start,
+ Len: len,
+ })
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
index 2872201b0..0398f4760 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
@@ -45,6 +45,7 @@ func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
osUnlock(file, _SHARED_FIRST, _SHARED_SIZE)
// Acquire the EXCLUSIVE lock.
+ // Can't wait here, because the file is not OVERLAPPED.
rc := osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)
if rc != _OK {
@@ -106,64 +107,73 @@ func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
return false, rc
}
-func osUnlock(file *os.File, start, len uint32) _ErrorCode {
- err := windows.UnlockFileEx(windows.Handle(file.Fd()),
- 0, len, 0, &windows.Overlapped{Offset: start})
- if err == windows.ERROR_NOT_LOCKED {
- return _OK
- }
- if err != nil {
- return _IOERR_UNLOCK
- }
- return _OK
+func osReadLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
+ return osLock(file, 0, start, len, timeout, _IOERR_RDLOCK)
+}
+
+func osWriteLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
+ return osLock(file, windows.LOCKFILE_EXCLUSIVE_LOCK, start, len, timeout, _IOERR_LOCK)
}
func osLock(file *os.File, flags, start, len uint32, timeout time.Duration, def _ErrorCode) _ErrorCode {
var err error
switch {
case timeout == 0:
- err = osLockEx(file, flags|windows.LOCKFILE_FAIL_IMMEDIATELY, start, len, 0)
+ err = osLockEx(file, flags|windows.LOCKFILE_FAIL_IMMEDIATELY, start, len)
case timeout < 0:
- err = osLockEx(file, flags, start, len, 0)
+ err = osLockEx(file, flags, start, len)
default:
- var event windows.Handle
- event, err = windows.CreateEvent(nil, 1, 0, nil)
- if err != nil {
- break
- }
- defer windows.CloseHandle(event)
-
- err = osLockEx(file, flags, start, len, event)
- if err == windows.ERROR_IO_PENDING {
- rc, serr := windows.WaitForSingleObject(event, uint32(timeout/time.Millisecond))
- if rc == windows.WAIT_OBJECT_0 {
- return _OK
- }
- if serr != nil {
- err = serr
- } else {
- err = windows.Errno(rc)
- }
- windows.CancelIo(windows.Handle(file.Fd()))
- }
+ err = osLockExTimeout(file, flags, start, len, timeout)
}
return osLockErrorCode(err, def)
}
-func osLockEx(file *os.File, flags, start, len uint32, event windows.Handle) error {
- return windows.LockFileEx(windows.Handle(file.Fd()), flags,
- 0, len, 0, &windows.Overlapped{
- Offset: start,
- HEvent: event,
- })
+func osUnlock(file *os.File, start, len uint32) _ErrorCode {
+ err := windows.UnlockFileEx(windows.Handle(file.Fd()),
+ 0, len, 0, &windows.Overlapped{Offset: start})
+ if err == windows.ERROR_NOT_LOCKED {
+ return _OK
+ }
+ if err != nil {
+ return _IOERR_UNLOCK
+ }
+ return _OK
}
-func osReadLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
- return osLock(file, 0, start, len, timeout, _IOERR_RDLOCK)
+func osLockEx(file *os.File, flags, start, len uint32) error {
+ return windows.LockFileEx(windows.Handle(file.Fd()), flags,
+ 0, len, 0, &windows.Overlapped{Offset: start})
}
-func osWriteLock(file *os.File, start, len uint32, timeout time.Duration) _ErrorCode {
- return osLock(file, windows.LOCKFILE_EXCLUSIVE_LOCK, start, len, timeout, _IOERR_LOCK)
+func osLockExTimeout(file *os.File, flags, start, len uint32, timeout time.Duration) error {
+ event, err := windows.CreateEvent(nil, 1, 0, nil)
+ if err != nil {
+ return err
+ }
+ defer windows.CloseHandle(event)
+
+ fd := windows.Handle(file.Fd())
+ overlapped := &windows.Overlapped{
+ Offset: start,
+ HEvent: event,
+ }
+
+ err = windows.LockFileEx(fd, flags, 0, len, 0, overlapped)
+ if err != windows.ERROR_IO_PENDING {
+ return err
+ }
+
+ ms := (timeout + time.Millisecond - 1) / time.Millisecond
+ rc, err := windows.WaitForSingleObject(event, uint32(ms))
+ if rc == windows.WAIT_OBJECT_0 {
+ return nil
+ }
+ defer windows.CancelIoEx(fd, overlapped)
+
+ if err != nil {
+ return err
+ }
+ return windows.Errno(rc)
}
func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
@@ -175,8 +185,8 @@ func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
switch errno {
case
windows.ERROR_LOCK_VIOLATION,
- windows.ERROR_IO_PENDING,
windows.ERROR_OPERATION_ABORTED,
+ windows.ERROR_IO_PENDING,
windows.WAIT_TIMEOUT:
return _BUSY
}