func (rows Rows) Next(dest []driver.Value) error { r := C.sqlite3_step(rows.stmt) if r == C.SQLITE_DONE { return io.EOF } if r != C.SQLITE_ROW { return stmtError(rows.stmt) } count := len(dest) for i := 0; i < count; i++ { t := C.sqlite3_column_type(rows.stmt, C.int(i)) switch t { case C.SQLITE_INTEGER: dest[i] = int64(C.sqlite3_column_int64(rows.stmt, C.int(i))) case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rows.stmt, C.int(i))) case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: n := C.sqlite3_column_bytes(rows.stmt, C.int(i)) blob := C.sqlite3_column_blob(rows.stmt, C.int(i)) dest[i] = C.GoBytes(blob, n) default: panic("unsupported type") } } return nil }
func (r *rows) Next(dst []driver.Value) error { if r.s == nil { panic("database/sql/driver: misuse of sqlite driver: Next of closed Rows") } rv := C.sqlite3_step(r.s.stmt) if errno(rv) != stepRow { if errno(rv) == stepDone { return io.EOF } if rv == 0 { rv = 21 } return r.s.c.error(rv) } for i := range dst { switch typ := C.sqlite3_column_type(r.s.stmt, C.int(i)); typ { default: return fmt.Errorf("unexpected sqlite3 column type %d", typ) case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(r.s.stmt, C.int(i))) switch r.s.coltypes[i] { case "timestamp", "datetime": dst[i] = time.Unix(val, 0).UTC() case "boolean": dst[i] = val > 0 default: dst[i] = val } case C.SQLITE_FLOAT: dst[i] = float64(C.sqlite3_column_double(r.s.stmt, C.int(i))) case C.SQLITE_BLOB, C.SQLITE_TEXT: n := int(C.sqlite3_column_bytes(r.s.stmt, C.int(i))) var b []byte if n > 0 { p := C.sqlite3_column_blob(r.s.stmt, C.int(i)) b = (*[maxslice]byte)(unsafe.Pointer(p))[:n] } dst[i] = b switch r.s.coltypes[i] { case "timestamp", "datetime": dst[i] = time.Time{} s := string(b) for _, f := range timefmt { if t, err := time.Parse(f, s); err == nil { dst[i] = t break } } } case C.SQLITE_NULL: dst[i] = nil } } 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))) } 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 }
func (s *Stmt) ColumnType(n int) ColType { switch C.sqlite3_column_type(s.stmt, C.int(n)) { case C.SQLITE_INTEGER: return Integer case C.SQLITE_FLOAT: return Float case C.SQLITE_BLOB: return Blob case C.SQLITE_NULL: return Null case C.SQLITE_TEXT: return Text } return Unknown }
// ColumnTypeScanType implement RowsColumnTypeScanType. func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) { case "timestamp", "datetime", "date": return reflect.TypeOf(time.Time{}) case "boolean": return reflect.TypeOf(false) } return reflect.TypeOf(int64(0)) case C.SQLITE_FLOAT: return reflect.TypeOf(float64(0)) case C.SQLITE_BLOB: return reflect.SliceOf(reflect.TypeOf(byte(0))) case C.SQLITE_NULL: return reflect.TypeOf(nil) case C.SQLITE_TEXT: return reflect.TypeOf("") } return reflect.SliceOf(reflect.TypeOf(byte(0))) }
// 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 }
func (self *sqlStatement) sqlColumnType(col int) int { return int(C.sqlite3_column_type(self.handle, C.int(col))) }
// ColumnType returns the datatype code for the initial data type of the result column. // The leftmost column is number 0. // Should not be cached (valid only for one row) (see dynamic type http://www.sqlite.org/datatype3.html) // // After a type conversion, the value returned by sqlite3_column_type() is undefined. // (See sqlite3_column_type: http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ColumnType(index int) Type { if index < 0 || index >= s.ColumnCount() { panic(fmt.Sprintf("column index %d out of range [0,%d[.", index, s.ColumnCount())) } return Type(C.sqlite3_column_type(s.stmt, C.int(index))) // TODO request all columns type at once }
// 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 }
// 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 (c ResultColumn) Type(s *Statement) int { return int(C.sqlite3_column_type(s.cptr, C.int(c))) }
// The sqlite3_column_type() routine returns the datatype code for the initial // data type of the result column. The returned value is one of SQLITE_INTEGER, // SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL func (h *Statement) ColumnType(column int) int { return int(C.sqlite3_column_type(h.cptr, C.int(column))) }
// ColumnType returns the datatype code for the initial data type of the result column. // The leftmost column is number 0. // Should not be cached (valid only for one row) (see dynamic type http://www.sqlite.org/datatype3.html) // // After a type conversion, the value returned by sqlite3_column_type() is undefined. // (See sqlite3_column_type: http://sqlite.org/c3ref/column_blob.html) func (s *Stmt) ColumnType(index int) Type { return Type(C.sqlite3_column_type(s.stmt, C.int(index))) }
func (s *Stmt) Scan(args ...interface{}) error { n := int(C.sqlite3_column_count(s.stmt)) if n != len(args) { return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Scan: have %d want %d", len(args), n)) } for i, v := range args { if C.sqlite3_column_type(s.stmt, C.int(i)) == C.SQLITE_NULL { switch v := v.(type) { case *[]byte: *v = nil case *string: *v = "" case *bool: *v = false case *int: *v = 0 case *int64: *v = 0 case *uint64: *v = 0 case *uint32: *v = 0 case *float64: *v = 0.0 case *NullTime: *v = NullTime{Valid: false} default: return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String()) } } else { n := C.sqlite3_column_bytes(s.stmt, C.int(i)) p := C.sqlite3_column_blob(s.stmt, C.int(i)) if p == nil && n > 0 { return errors.New("got nil blob") } var data []byte if n > 0 { data = (*[1 << 30]byte)(unsafe.Pointer(p))[0:n] } switch v := v.(type) { case *[]byte: *v = data case *string: *v = string(data) case *bool: *v = string(data) == "1" case *int: x, err := strconv.Atoi(string(data)) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as int: " + err.Error()) } *v = x case *int64: x, err := strconv.ParseInt(string(data), 10, 64) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error()) } *v = x case *uint64: x, err := strconv.ParseUint(string(data), 10, 64) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error()) } *v = x case *uint32: x, err := strconv.ParseUint(string(data), 10, 32) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as int64: " + err.Error()) } *v = uint32(x) case *float64: x, err := strconv.ParseFloat(string(data), 64) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as float64: " + err.Error()) } *v = x case *NullTime: x, err := time.Parse(ISO8601, string(data)) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as time: " + err.Error()) } *v = NullTime{Time: x, Valid: true} case *time.Time: x, err := time.Parse(ISO8601, string(data)) if err != nil { return errors.New("arg " + strconv.Itoa(i) + " as time: " + err.Error()) } *v = x default: return errors.New("unsupported type in Scan: " + reflect.TypeOf(v).String()) } } } 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 }