Documentation.

This commit is contained in:
Nuno Cruces
2023-02-22 17:51:30 +00:00
parent e91758c6a4
commit 71ae26e5c9
4 changed files with 45 additions and 30 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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
}