diff options
Diffstat (limited to 'vendor/modernc.org/sqlite')
| -rw-r--r-- | vendor/modernc.org/sqlite/AUTHORS | 1 | ||||
| -rw-r--r-- | vendor/modernc.org/sqlite/CONTRIBUTORS | 2 | ||||
| -rw-r--r-- | vendor/modernc.org/sqlite/sqlite.go | 88 |
3 files changed, 86 insertions, 5 deletions
diff --git a/vendor/modernc.org/sqlite/AUTHORS b/vendor/modernc.org/sqlite/AUTHORS index 61af343a1..268498a3b 100644 --- a/vendor/modernc.org/sqlite/AUTHORS +++ b/vendor/modernc.org/sqlite/AUTHORS @@ -15,6 +15,7 @@ Dan Peterson <danp@danp.net> David Walton <david@davidwalton.com> Davsk Ltd Co <skinner.david@gmail.com> FerretDB Inc. +Harald Albrecht <thediveo@gmx.eu> Jaap Aarts <jaap.aarts1@gmail.com> Jan Mercl <0xjnml@gmail.com> Josh Bleecher Snyder <josharian@gmail.com> diff --git a/vendor/modernc.org/sqlite/CONTRIBUTORS b/vendor/modernc.org/sqlite/CONTRIBUTORS index e9ea3aff5..625b7dcd2 100644 --- a/vendor/modernc.org/sqlite/CONTRIBUTORS +++ b/vendor/modernc.org/sqlite/CONTRIBUTORS @@ -17,6 +17,8 @@ David Walton <david@davidwalton.com> Elle Mouton <elle.mouton@gmail.com> FlyingOnion <731677080@qq.com> Gleb Sakhnov <gleb.sakhnov@gmail.com> +Guénaël Muller <inkey@inkey-art.net> +Harald Albrecht <thediveo@gmx.eu> Jaap Aarts <jaap.aarts1@gmail.com> Jan Mercl <0xjnml@gmail.com> Josh Bleecher Snyder <josharian@gmail.com> diff --git a/vendor/modernc.org/sqlite/sqlite.go b/vendor/modernc.org/sqlite/sqlite.go index 39675a68b..a0b6ca4eb 100644 --- a/vendor/modernc.org/sqlite/sqlite.go +++ b/vendor/modernc.org/sqlite/sqlite.go @@ -254,7 +254,30 @@ func (r *rows) Next(dest []driver.Value) (err error) { return err } - dest[i] = v + if !r.c.intToTime { + dest[i] = v + } else { + // Inspired by mattn/go-sqlite3: + // https://github.com/mattn/go-sqlite3/blob/f76bae4b0044cbba8fb2c72b8e4559e8fbcffd86/sqlite3.go#L2254-L2262 + // but we put make this compatibility optional behind a DSN + // query parameter, because this changes API behavior, so an + // opt-in is needed. + switch r.ColumnTypeDatabaseTypeName(i) { + case "DATE", "DATETIME", "TIMESTAMP": + // Is it a seconds timestamp or a milliseconds + // timestamp? + if v > 1e12 || v < -1e12 { + // time.Unix expects nanoseconds, but this is a + // milliseconds timestamp, so convert ms->ns. + v *= int64(time.Millisecond) + dest[i] = time.Unix(0, v).UTC() + } else { + dest[i] = time.Unix(v, 0) + } + default: + dest[i] = v + } + } case sqlite3.SQLITE_FLOAT: v, err := r.c.columnDouble(r.pstmt, i) if err != nil { @@ -752,8 +775,10 @@ type conn struct { db uintptr // *sqlite3.Xsqlite3 tls *libc.TLS - writeTimeFormat string - beginMode string + writeTimeFormat string + beginMode string + intToTime bool + integerTimeFormat string } func newConn(dsn string) (*conn, error) { @@ -858,6 +883,17 @@ func applyQueryParams(c *conn, query string) error { } c.writeTimeFormat = f } + if v := q.Get("_time_integer_format"); v != "" { + switch v { + case "unix": + case "unix_milli": + case "unix_micro": + case "unix_nano": + default: + return fmt.Errorf("unknown _time_integer_format %q", v) + } + c.integerTimeFormat = v + } if v := q.Get("_txlock"); v != "" { lower := strings.ToLower(v) @@ -867,6 +903,15 @@ func applyQueryParams(c *conn, query string) error { c.beginMode = v } + if v := q.Get("_inttotime"); v != "" { + onoff, err := strconv.ParseBool(v) + if err != nil { + return fmt.Errorf("unknown _inttotime %q, must be 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False", + v) + } + c.intToTime = onoff + } + return nil } @@ -1117,9 +1162,29 @@ func (c *conn) bind(pstmt uintptr, n int, args []driver.NamedValue) (allocs []ui return allocs, err } case time.Time: - if p, err = c.bindText(pstmt, i, c.formatTime(x)); err != nil { - return allocs, err + switch c.integerTimeFormat { + case "unix": + if err := c.bindInt64(pstmt, i, x.Unix()); err != nil { + return allocs, err + } + case "unix_milli": + if err := c.bindInt64(pstmt, i, x.UnixMilli()); err != nil { + return allocs, err + } + case "unix_micro": + if err := c.bindInt64(pstmt, i, x.UnixMicro()); err != nil { + return allocs, err + } + case "unix_nano": + if err := c.bindInt64(pstmt, i, x.UnixNano()); err != nil { + return allocs, err + } + default: + if p, err = c.bindText(pstmt, i, c.formatTime(x)); err != nil { + return allocs, err + } } + case nil: if p, err = c.bindNull(pstmt, i); err != nil { return allocs, err @@ -1913,6 +1978,19 @@ func newDriver() *Driver { return d } // including the timezone specifier. If this parameter is not specified, then // the default String() format will be used. // +// _time_integer_format: The name of a integer format to use when writing time values. +// By default, the time is stored as string and the format can be set with _time_format +// parameter. If _time_integer_format is set, the time will be stored as an integer and +// the integer value will depend on the integer format. +// If you decide to set both _time_format and _time_integer_format, the time will be +// converted as integer and the _time_format value will be ignored. +// Currently the supported value are "unix","unix_milli", "unix_micro" and "unix_nano", +// which corresponds to seconds, milliseconds, microseconds or nanoseconds +// since unixepoch (1 January 1970 00:00:00 UTC). +// +// _inttotime: Enable conversion of time column (DATE, DATETIME,TIMESTAMP) from integer +// to time if the field contain integer (int64). +// // _txlock: The locking behavior to use when beginning a transaction. May be // "deferred" (the default), "immediate", or "exclusive" (case insensitive). See: // https://www.sqlite.org/lang_transaction.html#deferred_immediate_and_exclusive_transactions |
