Skip to content

Commit

Permalink
When using an external handle, create a new service context handle so…
Browse files Browse the repository at this point in the history
… that

there are no discrepancies in character sets between the service context and
the newly created environment handle
(oracle/python-cx_Oracle#273).
  • Loading branch information
anthony-tuininga committed Mar 7, 2019
1 parent 777ca69 commit 9292f4e
Showing 1 changed file with 46 additions and 5 deletions.
51 changes: 46 additions & 5 deletions src/dpiConn.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <time.h>

// forward declarations of internal functions only used in this file
static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle,
dpiError *error);
static int dpiConn__createStandalone(dpiConn *conn, const char *userName,
uint32_t userNameLength, const char *password, uint32_t passwordLength,
const char *connectString, uint32_t connectStringLength,
Expand Down Expand Up @@ -45,6 +47,45 @@ static int dpiConn__setShardingKeyValue(dpiConn *conn, void *shardingKey,
dpiShardingKeyColumn *column, dpiError *error);


//-----------------------------------------------------------------------------
// dpiConn__attachExternal() [INTERNAL]
// Attach to the server and session of an existing service context handle.
//-----------------------------------------------------------------------------
static int dpiConn__attachExternal(dpiConn *conn, void *externalHandle,
dpiError *error)
{
// mark connection as using an external handle so that no attempts are
// made to close it
conn->externalHandle = 1;

// acquire handles from existing service context handle
conn->handle = externalHandle;
if (dpiConn__getHandles(conn, error) < 0) {
conn->handle = NULL;
return DPI_FAILURE;
}

// allocate a new service context handle which will use the new environment
// handle independent of the original service context handle
conn->handle = NULL;
if (dpiOci__handleAlloc(conn->env->handle, &conn->handle,
DPI_OCI_HTYPE_SVCCTX, "allocate service context handle",
error) < 0)
return DPI_FAILURE;

// set these handles on the newly created service context
if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX, conn->serverHandle,
0, DPI_OCI_ATTR_SERVER, "set server handle", error) < 0)
return DPI_FAILURE;
if (dpiOci__attrSet(conn->handle, DPI_OCI_HTYPE_SVCCTX,
conn->sessionHandle, 0, DPI_OCI_ATTR_SESSION, "set session handle",
error) < 0)
return DPI_FAILURE;

return DPI_SUCCESS;
}


//-----------------------------------------------------------------------------
// dpiConn__check() [INTERNAL]
// Validate the connection handle and that it is still connected to the
Expand Down Expand Up @@ -183,6 +224,8 @@ static int dpiConn__close(dpiConn *conn, uint32_t mode, const char *tag,

// handle connections created with an external handle
if (conn->externalHandle) {
if (conn->handle)
dpiOci__handleFree(conn->handle, DPI_OCI_HTYPE_SVCCTX);
conn->sessionHandle = NULL;

// handle standalone connections
Expand Down Expand Up @@ -303,11 +346,9 @@ int dpiConn__create(dpiConn *conn, const dpiContext *context,
return DPI_FAILURE;

// if a handle is specified, use it
if (createParams->externalHandle) {
conn->handle = createParams->externalHandle;
conn->externalHandle = 1;
return dpiConn__getHandles(conn, error);
}
if (createParams->externalHandle)
return dpiConn__attachExternal(conn, createParams->externalHandle,
error);

// connection class, sharding and the use of session pools require the use
// of the OCISessionGet() method; all other cases use the OCISessionBegin()
Expand Down

0 comments on commit 9292f4e

Please sign in to comment.