mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Optimize time.
This commit is contained in:
@@ -318,7 +318,7 @@ func (s stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (drive
|
||||
case sqlite3.ZeroBlob:
|
||||
err = s.stmt.BindZeroBlob(id, int64(a))
|
||||
case time.Time:
|
||||
err = s.stmt.BindText(id, a.Format(time.RFC3339Nano))
|
||||
err = s.stmt.BindTime(id, a, sqlite3.TimeFormatDefault)
|
||||
case nil:
|
||||
err = s.stmt.BindNull(id)
|
||||
default:
|
||||
@@ -389,10 +389,10 @@ func (r rows) Next(dest []driver.Value) error {
|
||||
dest[i] = r.stmt.ColumnInt64(i)
|
||||
case sqlite3.FLOAT:
|
||||
dest[i] = r.stmt.ColumnFloat(i)
|
||||
case sqlite3.TEXT:
|
||||
dest[i] = maybeTime(r.stmt.ColumnText(i))
|
||||
case sqlite3.BLOB:
|
||||
dest[i] = r.stmt.ColumnRawBlob(i)
|
||||
case sqlite3.TEXT:
|
||||
dest[i] = stringOrTime(r.stmt.ColumnRawText(i))
|
||||
case sqlite3.NULL:
|
||||
if buf, ok := dest[i].([]byte); ok {
|
||||
dest[i] = buf[0:0]
|
||||
|
||||
@@ -9,23 +9,23 @@ import (
|
||||
// if it roundtrips back to the same string.
|
||||
// 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.
|
||||
func maybeTime(text string) driver.Value {
|
||||
func stringOrTime(text []byte) driver.Value {
|
||||
// Weed out (some) values that can't possibly be
|
||||
// [time.RFC3339Nano] timestamps.
|
||||
if len(text) < len("2006-01-02T15:04:05Z") {
|
||||
return text
|
||||
return string(text)
|
||||
}
|
||||
if len(text) > len(time.RFC3339Nano) {
|
||||
return text
|
||||
return string(text)
|
||||
}
|
||||
if text[4] != '-' || text[10] != 'T' || text[16] != ':' {
|
||||
return text
|
||||
return string(text)
|
||||
}
|
||||
|
||||
// Slow path.
|
||||
date, err := time.Parse(time.RFC3339Nano, text)
|
||||
if err == nil && date.Format(time.RFC3339Nano) == text {
|
||||
date, err := time.Parse(time.RFC3339Nano, string(text))
|
||||
if err == nil && date.Format(time.RFC3339Nano) == string(text) {
|
||||
return date
|
||||
}
|
||||
return text
|
||||
return string(text)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
// This checks that any string can be recovered as the same string.
|
||||
func Fuzz_maybeTime_1(f *testing.F) {
|
||||
func Fuzz_stringOrTime_1(f *testing.F) {
|
||||
f.Add("")
|
||||
f.Add(" ")
|
||||
f.Add("SQLite")
|
||||
@@ -22,7 +22,7 @@ func Fuzz_maybeTime_1(f *testing.F) {
|
||||
f.Add("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
|
||||
|
||||
f.Fuzz(func(t *testing.T, str string) {
|
||||
value := maybeTime(str)
|
||||
value := stringOrTime([]byte(str))
|
||||
|
||||
switch v := value.(type) {
|
||||
case time.Time:
|
||||
@@ -48,7 +48,7 @@ func Fuzz_maybeTime_1(f *testing.F) {
|
||||
|
||||
// This checks that any [time.Time] can be recovered as a [time.Time],
|
||||
// with nanosecond accuracy, and preserving any timezone offset.
|
||||
func Fuzz_maybeTime_2(f *testing.F) {
|
||||
func Fuzz_stringOrTime_2(f *testing.F) {
|
||||
f.Add(0, 0)
|
||||
f.Add(0, 1)
|
||||
f.Add(0, -1)
|
||||
@@ -59,7 +59,7 @@ func Fuzz_maybeTime_2(f *testing.F) {
|
||||
f.Add(-763421161058, 222_222_222) // twosday, year 22222BC
|
||||
|
||||
checkTime := func(t *testing.T, date time.Time) {
|
||||
value := maybeTime(date.Format(time.RFC3339Nano))
|
||||
value := stringOrTime([]byte(date.Format(time.RFC3339Nano)))
|
||||
|
||||
switch v := value.(type) {
|
||||
case time.Time:
|
||||
|
||||
Reference in New Issue
Block a user