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 }
func (c *OCI8Conn) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var s unsafe.Pointer rv := C.OCIHandleAlloc( c.env, &s, C.OCI_HTYPE_STMT, 0, nil) if rv == C.OCI_ERROR { return nil, ociGetError(c.err) } rv = C.OCIStmtPrepare( (*C.OCIStmt)(s), (*C.OCIError)(c.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(OCI_MODE)) if rv == C.OCI_ERROR { return nil, ociGetError(c.err) } return &OCI8Stmt{c: c, s: s}, nil }
func (c *ConnectionOracle) NewStatement(sql string) (s *StatementOracle, err int) { s = new(StatementOracle) pStatement := unsafe.Pointer(&s.hStatement) res := C.OCIHandleAlloc(unsafe.Pointer(c.driver.hEnv), (*unsafe.Pointer)(pStatement), C.OCI_HTYPE_STMT, 0, nil) if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ { fmt.Printf("Result hSession=%v\n", res) C.AuxOCIErrorGet(c.driver.hError) return nil, -1 } cSql := C.CString(sql) defer C.free(unsafe.Pointer(cSql)) var osql *C.OraText = C.Get_OraText(cSql) //fmt.Printf( "%v:%v\n", C.strlen(sql), C.GoString(sql)) res = C.OCIStmtPrepare(s.hStatement, c.driver.hError, osql, C.ub4(C.strlen(cSql)), C.OCI_NTV_SYNTAX, C.OCI_DEFAULT) if C.OCI_SUCCESS != res /*&& C.OCI_STILL_EXECUTING != res*/ { fmt.Printf("Resultado OCIStmtPrepare=%v\n", res) C.AuxOCIErrorGet(c.driver.hError) return nil, -2 } s.fetchDone = false s.con = c return s, 0 }
func (conn *OCI8Conn) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var s unsafe.Pointer rv := C.OCIHandleAlloc( conn.env, &s, C.OCI_HTYPE_STMT, 0, nil) if err := conn.check(rv, "OCI8Conn.Prepare() allocate statement handle"); err != nil { return nil, err } rv = C.OCIStmtPrepare( (*C.OCIStmt)(s), (*C.OCIError)(conn.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(C.OCI_DEFAULT)) if err := conn.check(rv, "OCI8Conn.Prepare() prepare statement"); err != nil { return nil, err } return &OCI8Stmt{c: conn, s: s}, nil }
func ociHandleAlloc(parent unsafe.Pointer, typ C.ub4, dst *unsafe.Pointer, at string) error { // var vsize C.ub4 if err := checkStatus(C.OCIHandleAlloc(parent, dst, typ, C.size_t(0), nil), false); err != nil { return errgo.New(at + ": " + err.Error()) } return nil }
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 }
func (conn *OCI8Conn) Begin() (driver.Tx, error) { if conn.inTx { return nil, errors.New("transaction already in progress") } var txHandle unsafe.Pointer // determine if a transaction handle was previously allocated rv := C.OCIAttrGet( conn.svc, C.OCI_HTYPE_SVCCTX, unsafe.Pointer(&txHandle), nil, C.OCI_ATTR_TRANS, (*C.OCIError)(conn.err), ) if err := conn.check(rv, "OCI8Conn.Begin() find existing transaction handle"); err != nil { return nil, err } if txHandle == nil { rv := C.OCIHandleAlloc( conn.env, &txHandle, C.OCI_HTYPE_TRANS, 0, nil, ) if err := conn.check(rv, "OCI8Conn.Begin() allocate transaction handle"); err != nil { return nil, err } } rv = C.OCIAttrSet( conn.svc, C.OCI_HTYPE_SVCCTX, txHandle, 0, C.OCI_ATTR_TRANS, (*C.OCIError)(conn.err), ) if err := conn.check(rv, "OCI8Conn.Begin(): associate transaction"); err != nil { return nil, err } rv = C.OCITransStart( (*C.OCISvcCtx)(conn.svc), (*C.OCIError)(conn.err), 60, C.OCI_TRANS_NEW, ) if err := conn.check(rv, "OCI8Conn.Begin(): start transaction"); err != nil { return nil, err } conn.inTx = true return conn, nil }
// allocateOciHandle allocates an oci handle. No locking occurs. func (env *Env) allocOciHandle(handleType C.ub4) (unsafe.Pointer, error) { // OCIHandleAlloc returns: OCI_SUCCESS, OCI_INVALID_HANDLE var handle unsafe.Pointer r := C.OCIHandleAlloc( unsafe.Pointer(env.ocienv), //const void *parenth, &handle, //void **hndlpp, handleType, //ub4 type, C.size_t(0), //size_t xtramem_sz, nil) //void **usrmempp if r == C.OCI_INVALID_HANDLE { return nil, er("Unable to allocate handle") } return handle, nil }
func (conn *connection) Prepare(query string) (driver.Stmt, error) { pquery := C.CString(query) defer C.free(unsafe.Pointer(pquery)) var stmt unsafe.Pointer if C.OCIHandleAlloc(conn.env, &stmt, C.OCI_HTYPE_STMT, 0, nil) != C.OCI_SUCCESS { return nil, ociGetError(conn.err) } result := C.OCIStmtPrepare((*C.OCIStmt)(stmt), (*C.OCIError)(conn.err), (*C.OraText)(unsafe.Pointer(pquery)), C.ub4(C.strlen(pquery)), C.ub4(C.OCI_NTV_SYNTAX), C.ub4(C.OCI_DEFAULT)) if result != C.OCI_SUCCESS { return nil, ociGetError(conn.err) } return &statement{handle: stmt, conn: conn}, nil }
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 }
func ociHandleAlloc(parent unsafe.Pointer, typ C.ub4, dst *unsafe.Pointer, at string) error { // var vsize C.ub4 return checkStatus(C.OCIHandleAlloc(parent, dst, typ, C.size_t(0), nil), false) }
// 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 }
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 }
func (d *DriverOracle) NewConnection(tns string, username string, password string) (c *ConnectionOracle, err int) { fmt.Printf("username=%v, password=%v, tns=%v\n", username, password, tns) fmt.Println("Connecting to Oracle...") c = new(ConnectionOracle) pServer := unsafe.Pointer(&c.hServer) res := C.OCIHandleAlloc(unsafe.Pointer(d.hEnv), (*unsafe.Pointer)(pServer), C.OCI_HTYPE_SERVER, 0, nil) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado3=%v\n", res) return nil, 4 } pTns := C.CString(tns) defer C.free(unsafe.Pointer(pTns)) // C.Printw (pTns); res = C.AuxOCIServerAttach(c.hServer, d.hError, pTns) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIServerAttach=%v\n", res) C.AuxOCIErrorGet(d.hError) return nil, 5 } res = C.OCIAttrSet(unsafe.Pointer(d.hService), C.OCI_HTYPE_SVCCTX, unsafe.Pointer(c.hServer), 0, C.OCI_ATTR_SERVER, d.hError) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIAttrSet SERVICE-SERVER=%v\n", res) C.AuxOCIErrorGet(d.hError) return nil, 6 } var test [1000]C.OraText res = C.OCIServerVersion(unsafe.Pointer(c.hServer), d.hError, &test[0], C.ub4(len(test)), C.OCI_HTYPE_SERVER) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIServerVersion=%v\n", res) C.AuxOCIErrorGet(d.hError) return nil, 7 } fmt.Printf("Version=%s\n", test) pSession := unsafe.Pointer(&c.hSession) res = C.OCIHandleAlloc(unsafe.Pointer(d.hEnv), (*unsafe.Pointer)(pSession), C.OCI_HTYPE_SESSION, 0, nil) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado hSession=%v\n", res) return nil, 8 } pUsername := unsafe.Pointer(C.CString(username)) defer C.free(pUsername) res = C.OCIAttrSet(unsafe.Pointer(c.hSession), C.OCI_HTYPE_SESSION, pUsername, C.ub4(len(username)), C.OCI_ATTR_USERNAME, d.hError) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIAttrSet USERNAME=%v\n", res) return nil, 9 } cPassword := C.CString(password) // pPassword := unsafe.Pointer(C.CString(password)) pPassword := unsafe.Pointer(cPassword) defer C.free(pPassword) res = C.OCIAttrSet(unsafe.Pointer(c.hSession), C.OCI_HTYPE_SESSION, pPassword, C.ub4(len(password)), C.OCI_ATTR_PASSWORD, d.hError) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIAttrSet PASSWORD=%v\n", res) return nil, 10 } res = C.OCISessionBegin(d.hService, d.hError, c.hSession, C.OCI_CRED_RDBMS, C.OCI_DEFAULT) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIAttrSet SessionBegin=%v\n", res) C.AuxOCIErrorGet(d.hError) return nil, 11 } res = C.OCIAttrSet(unsafe.Pointer(d.hService), C.OCI_HTYPE_SVCCTX, unsafe.Pointer(c.hSession), 0, C.OCI_ATTR_SESSION, d.hError) if C.OCI_SUCCESS != res && C.OCI_STILL_EXECUTING != res { fmt.Printf("Resultado OCIAttrSet Service<-Session=%v\n", res) C.AuxOCIErrorGet(d.hError) return nil, 12 } fmt.Printf("End NewConnection\n") c.driver = d return c, 0 }