mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
update go-sqlite3 to v0.18.0 (#3204)
This commit is contained in:
158
vendor/github.com/ncruces/go-sqlite3/driver/driver.go
generated
vendored
158
vendor/github.com/ncruces/go-sqlite3/driver/driver.go
generated
vendored
@ -8,21 +8,50 @@
|
||||
//
|
||||
// The data source name for "sqlite3" databases can be a filename or a "file:" [URI].
|
||||
//
|
||||
// # Default transaction mode
|
||||
//
|
||||
// The [TRANSACTION] mode can be specified using "_txlock":
|
||||
//
|
||||
// sql.Open("sqlite3", "file:demo.db?_txlock=immediate")
|
||||
//
|
||||
// Possible values are: "deferred", "immediate", "exclusive".
|
||||
// A [read-only] transaction is always "deferred", regardless of "_txlock".
|
||||
// Possible values are: "deferred" (the default), "immediate", "exclusive".
|
||||
// Regardless of "_txlock":
|
||||
// - a [linearizable] transaction is always "exclusive";
|
||||
// - a [serializable] transaction is always "immediate";
|
||||
// - a [read-only] transaction is always "deferred".
|
||||
//
|
||||
// # Working with time
|
||||
//
|
||||
// The time encoding/decoding format can be specified using "_timefmt":
|
||||
//
|
||||
// sql.Open("sqlite3", "file:demo.db?_timefmt=sqlite")
|
||||
//
|
||||
// Possible values are: "auto" (the default), "sqlite", "rfc3339";
|
||||
// "auto" encodes as RFC 3339 and decodes any [format] supported by SQLite;
|
||||
// "sqlite" encodes as SQLite and decodes any [format] supported by SQLite;
|
||||
// "rfc3339" encodes and decodes RFC 3339 only.
|
||||
// - "auto" encodes as RFC 3339 and decodes any [format] supported by SQLite;
|
||||
// - "sqlite" encodes as SQLite and decodes any [format] supported by SQLite;
|
||||
// - "rfc3339" encodes and decodes RFC 3339 only.
|
||||
//
|
||||
// If you encode as RFC 3339 (the default),
|
||||
// consider using the TIME [collating sequence] to produce a time-ordered sequence.
|
||||
//
|
||||
// To scan values in other formats, [sqlite3.TimeFormat.Scanner] may be helpful.
|
||||
// To bind values in other formats, [sqlite3.TimeFormat.Encode] them before binding.
|
||||
//
|
||||
// When using a custom time struct, you'll have to implement
|
||||
// [database/sql/driver.Valuer] and [database/sql.Scanner].
|
||||
//
|
||||
// The Value method should ideally serialise to a time [format] supported by SQLite.
|
||||
// This ensures SQL date and time functions work as they should,
|
||||
// and that your schema works with other SQLite tools.
|
||||
// [sqlite3.TimeFormat.Encode] may help.
|
||||
//
|
||||
// The Scan method needs to take into account that the value it receives can be of differing types.
|
||||
// It can already be a [time.Time], if the driver decoded the value according to "_timefmt" rules.
|
||||
// Or it can be a: string, int64, float64, []byte, nil,
|
||||
// depending on the column type and what whoever wrote the value.
|
||||
// [sqlite3.TimeFormat.Decode] may help.
|
||||
//
|
||||
// # Setting PRAGMAs
|
||||
//
|
||||
// [PRAGMA] statements can be specified using "_pragma":
|
||||
//
|
||||
@ -31,13 +60,17 @@
|
||||
// If no PRAGMAs are specified, a busy timeout of 1 minute is set.
|
||||
//
|
||||
// Order matters:
|
||||
// busy timeout and locking mode should be the first PRAGMAs set, in that order.
|
||||
// encryption keys, busy timeout and locking mode should be the first PRAGMAs set,
|
||||
// in that order.
|
||||
//
|
||||
// [URI]: https://sqlite.org/uri.html
|
||||
// [PRAGMA]: https://sqlite.org/pragma.html
|
||||
// [format]: https://sqlite.org/lang_datefunc.html#time_values
|
||||
// [TRANSACTION]: https://sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions
|
||||
// [linearizable]: https://pkg.go.dev/database/sql#TxOptions
|
||||
// [serializable]: https://pkg.go.dev/database/sql#TxOptions
|
||||
// [read-only]: https://pkg.go.dev/database/sql#TxOptions
|
||||
// [format]: https://sqlite.org/lang_datefunc.html#time_values
|
||||
// [collating sequence]: https://sqlite.org/datatype3.html#collating_sequences
|
||||
package driver
|
||||
|
||||
import (
|
||||
@ -69,11 +102,22 @@ func init() {
|
||||
|
||||
// Open opens the SQLite database specified by dataSourceName as a [database/sql.DB].
|
||||
//
|
||||
// The init function is called by the driver on new connections.
|
||||
// Open accepts zero, one, or two callbacks (nil callbacks are ignored).
|
||||
// The first callback is called when the driver opens a new connection.
|
||||
// The second callback is called before the driver closes a connection.
|
||||
// The [sqlite3.Conn] can be used to execute queries, register functions, etc.
|
||||
// Any error returned closes the connection and is returned to [database/sql].
|
||||
func Open(dataSourceName string, init func(*sqlite3.Conn) error) (*sql.DB, error) {
|
||||
c, err := (&SQLite{Init: init}).OpenConnector(dataSourceName)
|
||||
func Open(dataSourceName string, fn ...func(*sqlite3.Conn) error) (*sql.DB, error) {
|
||||
var drv SQLite
|
||||
if len(fn) > 2 {
|
||||
return nil, sqlite3.MISUSE
|
||||
}
|
||||
if len(fn) > 1 {
|
||||
drv.term = fn[1]
|
||||
}
|
||||
if len(fn) > 0 {
|
||||
drv.init = fn[0]
|
||||
}
|
||||
c, err := drv.OpenConnector(dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -82,10 +126,8 @@ func Open(dataSourceName string, init func(*sqlite3.Conn) error) (*sql.DB, error
|
||||
|
||||
// SQLite implements [database/sql/driver.Driver].
|
||||
type SQLite struct {
|
||||
// Init function is called by the driver on new connections.
|
||||
// The [sqlite3.Conn] can be used to execute queries, register functions, etc.
|
||||
// Any error returned closes the connection and is returned to [database/sql].
|
||||
Init func(*sqlite3.Conn) error
|
||||
init func(*sqlite3.Conn) error
|
||||
term func(*sqlite3.Conn) error
|
||||
}
|
||||
|
||||
// Open implements [database/sql/driver.Driver].
|
||||
@ -119,10 +161,8 @@ func (d *SQLite) newConnector(name string) (*connector, error) {
|
||||
}
|
||||
|
||||
switch txlock {
|
||||
case "":
|
||||
c.txBegin = "BEGIN"
|
||||
case "deferred", "immediate", "exclusive":
|
||||
c.txBegin = "BEGIN " + txlock
|
||||
case "", "deferred", "concurrent", "immediate", "exclusive":
|
||||
c.txLock = txlock
|
||||
default:
|
||||
return nil, fmt.Errorf("sqlite3: invalid _txlock: %s", txlock)
|
||||
}
|
||||
@ -147,7 +187,7 @@ func (d *SQLite) newConnector(name string) (*connector, error) {
|
||||
type connector struct {
|
||||
driver *SQLite
|
||||
name string
|
||||
txBegin string
|
||||
txLock string
|
||||
tmRead sqlite3.TimeFormat
|
||||
tmWrite sqlite3.TimeFormat
|
||||
pragmas bool
|
||||
@ -159,7 +199,7 @@ func (n *connector) Driver() driver.Driver {
|
||||
|
||||
func (n *connector) Connect(ctx context.Context) (_ driver.Conn, err error) {
|
||||
c := &conn{
|
||||
txBegin: n.txBegin,
|
||||
txLock: n.txLock,
|
||||
tmRead: n.tmRead,
|
||||
tmWrite: n.tmWrite,
|
||||
}
|
||||
@ -178,18 +218,18 @@ func (n *connector) Connect(ctx context.Context) (_ driver.Conn, err error) {
|
||||
defer c.Conn.SetInterrupt(old)
|
||||
|
||||
if !n.pragmas {
|
||||
err = c.Conn.BusyTimeout(60 * time.Second)
|
||||
err = c.Conn.BusyTimeout(time.Minute)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if n.driver.Init != nil {
|
||||
err = n.driver.Init(c.Conn)
|
||||
if n.driver.init != nil {
|
||||
err = n.driver.init(c.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if n.pragmas || n.driver.Init != nil {
|
||||
if n.pragmas || n.driver.init != nil {
|
||||
s, _, err := c.Conn.Prepare(`PRAGMA query_only`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -204,17 +244,24 @@ func (n *connector) Connect(ctx context.Context) (_ driver.Conn, err error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if n.driver.term != nil {
|
||||
err = c.Conn.Trace(sqlite3.TRACE_CLOSE, func(sqlite3.TraceEvent, any, any) error {
|
||||
return n.driver.term(c.Conn)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type conn struct {
|
||||
*sqlite3.Conn
|
||||
txBegin string
|
||||
txCommit string
|
||||
txRollback string
|
||||
tmRead sqlite3.TimeFormat
|
||||
tmWrite sqlite3.TimeFormat
|
||||
readOnly byte
|
||||
txLock string
|
||||
txReset string
|
||||
tmRead sqlite3.TimeFormat
|
||||
tmWrite sqlite3.TimeFormat
|
||||
readOnly byte
|
||||
}
|
||||
|
||||
var (
|
||||
@ -231,31 +278,30 @@ func (c *conn) Raw() *sqlite3.Conn {
|
||||
|
||||
// Deprecated: use BeginTx instead.
|
||||
func (c *conn) Begin() (driver.Tx, error) {
|
||||
// notest
|
||||
return c.BeginTx(context.Background(), driver.TxOptions{})
|
||||
}
|
||||
|
||||
func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
txBegin := c.txBegin
|
||||
c.txCommit = `COMMIT`
|
||||
c.txRollback = `ROLLBACK`
|
||||
|
||||
if opts.ReadOnly {
|
||||
txBegin = `
|
||||
BEGIN deferred;
|
||||
PRAGMA query_only=on`
|
||||
c.txRollback = `
|
||||
ROLLBACK;
|
||||
PRAGMA query_only=` + string(c.readOnly)
|
||||
c.txCommit = c.txRollback
|
||||
}
|
||||
|
||||
var txLock string
|
||||
switch opts.Isolation {
|
||||
default:
|
||||
return nil, util.IsolationErr
|
||||
case
|
||||
driver.IsolationLevel(sql.LevelDefault),
|
||||
driver.IsolationLevel(sql.LevelSerializable):
|
||||
break
|
||||
case driver.IsolationLevel(sql.LevelLinearizable):
|
||||
txLock = "exclusive"
|
||||
case driver.IsolationLevel(sql.LevelSerializable):
|
||||
txLock = "immediate"
|
||||
case driver.IsolationLevel(sql.LevelDefault):
|
||||
if !opts.ReadOnly {
|
||||
txLock = c.txLock
|
||||
}
|
||||
}
|
||||
|
||||
c.txReset = ``
|
||||
txBegin := `BEGIN ` + txLock
|
||||
if opts.ReadOnly {
|
||||
txBegin += ` ; PRAGMA query_only=on`
|
||||
c.txReset = `; PRAGMA query_only=` + string(c.readOnly)
|
||||
}
|
||||
|
||||
old := c.Conn.SetInterrupt(ctx)
|
||||
@ -269,7 +315,7 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e
|
||||
}
|
||||
|
||||
func (c *conn) Commit() error {
|
||||
err := c.Conn.Exec(c.txCommit)
|
||||
err := c.Conn.Exec(`COMMIT` + c.txReset)
|
||||
if err != nil && !c.Conn.GetAutocommit() {
|
||||
c.Rollback()
|
||||
}
|
||||
@ -277,16 +323,17 @@ func (c *conn) Commit() error {
|
||||
}
|
||||
|
||||
func (c *conn) Rollback() error {
|
||||
err := c.Conn.Exec(c.txRollback)
|
||||
err := c.Conn.Exec(`ROLLBACK` + c.txReset)
|
||||
if errors.Is(err, sqlite3.INTERRUPT) {
|
||||
old := c.Conn.SetInterrupt(context.Background())
|
||||
defer c.Conn.SetInterrupt(old)
|
||||
err = c.Conn.Exec(c.txRollback)
|
||||
err = c.Conn.Exec(`ROLLBACK` + c.txReset)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *conn) Prepare(query string) (driver.Stmt, error) {
|
||||
// notest
|
||||
return c.PrepareContext(context.Background(), query)
|
||||
}
|
||||
|
||||
@ -329,6 +376,8 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
|
||||
}
|
||||
|
||||
func (c *conn) CheckNamedValue(arg *driver.NamedValue) error {
|
||||
// Fast path: short circuit argument verification.
|
||||
// Arguments will be rejected by conn.ExecContext.
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -363,11 +412,13 @@ func (s *stmt) NumInput() int {
|
||||
|
||||
// Deprecated: use ExecContext instead.
|
||||
func (s *stmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
// notest
|
||||
return s.ExecContext(context.Background(), namedValues(args))
|
||||
}
|
||||
|
||||
// Deprecated: use QueryContext instead.
|
||||
func (s *stmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
// notest
|
||||
return s.QueryContext(context.Background(), namedValues(args))
|
||||
}
|
||||
|
||||
@ -561,7 +612,8 @@ func (r *rows) Next(dest []driver.Value) error {
|
||||
}
|
||||
|
||||
func (r *rows) decodeTime(i int, v any) (_ time.Time, ok bool) {
|
||||
if r.tmRead == sqlite3.TimeFormatDefault {
|
||||
switch r.tmRead {
|
||||
case sqlite3.TimeFormatDefault, time.RFC3339Nano:
|
||||
// handled by maybeTime
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user