func (c *OCI8Conn) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var s unsafe.Pointer rv := C.OCIHandleAlloc( c.env, &s, C.OCI_HTYPE_STMT, 0, nil) if rv == C.OCI_ERROR { return nil, ociGetError(c.err) } rv = C.OCIStmtPrepare( (*C.OCIStmt)(s), (*C.OCIError)(c.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(OCI_MODE)) if rv == C.OCI_ERROR { return nil, ociGetError(c.err) } return &OCI8Stmt{c: c, s: s}, nil }
func (c *OCI8Conn) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var s, bp, defp unsafe.Pointer if rv := C.WrapOCIHandleAlloc( c.env, C.OCI_HTYPE_STMT, (C.size_t)(unsafe.Sizeof(bp)*2)); rv.rv != C.OCI_SUCCESS { return nil, ociGetError(c.err) } else { s = rv.ptr bp = rv.extra defp = unsafe.Pointer(uintptr(rv.extra) + unsafe.Sizeof(unsafe.Pointer(nil))) } if rv := C.OCIStmtPrepare( (*C.OCIStmt)(s), (*C.OCIError)(c.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(C.OCI_DEFAULT)); rv != C.OCI_SUCCESS { return nil, ociGetError(c.err) } ss := &OCI8Stmt{c: c, s: s, bp: (**C.OCIBind)(bp), defp: (**C.OCIDefine)(defp)} runtime.SetFinalizer(ss, (*OCI8Stmt).Close) return ss, nil }
func (conn *connection) performLogon(dsn string) error { user, pwd, host := parseDsn(dsn) puser := C.CString(user) defer C.free(unsafe.Pointer(puser)) ppwd := C.CString(pwd) defer C.free(unsafe.Pointer(ppwd)) phost := C.CString(host) defer C.free(unsafe.Pointer(phost)) result := C.OCILogon2((*C.OCIEnv)(unsafe.Pointer(conn.env)), (*C.OCIError)(conn.err), (**C.OCIServer)(unsafe.Pointer(&conn.svr)), (*C.OraText)(unsafe.Pointer(puser)), C.ub4(C.strlen(puser)), (*C.OraText)(unsafe.Pointer(ppwd)), C.ub4(C.strlen(ppwd)), (*C.OraText)(unsafe.Pointer(phost)), C.ub4(C.strlen(phost)), C.OCI_LOGON2_STMTCACHE) if result != C.OCI_SUCCESS { return ociGetError(conn.err) } return nil }
func (conn *OCI8Conn) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var s unsafe.Pointer rv := C.OCIHandleAlloc( conn.env, &s, C.OCI_HTYPE_STMT, 0, nil) if err := conn.check(rv, "OCI8Conn.Prepare() allocate statement handle"); err != nil { return nil, err } rv = C.OCIStmtPrepare( (*C.OCIStmt)(s), (*C.OCIError)(conn.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(C.OCI_DEFAULT)) if err := conn.check(rv, "OCI8Conn.Prepare() prepare statement"); err != nil { return nil, err } return &OCI8Stmt{c: conn, s: s}, nil }
// Allocate a variable and bind it to the given statement. func (v *Variable) internalBind() (err error) { var status C.sword // perform the bind aL, rC := v.aLrC() allElts := C.ub4(0) //actElts := C.ub4(v.actualElements) pActElts := &v.actualElements if v.isArray { allElts = C.ub4(v.allocatedElements) } else { pActElts = nil } //log.Printf("%v isArray? %b allElts=%d", v.typ.Name, v.isArray, allElts) if v.boundName != "" { bname := []byte(v.boundName) if CTrace { ctrace("internalBind.OCIBindByName", v.boundCursorHandle, &v.bindHandle, v.environment.errorHandle, "name="+string(bname), len(bname), v.getDataArr(), v.bufferSize, v.typ.oracleType, v.indicator, aL, rC, allElts, pActElts, "DEFAULT") } status = C.OCIBindByName(v.boundCursorHandle, &v.bindHandle, v.environment.errorHandle, (*C.OraText)(&bname[0]), C.sb4(len(bname)), v.getDataArr(), C.sb4(v.bufferSize), v.typ.oracleType, unsafe.Pointer(&v.indicator[0]), aL, rC, allElts, pActElts, C.OCI_DEFAULT) } else { if CTrace { ctrace("internalBind.OCIBindByPos", v.boundCursorHandle, &v.bindHandle, v.environment.errorHandle, fmt.Sprintf("pos=%d", v.boundPos), "dataArr:", fmt.Sprintf("%x", v.dataBytes[:v.bufferSize]), "bufsize:", v.bufferSize, "typ:", v.typ.oracleType, v.indicator, aL, rC, allElts, pActElts, "DEFAULT") } status = C.OCIBindByPos(v.boundCursorHandle, &v.bindHandle, v.environment.errorHandle, C.ub4(v.boundPos), v.getDataArr(), C.sb4(v.bufferSize), v.typ.oracleType, unsafe.Pointer(&v.indicator[0]), aL, rC, allElts, pActElts, C.OCI_DEFAULT) } if err = v.environment.CheckStatus(status, "BindBy"); err != nil { return } // set the max data size for strings if (v.typ == StringVarType || v.typ == FixedCharVarType) && v.size > v.typ.size { err = v.environment.AttrSet( unsafe.Pointer(v.bindHandle), C.OCI_HTYPE_BIND, C.OCI_ATTR_MAXDATA_SIZE, unsafe.Pointer(&v.typ.size), C.sizeof_ub4) } return }
func (d *OCI8Driver) Open(dsn string) (driver.Conn, error) { var conn OCI8Conn token := strings.SplitN(dsn, "@", 2) userpass := strings.SplitN(token[0], "/", 2) rv := C.OCIInitialize( C.OCI_DEFAULT, nil, nil, nil, nil) if rv == C.OCI_ERROR { return nil, ociGetError(conn.err) } rv = C.OCIEnvInit( (**C.OCIEnv)(unsafe.Pointer(&conn.env)), C.OCI_DEFAULT, 0, nil) rv = C.OCIHandleAlloc( conn.env, &conn.err, C.OCI_HTYPE_ERROR, 0, nil) if rv == C.OCI_ERROR { return nil, ociGetError(conn.err) } var phost *C.char phostlen := C.size_t(0) if len(token) > 1 { phost = C.CString(token[1]) defer C.free(unsafe.Pointer(phost)) phostlen = C.strlen(phost) } puser := C.CString(userpass[0]) defer C.free(unsafe.Pointer(puser)) ppass := C.CString(userpass[1]) defer C.free(unsafe.Pointer(ppass)) rv = C.OCILogon( (*C.OCIEnv)(conn.env), (*C.OCIError)(conn.err), (**C.OCIServer)(unsafe.Pointer(&conn.svc)), (*C.OraText)(unsafe.Pointer(puser)), C.ub4(C.strlen(puser)), (*C.OraText)(unsafe.Pointer(ppass)), C.ub4(C.strlen(ppass)), (*C.OraText)(unsafe.Pointer(phost)), C.ub4(phostlen)) if rv == C.OCI_ERROR { return nil, ociGetError(conn.err) } return &conn, nil }
// Prep prepares a sql statement returning a *Stmt and possible error. func (ses *Ses) Prep(sql string, gcts ...GoColumnType) (stmt *Stmt, err error) { ses.mu.Lock() defer ses.mu.Unlock() defer func() { if value := recover(); value != nil { err = errR(value) } }() ses.log(_drv.cfg.Log.Ses.Prep, sql) err = ses.checkClosed() if err != nil { return nil, errE(err) } // allocate statement handle upOciStmt, err := ses.srv.env.allocOciHandle(C.OCI_HTYPE_STMT) if err != nil { return nil, errE(err) } ocistmt := (*C.OCIStmt)(upOciStmt) cSql := C.CString(sql) // prepare sql text with statement handle defer C.free(unsafe.Pointer(cSql)) r := C.OCIStmtPrepare2( ses.srv.ocisvcctx, // OCISvcCtx *svchp, &ocistmt, // OCIStmt *stmtp, ses.srv.env.ocierr, // OCIError *errhp, (*C.OraText)(unsafe.Pointer(cSql)), // const OraText *stmt, C.ub4(len(sql)), // ub4 stmt_len, nil, // const OraText *key, C.ub4(0), // ub4 keylen, C.OCI_NTV_SYNTAX, // ub4 language, C.OCI_DEFAULT) // ub4 mode ); if r == C.OCI_ERROR { return nil, errE(ses.srv.env.ociError()) } // set stmt struct stmt = _drv.stmtPool.Get().(*Stmt) stmt.ses = ses stmt.ocistmt = (*C.OCIStmt)(ocistmt) stmtCfg := ses.cfg.StmtCfg if stmtCfg == nil { stmtCfg = NewStmtCfg() } if !ses.srv.dbIsUTF8 && stmtCfg.stringPtrBufferSize > 1000 { stmtCfg.stringPtrBufferSize = 1000 } stmt.cfg = *stmtCfg stmt.sql = sql stmt.gcts = gcts if stmt.id == 0 { stmt.id = _drv.stmtId.nextId() } err = stmt.attr(unsafe.Pointer(&stmt.stmtType), 4, C.OCI_ATTR_STMT_TYPE) // determine statement type if err != nil { return nil, errE(err) } ses.openStmts.add(stmt) return stmt, nil }
func (bnd *bndStringSlice) bind(values []string, nullInds []C.sb2, position int, stmt *Stmt) (err error) { bnd.stmt = stmt if nullInds == nil { nullInds = make([]C.sb2, len(values)) } alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) var maxLen int for _, str := range values { strLen := len(str) if strLen > maxLen { maxLen = strLen } } for m := 0; m < len(values); m++ { _, err = bnd.buf.WriteString(values[m]) if err != nil { return err } // pad to make equal to max len if necessary padLen := maxLen - len(values[m]) for n := 0; n < padLen; n++ { _, err = bnd.buf.WriteRune('0') if err != nil { return err } } alenp[m] = C.ACTUAL_LENGTH_TYPE(len(values[m])) } bnd.bytes = bnd.buf.Bytes() 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.bytes[0]), //void *valuep, C.LENGTH_TYPE(maxLen), //sb8 value_sz, C.SQLT_CHR, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub4 *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(maxLen), //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 }
// close closes the SQL statement. // does not remove Stmt from Ses.openStmts func (stmt *Stmt) close() (err error) { stmt.mu.Lock() defer stmt.mu.Unlock() stmt.log(_drv.cfg.Log.Stmt.Close) err = stmt.checkClosed() if err != nil { return errE(err) } errs := _drv.listPool.Get().(*list.List) defer func() { if value := recover(); value != nil { errs.PushBack(errR(value)) } // free ocistmt to release cursor on server // OCIStmtRelease must be called with OCIStmtPrepare2 // See https://docs.oracle.com/database/121/LNOCI/oci09adv.htm#LNOCI16655 r := C.OCIStmtRelease( stmt.ocistmt, // OCIStmt *stmthp stmt.ses.srv.env.ocierr, // OCIError *errhp, nil, // const OraText *key C.ub4(0), // ub4 keylen C.OCI_DEFAULT, // ub4 mode ) if r == C.OCI_ERROR { errs.PushBack(errE(stmt.ses.srv.env.ociError())) } stmt.ses = nil stmt.ocistmt = nil stmt.stmtType = C.ub4(0) stmt.sql = "" stmt.gcts = nil stmt.bnds = nil stmt.hasPtrBind = false stmt.openRsets.clear() _drv.stmtPool.Put(stmt) multiErr := newMultiErrL(errs) if multiErr != nil { err = errE(*multiErr) } errs.Init() _drv.listPool.Put(errs) }() if len(stmt.bnds) > 0 { // close binds for _, bind := range stmt.bnds { if bind != nil { err = bind.close() if err != nil { errs.PushBack(errE(err)) } } } } stmt.openRsets.closeAll(errs) return 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, 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 (bnd *bndBinSlice) bind(values [][]byte, nullInds []C.sb2, position int, lobBufferSize int, stmt *Stmt) error { bnd.stmt = stmt if nullInds == nil { nullInds = make([]C.sb2, len(values)) } alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) var maxLen int for _, b := range values { if len(b) > maxLen { maxLen = len(b) } } n := maxLen * len(values) if cap(bnd.buf) < n { bnd.buf = make([]byte, n) } else { bnd.buf = bnd.buf[:n] // reset buffer for i := range bnd.buf { bnd.buf[i] = 0 } } for i, b := range values { copy(bnd.buf[i*maxLen:], b) alenp[i] = C.ACTUAL_LENGTH_TYPE(len(b)) } 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.buf[0]), //void *valuep, C.LENGTH_TYPE(maxLen), //sb8 value_sz, C.SQLT_LBI, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub4 *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(maxLen), //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 (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 (d *OCI8Driver) Open(dsnString string) (connection driver.Conn, err error) { var ( conn OCI8Conn dsn *DSN ) if dsn, err = ParseDSN(dsnString); err != nil { return nil, err } if rv := C.WrapOCIEnvCreate( C.OCI_DEFAULT|C.OCI_THREADED, 0); rv.rv != C.OCI_SUCCESS && rv.rv != C.OCI_SUCCESS_WITH_INFO { // TODO: error handle not yet allocated, we can't get string error from oracle return nil, errors.New("can't OCIEnvCreate") } else { conn.env = rv.ptr } if rv := C.WrapOCIHandleAlloc( conn.env, C.OCI_HTYPE_ERROR, 0); rv.rv != C.OCI_SUCCESS { return nil, errors.New("cant allocate error handle") } else { conn.err = rv.ptr } phost := C.CString(dsn.Connect) defer C.free(unsafe.Pointer(phost)) puser := C.CString(dsn.Username) defer C.free(unsafe.Pointer(puser)) ppass := C.CString(dsn.Password) defer C.free(unsafe.Pointer(ppass)) if rv := C.WrapOCILogon( (*C.OCIEnv)(conn.env), (*C.OCIError)(conn.err), (*C.OraText)(unsafe.Pointer(puser)), C.ub4(len(dsn.Username)), (*C.OraText)(unsafe.Pointer(ppass)), C.ub4(len(dsn.Password)), (*C.OraText)(unsafe.Pointer(phost)), C.ub4(len(dsn.Connect))); rv.rv != C.OCI_SUCCESS && rv.rv != C.OCI_SUCCESS_WITH_INFO { return nil, ociGetError(rv.rv, conn.err) } else { conn.svc = rv.ptr } conn.location = dsn.Location conn.transactionMode = dsn.transactionMode conn.prefetch_rows = dsn.prefetch_rows conn.prefetch_memory = dsn.prefetch_memory conn.enableQMPlaceholders = dsn.enableQMPlaceholders return &conn, nil }
func (bnd *bndBoolSlice) bind(values []bool, nullInds []C.sb2, position int, falseRune rune, trueRune rune, stmt *Stmt) (err error) { bnd.stmt = stmt if nullInds == nil { nullInds = make([]C.sb2, len(values)) } alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) var maxLen int = 1 for n, bValue := range values { if bValue { _, err = bnd.buf.WriteRune(trueRune) if err != nil { return err } } else { _, err = bnd.buf.WriteRune(falseRune) if err != nil { return err } } alenp[n] = 1 } bnd.bytes = bnd.buf.Bytes() 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.bytes[0]), //void *valuep, C.LENGTH_TYPE(maxLen), //sb8 value_sz, C.SQLT_CHR, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub4 *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, //OCIBind *bindp, bnd.stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(maxLen), //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 }
// qry runs a SQL query on an Oracle server returning a *Rset and possible error. func (stmt *Stmt) qry(params []interface{}) (rset *Rset, err error) { stmt.mu.Lock() defer stmt.mu.Unlock() defer func() { if value := recover(); value != nil { err = errR(value) } }() stmt.log(_drv.cfg.Log.Stmt.Qry) err = stmt.checkClosed() if err != nil { return nil, errE(err) } _, err = stmt.bind(params) // bind parameters if err != nil { return nil, errE(err) } err = stmt.setPrefetchSize() // set prefetch size if err != nil { return nil, errE(err) } // Query statement on Oracle server r := C.OCIStmtExecute( stmt.ses.ocisvcctx, //OCISvcCtx *svchp, stmt.ocistmt, //OCIStmt *stmtp, stmt.ses.srv.env.ocierr, //OCIError *errhp, C.ub4(0), //ub4 iters, C.ub4(0), //ub4 rowoff, nil, //const OCISnapshot *snap_in, nil, //OCISnapshot *snap_out, C.OCI_DEFAULT) //ub4 mode ); if r == C.OCI_ERROR { return nil, errE(stmt.ses.srv.env.ociError()) } if stmt.hasPtrBind { // set any bind pointers err = stmt.setBindPtrs() if err != nil { return nil, errE(err) } } // create result set and open rset = _drv.rsetPool.Get().(*Rset) if rset.id == 0 { rset.id = _drv.rsetId.nextId() } err = rset.open(stmt, stmt.ocistmt) if err != nil { rset.close() return nil, errE(err) } stmt.openRsets.add(rset) return rset, nil }
// Set the value of the variable from a Python decimal.Decimal object. func (env *Environment) numberFromText(value string, dst unsafe.Pointer) error { valuebuf := []byte(value) formatbuf := []byte(numberVarformatForString(value)) return env.CheckStatus( C.OCINumberFromText(env.errorHandle, (*C.oratext)(&valuebuf[0]), C.ub4(len(valuebuf)), (*C.oratext)(&formatbuf[0]), C.ub4(len(formatbuf)), (*C.oratext)(&env.nlsNumericCharactersBuffer[0]), C.ub4(len(env.nlsNumericCharactersBuffer)), (*C.OCINumber)(dst)), "numberFromText") }
// internalRead returns the size of the LOB variable for internal comsumption. func (lv *ExternalLobVar) internalRead(p []byte, off int64) (length int64, err error) { var charsetID C.ub2 j := lv.pos * lv.lobVar.typ.size if lv.isFile { // Py_BEGIN_ALLOW_THREADS if err = lv.lobVar.environment.CheckStatus( C.OCILobFileOpen(lv.lobVar.connection.handle, lv.lobVar.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j])), C.OCI_FILE_READONLY), "LobFileOpen"); err != nil { return } } // Py_END_ALLOW_THREADS // Py_BEGIN_ALLOW_THREADS if lv.lobVar.typ == NClobVarType { // charsetID = C.OCI_UTF16ID charsetID = CsIDAl32UTF8 } else { charsetID = 0 } length = int64(len(p)) olength := C.ub4(length + 1) if err = lv.lobVar.environment.CheckStatus( C.OCILobRead(lv.lobVar.connection.handle, lv.lobVar.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j])), &olength, C.ub4(off+1), unsafe.Pointer(&p[0]), C.ub4(len(p)), nil, nil, charsetID, lv.lobVar.typ.charsetForm), "LobRead"); err != nil { // Py_END_ALLOW_THREADS C.OCILobFileClose(lv.lobVar.connection.handle, lv.lobVar.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j]))) return } if lv.isFile { // Py_BEGIN_ALLOW_THREADS if err = lv.lobVar.environment.CheckStatus( C.OCILobFileClose(lv.lobVar.connection.handle, lv.lobVar.environment.errorHandle, (*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j]))), "LobFileClose"); err != nil { return } } return }
func (env *Environment) AttrGet(parent unsafe.Pointer, parentType, key int, dst unsafe.Pointer, errText string) (int, error) { var osize C.ub4 if CTrace { ctrace("OCIAttrGet", parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle) } if err := env.CheckStatus( C.OCIAttrGet(parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle), errText); err != nil { // log.Printf("error gettint attr: %s", err) return -1, err } return int(osize), nil }
func (bnd *bndInt16Slice) bind(values []int16, nullInds []C.sb2, position int, stmt *Stmt) error { bnd.stmt = stmt if nullInds == nil { nullInds = make([]C.sb2, len(values)) } alenp := make([]C.ACTUAL_LENGTH_TYPE, len(values)) rcodep := make([]C.ub2, len(values)) bnd.ociNumbers = make([]C.OCINumber, len(values)) for n := range values { alenp[n] = C.ACTUAL_LENGTH_TYPE(C.sizeof_OCINumber) r := C.OCINumberFromInt( bnd.stmt.ses.srv.env.ocierr, //OCIError *err, unsafe.Pointer(&values[n]), //const void *inum, 2, //uword inum_length, C.OCI_NUMBER_SIGNED, //uword inum_s_flag, &bnd.ociNumbers[n]) //OCINumber *number ); 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.ociNumbers[0]), //void *valuep, C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz, C.SQLT_VNU, //ub2 dty, unsafe.Pointer(&nullInds[0]), //void *indp, &alenp[0], //ub4 *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(C.sizeof_OCINumber), //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 }
//AttrGet gets the parent's attribute identified by key, and stores it in dst func (env *Environment) AttrGet(parent unsafe.Pointer, parentType, key int, dst unsafe.Pointer, errText string) (int, error) { var osize C.ub4 if CTrace { ctrace("OCIAttrGet(parent=%p, parentType=%d, dst=%p, osize=%p, key=%d, env=%p)", parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle) } if err := env.CheckStatus( C.OCIAttrGet(parent, C.ub4(parentType), dst, &osize, C.ub4(key), env.errorHandle), errText); err != nil { Log.Error("AttrGet", "attr", key, "error", err) return -1, err } return int(osize), nil }
// Returns the value stored at the given array position. func numberVarGetValue(v *Variable, pos uint) (interface{}, error) { if v.dataFloats != nil { // log.Printf("getting pos=%d from %+v", pos, v.dataFloats) return v.dataFloats[pos], nil } if v.dataInts != nil { // log.Printf("getting pos=%d from %+v", pos, v.dataInts) return v.dataInts[pos], nil } num := (*C.OCINumber)(v.getHandle(pos)) buf := make([]byte, 64) size := C.ub4(len(buf)) if err := v.environment.CheckStatus( C.OCINumberToText(v.environment.errorHandle, num, (*C.oratext)(unsafe.Pointer(&v.environment.numberToStringFormatBuffer[0])), C.ub4(len(v.environment.numberToStringFormatBuffer)), nil, 0, &size, (*C.oratext)(&buf[0])), "NumberToText", ); err != nil { var floatVal float64 _ = v.environment.CheckStatus( C.OCINumberToReal(v.environment.errorHandle, num, C.sizeof_double, unsafe.Pointer(&floatVal)), "numberToFloat") log.Printf("floatVal=%f format=%q len=%d num=%p (%d) size=%p buf=%p", floatVal, v.environment.numberToStringFormatBuffer, len(v.environment.numberToStringFormatBuffer), num, *((*byte)(unsafe.Pointer(num))), &size, &buf[0]) return 0, errgo.Notef(err, "want string (%f)", floatVal) } numS := strings.Replace( v.environment.FromEncodedString(buf[:int(size)]), ",", ".", -1) if v.typ == NumberAsStringVarType { return numS, nil } if len(numS) <= 9 && strings.IndexByte(numS, '.') < 0 { intVal, err := numAsInt(v, num) return intVal, errgo.Mask(err) } return numS, nil }
func (env *Environment) AttrSet(parent unsafe.Pointer, parentTyp C.ub4, key C.ub4, value unsafe.Pointer, valueLength int) error { return env.CheckStatus(C.OCIAttrSet(parent, parentTyp, value, C.ub4(valueLength), key, env.errorHandle), "AttrSet") }
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 (c *ConnectionOracle) NewStatement(sql string) (s *StatementOracle, err int) { s = new(StatementOracle) pStatement := unsafe.Pointer(&s.hStatement) res := C.OCIHandleAlloc(unsafe.Pointer(c.driver.hEnv), (*unsafe.Pointer)(pStatement), C.OCI_HTYPE_STMT, 0, nil) if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ { fmt.Printf("Result hSession=%v\n", res) C.AuxOCIErrorGet(c.driver.hError) return nil, -1 } cSql := C.CString(sql) defer C.free(unsafe.Pointer(cSql)) var osql *C.OraText = C.Get_OraText(cSql) //fmt.Printf( "%v:%v\n", C.strlen(sql), C.GoString(sql)) res = C.OCIStmtPrepare(s.hStatement, c.driver.hError, osql, C.ub4(C.strlen(cSql)), C.OCI_NTV_SYNTAX, C.OCI_DEFAULT) if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ { fmt.Printf("Resultado OCIStmtPrepare=%v\n", res) C.AuxOCIErrorGet(c.driver.hError) return nil, -2 } s.fetchDone = false s.con = c return s, 0 }
func (conn *connection) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var stmt unsafe.Pointer if C.OCIHandleAlloc(conn.env, &stmt, C.OCI_HTYPE_STMT, 0, nil) != C.OCI_SUCCESS { return nil, ociGetError(conn.err) } result := C.OCIStmtPrepare((*C.OCIStmt)(stmt), (*C.OCIError)(conn.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(C.OCI_DEFAULT)) if result != C.OCI_SUCCESS { return nil, ociGetError(conn.err) } return &statement{handle: stmt, conn: conn}, nil }
func (bnd *bndBool) bind(value bool, position int, c StmtCfg, stmt *Stmt) (err error) { //Log.Infof("%s.bind(%t, %d)", bnd, value, position) bnd.stmt = stmt var str string if value { str, err = strconv.Unquote(strconv.QuoteRune(c.TrueRune)) } else { str, err = strconv.Unquote(strconv.QuoteRune(c.FalseRune)) } if err != nil { return err } bnd.cString = C.CString(str) 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.cString), //void *valuep, C.LENGTH_TYPE(1), //sb8 value_sz, C.SQLT_AFC, //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 *bndInt32) bind(value int32, position int, stmt *Stmt) error { bnd.stmt = stmt r := C.OCINumberFromInt( bnd.stmt.ses.srv.env.ocierr, //OCIError *err, unsafe.Pointer(&value), //const void *inum, 4, //uword inum_length, C.OCI_NUMBER_SIGNED, //uword inum_s_flag, &bnd.ociNumber) //OCINumber *number ); 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.ociNumber), //void *valuep, C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz, C.SQLT_VNU, //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 *bndFloat64Ptr) bind(value *float64, position int, stmt *Stmt) error { bnd.stmt = stmt bnd.value = value if value == nil { bnd.isNull = C.sb2(-1) } else { r := C.OCINumberFromReal( bnd.stmt.ses.srv.env.ocierr, //OCIError *err, unsafe.Pointer(value), //const void *rnum, 8, //uword rnum_length, &bnd.ociNumber) //OCINumber *number ); 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.ociNumber), //void *valuep, C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8 value_sz, C.SQLT_VNU, //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 }
// Allocate a variable and define it for the given statement. func (cur *Cursor) varDefine(numElements, position uint) (*Variable, error) { var param *C.OCIParam // retrieve parameter descriptor if cur.handle == nil { log.Printf("WARN: nil cursor handle in varDefine!") } // log.Printf("retrieve parameter descriptor cur.handle=%s pos=%d", cur.handle, position) if CTrace { ctrace("OCIParamGet(cur=%p, HTYPE_STMT, env=%p, param=%p, position=%d)", cur.handle, "HTYPE_STMT", cur.environment.errorHandle, ¶m, position) } if err := cur.environment.CheckStatus( C.OCIParamGet(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT, cur.environment.errorHandle, (*unsafe.Pointer)(unsafe.Pointer(¶m)), C.ub4(position)), "parameter"); err != nil { log.Printf("NO PARAM! %s", err) return nil, err } // log.Printf("got param handle") // call the helper to do the actual work v, err := cur.variableDefineHelper(param, position, numElements) // log.Printf("variable defined err=%s nil?%s", err, err == nil) if CTrace { ctrace("OCIDescriptorFree(%p, DTYPE_PARAM)", param) } C.OCIDescriptorFree(unsafe.Pointer(param), C.OCI_DTYPE_PARAM) return v, err }
func (s *OCI8Stmt) bind(args []driver.Value) error { if args == nil { return nil } var bp *C.OCIBind for i, v := range args { b := []byte(fmt.Sprintf("%v", v)) b = append(b, 0) rv := C.OCIBindByPos( (*C.OCIStmt)(s.s), &bp, (*C.OCIError)(s.c.err), C.ub4(i+1), unsafe.Pointer(&b[0]), C.sb4(len(b)), C.SQLT_STR, nil, nil, nil, 0, nil, OCI_MODE) if rv == C.OCI_ERROR { return ociGetError(s.c.err) } } return nil }