mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Documentation.
This commit is contained in:
@@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
⚠️ CAUTION ⚠️
|
⚠️ CAUTION ⚠️
|
||||||
|
|
||||||
This is a WIP.\
|
This is a WIP.
|
||||||
DO NOT USE with data you care about.
|
|
||||||
|
|
||||||
Roadmap:
|
Roadmap:
|
||||||
- [x] build SQLite using `zig cc --target=wasm32-wasi`
|
- [x] build SQLite using `zig cc --target=wasm32-wasi`
|
||||||
@@ -19,8 +18,10 @@ Roadmap:
|
|||||||
- [x] file locking, compatible with SQLite on Windows/Unix
|
- [x] file locking, compatible with SQLite on Windows/Unix
|
||||||
- [ ] shared memory, compatible with SQLite on Windows/Unix
|
- [ ] shared memory, compatible with SQLite on Windows/Unix
|
||||||
- needed for improved WAL mode
|
- needed for improved WAL mode
|
||||||
- [ ] advanced features
|
- [ ] advanced SQLite features
|
||||||
|
- [ ] nested transactions
|
||||||
- [ ] incremental BLOB I/O
|
- [ ] incremental BLOB I/O
|
||||||
- [ ] online backup
|
- [ ] online backup
|
||||||
- [ ] session extension
|
- [ ] session extension
|
||||||
- [ ] snapshot
|
- [ ] snapshots
|
||||||
|
- [ ] SQL functions
|
||||||
2
blob.go
2
blob.go
@@ -2,5 +2,5 @@ package sqlite3
|
|||||||
|
|
||||||
// ZeroBlob represents a zero-filled, length n BLOB
|
// ZeroBlob represents a zero-filled, length n BLOB
|
||||||
// that can be used as an argument to
|
// that can be used as an argument to
|
||||||
// [database.sql.DB.Exec] and similar methods.
|
// [database/sql.DB.Exec] and similar methods.
|
||||||
type ZeroBlob int64
|
type ZeroBlob int64
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
// Convert a string in [time.RFC3339Nano] format into a [time.Time]
|
// Convert a string in [time.RFC3339Nano] format into a [time.Time]
|
||||||
// if it roundtrips back to the same string.
|
// if it roundtrips back to the same string.
|
||||||
// This way times can be persisted to, and recovered from, the database,
|
// This way times can be persisted to, and recovered from, the database,
|
||||||
// but if a string is needed, [database.sql] will recover the same string.
|
// but if a string is needed, [database/sql] will recover the same string.
|
||||||
func maybeDate(text string) driver.Value {
|
func maybeDate(text string) driver.Value {
|
||||||
// Weed out (some) values that can't possibly be
|
// Weed out (some) values that can't possibly be
|
||||||
// [time.RFC3339Nano] timestamps.
|
// [time.RFC3339Nano] timestamps.
|
||||||
|
|||||||
62
time.go
62
time.go
@@ -59,9 +59,13 @@ const (
|
|||||||
// [TimeFormatDefault] and [TimeFormatAuto] encode using [time.RFC3339Nano],
|
// [TimeFormatDefault] and [TimeFormatAuto] encode using [time.RFC3339Nano],
|
||||||
// with nanosecond accuracy, and preserving timezone.
|
// with nanosecond accuracy, and preserving timezone.
|
||||||
//
|
//
|
||||||
// Formats that don't record the timezone
|
// Formats [TimeFormat1] through [TimeFormat10]
|
||||||
// convert time values to UTC before encoding.
|
// convert time values to UTC before encoding.
|
||||||
//
|
//
|
||||||
|
// Returns a string for the text formats,
|
||||||
|
// a float64 for [TimeFormatJulianDay] and [TimeFormatUnixFrac],
|
||||||
|
// or an int64 for the other numeric formats.
|
||||||
|
//
|
||||||
// https://www.sqlite.org/lang_datefunc.html
|
// https://www.sqlite.org/lang_datefunc.html
|
||||||
func (f TimeFormat) Encode(t time.Time) any {
|
func (f TimeFormat) Encode(t time.Time) any {
|
||||||
switch f {
|
switch f {
|
||||||
@@ -81,11 +85,13 @@ func (f TimeFormat) Encode(t time.Time) any {
|
|||||||
// Special formats
|
// Special formats
|
||||||
case TimeFormatDefault, TimeFormatAuto:
|
case TimeFormatDefault, TimeFormatAuto:
|
||||||
f = time.RFC3339Nano
|
f = time.RFC3339Nano
|
||||||
}
|
|
||||||
// SQLite assumes UTC if unspecified.
|
// SQLite assumes UTC if unspecified.
|
||||||
if !strings.Contains(string(f), "MST") &&
|
case
|
||||||
!strings.Contains(string(f), "Z07") &&
|
TimeFormat1, TimeFormat2,
|
||||||
!strings.Contains(string(f), "-07") {
|
TimeFormat3, TimeFormat4,
|
||||||
|
TimeFormat5, TimeFormat6,
|
||||||
|
TimeFormat7, TimeFormat8,
|
||||||
|
TimeFormat9, TimeFormat10:
|
||||||
t = t.UTC()
|
t = t.UTC()
|
||||||
}
|
}
|
||||||
return t.Format(string(f))
|
return t.Format(string(f))
|
||||||
@@ -93,8 +99,19 @@ func (f TimeFormat) Encode(t time.Time) any {
|
|||||||
|
|
||||||
// Decode decodes a time value using this format.
|
// Decode decodes a time value using this format.
|
||||||
//
|
//
|
||||||
// Decoding of SQLite recognized formats is lenient:
|
// The time value can be a string, an int64, or a float64.
|
||||||
// timezones and fractional seconds are always optional.
|
//
|
||||||
|
// Formats [TimeFormat8] through [TimeFormat10]
|
||||||
|
// assume a date of 2000-01-01.
|
||||||
|
//
|
||||||
|
// The timezone indicator and fractional seconds are always optional
|
||||||
|
// for formats [TimeFormat2] through [TimeFormat10].
|
||||||
|
//
|
||||||
|
// [TimeFormatAuto] implements (and extends) the SQLite auto modifier.
|
||||||
|
// The julian day number is safe to use for historical dates,
|
||||||
|
// from 4712BC through 9999AD.
|
||||||
|
// Unix timestamps (expressed in seconds, milliseconds, microseconds, or nanoseconds),
|
||||||
|
// are safe to use for current events, from 1980 through at least 2260.
|
||||||
//
|
//
|
||||||
// https://www.sqlite.org/lang_datefunc.html
|
// https://www.sqlite.org/lang_datefunc.html
|
||||||
func (f TimeFormat) Decode(v any) (time.Time, error) {
|
func (f TimeFormat) Decode(v any) (time.Time, error) {
|
||||||
@@ -263,14 +280,7 @@ func (f TimeFormat) Decode(v any) (time.Time, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return time.Time{}, timeErr
|
return time.Time{}, timeErr
|
||||||
}
|
}
|
||||||
f := string(f)
|
return f.parseRelaxed(s)
|
||||||
f = strings.TrimSuffix(f, "Z07:00")
|
|
||||||
f = strings.TrimSuffix(f, ".000")
|
|
||||||
t, err := time.Parse(f+"Z07:00", s)
|
|
||||||
if err != nil {
|
|
||||||
t, err = time.Parse(f, s)
|
|
||||||
}
|
|
||||||
return t, err
|
|
||||||
|
|
||||||
case
|
case
|
||||||
TimeFormat8, TimeFormat8TZ,
|
TimeFormat8, TimeFormat8TZ,
|
||||||
@@ -280,13 +290,7 @@ func (f TimeFormat) Decode(v any) (time.Time, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return time.Time{}, timeErr
|
return time.Time{}, timeErr
|
||||||
}
|
}
|
||||||
f := string(f)
|
t, err := f.parseRelaxed(s)
|
||||||
f = strings.TrimSuffix(f, "Z07:00")
|
|
||||||
f = strings.TrimSuffix(f, ".000")
|
|
||||||
t, err := time.Parse(f+"Z07:00", s)
|
|
||||||
if err != nil {
|
|
||||||
t, err = time.Parse(f, s)
|
|
||||||
}
|
|
||||||
return t.AddDate(2000, 0, 0), err
|
return t.AddDate(2000, 0, 0), err
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -294,10 +298,20 @@ func (f TimeFormat) Decode(v any) (time.Time, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return time.Time{}, timeErr
|
return time.Time{}, timeErr
|
||||||
}
|
}
|
||||||
f := string(f)
|
|
||||||
if f == "" {
|
if f == "" {
|
||||||
f = time.RFC3339Nano
|
f = time.RFC3339Nano
|
||||||
}
|
}
|
||||||
return time.Parse(f, s)
|
return time.Parse(string(f), s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f TimeFormat) parseRelaxed(s string) (time.Time, error) {
|
||||||
|
fs := string(f)
|
||||||
|
fs = strings.TrimSuffix(fs, "Z07:00")
|
||||||
|
fs = strings.TrimSuffix(fs, ".000")
|
||||||
|
t, err := time.Parse(fs+"Z07:00", s)
|
||||||
|
if err != nil {
|
||||||
|
return time.Parse(fs, s)
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user