// Bind replaces the literals placed in the SQL statement with the actual // values supplied to the function. // // The following templates may be replaced by the values: // - ? // - ?NNN // - :VVV // - @VVV // - $VVV // In the templates above, NNN represents an integer literal, VVV represents // an alphanumeric identifier. func (p QueryParameter) Bind(s *Statement, value interface{}) (e error) { switch v := value.(type) { case nil: e = SQLiteError(C.sqlite3_bind_null(s.cptr, C.int(p))) case int: e = SQLiteError(C.sqlite3_bind_int(s.cptr, C.int(p), C.int(v))) case string: e = SQLiteError(C.gosqlite3_bind_text(s.cptr, C.int(p), C.CString(v), C.int(len(v)))) case int64: e = SQLiteError(C.sqlite3_bind_int64(s.cptr, C.int(p), C.sqlite3_int64(v))) case float32: e = SQLiteError(C.sqlite3_bind_double(s.cptr, C.int(p), C.double(v))) case float64: e = SQLiteError(C.sqlite3_bind_double(s.cptr, C.int(p), C.double(v))) default: buffer := new(bytes.Buffer) encoder := gob.NewEncoder(buffer) if encoder.Encode(value) != nil { e = ENCODER } else { rawbuffer := string(buffer.Bytes()) cs := C.CString(rawbuffer) defer C.free(unsafe.Pointer(cs)) e = SQLiteError(C.gosqlite3_bind_blob(s.cptr, C.int(p), unsafe.Pointer(cs), C.int(len(rawbuffer)))) } } return }
func (p QueryParameter) Bind(s *Statement, value interface{}) (e os.Error) { var rv Errno switch v := value.(type) { case nil: rv = Errno(C.sqlite3_bind_null(s.cptr, C.int(p))) case int: rv = Errno(C.sqlite3_bind_int(s.cptr, C.int(p), C.int(v))) case string: rv = Errno(C.gosqlite3_bind_text(s.cptr, C.int(p), C.CString(v), C.int(len(v)))) case int64: rv = Errno(C.sqlite3_bind_int64(s.cptr, C.int(p), C.sqlite3_int64(v))) case float32: rv = Errno(C.sqlite3_bind_double(s.cptr, C.int(p), C.double(v))) case float64: rv = Errno(C.sqlite3_bind_double(s.cptr, C.int(p), C.double(v))) default: buffer := new(bytes.Buffer) encoder := gob.NewEncoder(buffer) if encoder.Encode(value) != nil { rv = ENCODER } else { rawbuffer := string(buffer.Bytes()) rv = Errno(C.gosqlite3_bind_blob(s.cptr, C.int(p), unsafe.Pointer(C.CString(rawbuffer)), C.int(len(rawbuffer)))) } } if rv != OK { e = rv } return }
func (s *SQLiteStmt) bind(args []driver.Value) error { rv := C.sqlite3_reset(s.s) if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { return s.c.lastError() } for i, v := range args { n := C.int(i + 1) switch v := v.(type) { case nil: rv = C.sqlite3_bind_null(s.s, n) case string: if len(v) == 0 { b := []byte{0} rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) } else { b := []byte(v) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } case int: rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) case int32: rv = C.sqlite3_bind_int(s.s, n, C.int(v)) case int64: rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) case byte: rv = C.sqlite3_bind_int(s.s, n, C.int(v)) case bool: if bool(v) { rv = C.sqlite3_bind_int(s.s, n, 1) } else { rv = C.sqlite3_bind_int(s.s, n, 0) } case float32: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case float64: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case []byte: var p *byte if len(v) > 0 { p = &v[0] } rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(p), C.int(len(v))) case time.Time: b := []byte(v.UTC().Format(SQLiteTimestampFormats[0])) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } if rv != C.SQLITE_OK { return s.c.lastError() } } 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 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 *SQLiteStmt) bind(args []interface{}) error { rv := C.sqlite3_reset(s.s) if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { return errors.New(C.GoString(C.sqlite3_errmsg(s.c.db))) } for i, v := range args { n := C.int(i + 1) switch v := v.(type) { case nil: rv = C.sqlite3_bind_null(s.s, n) case string: if len(v) == 0 { b := []byte{0} rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) } else { b := []byte(v) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } case int: rv = C.sqlite3_bind_int(s.s, n, C.int(v)) case int64: rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) case byte: rv = C.sqlite3_bind_int(s.s, n, C.int(v)) case bool: if bool(v) { rv = C.sqlite3_bind_int(s.s, n, -1) } else { rv = C.sqlite3_bind_int(s.s, n, 0) } case float32: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case float64: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case []byte: var p *byte if len(v) > 0 { p = &v[0] } rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(p), C.int(len(v))) } if rv != C.SQLITE_OK { return errors.New(C.GoString(C.sqlite3_errmsg(s.c.db))) } } 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") }
func (stmt Stmt) bind(args []driver.Value) error { if C.sqlite3_clear_bindings(stmt.stmt) != C.SQLITE_OK { return stmtError(stmt.stmt) } for i, arg := range args { r := C.int(-1) switch val := arg.(type) { case int64: r = C.sqlite3_bind_int64(stmt.stmt, C.int(i+1), C.sqlite3_int64(val)) case float64: r = C.sqlite3_bind_double(stmt.stmt, C.int(i+1), C.double(val)) case bool: if val { r = C.sqlite3_bind_int64(stmt.stmt, C.int(i+1), C.sqlite3_int64(1)) } else { r = C.sqlite3_bind_int64(stmt.stmt, C.int(i+1), C.sqlite3_int64(0)) } case nil: r = C.sqlite3_bind_null(stmt.stmt, C.int(i+1)) case string: str := C.CString(val) defer C.free(unsafe.Pointer(str)) l := C.int(C.strlen(str)) r = C.bind_text(stmt.stmt, C.int(i+1), str, l) default: panic("unsupported type") } if r != C.SQLITE_OK { return stmtError(stmt.stmt) } } return nil }
func (s *SQLiteStmt) bind(args []namedValue) error { rv := C.sqlite3_reset(s.s) if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { return s.c.lastError() } for i, v := range args { if v.Name != "" { cname := C.CString(":" + v.Name) args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s.s, cname)) C.free(unsafe.Pointer(cname)) } } for _, arg := range args { n := C.int(arg.Ordinal) switch v := arg.Value.(type) { case nil: rv = C.sqlite3_bind_null(s.s, n) case string: if len(v) == 0 { b := []byte{0} rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) } else { b := []byte(v) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } case int64: rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) case bool: if bool(v) { rv = C.sqlite3_bind_int(s.s, n, 1) } else { rv = C.sqlite3_bind_int(s.s, n, 0) } case float64: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case []byte: if len(v) == 0 { rv = C._sqlite3_bind_blob(s.s, n, nil, 0) } else { rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(len(v))) } case time.Time: b := []byte(v.Format(SQLiteTimestampFormats[0])) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } if rv != C.SQLITE_OK { return s.c.lastError() } } 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") }
// 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 }
func (s *SQLiteStmt) bind(args []driver.Value) error { rv := C.sqlite3_reset(s.s) if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { return s.c.lastError() } var vargs []bindArg narg := len(args) vargs = make([]bindArg, narg) if len(s.nn) > 0 { for i, v := range s.nn { if pi, err := strconv.Atoi(v[1:]); err == nil { vargs[i] = bindArg{pi, args[i]} } } } else { for i, v := range args { vargs[i] = bindArg{i + 1, v} } } for _, varg := range vargs { n := C.int(varg.n) v := varg.v switch v := v.(type) { case nil: rv = C.sqlite3_bind_null(s.s, n) case string: if len(v) == 0 { b := []byte{0} rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(0)) } else { b := []byte(v) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } case int64: rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v)) case bool: if bool(v) { rv = C.sqlite3_bind_int(s.s, n, 1) } else { rv = C.sqlite3_bind_int(s.s, n, 0) } case float64: rv = C.sqlite3_bind_double(s.s, n, C.double(v)) case []byte: var p *byte if len(v) > 0 { p = &v[0] } rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(p), C.int(len(v))) case time.Time: b := []byte(v.UTC().Format(SQLiteTimestampFormats[0])) rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } if rv != C.SQLITE_OK { return s.c.lastError() } } return nil }
func (self *sqlStatement) sqlBindDouble(slot int, value float64) int { return int(C.sqlite3_bind_double(self.handle, C.int(slot+1), C.double(value))) }
// 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 }
func (h *Statement) BindDouble(column int, val float64) int { rv := C.sqlite3_bind_double(h.cptr, C.int(column), C.double(val)) return int(rv) }
func (s *Stmt) Exec2(args ...interface{}) os.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 os.NewError(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 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 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 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 []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 }