1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// Package sqshared contains shared types for the sqlite3 and moderncsqlite
// drivers.
package sqshared
import (
"database/sql/driver"
"errors"
"fmt"
"strings"
"time"
)
// ConvertBytes is the byte formatter func for sqlite3 databases.
func ConvertBytes(buf []byte, tfmt string) (string, error) {
// attempt to convert buf if it matches a time format, and if it
// does, then return a formatted time string.
s := string(buf)
if s != "" && strings.TrimSpace(s) != "" {
t := new(Time)
if err := t.Scan(buf); err == nil {
return time.Time(*t).Format(tfmt), nil
}
}
return s, nil
}
// Time provides a type that will correctly scan the various timestamps
// values stored by the github.com/mattn/go-sqlite3 driver for time.Time
// values, as well as correctly satisfying the sql/driver/Valuer interface.
type Time time.Time
// Value satisfies the Valuer interface.
func (t *Time) Value() (driver.Value, error) {
return t, nil
}
// Scan satisfies the Scanner interface.
func (t *Time) Scan(v interface{}) error {
switch x := v.(type) {
case time.Time:
*t = Time(x)
return nil
case []byte:
return t.Parse(string(x))
case string:
return t.Parse(x)
}
return fmt.Errorf("cannot convert type %T to Time", v)
}
// Parse attempts to Parse string s to t.
func (t *Time) Parse(s string) error {
if s == "" {
return nil
}
for _, f := range SQLiteTimestampFormats {
if z, err := time.Parse(f, s); err == nil {
*t = Time(z)
return nil
}
}
return errors.New("could not parse time")
}
// SQLiteTimestampFormats is timestamp formats understood by both this module
// and SQLite. The first format in the slice will be used when saving time
// values into the database. When parsing a string from a timestamp or datetime
// column, the formats are tried in order.
var SQLiteTimestampFormats = []string{
// By default, store timestamps with whatever timezone they come with.
// When parsed, they will be returned with the same timezone.
"2006-01-02 15:04:05.999999999-07:00",
"2006-01-02T15:04:05.999999999-07:00",
"2006-01-02 15:04:05.999999999",
"2006-01-02T15:04:05.999999999",
"2006-01-02 15:04:05",
"2006-01-02T15:04:05",
"2006-01-02 15:04",
"2006-01-02T15:04",
"2006-01-02",
}
|