Beispiel #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
}
Beispiel #2
0
// Close the connection, disconnecting from the database.
func (conn *Connection) Close() (err error) {
	if !conn.IsConnected() {
		return nil //?
	}

	// perform a rollback
	if err = conn.Rollback(); err != nil {
		setErrAt(err, "Close[rollback]")
		return
	}
	conn.srvMtx.Lock()
	defer conn.srvMtx.Unlock()

	// logoff of the server
	if conn.sessionHandle != nil {
		// Py_BEGIN_ALLOW_THREADS
		if err = conn.environment.CheckStatus(C.OCISessionEnd((conn.handle),
			conn.environment.errorHandle, conn.sessionHandle,
			C.OCI_DEFAULT), "Close[end session]"); err != nil {
			return
		}
		C.OCIHandleFree(unsafe.Pointer(conn.handle), C.OCI_HTYPE_SVCCTX)
	}
	conn.handle = nil
	if conn.serverHandle != nil {
		if err = conn.environment.CheckStatus(
			C.OCIServerDetach(conn.serverHandle, conn.environment.errorHandle, C.OCI_DEFAULT),
			"Close[server detach]"); err != nil {
			return
		}
		conn.serverHandle = nil
	}
	return nil
}
Beispiel #3
0
// Free frees the used handles
func (env *Environment) Free() error {
	if env.errorHandle != nil {
		C.OCIHandleFree(unsafe.Pointer(env.errorHandle), C.OCI_HTYPE_ERROR)
		env.errorHandle = nil
	}
	//if !env.cloneEnv {
	if env.handle != nil {
		C.OCIHandleFree(unsafe.Pointer(env.handle), C.OCI_HTYPE_ENV)
		env.handle = nil
	}
	env.numberToStringFormatBuffer = nil
	env.numberFromStringFormatBuffer = nil
	env.nlsNumericCharactersBuffer = nil
	//}
	return nil
}
Beispiel #4
0
// Free deallocates the connection, disconnecting from the database if necessary.
func (conn *Connection) Free(freeEnvironment bool) {
	if conn.release {
		// Py_BEGIN_ALLOW_THREADS
		conn.srvMtx.Lock()
		conn.rollback()
		C.OCISessionRelease(conn.handle, conn.environment.errorHandle, nil,
			0, C.OCI_DEFAULT)
		// Py_END_ALLOW_THREADS
		conn.srvMtx.Unlock()
	} else if !conn.attached {
		conn.srvMtx.Lock()
		if conn.sessionHandle != nil {
			// Py_BEGIN_ALLOW_THREADS
			conn.rollback()
			C.OCISessionEnd(conn.handle, conn.environment.errorHandle,
				conn.sessionHandle, C.OCI_DEFAULT)
			// Py_END_ALLOW_THREADS
		}
		if conn.serverHandle != nil {
			C.OCIServerDetach(conn.serverHandle,
				conn.environment.errorHandle, C.OCI_DEFAULT)
		}
		conn.srvMtx.Unlock()
	}
	if conn.sessionHandle != nil {
		C.OCIHandleFree(unsafe.Pointer(conn.sessionHandle), C.OCI_HTYPE_SESSION)
		conn.sessionHandle = nil
	}
	if conn.handle != nil {
		C.OCIHandleFree(unsafe.Pointer(conn.handle), C.OCI_HTYPE_SVCCTX)
		conn.handle = nil
	}
	if conn.serverHandle != nil {
		C.OCIHandleFree(unsafe.Pointer(conn.serverHandle), C.OCI_HTYPE_SERVER)
		conn.serverHandle = nil
	}
	if freeEnvironment {
		// Free env (Issue #10)
		if conn.environment != nil {
			conn.environment.Free()
			conn.environment = nil
		}
	}
}
Beispiel #5
0
func (stmt *statement) Close() error {
	if stmt.closed {
		return nil
	}
	stmt.closed = true
	C.OCIHandleFree(stmt.handle, C.OCI_HTYPE_STMT)
	stmt.handle = nil

	return nil
}
Beispiel #6
0
// freeOciHandle deallocates an oci handle. No locking occurs.
func (env *Env) freeOciHandle(ociHandle unsafe.Pointer, handleType C.ub4) error {
	// OCIHandleFree returns: OCI_SUCCESS, OCI_INVALID_HANDLE, or OCI_ERROR
	r := C.OCIHandleFree(
		ociHandle,  //void      *hndlp,
		handleType) //ub4       type );
	if r == C.OCI_INVALID_HANDLE {
		return er("Unable to free handle")
	} else if r == C.OCI_ERROR {
		return errE(env.ociError())
	}
	return nil
}
Beispiel #7
0
func (s *OCI8Stmt) Close() error {
	if s.closed {
		return nil
	}
	s.closed = true

	C.OCIHandleFree(
		s.s,
		C.OCI_HTYPE_STMT)
	s.s = nil
	return nil
}
Beispiel #8
0
func (s *OCI8Stmt) Close() error {
	if s.closed {
		return nil
	}
	s.closed = true

	C.OCIHandleFree(
		s.s,
		C.OCI_HTYPE_STMT)
	s.s = nil
	runtime.SetFinalizer(s, nil)
	return nil
}
Beispiel #9
0
// OpenEnv opens an Oracle environment.
//
// Optionally specify a cfg parameter. If cfg is nil, default cfg values are
// applied.
func OpenEnv(cfg *EnvCfg) (env *Env, err error) {
	_drv.mu.Lock()
	defer _drv.mu.Unlock()
	log(_drv.cfg.Log.OpenEnv)
	if cfg == nil { // ensure cfg
		tmp := *_drv.cfg.Env // copy by value to ensure independent cfgs
		cfg = &tmp
	}
	var csIDAl32UTF8 C.ub2
	if csIDAl32UTF8 == 0 { // Get the code for AL32UTF8
		var ocienv *C.OCIEnv
		r := C.OCIEnvCreate(&ocienv, C.OCI_DEFAULT|C.OCI_THREADED, nil, nil, nil, nil, 0, nil)
		if r == C.OCI_ERROR {
			return nil, errF("Unable to create environment handle (Return code = %d).", r)
		}
		csName := []byte("AL32UTF8\x00") // http://docs.oracle.com/cd/B10501_01/server.920/a96529/ch8.htm#14284
		csIDAl32UTF8 = C.OCINlsCharSetNameToId(unsafe.Pointer(ocienv), (*C.oratext)(&csName[0]))
		C.OCIHandleFree(unsafe.Pointer(ocienv), C.OCI_HTYPE_ENV)
	}
	// OCI_DEFAULT  - The default value, which is non-UTF-16 encoding.
	// OCI_THREADED - Uses threaded environment. Internal data structures not exposed to the user are protected from concurrent accesses by multiple threads.
	// OCI_OBJECT   - Uses object features such as OCINumber, OCINumberToInt, OCINumberFromInt. These are used in oracle-go type conversions.
	env = _drv.envPool.Get().(*Env) // set *Env
	r := C.OCIEnvNlsCreate(
		&env.ocienv, //OCIEnv        **envhpp,
		C.OCI_DEFAULT|C.OCI_OBJECT|C.OCI_THREADED, //ub4           mode,
		nil,          //void          *ctxp,
		nil,          //void          *(*malocfp)
		nil,          //void          *(*ralocfp)
		nil,          //void          (*mfreefp)
		0,            //size_t        xtramemsz,
		nil,          //void          **usrmempp
		csIDAl32UTF8, //ub2           charset,
		csIDAl32UTF8) //ub2           ncharset );
	if r == C.OCI_ERROR {
		return nil, errF("Unable to create environment handle (Return code = %d).", r)
	}
	ocierr, err := env.allocOciHandle(C.OCI_HTYPE_ERROR) // alloc oci error handle
	if err != nil {
		return nil, errE(err)
	}

	env.ocierr = (*C.OCIError)(ocierr)
	if env.id == 0 {
		env.id = _drv.envId.nextId()
	}
	env.cfg = *cfg
	_drv.openEnvs.add(env)

	return env, nil
}
Beispiel #10
0
func (c *OCI8Conn) Close() error {
	rv := C.OCILogoff(
		(*C.OCIServer)(c.svc),
		(*C.OCIError)(c.err))
	if rv == C.OCI_ERROR {
		return ociGetError(c.err)
	}

	C.OCIHandleFree(
		c.env,
		C.OCI_HTYPE_ENV)

	c.svc = nil
	c.env = nil
	c.err = nil
	return nil
}
Beispiel #11
0
func (c *OCI8Conn) Close() error {
	var err error
	if rv := C.OCILogoff(
		(*C.OCISvcCtx)(c.svc),
		(*C.OCIError)(c.err)); rv != C.OCI_SUCCESS {
		err = ociGetError(c.err)
	}

	C.OCIHandleFree(
		c.env,
		C.OCI_HTYPE_ENV)

	c.svc = nil
	c.env = nil
	c.err = nil
	runtime.SetFinalizer(c, nil)
	return err
}
Beispiel #12
0
func (conn *OCI8Conn) Close() error {
	//TODO: add C.OCITransRollback()
	C.OCISessionEnd(
		(*C.OCISvcCtx)(conn.svc),
		(*C.OCIError)(conn.err),
		(*C.OCISession)(conn.usr),
		C.OCI_DEFAULT)
	C.OCIServerDetach(
		(*C.OCIServer)(conn.srv),
		(*C.OCIError)(conn.err),
		C.OCI_DEFAULT)
	C.OCIHandleFree(
		conn.env,
		C.OCI_HTYPE_ENV)

	conn.srv = nil
	conn.svc = nil
	conn.env = nil
	conn.err = nil
	return nil
}
Beispiel #13
0
func (c *OCI8Conn) Close() error {
	if c.closed {
		return nil
	}
	c.closed = true

	var err error
	if rv := C.OCILogoff(
		(*C.OCISvcCtx)(c.svc),
		(*C.OCIError)(c.err)); rv != C.OCI_SUCCESS {
		err = ociGetError(rv, c.err)
	}

	C.OCIHandleFree(
		c.env,
		C.OCI_HTYPE_ENV)

	c.svc = nil
	c.env = nil
	c.err = nil
	return err
}
Beispiel #14
0
// Create and initialize a new environment object
func NewEnvironment() (*Environment, error) {
	var err error

	// create a new object for the Oracle environment
	env := &Environment{
		FixedWidth:                   false,
		MaxBytesPerCharacter:         4,
		maxStringBytes:               MAX_STRING_CHARS,
		numberToStringFormatBuffer:   []byte("TM9"),
		numberFromStringFormatBuffer: []byte("999999999999999999999999999999999999999999999999999999999999999"),
		nlsNumericCharactersBuffer:   []byte("NLS_NUMERIC_CHARACTERS='.,'"),
	}

	if CSID_AL32UTF8 == 0 {
		// create the new environment handle
		if err = checkStatus(C.OCIEnvNlsCreate(&env.handle,
			C.OCI_DEFAULT|C.OCI_THREADED, nil, nil, nil, nil, 0, nil, 0, 0),
			false); err != nil { //, C.ub2(873), 0),
			setErrAt(err, "Unable to acquire Oracle environment handle")
			return nil, err
		}
		buffer := []byte("AL32UTF8\000")
		CSID_AL32UTF8 = C.OCINlsCharSetNameToId(unsafe.Pointer(env.handle),
			(*C.oratext)(&buffer[0]))
		C.OCIHandleFree(unsafe.Pointer(&env.handle), C.OCI_HTYPE_ENV)
		// log.Printf("csid=%d", CSID_AL32UTF8)
	}
	if err = checkStatus(C.OCIEnvNlsCreate(
		&env.handle, C.OCI_DEFAULT|C.OCI_THREADED, nil, nil, nil, nil, 0, nil,
		CSID_AL32UTF8, CSID_AL32UTF8), false); err != nil {
		setErrAt(err, "Unable to acquire Oracle environment handle with AL32UTF8 charset")
		return nil, err
	}
	// log.Printf("env=%+v err=%+v", env.handle, err)

	// create the error handle
	if err = ociHandleAlloc(unsafe.Pointer(env.handle),
		C.OCI_HTYPE_ERROR, (*unsafe.Pointer)(unsafe.Pointer(&env.errorHandle)),
		"env.errorHandle"); err != nil || env.handle == nil {
		return nil, err
	}

	var sb4 C.sb4
	// acquire max bytes per character
	if err = env.CheckStatus(C.OCINlsNumericInfoGet(unsafe.Pointer(env.handle),
		env.errorHandle, &sb4, C.OCI_NLS_CHARSET_MAXBYTESZ),
		"Environment_New(): get max bytes per character"); err != nil {
		return nil, err
	}
	env.MaxBytesPerCharacter = uint(sb4)
	env.maxStringBytes = MAX_STRING_CHARS * env.MaxBytesPerCharacter
	// log.Printf("maxBytesPerCharacter=%d", env.maxBytesPerCharacter)

	// acquire whether character set is fixed width
	if err = env.CheckStatus(C.OCINlsNumericInfoGet(unsafe.Pointer(env.handle),
		env.errorHandle, &sb4, C.OCI_NLS_CHARSET_FIXEDWIDTH),
		"Environment_New(): determine if charset fixed width"); err != nil {
		return nil, err
	}
	env.FixedWidth = sb4 > 0

	var e error
	// determine encodings to use for Unicode values
	if env.Encoding, e = env.GetCharacterSetName(C.OCI_ATTR_ENV_CHARSET_ID); e != nil {
		return nil, e
	}
	if env.Nencoding, e = env.GetCharacterSetName(C.OCI_ATTR_ENV_NCHARSET_ID); e != nil {
		return nil, e
	}

	return env, nil
}
Beispiel #15
0
// Connect to the database.
// good minimal example: http://www.adp-gmbh.ch/ora/misc/oci/index.html
func (conn *Connection) Connect(mode int64, twophase bool /*, newPassword string*/) error {
	credentialType := C.OCI_CRED_EXT
	var (
		status C.sword
		err    error
	)
	defer func() {
		if err != nil {
			if conn.sessionHandle != nil {
				C.OCIHandleFree(unsafe.Pointer(conn.sessionHandle),
					C.OCI_HTYPE_SESSION)
			}
			if conn.handle != nil {
				C.OCIHandleFree(unsafe.Pointer(conn.handle),
					C.OCI_HTYPE_SVCCTX)
			}
			if conn.serverHandle != nil {
				C.OCIHandleFree(unsafe.Pointer(conn.serverHandle),
					C.OCI_HTYPE_SERVER)
			}
		}
	}()

	// allocate the server handle
	if ociHandleAlloc(unsafe.Pointer(conn.environment.handle),
		C.OCI_HTYPE_SERVER,
		(*unsafe.Pointer)(unsafe.Pointer(&conn.serverHandle)),
		"Connect[allocate server handle]"); err != nil {
		return err
	}

	// attach to the server
	/*
	   if (cxBuffer_FromObject(&buffer, self->dsn,
	           self->environment->encoding) < 0)
	       return -1;
	*/

	buffer := make([]byte, max(16, len(conn.dsn), len(conn.username), len(conn.password))+1)
	copy(buffer, []byte(conn.dsn))
	buffer[len(conn.dsn)] = 0
	// dsn := C.CString(conn.dsn)
	// defer C.free(unsafe.Pointer(dsn))
	// Py_BEGIN_ALLOW_THREADS
	conn.srvMtx.Lock()
	// log.Printf("buffer=%s", buffer)
	status = C.OCIServerAttach(conn.serverHandle,
		conn.environment.errorHandle, (*C.OraText)(&buffer[0]),
		C.sb4(len(buffer)), C.OCI_DEFAULT)
	// Py_END_ALLOW_THREADS
	conn.srvMtx.Unlock()
	// cxBuffer_Clear(&buffer);
	if err = conn.environment.CheckStatus(status, "Connect[server attach]"); err != nil {
		return err
	}
	// log.Printf("attached to server %s", conn.serverHandle)

	// allocate the service context handle
	if err = ociHandleAlloc(unsafe.Pointer(conn.environment.handle),
		C.OCI_HTYPE_SVCCTX, (*unsafe.Pointer)(unsafe.Pointer(&conn.handle)),
		"Connect[allocate service context handle]"); err != nil {
		return err
	}
	// log.Printf("allocated service context handle")

	// set attribute for server handle
	if err = conn.AttrSet(C.OCI_ATTR_SERVER, unsafe.Pointer(conn.serverHandle), 0); err != nil {
		setErrAt(err, "Connect[set server handle]")
		return err
	}

	// set the internal and external names; these are needed for global
	// transactions but are limited in terms of the lengths of the strings
	if twophase {
		name := []byte("goracle")
		copy(buffer, name)
		buffer[len(name)] = 0

		if err = conn.ServerAttrSet(C.OCI_ATTR_INTERNAL_NAME,
			unsafe.Pointer(&buffer[0]), len(name)); err != nil {
			setErrAt(err, "Connect[set internal name]")
			return err
		}
		if err = conn.ServerAttrSet(C.OCI_ATTR_EXTERNAL_NAME,
			unsafe.Pointer(&buffer[0]), len(name)); err != nil {
			setErrAt(err, "Connect[set external name]")
			return err
		}
	}

	// allocate the session handle
	if err = ociHandleAlloc(unsafe.Pointer(conn.environment.handle),
		C.OCI_HTYPE_SESSION,
		(*unsafe.Pointer)(unsafe.Pointer(&conn.sessionHandle)),
		"Connect[allocate session handle]"); err != nil {
		return err
	}
	// log.Printf("allocated session handle")

	// set user name in session handle
	if conn.username != "" {
		copy(buffer, []byte(conn.username))
		buffer[len(conn.username)] = 0
		credentialType = C.OCI_CRED_RDBMS

		if err = conn.SessionAttrSet(C.OCI_ATTR_USERNAME,
			unsafe.Pointer(&buffer[0]), len(conn.username)); err != nil {
			setErrAt(err, "Connect[set user name]")
			return err
		}
		// log.Printf("set user name %s", buffer)
	}

	// set password in session handle
	if conn.password != "" {
		copy(buffer, []byte(conn.password))
		buffer[len(conn.password)] = 0
		credentialType = C.OCI_CRED_RDBMS
		if err = conn.SessionAttrSet(C.OCI_ATTR_PASSWORD,
			unsafe.Pointer(&buffer[0]), len(conn.password)); err != nil {
			setErrAt(err, "Connect[set password]")
			return err
		}
		// log.Printf("set password %s", buffer)
	}

	/*
	   #ifdef OCI_ATTR_DRIVER_NAME
	       status = OCIAttrSet(self->sessionHandle, OCI_HTYPE_SESSION,
	               (text*) DRIVER_NAME, strlen(DRIVER_NAME), OCI_ATTR_DRIVER_NAME,
	               self->environment->errorHandle);
	       if (Environment_CheckForError(self->environment, status,
	               "Connection_Connect(): set driver name") < 0)
	           return -1;

	   #endif
	*/

	// set the session handle on the service context handle
	if err = conn.AttrSet(C.OCI_ATTR_SESSION,
		unsafe.Pointer(conn.sessionHandle), 0); err != nil {
		setErrAt(err, "Connect[set session handle]")
		return err
	}

	/*
	   // if a new password has been specified, change it which will also
	   // establish the session
	   if (newPasswordObj)
	       return Connection_ChangePassword(self, self->password, newPasswordObj);
	*/

	// begin the session
	// Py_BEGIN_ALLOW_THREADS
	conn.srvMtx.Lock()
	status = C.OCISessionBegin(conn.handle, conn.environment.errorHandle,
		conn.sessionHandle, C.ub4(credentialType), C.ub4(mode))
	// Py_END_ALLOW_THREADS
	conn.srvMtx.Unlock()
	if err = conn.environment.CheckStatus(status, "Connect[begin session]"); err != nil {
		conn.sessionHandle = nil
		return err
	}

	return nil
}