Example #1
0
// 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
}
Example #2
0
// 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
}
Example #3
0
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
}
Example #4
0
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
}