forked from mirror/go-sqlcipher
Fix loc parsing
This commit is contained in:
parent
71712f0ba9
commit
e48e0597ab
56
sqlite3.go
56
sqlite3.go
|
@ -267,20 +267,26 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var loc *time.Location
|
var loc *time.Location
|
||||||
if u, err := url.Parse(dsn); err == nil {
|
pos := strings.IndexRune(dsn, '?')
|
||||||
for k, v := range u.Query() {
|
if pos >= 1 {
|
||||||
switch k {
|
params, err := url.ParseQuery(dsn[pos+1:])
|
||||||
case "loc":
|
if err != nil {
|
||||||
if len(v) > 0 {
|
return nil, err
|
||||||
if v[0] == "auto" {
|
|
||||||
v[0] = time.Local.String()
|
|
||||||
}
|
|
||||||
if loc, err = time.LoadLocation(v[0]); err != nil {
|
|
||||||
return nil, fmt.Errorf("Invalid loc: %v: %v", v[0], err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loc
|
||||||
|
if val := params.Get("loc"); val != "" {
|
||||||
|
if val == "auto" {
|
||||||
|
loc = time.Local
|
||||||
|
} else {
|
||||||
|
loc, err = time.LoadLocation(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Invalid loc: %v: %v", val, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dsn = dsn[:pos-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
var db *C.sqlite3
|
var db *C.sqlite3
|
||||||
|
@ -525,24 +531,21 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||||
switch rc.decltype[i] {
|
switch rc.decltype[i] {
|
||||||
case "timestamp", "datetime", "date":
|
case "timestamp", "datetime", "date":
|
||||||
unixTimestamp := strconv.FormatInt(val, 10)
|
unixTimestamp := strconv.FormatInt(val, 10)
|
||||||
|
var t time.Time
|
||||||
if len(unixTimestamp) == 13 {
|
if len(unixTimestamp) == 13 {
|
||||||
duration, err := time.ParseDuration(unixTimestamp + "ms")
|
duration, err := time.ParseDuration(unixTimestamp + "ms")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing %s value %d, %s", rc.decltype[i], val, err)
|
return fmt.Errorf("error parsing %s value %d, %s", rc.decltype[i], val, err)
|
||||||
}
|
}
|
||||||
epoch := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
|
epoch := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
t = epoch.Add(duration)
|
||||||
|
} else {
|
||||||
|
t = time.Unix(val, 0)
|
||||||
|
}
|
||||||
if rc.s.c.loc != nil {
|
if rc.s.c.loc != nil {
|
||||||
dest[i] = epoch.Add(duration).In(rc.s.c.loc)
|
t = t.In(rc.s.c.loc)
|
||||||
} else {
|
|
||||||
dest[i] = epoch.Add(duration)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if rc.s.c.loc != nil {
|
|
||||||
dest[i] = time.Unix(val, 0).In(rc.s.c.loc)
|
|
||||||
} else {
|
|
||||||
dest[i] = time.Unix(val, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dest[i] = t
|
||||||
case "boolean":
|
case "boolean":
|
||||||
dest[i] = val > 0
|
dest[i] = val > 0
|
||||||
default:
|
default:
|
||||||
|
@ -574,20 +577,21 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||||
|
|
||||||
switch rc.decltype[i] {
|
switch rc.decltype[i] {
|
||||||
case "timestamp", "datetime", "date":
|
case "timestamp", "datetime", "date":
|
||||||
|
var t time.Time
|
||||||
for _, format := range SQLiteTimestampFormats {
|
for _, format := range SQLiteTimestampFormats {
|
||||||
if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil {
|
if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil {
|
||||||
if rc.s.c.loc != nil {
|
t = timeVal
|
||||||
dest[i] = timeVal.In(rc.s.c.loc)
|
|
||||||
} else {
|
|
||||||
dest[i] = timeVal
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The column is a time value, so return the zero time on parse failure.
|
// The column is a time value, so return the zero time on parse failure.
|
||||||
dest[i] = time.Time{}
|
t = time.Time{}
|
||||||
}
|
}
|
||||||
|
if rc.s.c.loc != nil {
|
||||||
|
t = t.In(rc.s.c.loc)
|
||||||
|
}
|
||||||
|
dest[i] = t
|
||||||
default:
|
default:
|
||||||
dest[i] = []byte(s)
|
dest[i] = []byte(s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -719,10 +719,10 @@ func TestTimezoneConversion(t *testing.T) {
|
||||||
t.Errorf("Datetime value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
|
t.Errorf("Datetime value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
|
||||||
}
|
}
|
||||||
if tests[id].expected.Location().String() != ts.Location().String() {
|
if tests[id].expected.Location().String() != ts.Location().String() {
|
||||||
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].expected.Location().String(), ts.Location().String())
|
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), ts.Location().String())
|
||||||
}
|
}
|
||||||
if tests[id].expected.Location().String() != dt.Location().String() {
|
if tests[id].expected.Location().String() != dt.Location().String() {
|
||||||
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].expected.Location().String(), dt.Location().String())
|
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), dt.Location().String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue