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 }
// Open("system/123456@XE") func (d *OCI8Driver) Open(dsn string) (driver.Conn, error) { var conn OCI8Conn token := strings.SplitN(dsn, "@", 2) userpass := strings.SplitN(token[0], "/", 2) // 老款的OCI初始化方式,但向后兼容,所以还是保留老方法 rv := C.OCIInitialize( OCI_MODE, // TODO nil, nil, nil, nil) if rv == C.OCI_ERROR { // 这种错误就是没有把OCI的路径加入到系统PATH中 return nil, errors.New("OCI Init FAIL, OCI not in system PATH?") } rv = C.OCIEnvInit( (**C.OCIEnv)(unsafe.Pointer(&conn.env)), OCI_MODE, 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 }
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) } 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 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)) phostlen := C.strlen(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.OCILogon( (*C.OCIEnv)(conn.env), (*C.OCIError)(conn.err), (**C.OCISvcCtx)(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) } conn.location = dsn.Location return &conn, nil }