// Write data to the LOB variable. func (v *Variable) lobVarWrite(data []byte, pos uint, off int64) (amount int, err error) { if !(v.typ == BlobVarType || v.typ == ClobVarType || v.typ == NClobVarType || v.typ == BFileVarType) { return 0, fmt.Errorf("only LOBs an be written into, not %T", v.typ) } amount = len(data) // verify the data type if v.typ == BFileVarType { return 0, errors.New("BFILEs are read only") } if v.typ == BlobVarType { // amount = len(data) /* #if PY_MAJOR_VERSION < 3 } else if (var->type == &vt_NCLOB) { if (cxBuffer_FromObject(&buffer, dataObj, var->environment->nencoding) < 0) return -1; *amount = buffer.size; #endif */ } else { if v.environment.FixedWidth && (v.environment.MaxBytesPerCharacter > 1) { amount /= int(v.environment.MaxBytesPerCharacter) } else { // amount = len(p) } } // nothing to do if no data to write if amount == 0 { return 0, nil } oamount := C.ub4(amount) // Py_BEGIN_ALLOW_THREADS if CTrace { ctrace("OCILobWrite(conn=%p, lob=%x, &oamount=%p, off=%d, cF=%d)", v.connection.handle, v.getHandleBytes(pos), &oamount, off, v.typ.charsetForm) } if err := v.environment.CheckStatus( C.OCILobWrite(v.connection.handle, v.environment.errorHandle, (*C.OCILobLocator)(v.getHandle(pos)), &oamount, C.ub4(off), unsafe.Pointer(&data[0]), C.ub4(len(data)), C.OCI_ONE_PIECE, nil, nil, 0, v.typ.charsetForm), "LobWrite"); err != nil { return 0, err } amount = int(oamount) // Py_END_ALLOW_THREADS return int(oamount), 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 }
// Write data to the LOB variable. func (v *Variable) lobVarWrite(data []byte, pos uint, off int64) (amount int, err error) { if !(v.typ == BlobVarType || v.typ == ClobVarType || v.typ == NClobVarType || v.typ == BFileVarType) { return 0, errgo.Newf("only LOBs an be written into, not %T", v.typ) } amount = len(data) // verify the data type if v.typ == BFileVarType { return 0, errgo.New("BFILEs are read only") } if v.typ == BlobVarType { // amount = len(data) /* #if PY_MAJOR_VERSION < 3 } else if (var->type == &vt_NCLOB) { if (cxBuffer_FromObject(&buffer, dataObj, var->environment->nencoding) < 0) return -1; *amount = buffer.size; #endif */ } else { if v.environment.FixedWidth && (v.environment.MaxBytesPerCharacter > 1) { amount /= int(v.environment.MaxBytesPerCharacter) } else { // amount = len(p) } } // nothing to do if no data to write if amount == 0 { return 0, nil } oamount := C.ub4(amount) // Py_BEGIN_ALLOW_THREADS hndl, err := v.getLobLoc(pos) off++ // "first position is 1" if CTrace { ctrace("OCILobWrite(conn=%p, lob=%p, oamount=%d, off=%d, cF=%d): %v", v.connection.handle, hndl, oamount, off, v.typ.charsetForm, err) } if err != nil { return 0, err } if err := v.environment.CheckStatus( // http://www-rohan.sdsu.edu/doc/oracle/appdev.102/b14250/oci16msc002.htm#i578761 C.OCILobWrite(v.connection.handle, v.environment.errorHandle, hndl, &oamount, C.ub4(off), unsafe.Pointer(&data[0]), C.ub4(len(data)), C.OCI_ONE_PIECE, nil, nil, 0, v.typ.charsetForm), "LobWrite"); err != nil { return 0, errgo.Mask(err) } amount = int(oamount) // Py_END_ALLOW_THREADS return int(oamount), nil }