// BindByIndex binds value to the specified host parameter of the prepared statement. // Value's type/kind is used to find the storage class. // The leftmost SQL parameter has an index of 1. func (s *Stmt) BindByIndex(index int, value interface{}) error { i := C.int(index) var rv C.int switch value := value.(type) { case nil: rv = C.sqlite3_bind_null(s.stmt, i) case string: if NullIfEmptyString && len(value) == 0 { rv = C.sqlite3_bind_null(s.stmt, i) } else { cs, l := cstring(value) rv = C.my_bind_text(s.stmt, i, cs, l) } case int: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case int64: rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value)) case byte: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case bool: rv = C.sqlite3_bind_int(s.stmt, i, btocint(value)) case float32: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case float64: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case []byte: var p *byte if len(value) > 0 { p = &value[0] } rv = C.my_bind_blob(s.stmt, i, unsafe.Pointer(p), C.int(len(value))) case time.Time: if NullIfZeroTime && value.IsZero() { rv = C.sqlite3_bind_null(s.stmt, i) } else { rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value.Unix())) } case ZeroBlobLength: rv = C.sqlite3_bind_zeroblob(s.stmt, i, C.int(value)) case driver.Valuer: v, err := value.Value() if err != nil { return err } return s.BindByIndex(index, v) default: return s.BindReflect(index, value) } return s.error(rv, "Stmt.Bind") }
// BindByIndex binds value to the specified host parameter of the prepared statement. // The leftmost SQL parameter has an index of 1. func (s *Stmt) BindByIndex(index int, value interface{}) error { i := C.int(index) var rv C.int switch value := value.(type) { case nil: rv = C.sqlite3_bind_null(s.stmt, i) case string: cs, l := cstring(value) rv = C.my_bind_text(s.stmt, i, cs, l) case int: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case int64: rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value)) case byte: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case bool: rv = C.sqlite3_bind_int(s.stmt, i, btocint(value)) case float32: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case float64: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case []byte: var p *byte if len(value) > 0 { p = &value[0] } rv = C.my_bind_blob(s.stmt, i, unsafe.Pointer(p), C.int(len(value))) case time.Time: // At least three representations are possible: string (YYYY-MM-DD HH:MM:SS.SSS), int64 (unix time), float64 (julian day) // rv = C.my_bind_text(s.stmt, i, value.format("2006-01-02 15:04:05.000")) rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value.Unix())) // rv = C.sqlite3_bind_double(s.stmt, i, JulianDay(value)) case ZeroBlobLength: rv = C.sqlite3_bind_zeroblob(s.stmt, i, C.int(value)) default: return s.specificError("unsupported type in Bind: %T", value) } return s.error(rv, "Stmt.Bind") }
// bind binds statement parameter i (starting at 1) to the value v. The // parameter name is only used for error reporting. func (s *Stmt) bind(i C.int, v interface{}, name string) error { if v == nil { return nil // Unbound parameters are NULL by default } var rc C.int switch v := v.(type) { case int: rc = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(v)) case int64: rc = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(v)) case float64: rc = C.sqlite3_bind_double(s.stmt, i, C.double(v)) case bool: rc = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(cBool(v))) case string: rc = C.bind_text(s.stmt, i, cStr(v), C.int(len(v)), 1) case []byte: rc = C.bind_blob(s.stmt, i, cBytes(v), C.int(len(v)), 1) case time.Time: rc = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(v.Unix())) case RawString: rc = C.bind_text(s.stmt, i, cStr(string(v)), C.int(len(v)), 0) case RawBytes: rc = C.bind_blob(s.stmt, i, cBytes(v), C.int(len(v)), 0) case ZeroBlob: rc = C.sqlite3_bind_zeroblob(s.stmt, i, C.int(v)) default: if name != "" { return pkgErr(MISUSE, "unsupported type for %s (%T)", name, v) } return pkgErr(MISUSE, "unsupported type at index %d (%T)", int(i-1), v) } if rc != OK { return libErr(rc, s.conn.db) } return nil }
// BindByIndex binds value to the specified host parameter of the prepared statement. // Value's type/kind is used to find the storage class. // The leftmost SQL parameter has an index of 1. func (s *Stmt) BindByIndex(index int, value interface{}) error { i := C.int(index) var rv C.int switch value := value.(type) { case nil: rv = C.sqlite3_bind_null(s.stmt, i) case string: if len(value) == 0 { if NullIfEmptyString { rv = C.sqlite3_bind_null(s.stmt, i) } else { rv = C.my_bind_empty_text(s.stmt, i) } } else { if i64 && len(value) > math.MaxInt32 { return s.specificError("string too big: %d at index %d", len(value), index) } rv = C.my_bind_text(s.stmt, i, C.CString(value), C.int(len(value))) } case int: if i64 { rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value)) } else { rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) } case int32: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case int64: rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value)) case byte: rv = C.sqlite3_bind_int(s.stmt, i, C.int(value)) case bool: rv = C.sqlite3_bind_int(s.stmt, i, btocint(value)) case float32: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case float64: rv = C.sqlite3_bind_double(s.stmt, i, C.double(value)) case []byte: if i64 && len(value) > math.MaxInt32 { return s.specificError("blob too big: %d at index %d", len(value), index) } var p *byte if len(value) > 0 { p = &value[0] } rv = C.my_bind_blob(s.stmt, i, unsafe.Pointer(p), C.int(len(value))) case time.Time: if NullIfZeroTime && value.IsZero() { rv = C.sqlite3_bind_null(s.stmt, i) } else if s.c.DefaultTimeLayout == "" { rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(value.Unix())) } else { v := value.Format(s.c.DefaultTimeLayout) rv = C.my_bind_text(s.stmt, i, C.CString(v), C.int(len(v))) } case ZeroBlobLength: rv = C.sqlite3_bind_zeroblob(s.stmt, i, C.int(value)) case driver.Valuer: v, err := value.Value() if err != nil { return err } return s.BindByIndex(index, v) default: return s.BindReflect(index, value) } return s.error(rv, "Stmt.Bind") }