Пример #1
0
func NewDriverOracle() (d *DriverOracle, err int) {
	d = new(DriverOracle)
	d.hEnv = new(C.OCIEnv)
	res := C.OCIEnvCreate(&d.hEnv, C.OCI_DEFAULT, nil, nil, nil, nil, 0, nil)
	if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res {
		fmt.Printf("Result1=%v\n", res)
		return nil, 1
	}

	pService := unsafe.Pointer(&d.hService)
	//    res = C.OCIHandleAlloc( unsafe.Pointer(env), (*unsafe.Pointer), C.OCI_HTYPE_SVCCTX, 0, nil);
	res = C.OCIHandleAlloc(unsafe.Pointer(d.hEnv), (*unsafe.Pointer)(pService), C.OCI_HTYPE_SVCCTX, 0, nil)
	if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res {
		fmt.Printf("Result2=%v\n", res)
		return nil, 2
	}

	pError := unsafe.Pointer(&d.hError)
	res = C.OCIHandleAlloc(unsafe.Pointer(d.hEnv), (*unsafe.Pointer)(pError), C.OCI_HTYPE_ERROR, 0, nil)
	if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res {
		fmt.Printf("Result3=%v\n", res)
		return nil, 3
	}
	return d, 0
}
Пример #2
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
}
Пример #3
0
func (d *drv) Open(dsn string) (driver.Conn, error) {
	conn := &connection{}

	// initialize the oci environment used for all other oci calls
	result := C.OCIEnvCreate((**C.OCIEnv)(unsafe.Pointer(&conn.env)), C.OCI_DEFAULT, nil, nil, nil, nil, 0, nil)
	if result != C.OCI_SUCCESS {
		return nil, errors.New("Failed: OCIEnvCreate()")
	}

	// error handle
	result = C.OCIHandleAlloc(conn.env, &conn.err, C.OCI_HTYPE_ERROR, 0, nil)
	if result != C.OCI_SUCCESS {
		return nil, errors.New("Failed: OCIHandleAlloc() - creating error handle")
	}

	// Log in the user
	err := conn.performLogon(dsn)
	if err != nil {
		return nil, err
	}
	return conn, nil
}
Пример #4
0
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
	}

	// set safe defaults
	conn.attrs = make(Values)
	conn.attrs.Set("prefetch_rows", 10)
	conn.attrs.Set("prefetch_memory", int64(0))

	for k, v := range parseEnviron(os.Environ()) {
		conn.attrs.Set(k, v)
	}

	/*
		OCI_ENV_NO_MUTEX - No mutual exclusion (mutex) locking occurs in this mode.
		All OCI calls done on the environment handle,
		or on handles derived from the environment handle, must be serialized.
		OCI_THREADED must also be specified when OCI_ENV_NO_MUTEX is specified.
	*/
	rv := C.OCIEnvCreate(
		(**C.OCIEnv)(unsafe.Pointer(&conn.env)),
		C.OCI_THREADED|C.OCI_ENV_NO_MUTEX,
		nil,
		nil,
		nil,
		nil,
		0,
		nil)
	if err := conn.check(rv, "Open.OCIEnvCreate"); err != nil {
		return nil, err
	}

	rv = C.OCIHandleAlloc(
		conn.env,
		&conn.err,
		C.OCI_HTYPE_ERROR,
		0,
		nil)
	if err := conn.check(rv, "Open.OCIHandleAlloc conn.err"); err != nil {
		return nil, err
	}
	rv = C.OCIHandleAlloc(
		conn.env,
		&conn.srv,
		C.OCI_HTYPE_SERVER,
		0,
		nil)
	if err := conn.check(rv, "Open.OCIHandleAlloc conn.srv"); err != nil {
		return nil, err
	}

	var phost *C.char
	if dsn.Host != "" {
		phost = C.CString(fmt.Sprintf("%s:%d/%s", dsn.Host, dsn.Port, dsn.SID))
	} else {
		phost = C.CString(dsn.SID)
	}
	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))

	rv = C.OCIServerAttach(
		(*C.OCIServer)(conn.srv),
		(*C.OCIError)(conn.err),
		(*C.OraText)(unsafe.Pointer(phost)),
		C.sb4(C.strlen(phost)),
		0,
	)

	if err := conn.check(rv, "Open.OCIServerAttach"); err != nil {
		return nil, err
	}

	rv = C.OCIHandleAlloc(
		conn.env,
		&conn.svc,
		C.OCI_HTYPE_SVCCTX,
		0,
		nil)

	if err := conn.check(rv, "Open.OCIHandleAlloc conn.svc"); err != nil {
		return nil, err
	}

	rv = C.OCIAttrSet(
		conn.svc,
		C.OCI_HTYPE_SVCCTX,
		conn.srv,
		0,
		C.OCI_ATTR_SERVER,
		(*C.OCIError)(conn.err),
	)

	if err := conn.check(rv, "Open.OCIAttrSet - srv"); err != nil {
		return nil, err
	}

	rv = C.OCIHandleAlloc(
		conn.env,
		&conn.usr,
		C.OCI_HTYPE_SESSION,
		0,
		nil,
	)
	if err := conn.check(rv, "Open.OCIHandleAlloc - usr"); err != nil {
		return nil, err
	}

	rv = C.OCIAttrSet(
		conn.usr,
		C.OCI_HTYPE_SESSION,
		unsafe.Pointer(puser),
		C.ub4(C.strlen(puser)),
		C.OCI_ATTR_USERNAME,
		(*C.OCIError)(conn.err),
	)

	if err := conn.check(rv, "Open.OCIAttrSet - user"); err != nil {
		return nil, err
	}

	rv = C.OCIAttrSet(
		conn.usr,
		C.OCI_HTYPE_SESSION,
		unsafe.Pointer(ppass),
		C.ub4(C.strlen(ppass)),
		C.OCI_ATTR_PASSWORD,
		(*C.OCIError)(conn.err),
	)
	if err := conn.check(rv, "Open.OCIAttrSet - ppass"); err != nil {
		return nil, err
	}

	rv = C.OCISessionBegin(
		(*C.OCISvcCtx)(conn.svc),
		(*C.OCIError)(conn.err),
		(*C.OCISession)(conn.usr),
		C.OCI_CRED_RDBMS,
		C.OCI_DEFAULT,
	)
	if err := conn.check(rv, "Open.OCISessionBegin"); err != nil {
		return nil, err
	}

	rv = C.OCIAttrSet(
		conn.svc,
		C.OCI_HTYPE_SVCCTX,
		conn.usr,
		0,
		C.OCI_ATTR_SESSION,
		(*C.OCIError)(conn.err),
	)

	if err := conn.check(rv, "Open.OCIAttrSet svc"); err != nil {
		return nil, err
	}

	conn.location = dsn.Location
	conn.logDebug = dsn.LogDebug
	conn.logBadConn = dsn.LogBadConn

	return &conn, nil
}