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 }
// BindParameterIndex returns the index of a parameter with a given name (cached). // The first host parameter has an index of 1, not 0. // (See http://sqlite.org/c3ref/bind_parameter_index.html) func (s *Stmt) BindParameterIndex(name string) (int, error) { if s.params == nil { count := s.BindParameterCount() s.params = make(map[string]int, count) } index, ok := s.params[name] if ok { return index, nil } cname := C.CString(name) index = int(C.sqlite3_bind_parameter_index(s.stmt, cname)) C.free(unsafe.Pointer(cname)) if index == 0 { return index, s.specificError("invalid parameter name: %q", name) } s.params[name] = index return index, nil }