func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db))) } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: dest[i] = int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) p := C.sqlite3_column_blob(rc.s.s, C.int(i)) dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: dest[i] = C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) } } return nil }
func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db))) } if rc.decltype == nil { rc.decltype = make([]string, rc.nc) for i := 0; i < rc.nc; i++ { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) switch rc.decltype[i] { case "timestamp": dest[i] = time.Unix(val, 0) case "boolean": dest[i] = val > 0 default: dest[i] = val } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) p := C.sqlite3_column_blob(rc.s.s, C.int(i)) switch dest[i].(type) { case sql.RawBytes: dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] default: slice := make([]byte, n) copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) dest[i] = slice } case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: var err error s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) if rc.decltype[i] == "timestamp" { dest[i], err = time.Parse(SQLiteTimestampFormat, s) if err != nil { return err } } else { dest[i] = s } } } return nil }
// ScanText scans result value from a query. // The leftmost column/index is number 0. // Returns true when column is null. // (See sqlite3_column_text: http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ScanText(index int) (value string, isNull bool) { p := C.sqlite3_column_text(s.stmt, C.int(index)) if p == nil { isNull = true } else { value = C.GoString((*C.char)(unsafe.Pointer(p))) } return }
// text returns the value of column i as a UTF-8 string. If copy is false, the // string will point to memory allocated by SQLite. func text(stmt *C.sqlite3_stmt, i C.int, copy bool) string { p := (*C.char)(unsafe.Pointer(C.sqlite3_column_text(stmt, i))) if n := C.sqlite3_column_bytes(stmt, i); n > 0 { if copy { return C.GoStringN(p, n) } return goStrN(p, n) } return "" }
// ScanTime scans result value from a query. // If time is persisted as string without timezone, UTC is used. // If time is persisted as numeric, local is used. // The leftmost column/index is number 0. // Returns true when column is null. // The column type affinity must be consistent with the format used (INTEGER or NUMERIC or NONE for unix time, REAL or NONE for julian day). func (s *Stmt) ScanTime(index int) (value time.Time, isNull bool, err error) { ctype := s.ColumnType(index) switch ctype { case Null: isNull = true case Text: // does not work as expected if column type affinity is TEXT but inserted value was a numeric p := C.sqlite3_column_text(s.stmt, C.int(index)) txt := C.GoString((*C.char)(unsafe.Pointer(p))) var layout string switch len(txt) { case 5: // HH:MM layout = "15:04" case 8: // HH:MM:SS layout = "15:04:05" case 10: // YYYY-MM-DD layout = "2006-01-02" case 12: // HH:MM:SS.SSS layout = "15:04:05.000" case 16: // YYYY-MM-DDTHH:MM if txt[10] == 'T' { layout = "2006-01-02T15:04" } else { layout = "2006-01-02 15:04" } case 19: // YYYY-MM-DDTHH:MM:SS if txt[10] == 'T' { layout = "2006-01-02T15:04:05" } else { layout = "2006-01-02 15:04:05" } case 23: // YYYY-MM-DDTHH:MM:SS.SSS if txt[10] == 'T' { layout = "2006-01-02T15:04:05.000" } else { layout = "2006-01-02 15:04:05.000" } default: // YYYY-MM-DDTHH:MM:SS.SSSZhh:mm or parse error if len(txt) > 10 && txt[10] == 'T' { layout = "2006-01-02T15:04:05.000Z07:00" } else { layout = "2006-01-02 15:04:05.000Z07:00" } } value, err = time.Parse(layout, txt) // UTC except when timezone is specified case Integer: unixepoch := int64(C.sqlite3_column_int64(s.stmt, C.int(index))) value = time.Unix(unixepoch, 0) // local time case Float: // does not work as expected if column affinity is REAL but inserted value was an integer jd := float64(C.sqlite3_column_double(s.stmt, C.int(index))) value = JulianDayToLocalTime(jd) // local time default: err = s.specificError("unexpected column type affinity for time persistence: %q", ctype) } return }
// ScanTime scans result value from a query. // If time is persisted as string without timezone, UTC is used. // If time is persisted as numeric, local is used. // The leftmost column/index is number 0. // Returns true when column is null. func (s *Stmt) ScanTime(index int) (value time.Time, isNull bool, err error) { switch s.ColumnType(index) { case Null: isNull = true case Text: p := C.sqlite3_column_text(s.stmt, C.int(index)) txt := C.GoString((*C.char)(unsafe.Pointer(p))) var layout string switch len(txt) { case 5: // HH:MM layout = "15:04" case 8: // HH:MM:SS layout = "15:04:05" case 10: // YYYY-MM-DD layout = "2006-01-02" case 12: // HH:MM:SS.SSS layout = "15:04:05.000" case 16: // YYYY-MM-DDTHH:MM if txt[10] == 'T' { layout = "2006-01-02T15:04" } else { layout = "2006-01-02 15:04" } case 19: // YYYY-MM-DDTHH:MM:SS if txt[10] == 'T' { layout = "2006-01-02T15:04:05" } else { layout = "2006-01-02 15:04:05" } case 23: // YYYY-MM-DDTHH:MM:SS.SSS if txt[10] == 'T' { layout = "2006-01-02T15:04:05.999" } else { layout = "2006-01-02 15:04:05.999" } default: // YYYY-MM-DDTHH:MM:SS.SSSZhh:mm or parse error if len(txt) > 10 && txt[10] == 'T' { layout = "2006-01-02T15:04:05.999Z07:00" } else { layout = "2006-01-02 15:04:05.999Z07:00" } } value, err = time.Parse(layout, txt) // UTC except when timezone is specified case Integer: unixepoch := int64(C.sqlite3_column_int64(s.stmt, C.int(index))) value = time.Unix(unixepoch, 0) // local time case Float: jd := float64(C.sqlite3_column_double(s.stmt, C.int(index))) value = JulianDayToLocalTime(jd) // local time default: panic("The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, or SQLITE_NULL") } return }
// ScanText scans result value from a query. // The leftmost column/index is number 0. // Returns true when column is null. // (See sqlite3_column_text: http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ScanText(index int) (value string, isNull bool) { if index < 0 || index >= s.ColumnCount() { panic(fmt.Sprintf("column index %d out of range [0,%d[.", index, s.ColumnCount())) } p := C.sqlite3_column_text(s.stmt, C.int(index)) if p == nil { isNull = true } else { value = C.GoString((*C.char)(unsafe.Pointer(p))) } return }
// ScanValue scans result value from a query. // The leftmost column/index is number 0. // // Destination type is decided by SQLite. // The returned value will be of one of the following types: // nil // string (exception if blob is true) // int64 // float64 // []byte // // Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type. // (See http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ScanValue(index int, blob bool) (value interface{}, isNull bool) { if index < 0 || index >= s.ColumnCount() { panic(fmt.Sprintf("column index %d out of range [0,%d[.", index, s.ColumnCount())) } switch s.ColumnType(index) { case Null: return nil, true case Text: // does not work as expected if column type affinity is TEXT but inserted value was a numeric if s.c.ScanNumericalAsTime && s.c.DefaultTimeLayout != "" && s.ColumnTypeAffinity(index) == Numerical { p := C.sqlite3_column_text(s.stmt, C.int(index)) txt := C.GoString((*C.char)(unsafe.Pointer(p))) value, err := time.Parse(s.c.DefaultTimeLayout, txt) if err == nil { return value, false } Log(-1, err.Error()) } if blob { p := C.sqlite3_column_blob(s.stmt, C.int(index)) n := C.sqlite3_column_bytes(s.stmt, C.int(index)) return C.GoBytes(p, n), false } p := C.sqlite3_column_text(s.stmt, C.int(index)) return C.GoString((*C.char)(unsafe.Pointer(p))), false case Integer: value := int64(C.sqlite3_column_int64(s.stmt, C.int(index))) if s.c.ScanNumericalAsTime && s.c.DefaultTimeLayout == "" && s.ColumnTypeAffinity(index) == Numerical { return time.Unix(value, 0), false } return value, false case Float: // does not work as expected if column type affinity is REAL but inserted value was an integer return float64(C.sqlite3_column_double(s.stmt, C.int(index))), false case Blob: p := C.sqlite3_column_blob(s.stmt, C.int(index)) n := C.sqlite3_column_bytes(s.stmt, C.int(index)) // value = (*[1 << 30]byte)(unsafe.Pointer(p))[:n] return C.GoBytes(p, n), false // The memory space used to hold strings and BLOBs is freed automatically. } panic("The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL") }
func ScanAsString(stmnt *Stmt) ([]string, error) { result := make([]string, Columns(stmnt)) for i := range result { p := C.sqlite3_column_text(stmnt.stmt, C.int(i)) n := C.sqlite3_column_bytes(stmnt.stmt, C.int(i)) temp := C.GoStringN((*C.char)(unsafe.Pointer(p)), n) if len(temp) == 0 { } result[i] = temp //result[i] = string(make([]byte, n)) //result[i] = "bob" } return result, nil }
func (c ResultColumn) Value(s *Statement) (value interface{}) { switch c.Type(s) { case INTEGER: value = int64(C.sqlite3_int64(C.sqlite3_column_int64(s.cptr, C.int(c)))) case FLOAT: value = float64(C.sqlite3_column_double(s.cptr, C.int(c))) case TEXT: value = c.make_buffer(s, C.sqlite3_column_text(s.cptr, C.int(c))) case BLOB: buffer := c.make_buffer(s, C.sqlite3_column_blob(s.cptr, C.int(c))) value = gob.NewDecoder(bytes.NewBuffer([]byte(buffer))) case NULL: value = nil default: panic("unknown column type") } return }
// ScanValue scans result value from a query. // The leftmost column/index is number 0. // // Destination type is decided by SQLite. // The returned value will be of one of the following types: // nil // string // int64 // float64 // []byte // // Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type. // (See http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ScanValue(index int) (value interface{}) { switch s.ColumnType(index) { case Null: value = nil case Text: p := C.sqlite3_column_text(s.stmt, C.int(index)) value = C.GoString((*C.char)(unsafe.Pointer(p))) case Integer: value = int64(C.sqlite3_column_int64(s.stmt, C.int(index))) case Float: value = float64(C.sqlite3_column_double(s.stmt, C.int(index))) case Blob: p := C.sqlite3_column_blob(s.stmt, C.int(index)) n := C.sqlite3_column_bytes(s.stmt, C.int(index)) // value = (*[1 << 30]byte)(unsafe.Pointer(p))[:n] value = C.GoBytes(p, n) // The memory space used to hold strings and BLOBs is freed automatically. default: panic("The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL") } return }
// ScanValue scans result value from a query. // The leftmost column/index is number 0. // // Destination type is decided by SQLite. // The returned value will be of one of the following types: // nil // string (exception if blob is true) // int64 // float64 // []byte // // Calls sqlite3_column_(blob|double|int|int64|text) depending on columns type. // (See http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ScanValue(index int, blob bool) (interface{}, bool) { switch s.ColumnType(index) { case Null: return nil, true case Text: if blob { p := C.sqlite3_column_blob(s.stmt, C.int(index)) n := C.sqlite3_column_bytes(s.stmt, C.int(index)) return C.GoBytes(p, n), false } p := C.sqlite3_column_text(s.stmt, C.int(index)) return C.GoString((*C.char)(unsafe.Pointer(p))), false case Integer: return int64(C.sqlite3_column_int64(s.stmt, C.int(index))), false case Float: return float64(C.sqlite3_column_double(s.stmt, C.int(index))), false case Blob: p := C.sqlite3_column_blob(s.stmt, C.int(index)) n := C.sqlite3_column_bytes(s.stmt, C.int(index)) // value = (*[1 << 30]byte)(unsafe.Pointer(p))[:n] return C.GoBytes(p, n), false // The memory space used to hold strings and BLOBs is freed automatically. } panic("The column type is not one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL") }
// Move cursor to next. func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { rv = C.sqlite3_reset(rc.s.s) if rv != C.SQLITE_OK { return rc.s.c.lastError() } return nil } if rc.decltype == nil { rc.decltype = make([]string, rc.nc) for i := 0; i < rc.nc; i++ { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) switch rc.decltype[i] { case "timestamp", "datetime", "date": unixTimestamp := strconv.FormatInt(val, 10) var t time.Time if len(unixTimestamp) == 13 { duration, err := time.ParseDuration(unixTimestamp + "ms") if err != nil { 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) t = epoch.Add(duration) } else { t = time.Unix(val, 0) } if rc.s.c.loc != nil { t = t.In(rc.s.c.loc) } dest[i] = t case "boolean": dest[i] = val > 0 default: dest[i] = val } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: p := C.sqlite3_column_blob(rc.s.s, C.int(i)) if p == nil { dest[i] = nil continue } n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) switch dest[i].(type) { case sql.RawBytes: dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] default: slice := make([]byte, n) copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) dest[i] = slice } case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: var err error var timeVal time.Time n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) switch rc.decltype[i] { case "timestamp", "datetime", "date": var t time.Time s = strings.TrimSuffix(s, "Z") for _, format := range SQLiteTimestampFormats { if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil { t = timeVal break } } if err != nil { // The column is a time value, so return the zero time on parse failure. t = time.Time{} } if rc.s.c.loc != nil { t = t.In(rc.s.c.loc) } dest[i] = t default: dest[i] = []byte(s) } } } return nil }
// Move cursor to next. func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db))) } if rc.decltype == nil { rc.decltype = make([]string, rc.nc) for i := 0; i < rc.nc; i++ { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) switch rc.decltype[i] { case "timestamp", "datetime": dest[i] = time.Unix(val, 0) case "boolean": dest[i] = val > 0 default: dest[i] = val } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) p := C.sqlite3_column_blob(rc.s.s, C.int(i)) switch dest[i].(type) { case sql.RawBytes: dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] default: slice := make([]byte, n) copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) dest[i] = slice } case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: var err error s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) switch rc.decltype[i] { case "timestamp", "datetime": for _, format := range SQLiteTimestampFormats { if dest[i], err = time.Parse(format, s); err == nil { break } } if err != nil { // The column is a time value, so return the zero time on parse failure. dest[i] = time.Time{} } default: // NOTE(bradfitz): local hack, without internet access. I imagine // this has been fixed upstream properly. (the database/sql/driver // docs say that you can't return strings here) dest[i] = []byte(s) } } } return nil }
// Move cursor to next. func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { rv = C.sqlite3_reset(rc.s.s) if rv != C.SQLITE_OK { return rc.s.c.lastError() } return nil } if rc.decltype == nil { rc.decltype = make([]string, rc.nc) for i := 0; i < rc.nc; i++ { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) switch rc.decltype[i] { case "timestamp", "datetime", "date": var t time.Time // Assume a millisecond unix timestamp if it's 13 digits -- too // large to be a reasonable timestamp in seconds. if val > 1e12 || val < -1e12 { val *= int64(time.Millisecond) // convert ms to nsec } else { val *= int64(time.Second) // convert sec to nsec } t = time.Unix(0, val).UTC() if rc.s.c.loc != nil { t = t.In(rc.s.c.loc) } dest[i] = t case "boolean": dest[i] = val > 0 default: dest[i] = val } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: p := C.sqlite3_column_blob(rc.s.s, C.int(i)) if p == nil { dest[i] = nil continue } n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) switch dest[i].(type) { case sql.RawBytes: dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] default: slice := make([]byte, n) copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) dest[i] = slice } case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: var err error var timeVal time.Time n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) switch rc.decltype[i] { case "timestamp", "datetime", "date": var t time.Time s = strings.TrimSuffix(s, "Z") for _, format := range SQLiteTimestampFormats { if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil { t = timeVal break } } if err != nil { // The column is a time value, so return the zero time on parse failure. t = time.Time{} } if rc.s.c.loc != nil { t = t.In(rc.s.c.loc) } dest[i] = t default: dest[i] = []byte(s) } } } return nil }
func (h *Statement) ColumnText(column int) string { rv := C.sqlite3_column_text(h.cptr, C.int(column)) return C.GoString((*C.char)(unsafe.Pointer(rv))) }
// Move cursor to next. func (rc *SQLiteRows) Next(dest []driver.Value) error { rv := C.sqlite3_step(rc.s.s) if rv == C.SQLITE_DONE { return io.EOF } if rv != C.SQLITE_ROW { rv = C.sqlite3_reset(rc.s.s) if rv != C.SQLITE_OK { return rc.s.c.lastError() } return nil } if rc.decltype == nil { rc.decltype = make([]string, rc.nc) for i := 0; i < rc.nc; i++ { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) switch rc.decltype[i] { case "timestamp", "datetime": dest[i] = time.Unix(val, 0) case "boolean": dest[i] = val > 0 default: dest[i] = val } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: p := C.sqlite3_column_blob(rc.s.s, C.int(i)) if p == nil { dest[i] = nil continue } n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) switch dest[i].(type) { case sql.RawBytes: dest[i] = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] default: slice := make([]byte, n) copy(slice[:], (*[1 << 30]byte)(unsafe.Pointer(p))[0:n]) dest[i] = slice } case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: var err error s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) switch rc.decltype[i] { case "timestamp", "datetime": for _, format := range SQLiteTimestampFormats { if dest[i], err = time.Parse(format, s); err == nil { break } } if err != nil { // The column is a time value, so return the zero time on parse failure. dest[i] = time.Time{} } default: dest[i] = s } } } return nil }