// 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 }
// 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 }