summaryrefslogtreecommitdiff
path: root/vendor/github.com
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/conn.go27
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/context.go16
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/driver/driver.go107
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/internal/util/json.go2
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/internal/util/json_v2.go52
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/json.go83
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/json_v2.go113
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/sqlite.go8
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/stmt.go40
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/time.go2
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/value.go23
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/const.go4
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/file.go68
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/lock.go2
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/memdb/README.md5
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/memdb/api.go19
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go22
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go2
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sync.go2
19 files changed, 414 insertions, 183 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/conn.go b/vendor/github.com/ncruces/go-sqlite3/conn.go
index 7e88d8c85..a7eca1652 100644
--- a/vendor/github.com/ncruces/go-sqlite3/conn.go
+++ b/vendor/github.com/ncruces/go-sqlite3/conn.go
@@ -444,20 +444,27 @@ func (c *Conn) Status(op DBStatus, reset bool) (current, highwater int, err erro
// https://sqlite.org/c3ref/table_column_metadata.html
func (c *Conn) TableColumnMetadata(schema, table, column string) (declType, collSeq string, notNull, primaryKey, autoInc bool, err error) {
defer c.arena.mark()()
-
- var schemaPtr, columnPtr ptr_t
- declTypePtr := c.arena.new(ptrlen)
- collSeqPtr := c.arena.new(ptrlen)
- notNullPtr := c.arena.new(ptrlen)
- autoIncPtr := c.arena.new(ptrlen)
- primaryKeyPtr := c.arena.new(ptrlen)
+ var (
+ declTypePtr ptr_t
+ collSeqPtr ptr_t
+ notNullPtr ptr_t
+ primaryKeyPtr ptr_t
+ autoIncPtr ptr_t
+ columnPtr ptr_t
+ schemaPtr ptr_t
+ )
+ if column != "" {
+ declTypePtr = c.arena.new(ptrlen)
+ collSeqPtr = c.arena.new(ptrlen)
+ notNullPtr = c.arena.new(ptrlen)
+ primaryKeyPtr = c.arena.new(ptrlen)
+ autoIncPtr = c.arena.new(ptrlen)
+ columnPtr = c.arena.string(column)
+ }
if schema != "" {
schemaPtr = c.arena.string(schema)
}
tablePtr := c.arena.string(table)
- if column != "" {
- columnPtr = c.arena.string(column)
- }
rc := res_t(c.call("sqlite3_table_column_metadata", stk_t(c.handle),
stk_t(schemaPtr), stk_t(tablePtr), stk_t(columnPtr),
diff --git a/vendor/github.com/ncruces/go-sqlite3/context.go b/vendor/github.com/ncruces/go-sqlite3/context.go
index 154c228cf..269bf52f9 100644
--- a/vendor/github.com/ncruces/go-sqlite3/context.go
+++ b/vendor/github.com/ncruces/go-sqlite3/context.go
@@ -1,7 +1,6 @@
package sqlite3
import (
- "encoding/json"
"errors"
"math"
"time"
@@ -173,21 +172,6 @@ func (ctx Context) ResultPointer(ptr any) {
stk_t(ctx.handle), stk_t(valPtr))
}
-// ResultJSON sets the result of the function to the JSON encoding of value.
-//
-// https://sqlite.org/c3ref/result_blob.html
-func (ctx Context) ResultJSON(value any) {
- err := json.NewEncoder(callbackWriter(func(p []byte) (int, error) {
- ctx.ResultRawText(p[:len(p)-1]) // remove the newline
- return 0, nil
- })).Encode(value)
-
- if err != nil {
- ctx.ResultError(err)
- return // notest
- }
-}
-
// ResultValue sets the result of the function to a copy of [Value].
//
// https://sqlite.org/c3ref/result_blob.html
diff --git a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
index 27496f6cb..5d2847369 100644
--- a/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
+++ b/vendor/github.com/ncruces/go-sqlite3/driver/driver.go
@@ -607,14 +607,24 @@ func (r resultRowsAffected) RowsAffected() (int64, error) {
type scantype byte
const (
- _ANY scantype = iota
- _INT scantype = scantype(sqlite3.INTEGER)
- _REAL scantype = scantype(sqlite3.FLOAT)
- _TEXT scantype = scantype(sqlite3.TEXT)
- _BLOB scantype = scantype(sqlite3.BLOB)
- _NULL scantype = scantype(sqlite3.NULL)
- _BOOL scantype = iota
+ _ANY scantype = iota
+ _INT
+ _REAL
+ _TEXT
+ _BLOB
+ _NULL
+ _BOOL
_TIME
+ _NOT_NULL
+)
+
+var (
+ _ [0]struct{} = [scantype(sqlite3.INTEGER) - _INT]struct{}{}
+ _ [0]struct{} = [scantype(sqlite3.FLOAT) - _REAL]struct{}{}
+ _ [0]struct{} = [scantype(sqlite3.TEXT) - _TEXT]struct{}{}
+ _ [0]struct{} = [scantype(sqlite3.BLOB) - _BLOB]struct{}{}
+ _ [0]struct{} = [scantype(sqlite3.NULL) - _NULL]struct{}{}
+ _ [0]struct{} = [_NOT_NULL & (_NOT_NULL - 1)]struct{}{}
)
func scanFromDecl(decl string) scantype {
@@ -644,8 +654,8 @@ type rows struct {
*stmt
names []string
types []string
- nulls []bool
scans []scantype
+ dest []driver.Value
}
var (
@@ -675,34 +685,36 @@ func (r *rows) Columns() []string {
func (r *rows) scanType(index int) scantype {
if r.scans == nil {
- count := r.Stmt.ColumnCount()
+ count := len(r.names)
scans := make([]scantype, count)
for i := range scans {
scans[i] = scanFromDecl(strings.ToUpper(r.Stmt.ColumnDeclType(i)))
}
r.scans = scans
}
- return r.scans[index]
+ return r.scans[index] &^ _NOT_NULL
}
func (r *rows) loadColumnMetadata() {
- if r.nulls == nil {
+ if r.types == nil {
c := r.Stmt.Conn()
- count := r.Stmt.ColumnCount()
- nulls := make([]bool, count)
+ count := len(r.names)
types := make([]string, count)
scans := make([]scantype, count)
- for i := range nulls {
+ for i := range types {
+ var notnull bool
if col := r.Stmt.ColumnOriginName(i); col != "" {
- types[i], _, nulls[i], _, _, _ = c.TableColumnMetadata(
+ types[i], _, notnull, _, _, _ = c.TableColumnMetadata(
r.Stmt.ColumnDatabaseName(i),
r.Stmt.ColumnTableName(i),
col)
types[i] = strings.ToUpper(types[i])
scans[i] = scanFromDecl(types[i])
+ if notnull {
+ scans[i] |= _NOT_NULL
+ }
}
}
- r.nulls = nulls
r.types = types
r.scans = scans
}
@@ -721,15 +733,13 @@ func (r *rows) ColumnTypeDatabaseTypeName(index int) string {
func (r *rows) ColumnTypeNullable(index int) (nullable, ok bool) {
r.loadColumnMetadata()
- if r.nulls[index] {
- return false, true
- }
- return true, false
+ nullable = r.scans[index]&^_NOT_NULL == 0
+ return nullable, !nullable
}
func (r *rows) ColumnTypeScanType(index int) (typ reflect.Type) {
r.loadColumnMetadata()
- scan := r.scans[index]
+ scan := r.scans[index] &^ _NOT_NULL
if r.Stmt.Busy() {
// SQLite is dynamically typed and we now have a row.
@@ -772,6 +782,7 @@ func (r *rows) ColumnTypeScanType(index int) (typ reflect.Type) {
}
func (r *rows) Next(dest []driver.Value) error {
+ r.dest = nil
c := r.Stmt.Conn()
if old := c.SetInterrupt(r.ctx); old != r.ctx {
defer c.SetInterrupt(old)
@@ -790,18 +801,7 @@ func (r *rows) Next(dest []driver.Value) error {
}
for i := range dest {
scan := r.scanType(i)
- switch v := dest[i].(type) {
- case int64:
- if scan == _BOOL {
- switch v {
- case 1:
- dest[i] = true
- case 0:
- dest[i] = false
- }
- continue
- }
- case []byte:
+ if v, ok := dest[i].([]byte); ok {
if len(v) == cap(v) { // a BLOB
continue
}
@@ -816,38 +816,49 @@ func (r *rows) Next(dest []driver.Value) error {
}
}
dest[i] = string(v)
- case float64:
- break
- default:
- continue
}
- if scan == _TIME {
+ switch scan {
+ case _TIME:
t, err := r.tmRead.Decode(dest[i])
if err == nil {
dest[i] = t
- continue
+ }
+ case _BOOL:
+ switch dest[i] {
+ case int64(0):
+ dest[i] = false
+ case int64(1):
+ dest[i] = true
}
}
}
+ r.dest = dest
return nil
}
-func (r *rows) ScanColumn(dest any, index int) error {
+func (r *rows) ScanColumn(dest any, index int) (err error) {
// notest // Go 1.26
- var ptr *time.Time
+ var tm *time.Time
+ var ok *bool
switch d := dest.(type) {
case *time.Time:
- ptr = d
+ tm = d
case *sql.NullTime:
- ptr = &d.Time
+ tm = &d.Time
+ ok = &d.Valid
case *sql.Null[time.Time]:
- ptr = &d.V
+ tm = &d.V
+ ok = &d.Valid
default:
return driver.ErrSkip
}
- if t := r.Stmt.ColumnTime(index, r.tmRead); !t.IsZero() {
- *ptr = t
- return nil
+ value := r.dest[index]
+ *tm, err = r.tmRead.Decode(value)
+ if ok != nil {
+ *ok = err == nil
+ if value == nil {
+ return nil
+ }
}
- return driver.ErrSkip
+ return err
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/json.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/json.go
index 846237405..f582734cf 100644
--- a/vendor/github.com/ncruces/go-sqlite3/internal/util/json.go
+++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/json.go
@@ -1,3 +1,5 @@
+//go:build !goexperiment.jsonv2
+
package util
import (
diff --git a/vendor/github.com/ncruces/go-sqlite3/internal/util/json_v2.go b/vendor/github.com/ncruces/go-sqlite3/internal/util/json_v2.go
new file mode 100644
index 000000000..2fb052233
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/internal/util/json_v2.go
@@ -0,0 +1,52 @@
+//go:build goexperiment.jsonv2
+
+package util
+
+import (
+ "encoding/json/v2"
+ "math"
+ "strconv"
+ "time"
+ "unsafe"
+)
+
+type JSON struct{ Value any }
+
+func (j JSON) Scan(value any) error {
+ var buf []byte
+
+ switch v := value.(type) {
+ case []byte:
+ buf = v
+ case string:
+ buf = unsafe.Slice(unsafe.StringData(v), len(v))
+ case int64:
+ buf = strconv.AppendInt(nil, v, 10)
+ case float64:
+ buf = AppendNumber(nil, v)
+ case time.Time:
+ buf = append(buf, '"')
+ buf = v.AppendFormat(buf, time.RFC3339Nano)
+ buf = append(buf, '"')
+ case nil:
+ buf = []byte("null")
+ default:
+ panic(AssertErr())
+ }
+
+ return json.Unmarshal(buf, j.Value)
+}
+
+func AppendNumber(dst []byte, f float64) []byte {
+ switch {
+ case math.IsNaN(f):
+ dst = append(dst, "null"...)
+ case math.IsInf(f, 1):
+ dst = append(dst, "9.0e999"...)
+ case math.IsInf(f, -1):
+ dst = append(dst, "-9.0e999"...)
+ default:
+ return strconv.AppendFloat(dst, f, 'g', -1, 64)
+ }
+ return dst
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/json.go b/vendor/github.com/ncruces/go-sqlite3/json.go
index 2b762c092..78195f2e3 100644
--- a/vendor/github.com/ncruces/go-sqlite3/json.go
+++ b/vendor/github.com/ncruces/go-sqlite3/json.go
@@ -1,6 +1,13 @@
+//go:build !goexperiment.jsonv2
+
package sqlite3
-import "github.com/ncruces/go-sqlite3/internal/util"
+import (
+ "encoding/json"
+ "strconv"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
// JSON returns a value that can be used as an argument to
// [database/sql.DB.Exec], [database/sql.Row.Scan] and similar methods to
@@ -10,3 +17,77 @@ import "github.com/ncruces/go-sqlite3/internal/util"
func JSON(value any) any {
return util.JSON{Value: value}
}
+
+// ResultJSON sets the result of the function to the JSON encoding of value.
+//
+// https://sqlite.org/c3ref/result_blob.html
+func (ctx Context) ResultJSON(value any) {
+ err := json.NewEncoder(callbackWriter(func(p []byte) (int, error) {
+ ctx.ResultRawText(p[:len(p)-1]) // remove the newline
+ return 0, nil
+ })).Encode(value)
+
+ if err != nil {
+ ctx.ResultError(err)
+ return // notest
+ }
+}
+
+// BindJSON binds the JSON encoding of value to the prepared statement.
+// The leftmost SQL parameter has an index of 1.
+//
+// https://sqlite.org/c3ref/bind_blob.html
+func (s *Stmt) BindJSON(param int, value any) error {
+ return json.NewEncoder(callbackWriter(func(p []byte) (int, error) {
+ return 0, s.BindRawText(param, p[:len(p)-1]) // remove the newline
+ })).Encode(value)
+}
+
+// ColumnJSON parses the JSON-encoded value of the result column
+// and stores it in the value pointed to by ptr.
+// The leftmost column of the result set has the index 0.
+//
+// https://sqlite.org/c3ref/column_blob.html
+func (s *Stmt) ColumnJSON(col int, ptr any) error {
+ var data []byte
+ switch s.ColumnType(col) {
+ case NULL:
+ data = []byte("null")
+ case TEXT:
+ data = s.ColumnRawText(col)
+ case BLOB:
+ data = s.ColumnRawBlob(col)
+ case INTEGER:
+ data = strconv.AppendInt(nil, s.ColumnInt64(col), 10)
+ case FLOAT:
+ data = util.AppendNumber(nil, s.ColumnFloat(col))
+ default:
+ panic(util.AssertErr())
+ }
+ return json.Unmarshal(data, ptr)
+}
+
+// JSON parses a JSON-encoded value
+// and stores the result in the value pointed to by ptr.
+func (v Value) JSON(ptr any) error {
+ var data []byte
+ switch v.Type() {
+ case NULL:
+ data = []byte("null")
+ case TEXT:
+ data = v.RawText()
+ case BLOB:
+ data = v.RawBlob()
+ case INTEGER:
+ data = strconv.AppendInt(nil, v.Int64(), 10)
+ case FLOAT:
+ data = util.AppendNumber(nil, v.Float())
+ default:
+ panic(util.AssertErr())
+ }
+ return json.Unmarshal(data, ptr)
+}
+
+type callbackWriter func(p []byte) (int, error)
+
+func (fn callbackWriter) Write(p []byte) (int, error) { return fn(p) }
diff --git a/vendor/github.com/ncruces/go-sqlite3/json_v2.go b/vendor/github.com/ncruces/go-sqlite3/json_v2.go
new file mode 100644
index 000000000..4b74bc7a4
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/json_v2.go
@@ -0,0 +1,113 @@
+//go:build goexperiment.jsonv2
+
+package sqlite3
+
+import (
+ "encoding/json/v2"
+ "strconv"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
+
+// JSON returns a value that can be used as an argument to
+// [database/sql.DB.Exec], [database/sql.Row.Scan] and similar methods to
+// store value as JSON, or decode JSON into value.
+// JSON should NOT be used with [Stmt.BindJSON], [Stmt.ColumnJSON],
+// [Value.JSON], or [Context.ResultJSON].
+func JSON(value any) any {
+ return util.JSON{Value: value}
+}
+
+// ResultJSON sets the result of the function to the JSON encoding of value.
+//
+// https://sqlite.org/c3ref/result_blob.html
+func (ctx Context) ResultJSON(value any) {
+ w := bytesWriter{sqlite: ctx.c.sqlite}
+ if err := json.MarshalWrite(&w, value); err != nil {
+ ctx.c.free(w.ptr)
+ ctx.ResultError(err)
+ return // notest
+ }
+ ctx.c.call("sqlite3_result_text_go",
+ stk_t(ctx.handle), stk_t(w.ptr), stk_t(len(w.buf)))
+}
+
+// BindJSON binds the JSON encoding of value to the prepared statement.
+// The leftmost SQL parameter has an index of 1.
+//
+// https://sqlite.org/c3ref/bind_blob.html
+func (s *Stmt) BindJSON(param int, value any) error {
+ w := bytesWriter{sqlite: s.c.sqlite}
+ if err := json.MarshalWrite(&w, value); err != nil {
+ s.c.free(w.ptr)
+ return err
+ }
+ rc := res_t(s.c.call("sqlite3_bind_text_go",
+ stk_t(s.handle), stk_t(param),
+ stk_t(w.ptr), stk_t(len(w.buf))))
+ return s.c.error(rc)
+}
+
+// ColumnJSON parses the JSON-encoded value of the result column
+// and stores it in the value pointed to by ptr.
+// The leftmost column of the result set has the index 0.
+//
+// https://sqlite.org/c3ref/column_blob.html
+func (s *Stmt) ColumnJSON(col int, ptr any) error {
+ var data []byte
+ switch s.ColumnType(col) {
+ case NULL:
+ data = []byte("null")
+ case TEXT:
+ data = s.ColumnRawText(col)
+ case BLOB:
+ data = s.ColumnRawBlob(col)
+ case INTEGER:
+ data = strconv.AppendInt(nil, s.ColumnInt64(col), 10)
+ case FLOAT:
+ data = util.AppendNumber(nil, s.ColumnFloat(col))
+ default:
+ panic(util.AssertErr())
+ }
+ return json.Unmarshal(data, ptr)
+}
+
+// JSON parses a JSON-encoded value
+// and stores the result in the value pointed to by ptr.
+func (v Value) JSON(ptr any) error {
+ var data []byte
+ switch v.Type() {
+ case NULL:
+ data = []byte("null")
+ case TEXT:
+ data = v.RawText()
+ case BLOB:
+ data = v.RawBlob()
+ case INTEGER:
+ data = strconv.AppendInt(nil, v.Int64(), 10)
+ case FLOAT:
+ data = util.AppendNumber(nil, v.Float())
+ default:
+ panic(util.AssertErr())
+ }
+ return json.Unmarshal(data, ptr)
+}
+
+type bytesWriter struct {
+ *sqlite
+ buf []byte
+ ptr ptr_t
+}
+
+func (b *bytesWriter) Write(p []byte) (n int, err error) {
+ if len(p) > cap(b.buf)-len(b.buf) {
+ want := int64(len(b.buf)) + int64(len(p))
+ grow := int64(cap(b.buf))
+ grow += grow >> 1
+ want = max(want, grow)
+ b.ptr = b.realloc(b.ptr, want)
+ b.buf = util.View(b.mod, b.ptr, want)[:len(b.buf)]
+ }
+ b.buf = append(b.buf, p...)
+ return len(p), nil
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/sqlite.go b/vendor/github.com/ncruces/go-sqlite3/sqlite.go
index c05a86fde..fb64ac5c0 100644
--- a/vendor/github.com/ncruces/go-sqlite3/sqlite.go
+++ b/vendor/github.com/ncruces/go-sqlite3/sqlite.go
@@ -5,6 +5,7 @@ import (
"context"
"math/bits"
"os"
+ "strings"
"sync"
"unsafe"
@@ -128,11 +129,10 @@ func (sqlt *sqlite) error(rc res_t, handle ptr_t, sql ...string) error {
var msg, query string
if ptr := ptr_t(sqlt.call("sqlite3_errmsg", stk_t(handle))); ptr != 0 {
msg = util.ReadString(sqlt.mod, ptr, _MAX_LENGTH)
- switch {
- case msg == "not an error":
- msg = ""
- case msg == util.ErrorCodeString(uint32(rc))[len("sqlite3: "):]:
+ if msg == "not an error" {
msg = ""
+ } else {
+ msg = strings.TrimPrefix(msg, util.ErrorCodeString(uint32(rc))[len("sqlite3: "):])
}
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/stmt.go b/vendor/github.com/ncruces/go-sqlite3/stmt.go
index 706182f9f..e2523b6cb 100644
--- a/vendor/github.com/ncruces/go-sqlite3/stmt.go
+++ b/vendor/github.com/ncruces/go-sqlite3/stmt.go
@@ -1,9 +1,7 @@
package sqlite3
import (
- "encoding/json"
"math"
- "strconv"
"time"
"github.com/ncruces/go-sqlite3/internal/util"
@@ -362,16 +360,6 @@ func (s *Stmt) BindPointer(param int, ptr any) error {
return s.c.error(rc)
}
-// BindJSON binds the JSON encoding of value to the prepared statement.
-// The leftmost SQL parameter has an index of 1.
-//
-// https://sqlite.org/c3ref/bind_blob.html
-func (s *Stmt) BindJSON(param int, value any) error {
- return json.NewEncoder(callbackWriter(func(p []byte) (int, error) {
- return 0, s.BindRawText(param, p[:len(p)-1]) // remove the newline
- })).Encode(value)
-}
-
// BindValue binds a copy of value to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
@@ -598,30 +586,6 @@ func (s *Stmt) columnRawBytes(col int, ptr ptr_t, nul int32) []byte {
return util.View(s.c.mod, ptr, int64(n+nul))[:n]
}
-// ColumnJSON parses the JSON-encoded value of the result column
-// and stores it in the value pointed to by ptr.
-// The leftmost column of the result set has the index 0.
-//
-// https://sqlite.org/c3ref/column_blob.html
-func (s *Stmt) ColumnJSON(col int, ptr any) error {
- var data []byte
- switch s.ColumnType(col) {
- case NULL:
- data = []byte("null")
- case TEXT:
- data = s.ColumnRawText(col)
- case BLOB:
- data = s.ColumnRawBlob(col)
- case INTEGER:
- data = strconv.AppendInt(nil, s.ColumnInt64(col), 10)
- case FLOAT:
- data = util.AppendNumber(nil, s.ColumnFloat(col))
- default:
- panic(util.AssertErr())
- }
- return json.Unmarshal(data, ptr)
-}
-
// ColumnValue returns the unprotected value of the result column.
// The leftmost column of the result set has the index 0.
//
@@ -748,7 +712,3 @@ func (s *Stmt) columns(count int64) ([]byte, ptr_t, error) {
return util.View(s.c.mod, typePtr, count), dataPtr, nil
}
-
-type callbackWriter func(p []byte) (int, error)
-
-func (fn callbackWriter) Write(p []byte) (int, error) { return fn(p) }
diff --git a/vendor/github.com/ncruces/go-sqlite3/time.go b/vendor/github.com/ncruces/go-sqlite3/time.go
index d9c516c81..19bcd2b0b 100644
--- a/vendor/github.com/ncruces/go-sqlite3/time.go
+++ b/vendor/github.com/ncruces/go-sqlite3/time.go
@@ -94,7 +94,7 @@ func (f TimeFormat) Encode(t time.Time) any {
case TimeFormatUnix:
return t.Unix()
case TimeFormatUnixFrac:
- return float64(t.Unix()) + float64(t.Nanosecond())*1e-9
+ return math.FMA(1e-9, float64(t.Nanosecond()), float64(t.Unix()))
case TimeFormatUnixMilli:
return t.UnixMilli()
case TimeFormatUnixMicro:
diff --git a/vendor/github.com/ncruces/go-sqlite3/value.go b/vendor/github.com/ncruces/go-sqlite3/value.go
index 6806e9a79..994743f82 100644
--- a/vendor/github.com/ncruces/go-sqlite3/value.go
+++ b/vendor/github.com/ncruces/go-sqlite3/value.go
@@ -1,9 +1,7 @@
package sqlite3
import (
- "encoding/json"
"math"
- "strconv"
"time"
"github.com/ncruces/go-sqlite3/internal/util"
@@ -162,27 +160,6 @@ func (v Value) Pointer() any {
return util.GetHandle(v.c.ctx, ptr)
}
-// JSON parses a JSON-encoded value
-// and stores the result in the value pointed to by ptr.
-func (v Value) JSON(ptr any) error {
- var data []byte
- switch v.Type() {
- case NULL:
- data = []byte("null")
- case TEXT:
- data = v.RawText()
- case BLOB:
- data = v.RawBlob()
- case INTEGER:
- data = strconv.AppendInt(nil, v.Int64(), 10)
- case FLOAT:
- data = util.AppendNumber(nil, v.Float())
- default:
- panic(util.AssertErr())
- }
- return json.Unmarshal(data, ptr)
-}
-
// NoChange returns true if and only if the value is unchanged
// in a virtual table update operatiom.
//
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/const.go b/vendor/github.com/ncruces/go-sqlite3/vfs/const.go
index 11afb1254..9ed67e385 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/const.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/const.go
@@ -94,6 +94,10 @@ const (
OPEN_PRIVATECACHE OpenFlag = 0x00040000 /* Ok for sqlite3_open_v2() */
OPEN_WAL OpenFlag = 0x00080000 /* VFS only */
OPEN_NOFOLLOW OpenFlag = 0x01000000 /* Ok for sqlite3_open_v2() */
+ _FLAG_ATOMIC OpenFlag = 0x10000000
+ _FLAG_KEEP_WAL OpenFlag = 0x20000000
+ _FLAG_PSOW OpenFlag = 0x40000000
+ _FLAG_SYNC_DIR OpenFlag = 0x80000000
)
// AccessFlag is a flag for the [VFS] Access method.
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go
index 06906c961..bdebdf6aa 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/file.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/file.go
@@ -51,7 +51,7 @@ func (vfsOS) Delete(path string, syncDir bool) error {
return _OK
}
defer f.Close()
- err = osSync(f, false, false)
+ err = osSync(f, 0, SYNC_FULL)
if err != nil {
return _IOERR_DIR_FSYNC
}
@@ -131,27 +131,24 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
}
file := vfsFile{
- File: f,
- psow: true,
- atomic: osBatchAtomic(f),
- readOnly: flags&OPEN_READONLY != 0,
- syncDir: isUnix && isCreate && isJournl,
- delete: !isUnix && flags&OPEN_DELETEONCLOSE != 0,
- shm: NewSharedMemory(name.String()+"-shm", flags),
+ File: f,
+ flags: flags | _FLAG_PSOW,
+ shm: NewSharedMemory(name.String()+"-shm", flags),
+ }
+ if osBatchAtomic(f) {
+ file.flags |= _FLAG_ATOMIC
+ }
+ if isUnix && isCreate && isJournl {
+ file.flags |= _FLAG_SYNC_DIR
}
return &file, flags, nil
}
type vfsFile struct {
*os.File
- shm SharedMemory
- lock LockLevel
- readOnly bool
- keepWAL bool
- syncDir bool
- atomic bool
- delete bool
- psow bool
+ shm SharedMemory
+ lock LockLevel
+ flags OpenFlag
}
var (
@@ -164,7 +161,7 @@ var (
)
func (f *vfsFile) Close() error {
- if f.delete {
+ if !isUnix && f.flags&OPEN_DELETEONCLOSE != 0 {
defer os.Remove(f.Name())
}
if f.shm != nil {
@@ -183,21 +180,18 @@ func (f *vfsFile) WriteAt(p []byte, off int64) (n int, err error) {
}
func (f *vfsFile) Sync(flags SyncFlag) error {
- dataonly := (flags & SYNC_DATAONLY) != 0
- fullsync := (flags & 0x0f) == SYNC_FULL
-
- err := osSync(f.File, fullsync, dataonly)
+ err := osSync(f.File, f.flags, flags)
if err != nil {
return err
}
- if isUnix && f.syncDir {
- f.syncDir = false
+ if isUnix && f.flags&_FLAG_SYNC_DIR != 0 {
+ f.flags ^= _FLAG_SYNC_DIR
d, err := os.Open(filepath.Dir(f.File.Name()))
if err != nil {
return nil
}
defer d.Close()
- err = osSync(d, false, false)
+ err = osSync(f.File, f.flags, flags)
if err != nil {
return _IOERR_DIR_FSYNC
}
@@ -215,10 +209,10 @@ func (f *vfsFile) SectorSize() int {
func (f *vfsFile) DeviceCharacteristics() DeviceCharacteristic {
ret := IOCAP_SUBPAGE_READ
- if f.atomic {
+ if f.flags&_FLAG_ATOMIC != 0 {
ret |= IOCAP_BATCH_ATOMIC
}
- if f.psow {
+ if f.flags&_FLAG_PSOW != 0 {
ret |= IOCAP_POWERSAFE_OVERWRITE
}
if runtime.GOOS == "windows" {
@@ -249,8 +243,20 @@ func (f *vfsFile) HasMoved() (bool, error) {
return !os.SameFile(fi, pi), nil
}
-func (f *vfsFile) LockState() LockLevel { return f.lock }
-func (f *vfsFile) PowersafeOverwrite() bool { return f.psow }
-func (f *vfsFile) PersistWAL() bool { return f.keepWAL }
-func (f *vfsFile) SetPowersafeOverwrite(psow bool) { f.psow = psow }
-func (f *vfsFile) SetPersistWAL(keepWAL bool) { f.keepWAL = keepWAL }
+func (f *vfsFile) LockState() LockLevel { return f.lock }
+func (f *vfsFile) PowersafeOverwrite() bool { return f.flags&_FLAG_PSOW != 0 }
+func (f *vfsFile) PersistWAL() bool { return f.flags&_FLAG_KEEP_WAL != 0 }
+
+func (f *vfsFile) SetPowersafeOverwrite(psow bool) {
+ f.flags &^= _FLAG_PSOW
+ if psow {
+ f.flags |= _FLAG_PSOW
+ }
+}
+
+func (f *vfsFile) SetPersistWAL(keepWAL bool) {
+ f.flags &^= _FLAG_KEEP_WAL
+ if keepWAL {
+ f.flags |= _FLAG_KEEP_WAL
+ }
+}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/lock.go b/vendor/github.com/ncruces/go-sqlite3/vfs/lock.go
index b28d83230..253057aea 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/lock.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/lock.go
@@ -41,7 +41,7 @@ func (f *vfsFile) Lock(lock LockLevel) error {
}
// Do not allow any kind of write-lock on a read-only database.
- if f.readOnly && lock >= LOCK_RESERVED {
+ if lock >= LOCK_RESERVED && f.flags&OPEN_READONLY != 0 {
return _IOERR_LOCK
}
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/README.md b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/README.md
index 2e2611bf8..e37db1be6 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/README.md
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/README.md
@@ -6,4 +6,7 @@ SQLite VFS in pure Go.
It has some benefits over the C version:
- the memory backing the database needs not be contiguous,
- the database can grow/shrink incrementally without copying,
-- reader-writer concurrency is slightly improved. \ No newline at end of file
+- reader-writer concurrency is slightly improved.
+
+[`memdb.TestDB`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/memdb#TestDB)
+is the preferred way to setup an in-memory database for testing. \ No newline at end of file
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/api.go b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/api.go
index eb12eba09..a12819855 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/api.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/memdb/api.go
@@ -10,6 +10,7 @@
package memdb
import (
+ "crypto/rand"
"fmt"
"net/url"
"sync"
@@ -74,11 +75,27 @@ func Delete(name string) {
// TestDB creates an empty shared memory database for the test to use.
// The database is automatically deleted when the test and all its subtests complete.
+// Returns a URI filename appropriate to call Open with.
// Each subsequent call to TestDB returns a unique database.
+//
+// func Test_something(t *testing.T) {
+// t.Parallel()
+// dsn := memdb.TestDB(t, url.Values{
+// "_pragma": {"busy_timeout(1000)"},
+// })
+//
+// db, err := sql.Open("sqlite3", dsn)
+// if err != nil {
+// t.Fatal(err)
+// }
+// defer db.Close()
+//
+// // ...
+// }
func TestDB(tb testing.TB, params ...url.Values) string {
tb.Helper()
- name := fmt.Sprintf("%s_%p", tb.Name(), tb)
+ name := fmt.Sprintf("%s_%s", tb.Name(), rand.Text())
tb.Cleanup(func() { Delete(name) })
Create(name, nil)
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 ee08e9a7b..9bb8b559c 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_darwin.go
@@ -23,12 +23,26 @@ type flocktimeout_t struct {
timeout unix.Timespec
}
-func osSync(file *os.File, fullsync, _ /*dataonly*/ bool) error {
- if fullsync {
- return file.Sync()
+func osSync(file *os.File, open OpenFlag, sync SyncFlag) error {
+ var cmd int
+ if sync&SYNC_FULL == SYNC_FULL {
+ // For rollback journals all we really need is a barrier.
+ if open&OPEN_MAIN_JOURNAL != 0 {
+ cmd = unix.F_BARRIERFSYNC
+ } else {
+ cmd = unix.F_FULLFSYNC
+ }
}
+
+ fd := file.Fd()
for {
- err := unix.Fsync(int(file.Fd()))
+ err := error(unix.ENOTSUP)
+ if cmd != 0 {
+ _, err = unix.FcntlInt(fd, cmd, 0)
+ }
+ if err == unix.ENOTSUP {
+ err = unix.Fsync(int(fd))
+ }
if err != unix.EINTR {
return err
}
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 d112c5a99..893f1512c 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_linux.go
@@ -10,7 +10,7 @@ import (
"golang.org/x/sys/unix"
)
-func osSync(file *os.File, _ /*fullsync*/, _ /*dataonly*/ bool) error {
+func osSync(file *os.File, _ OpenFlag, _ SyncFlag) error {
// SQLite trusts Linux's fdatasync for all fsync's.
for {
err := unix.Fdatasync(int(file.Fd()))
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sync.go b/vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sync.go
index b32e83e08..87427d9ed 100644
--- a/vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sync.go
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/os_std_sync.go
@@ -4,6 +4,6 @@ package vfs
import "os"
-func osSync(file *os.File, _ /*fullsync*/, _ /*dataonly*/ bool) error {
+func osSync(file *os.File, _ OpenFlag, _ SyncFlag) error {
return file.Sync()
}