Ejemplo n.º 1
0
//   Free the handle which may be reallocated if necessary.
func (cur *Cursor) freeHandle() error {
	if cur.handle == nil {
		return nil
	}
	// debug("freeing cursor handle %v", cur.handle)
	if cur.isOwned {
		if CTrace {
			ctrace("OCIHandleFree", cur.handle, "htype_stmt")
		}
		return cur.environment.CheckStatus(
			C.OCIHandleFree(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT),
			"freeCursor")
	} else if cur.connection.handle != nil &&
		cur.statementTag != nil && len(cur.statementTag) > 0 {
		if CTrace {
			ctrace("OCIStmtRelease", cur.handle, cur.environment.errorHandle,
				cur.statementTag, len(cur.statementTag), "OCI_DEFAULT")
		}
		return cur.environment.CheckStatus(C.OCIStmtRelease(cur.handle,
			cur.environment.errorHandle, (*C.OraText)(&cur.statementTag[0]),
			C.ub4(len(cur.statementTag)), C.OCI_DEFAULT),
			"statement release")
	}
	cur.handle = nil
	return nil
}
Ejemplo n.º 2
0
// 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
}