func (s *Stmt) Exec(args ...interface{}) error { s.args = fmt.Sprintf(" %v", []interface{}(args)) rv := C.sqlite3_reset(s.stmt) if rv != 0 { return s.c.error(rv) } n := int(C.sqlite3_bind_parameter_count(s.stmt)) if n != len(args) { return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n)) } for i, v := range args { var str string switch v := v.(type) { case []byte: var p *byte if len(v) > 0 { p = &v[0] } if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 { return s.c.error(rv) } continue case nil: if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 { return s.c.error(rv) } continue case int: if rv := C.sqlite3_bind_int(s.stmt, C.int(i+1), C.int(v)); rv != 0 { return s.c.error(rv) } continue case bool: intVal := 0 if v { intVal = 1 } if rv := C.sqlite3_bind_int(s.stmt, C.int(i+1), C.int(intVal)); rv != 0 { return s.c.error(rv) } continue default: str = fmt.Sprint(v) } cstr := C.CString(str) rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str))) C.free(unsafe.Pointer(cstr)) if rv != 0 { return s.c.error(rv) } } return nil }
func (s *Stmt) Exec(args ...interface{}) error { s.args = fmt.Sprintf(" %v", []interface{}(args)) rv := C.sqlite3_reset(s.stmt) if rv != 0 { return s.c.error(rv) } n := int(C.sqlite3_bind_parameter_count(s.stmt)) if n != len(args) { return errors.New(fmt.Sprintf("incorrect argument count for Stmt.Exec: have %d want %d", len(args), n)) } for i, v := range args { var str string var rv C.int if v == nil { rv = C.sqlite3_bind_null(s.stmt, C.int(i+1)) } else { switch v := v.(type) { case []byte: var p *byte if len(v) > 0 { p = &v[0] } if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 { return s.c.error(rv) } continue case bool: if v { str = "1" } else { str = "0" } case time.Time: str = v.In(time.UTC).Format(ISO8601) case NullTime: if v.Valid { str = v.Time.Format(ISO8601) } else { if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 { return s.c.error(rv) } continue } default: str = fmt.Sprint(v) } cstr := C.CString(str) rv = C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str))) C.free(unsafe.Pointer(cstr)) } if rv != 0 { return s.c.error(rv) } } return nil }
// BindReflect binds value to the specified host parameter of the prepared statement. // Value's (reflect) Kind is used to find the storage class. // The leftmost SQL parameter has an index of 1. func (s *Stmt) BindReflect(index int, value interface{}) error { i := C.int(index) var rv C.int v := reflect.ValueOf(value) switch v.Kind() { case reflect.String: vs := v.String() // TODO NullIfEmptyString rv = C.my_bind_text(s.stmt, i, C.CString(vs), C.int(len(vs))) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(v.Int())) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: ui := v.Uint() if ui > math.MaxInt64 { return s.specificError("int overflow") } rv = C.sqlite3_bind_int64(s.stmt, i, C.sqlite3_int64(ui)) case reflect.Bool: rv = C.sqlite3_bind_int(s.stmt, i, btocint(v.Bool())) case reflect.Float32, reflect.Float64: rv = C.sqlite3_bind_double(s.stmt, i, C.double(v.Float())) default: name, _ := s.BindParameterName(index) return s.specificError("unsupported type in Bind: %T (index: %d, name: %q)", value, index, name) } return s.error(rv, "Stmt.Bind") }
// 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") }
func (s *Stmt) Exec(args ...interface{}) os.Error { var rv C.int var str string var cstr *C.char if rv = C.sqlite3_reset(s.stmt); rv != 0 { return s.c.error(rv) } if n := int(C.sqlite3_bind_parameter_count(s.stmt)); n != len(args) { return os.NewError(fmt.Sprintf("incorrect argument count: have %d, want %d", len(args), n)) } for i, v := range args { switch v := v.(type) { case []byte: var p *byte if len(v) > 0 { p = &v[0] } if rv = C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 { return s.c.error(rv) } continue case bool: if v { str = "1" } else { str = "0" } default: str = fmt.Sprint(v) } cstr = C.CString(str) rv = C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str))) C.free(unsafe.Pointer(cstr)) if rv != 0 { return s.c.error(rv) } } return nil }
// 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") }
// 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") }
func (s *stmt) start(args []driver.Value) error { if err := s.reset(); err != nil { return err } n := int(C.sqlite3_bind_parameter_count(s.stmt)) if n != len(args) { return fmt.Errorf("incorrect argument count for command: have %d want %d", len(args), n) } for i, v := range args { var str string switch v := v.(type) { case nil: if rv := C.sqlite3_bind_null(s.stmt, C.int(i+1)); rv != 0 { return s.c.error(rv) } continue case float64: if rv := C.sqlite3_bind_double(s.stmt, C.int(i+1), C.double(v)); rv != 0 { return s.c.error(rv) } continue case int64: if rv := C.sqlite3_bind_int64(s.stmt, C.int(i+1), C.sqlite3_int64(v)); rv != 0 { return s.c.error(rv) } continue case []byte: var p *byte if len(v) > 0 { p = &v[0] } if rv := C.my_bind_blob(s.stmt, C.int(i+1), unsafe.Pointer(p), C.int(len(v))); rv != 0 { return s.c.error(rv) } continue case bool: var vi int64 if v { vi = 1 } if rv := C.sqlite3_bind_int64(s.stmt, C.int(i+1), C.sqlite3_int64(vi)); rv != 0 { return s.c.error(rv) } continue case time.Time: str = v.UTC().Format(timefmt[0]) case string: str = v default: str = fmt.Sprint(v) } cstr := C.CString(str) rv := C.my_bind_text(s.stmt, C.int(i+1), cstr, C.int(len(str))) C.free(unsafe.Pointer(cstr)) if rv != 0 { return s.c.error(rv) } } return nil }