func (bnd *bndTimePtr) bind(value *time.Time, position int, stmt *Stmt) error { bnd.stmt = stmt bnd.value = value r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociDateTime)), //dvoid **descpp, C.OCI_DTYPE_TIMESTAMP_TZ, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci timestamp handle during bind") } r = C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociDateTime), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociDateTime)), //sb8 value_sz, C.SQLT_TIMESTAMP_TZ, //ub2 dty, unsafe.Pointer(&bnd.isNull), //void *indp, nil, //ub2 *alenp, nil, //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }
func (env *Environment) ociDescrAlloc(dst *unsafe.Pointer, typ C.ub4, at string) error { if err := checkStatus( C.OCIDescriptorAlloc(unsafe.Pointer(env.handle), dst, typ, C.size_t(0), nil), false); err != nil { return errgo.New(at + ": " + err.Error()) } return nil }
func (bnd *bndBfile) bind(value Bfile, position int, stmt *Stmt) error { // DirectoryAlias must be specified to avoid error "ORA-24801: illegal parameter value in OCI lob function" // Raising a driver error clarifies the user error if value.DirectoryAlias == "" { return errNew("DirectoryAlias must be specified when binding a non-null Bfile") } // Filename must be specified to avoid error "ORA-24801: illegal parameter value in OCI lob function" // Raising a driver error clarifies the user error if value.Filename == "" { return errNew("Filename must be specified when binding a non-null Bfile") } bnd.stmt = stmt // Allocate lob locator handle r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociLobLocator)), //dvoid **descpp, C.OCI_DTYPE_FILE, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci lob handle during bind") } bnd.cDirectoryAlias = C.CString(value.DirectoryAlias) bnd.cFilename = C.CString(value.Filename) r = C.OCILobFileSetName( bnd.stmt.ses.srv.env.ocienv, //OCIEnv *envhp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, &bnd.ociLobLocator, //OCILobLocator **filepp, (*C.OraText)(unsafe.Pointer(bnd.cDirectoryAlias)), //const OraText *dir_alias, C.ub2(len(value.DirectoryAlias)), //ub2 d_length, (*C.OraText)(unsafe.Pointer(bnd.cFilename)), //const OraText *filename, C.ub2(len(value.Filename))) //ub2 f_length ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } r = C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociLobLocator), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociLobLocator)), //sb8 value_sz, C.SQLT_FILE, //ub2 dty, nil, //void *indp, nil, //ub2 *alenp, nil, //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }
func (bnd *bndTimePtr) bind(value *time.Time, position int, stmt *Stmt) error { bnd.stmt = stmt bnd.value = value r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociDateTime)), //dvoid **descpp, C.OCI_DTYPE_TIMESTAMP_TZ, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci timestamp handle during bind") } if value == nil { bnd.isNull = C.sb2(-1) } else { zone := zoneOffset(*value, &bnd.zoneBuf) bnd.cZone = C.CString(zone) r = C.OCIDateTimeConstruct( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //dvoid *hndl, bnd.stmt.ses.srv.env.ocierr, //OCIError *err, bnd.ociDateTime, //OCIDateTime *datetime, C.sb2(value.Year()), //sb2 year, C.ub1(int32(value.Month())), //ub1 month, C.ub1(value.Day()), //ub1 day, C.ub1(value.Hour()), //ub1 hour, C.ub1(value.Minute()), //ub1 min, C.ub1(value.Second()), //ub1 sec, C.ub4(value.Nanosecond()), //ub4 fsec, (*C.OraText)(unsafe.Pointer(bnd.cZone)), //OraText *timezone, C.size_t(len(zone))) //size_t timezone_length ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } } r = C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociDateTime), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociDateTime)), //sb8 value_sz, C.SQLT_TIMESTAMP_TZ, //ub2 dty, unsafe.Pointer(&bnd.isNull), //void *indp, nil, //ub2 *alenp, nil, //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }
func (def *defIntervalDS) alloc() error { r := C.OCIDescriptorAlloc( unsafe.Pointer(def.rset.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&def.ociInterval)), //dvoid **descpp, C.OCI_DTYPE_INTERVAL_DS, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return def.rset.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci interval handle during define") } return nil }
func (def *defBfile) alloc() error { // Allocate lob locator handle r := C.OCIDescriptorAlloc( unsafe.Pointer(def.rset.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&def.ociLobLocator)), //dvoid **descpp, C.OCI_DTYPE_FILE, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return def.rset.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci lob handle during define") } return nil }
func allocTempLob(stmt *Stmt) ( ociLobLocator *C.OCILobLocator, finish func(), err error, ) { // Allocate lob locator handle r := C.OCIDescriptorAlloc( unsafe.Pointer(stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&ociLobLocator)), //dvoid **descpp, C.OCI_DTYPE_LOB, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return nil, nil, stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return nil, nil, errNew("unable to allocate oci lob handle during bind") } // Create temporary lob r = C.OCILobCreateTemporary( stmt.ses.srv.ocisvcctx, //OCISvcCtx *svchp, stmt.ses.srv.env.ocierr, //OCIError *errhp, ociLobLocator, //OCILobLocator *locp, C.OCI_DEFAULT, //ub2 csid, C.SQLCS_IMPLICIT, //ub1 csfrm, C.OCI_TEMP_BLOB, //ub1 lobtype, C.TRUE, //boolean cache, C.OCI_DURATION_SESSION) //OCIDuration duration); if r == C.OCI_ERROR { // free lob locator handle C.OCIDescriptorFree( unsafe.Pointer(ociLobLocator), //void *descp, C.OCI_DTYPE_LOB) //ub4 type ); return nil, nil, stmt.ses.srv.env.ociError() } return ociLobLocator, func() { C.OCILobFreeTemporary( stmt.ses.srv.ocisvcctx, //OCISvcCtx *svchp, stmt.ses.srv.env.ocierr, //OCIError *errhp, ociLobLocator) //OCILobLocator *locp, // free lob locator handle C.OCIDescriptorFree( unsafe.Pointer(ociLobLocator), //void *descp, C.OCI_DTYPE_LOB) //ub4 type ); }, nil }
func (bnd *bndIntervalDS) bind(value IntervalDS, position int, stmt *Stmt) error { bnd.stmt = stmt r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociInterval)), //dvoid **descpp, C.OCI_DTYPE_INTERVAL_DS, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci interval handle during bind") } r = C.OCIIntervalSetDaySecond( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //void *hndl, bnd.stmt.ses.srv.env.ocierr, //OCIError *err, C.sb4(value.Day), //sb4 dy, C.sb4(value.Hour), //sb4 hr, C.sb4(value.Minute), //sb4 mm, C.sb4(value.Second), //sb4 ss, C.sb4(value.Nanosecond), //sb4 fsec, bnd.ociInterval) //OCIInterval *result ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } r = C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociInterval), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociInterval)), //sb8 value_sz, C.SQLT_INTERVAL_DS, //ub2 dty, nil, //void *indp, nil, //ub2 *alenp, nil, //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }
// Initialize the variable. func lobVar_Initialize(v *Variable, cur *Cursor) error { // initialize members v.connection = cur.connection // v.isFile = v.typ == BFileVarType // initialize the LOB locators var err error for i := uint(0); i < v.allocatedElements; i++ { if err = v.environment.CheckStatus( C.OCIDescriptorAlloc(unsafe.Pointer(v.environment.handle), (*unsafe.Pointer)(unsafe.Pointer(&v.dataBytes[i])), C.OCI_DTYPE_LOB, 0, nil), "DescrAlloc"); err != nil { return err } } return nil }
func (bnd *bndIntervalDSSlice) bind(values []IntervalDS, position int, stmt *Stmt) error { bnd.stmt = stmt bnd.ociIntervals = make([]*C.OCIInterval, len(values)) nullInds := make([]C.sb2, len(values)) alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) for n, value := range values { r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociIntervals[n])), //dvoid **descpp, C.OCI_DTYPE_INTERVAL_DS, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci interval handle during bind") } r = C.OCIIntervalSetDaySecond( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //void *hndl, bnd.stmt.ses.srv.env.ocierr, //OCIError *err, C.sb4(value.Day), //sb4 dy, C.sb4(value.Hour), //sb4 hr, C.sb4(value.Minute), //sb4 mm, C.sb4(value.Second), //sb4 ss, C.sb4(value.Nanosecond), //sb4 fsec, bnd.ociIntervals[n]) //OCIInterval *result ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } if values[n].IsNull { nullInds[n] = C.sb2(-1) } else { nullInds[n] = C.sb2(0) } alenp[n] = C.ACTUAL_LENGTH_TYPE(unsafe.Sizeof(bnd.ociIntervals[n])) } r := C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociIntervals[0]), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociIntervals[0])), //sb8 value_sz, C.SQLT_INTERVAL_DS, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub2 *alenp, &rcodep[0], //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } r = C.OCIBindArrayOfStruct( bnd.ocibnd, bnd.stmt.ses.srv.env.ocierr, C.ub4(unsafe.Sizeof(bnd.ociIntervals[0])), //ub4 pvskip, C.ub4(C.sizeof_sb2), //ub4 indskip, C.ub4(C.sizeof_ub4), //ub4 alskip, C.ub4(C.sizeof_ub2)) //ub4 rcskip if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }
func (s *OCI8Stmt) Query(args []driver.Value) (rows driver.Rows, err error) { var ( freeBoundParameters func() ) if freeBoundParameters, err = s.bind(args); err != nil { return nil, err } defer freeBoundParameters() var t C.int C.OCIAttrGet( s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&t), nil, C.OCI_ATTR_STMT_TYPE, (*C.OCIError)(s.c.err)) iter := C.ub4(1) if t == C.OCI_STMT_SELECT { iter = 0 } // set the row prefetch. Only one extra row per fetch will be returned unless this is set. prefetch_size := C.ub4(s.c.attrs.Get("prefetch_rows").(int)) C.OCIAttrSet(s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&prefetch_size), 0, C.OCI_ATTR_PREFETCH_ROWS, (*C.OCIError)(s.c.err)) // if non-zero, oci will fetch rows until the memory limit or row prefetch limit is hit. // useful for memory constrained systems prefetch_memory := C.ub4(s.c.attrs.Get("prefetch_memory").(int64)) C.OCIAttrSet(s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&prefetch_memory), 0, C.OCI_ATTR_PREFETCH_MEMORY, (*C.OCIError)(s.c.err)) rv := C.OCIStmtExecute( (*C.OCISvcCtx)(s.c.svc), (*C.OCIStmt)(s.s), (*C.OCIError)(s.c.err), iter, 0, nil, nil, C.OCI_DEFAULT) if rv == C.OCI_ERROR { return nil, ociGetError(s.c.err) } var rc C.ub2 C.OCIAttrGet( s.s, C.OCI_HTYPE_STMT, unsafe.Pointer(&rc), nil, C.OCI_ATTR_PARAM_COUNT, (*C.OCIError)(s.c.err)) oci8cols := make([]oci8col, int(rc)) for i := 0; i < int(rc); i++ { var p unsafe.Pointer var np *C.char var ns C.ub4 var tp C.ub2 var lp C.ub2 C.OCIParamGet( s.s, C.OCI_HTYPE_STMT, (*C.OCIError)(s.c.err), (*unsafe.Pointer)(unsafe.Pointer(&p)), C.ub4(i+1)) C.OCIAttrGet( p, C.OCI_DTYPE_PARAM, unsafe.Pointer(&tp), nil, C.OCI_ATTR_DATA_TYPE, (*C.OCIError)(s.c.err)) C.OCIAttrGet( p, C.OCI_DTYPE_PARAM, unsafe.Pointer(&np), &ns, C.OCI_ATTR_NAME, (*C.OCIError)(s.c.err)) C.OCIAttrGet( p, C.OCI_DTYPE_PARAM, unsafe.Pointer(&lp), nil, C.OCI_ATTR_DATA_SIZE, (*C.OCIError)(s.c.err)) switch tp { case C.SQLT_NUM: oci8cols[i].kind = C.SQLT_CHR default: oci8cols[i].kind = tp } oci8cols[i].name = string((*[1 << 30]byte)(unsafe.Pointer(np))[0:int(ns)]) oci8cols[i].size = int(lp) var defp *C.OCIDefine if tp == C.SQLT_CLOB || tp == C.SQLT_BLOB { rv = C.OCIDescriptorAlloc( s.c.env, &oci8cols[i].pbuf, C.OCI_DTYPE_LOB, 0, nil) if rv == C.OCI_ERROR { return nil, ociGetError(s.c.err) } rv = C.OCIDefineByPos( (*C.OCIStmt)(s.s), &defp, (*C.OCIError)(s.c.err), C.ub4(i+1), unsafe.Pointer(&oci8cols[i].pbuf), -1, oci8cols[i].kind, unsafe.Pointer(&oci8cols[i].ind), &oci8cols[i].rlen, nil, C.OCI_DEFAULT) } else { oci8cols[i].pbuf = C.malloc(C.size_t(lp) + 1) rv = C.OCIDefineByPos( (*C.OCIStmt)(s.s), &defp, (*C.OCIError)(s.c.err), C.ub4(i+1), oci8cols[i].pbuf, C.sb4(lp+1), oci8cols[i].kind, unsafe.Pointer(&oci8cols[i].ind), &oci8cols[i].rlen, nil, C.OCI_DEFAULT) } if rv == C.OCI_ERROR { return nil, ociGetError(s.c.err) } } return &OCI8Rows{s, oci8cols, false}, nil }
func (s *OCI8Stmt) bind(args []driver.Value) (freeBoundParameters func(), err error) { if args == nil { return func() {}, nil } var ( bp *C.OCIBind dty C.ub2 data []byte cdata *C.char boundParameters []oci8bind ) freeBoundParameters = func() { for _, col := range boundParameters { if col.pbuf != nil { if col.kind == C.SQLT_CLOB || col.kind == C.SQLT_BLOB { C.OCIDescriptorFree( col.pbuf, C.OCI_DTYPE_LOB) } else { C.free(col.pbuf) } } } } for i, v := range args { data = []byte{} switch v.(type) { case nil: dty = C.SQLT_STR boundParameters = append(boundParameters, oci8bind{dty, nil}) rv := C.OCIBindByPos( (*C.OCIStmt)(s.s), &bp, (*C.OCIError)(s.c.err), C.ub4(i+1), nil, 0, dty, nil, nil, nil, 0, nil, C.OCI_DEFAULT) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } case []byte: // FIXME: Currently, CLOB not supported dty = C.SQLT_BLOB data = v.([]byte) var bamt C.ub4 var pbuf unsafe.Pointer rv := C.OCIDescriptorAlloc( s.c.env, &pbuf, C.OCI_DTYPE_LOB, 0, nil) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } rv = C.OCILobCreateTemporary( (*C.OCISvcCtx)(s.c.svc), (*C.OCIError)(s.c.err), (*C.OCILobLocator)(pbuf), 0, C.SQLCS_IMPLICIT, C.OCI_TEMP_BLOB, C.OCI_ATTR_NOCACHE, C.OCI_DURATION_SESSION) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } bamt = C.ub4(len(data)) rv = C.OCILobWrite( (*C.OCISvcCtx)(s.c.svc), (*C.OCIError)(s.c.err), (*C.OCILobLocator)(pbuf), &bamt, 1, unsafe.Pointer(&data[0]), C.ub4(len(data)), C.OCI_ONE_PIECE, nil, nil, 0, C.SQLCS_IMPLICIT) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } boundParameters = append(boundParameters, oci8bind{dty, pbuf}) rv = C.OCIBindByPos( (*C.OCIStmt)(s.s), &bp, (*C.OCIError)(s.c.err), C.ub4(i+1), unsafe.Pointer(&pbuf), 0, dty, nil, nil, nil, 0, nil, C.OCI_DEFAULT) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } case time.Time: dty = C.SQLT_DAT now := v.(time.Time).In(s.c.location) //TODO Handle BCE dates (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#438305) //TODO Handle timezones (http://docs.oracle.com/cd/B12037_01/appdev.101/b10779/oci03typ.htm#443601) data = []byte{ byte(now.Year()/100 + 100), byte(now.Year()%100 + 100), byte(now.Month()), byte(now.Day()), byte(now.Hour() + 1), byte(now.Minute() + 1), byte(now.Second() + 1), } cdata = C.CString(string(data)) boundParameters = append(boundParameters, oci8bind{dty, unsafe.Pointer(cdata)}) rv := C.OCIBindByPos( (*C.OCIStmt)(s.s), &bp, (*C.OCIError)(s.c.err), C.ub4(i+1), unsafe.Pointer(cdata), C.sb4(len(data)), dty, nil, nil, nil, 0, nil, C.OCI_DEFAULT) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } default: dty = C.SQLT_STR data = []byte(fmt.Sprintf("%v", v)) data = append(data, 0) cdata = C.CString(string(data)) boundParameters = append(boundParameters, oci8bind{dty, unsafe.Pointer(cdata)}) rv := C.OCIBindByPos( (*C.OCIStmt)(s.s), &bp, (*C.OCIError)(s.c.err), C.ub4(i+1), unsafe.Pointer(cdata), C.sb4(len(data)), dty, nil, nil, nil, 0, nil, C.OCI_DEFAULT) if rv == C.OCI_ERROR { defer freeBoundParameters() return nil, ociGetError(s.c.err) } } } return freeBoundParameters, nil }
func (bnd *bndTimeSlice) bind(values []time.Time, nullInds []C.sb2, position int, stmt *Stmt) error { bnd.stmt = stmt bnd.ociDateTimes = make([]*C.OCIDateTime, len(values)) if nullInds == nil { nullInds = make([]C.sb2, len(values)) } alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) for n, timeValue := range values { timezoneStr := zoneOffset(timeValue, &bnd.zoneBuf) cTimezoneStr := C.CString(timezoneStr) defer func() { C.free(unsafe.Pointer(cTimezoneStr)) }() r := C.OCIDescriptorAlloc( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //CONST dvoid *parenth, (*unsafe.Pointer)(unsafe.Pointer(&bnd.ociDateTimes[n])), //dvoid **descpp, C.OCI_DTYPE_TIMESTAMP_TZ, //ub4 type, 0, //size_t xtramem_sz, nil) //dvoid **usrmempp); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } else if r == C.OCI_INVALID_HANDLE { return errNew("unable to allocate oci timestamp handle during bind") } r = C.OCIDateTimeConstruct( unsafe.Pointer(bnd.stmt.ses.srv.env.ocienv), //dvoid *hndl, bnd.stmt.ses.srv.env.ocierr, //OCIError *err, bnd.ociDateTimes[n], //OCIDateTime *datetime, C.sb2(timeValue.Year()), //sb2 year, C.ub1(int32(timeValue.Month())), //ub1 month, C.ub1(timeValue.Day()), //ub1 day, C.ub1(timeValue.Hour()), //ub1 hour, C.ub1(timeValue.Minute()), //ub1 min, C.ub1(timeValue.Second()), //ub1 sec, C.ub4(timeValue.Nanosecond()), //ub4 fsec, (*C.OraText)(unsafe.Pointer(cTimezoneStr)), //OraText *timezone, C.size_t(len(timezoneStr))) //size_t timezone_length ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } alenp[n] = C.ACTUAL_LENGTH_TYPE(unsafe.Sizeof(bnd.ociDateTimes[n])) } r := C.OCIBINDBYPOS( bnd.stmt.ocistmt, //OCIStmt *stmtp, (**C.OCIBind)(&bnd.ocibnd), //OCIBind **bindpp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(position), //ub4 position, unsafe.Pointer(&bnd.ociDateTimes[0]), //void *valuep, C.LENGTH_TYPE(unsafe.Sizeof(bnd.ociDateTimes[0])), //sb8 value_sz, C.SQLT_TIMESTAMP_TZ, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub2 *alenp, &rcodep[0], //ub2 *rcodep, 0, //ub4 maxarr_len, nil, //ub4 *curelep, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } r = C.OCIBindArrayOfStruct( bnd.ocibnd, bnd.stmt.ses.srv.env.ocierr, C.ub4(unsafe.Sizeof(bnd.ociDateTimes[0])), //ub4 pvskip, C.ub4(C.sizeof_sb2), //ub4 indskip, C.ub4(C.sizeof_ub4), //ub4 alskip, C.ub4(C.sizeof_ub2)) //ub4 rcskip if r == C.OCI_ERROR { return bnd.stmt.ses.srv.env.ociError() } return nil }