// Sets the value stored at the given array position. func lobVarSetValue(v *Variable, pos uint, value interface{}) error { x, ok := value.([]byte) if !ok { return errgo.Newf("requires []byte, got %T", value) } var ( isTemporary C.boolean lobType C.ub1 ) hndl, err := v.getLobLoc(pos) if err != nil { return err } // make sure have temporary LOBs set up if err = v.environment.CheckStatus( C.OCILobIsTemporary(v.environment.handle, v.environment.errorHandle, hndl, &isTemporary), "LobIsTemporary"); err != nil { if CTrace { ctrace("OCILobIsTemporary(env=%p, err=%p, handle=%p, dst=%p): %v", v.environment.handle, v.environment.errorHandle, hndl, &isTemporary, err) } return errgo.Mask(err) } if isTemporary != C.TRUE { if v.typ.oracleType == C.SQLT_BLOB { lobType = C.OCI_TEMP_BLOB } else { lobType = C.OCI_TEMP_CLOB } // Py_BEGIN_ALLOW_THREADS if err = v.environment.CheckStatus( C.OCILobCreateTemporary(v.connection.handle, v.environment.errorHandle, hndl, C.OCI_DEFAULT, v.typ.charsetForm, lobType, C.FALSE, C.OCI_DURATION_SESSION), "LobCreateTemporary"); err != nil { // Py_END_ALLOW_THREADS return errgo.Mask(err) } } // trim the current value // Py_BEGIN_ALLOW_THREADS if err = v.environment.CheckStatus( C.OCILobTrim(v.connection.handle, v.environment.errorHandle, hndl, 0), "LobTrim"); err != nil { return errgo.Mask( // Py_END_ALLOW_THREADS err) } // set the current value // func (v *Variable) lobVarWrite(data []byte, pos uint, off int64) (amount int, err error) { _, err = v.lobVarWrite(x, pos, 0) return err }
// Sets the value stored at the given array position. func lobVarSetValue(v *Variable, pos uint, value interface{}) error { x, ok := value.([]byte) if !ok { return fmt.Errorf("requires []byte, got %T", value) } var ( isTemporary C.boolean lobType C.ub1 err error ) j := pos * v.typ.size // make sure have temporary LOBs set up if err = v.environment.CheckStatus( C.OCILobIsTemporary(v.environment.handle, v.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&v.dataBytes[j])), &isTemporary), "LobIsTemporary"); err != nil { return err } if isTemporary != C.TRUE { if v.typ.oracleType == C.SQLT_BLOB { lobType = C.OCI_TEMP_BLOB } else { lobType = C.OCI_TEMP_CLOB } // Py_BEGIN_ALLOW_THREADS if err = v.environment.CheckStatus( C.OCILobCreateTemporary(v.connection.handle, v.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&v.dataBytes[j])), C.OCI_DEFAULT, v.typ.charsetForm, lobType, C.FALSE, C.OCI_DURATION_SESSION), "LobCreateTemporary"); err != nil { // Py_END_ALLOW_THREADS return err } } // trim the current value // Py_BEGIN_ALLOW_THREADS if err = v.environment.CheckStatus( C.OCILobTrim(v.connection.handle, v.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&v.dataBytes[j])), 0), "LobTrim"); err != nil { return err } // Py_END_ALLOW_THREADS // set the current value // func (v *Variable) lobVarWrite(data []byte, pos uint, off int64) (amount int, err error) { _, err = v.lobVarWrite(x, pos, 0) return err }
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 (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 }