#include "dpiImpl.h"
int dpiEnv__getBaseDate(dpiEnv *env, uint32_t dataType, void **baseDate,
dpiError *error)
{
uint32_t descriptorType;
char timezoneBuffer[20];
size_t timezoneLength;
void **storedBaseDate;
switch (dataType) {
case DPI_ORACLE_TYPE_TIMESTAMP:
storedBaseDate = &env->baseDate;
descriptorType = DPI_OCI_DTYPE_TIMESTAMP;
break;
case DPI_ORACLE_TYPE_TIMESTAMP_TZ:
storedBaseDate = &env->baseDateTZ;
descriptorType = DPI_OCI_DTYPE_TIMESTAMP_TZ;
break;
case DPI_ORACLE_TYPE_TIMESTAMP_LTZ:
storedBaseDate = &env->baseDateLTZ;
descriptorType = DPI_OCI_DTYPE_TIMESTAMP_LTZ;
break;
default:
return dpiError__set(error, "get base date",
DPI_ERR_UNHANDLED_DATA_TYPE, dataType);
}
if (!*storedBaseDate) {
if (dpiOci__descriptorAlloc(env->handle, storedBaseDate,
descriptorType, "alloc base date descriptor", error) < 0)
return DPI_FAILURE;
if (dpiOci__nlsCharSetConvert(env->handle, env->charsetId,
timezoneBuffer, sizeof(timezoneBuffer), DPI_CHARSET_ID_ASCII,
"+00:00", 6, &timezoneLength, error) < 0)
return DPI_FAILURE;
if (dpiOci__dateTimeConstruct(env->handle, *storedBaseDate, 1970, 1, 1,
0, 0, 0, 0, timezoneBuffer, timezoneLength, error) < 0)
return DPI_FAILURE;
}
*baseDate = *storedBaseDate;
return DPI_SUCCESS;
}
void dpiEnv__free(dpiEnv *env, dpiError *error)
{
if (env->threaded)
dpiMutex__destroy(env->mutex);
if (env->handle && !env->externalHandle) {
dpiOci__handleFree(env->handle, DPI_OCI_HTYPE_ENV);
env->handle = NULL;
}
if (env->errorHandles) {
dpiHandlePool__free(env->errorHandles);
env->errorHandles = NULL;
error->handle = NULL;
}
dpiUtils__freeMemory(env);
}
static int dpiEnv__getCharacterSetIdAndName(dpiEnv *env, uint16_t attribute,
uint16_t *charsetId, char *encoding, dpiError *error)
{
*charsetId = 0;
dpiOci__attrGet(env->handle, DPI_OCI_HTYPE_ENV, charsetId, NULL, attribute,
"get environment", error);
return dpiGlobal__lookupEncoding(*charsetId, encoding, error);
}
int dpiEnv__getEncodingInfo(dpiEnv *env, dpiEncodingInfo *info)
{
info->encoding = env->encoding;
info->maxBytesPerCharacter = env->maxBytesPerCharacter;
info->nencoding = env->nencoding;
info->nmaxBytesPerCharacter = env->nmaxBytesPerCharacter;
return DPI_SUCCESS;
}
int dpiEnv__init(dpiEnv *env, const dpiContext *context,
const dpiCommonCreateParams *params, void *externalHandle,
dpiCreateMode createMode, dpiError *error)
{
int temp;
env->context = context;
env->versionInfo = context->versionInfo;
if (externalHandle) {
env->handle = externalHandle;
env->externalHandle = 1;
} else {
if (params->encoding && dpiGlobal__lookupCharSet(params->encoding,
&env->charsetId, error) < 0)
return DPI_FAILURE;
if (params->nencoding && params->encoding &&
strcmp(params->nencoding, params->encoding) == 0)
env->ncharsetId = env->charsetId;
else if (params->nencoding &&
dpiGlobal__lookupCharSet(params->nencoding,
&env->ncharsetId, error) < 0)
return DPI_FAILURE;
if (env->charsetId && !env->ncharsetId) {
if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_NCHARSET_ID,
&env->ncharsetId, error) < 0)
return DPI_FAILURE;
} else if (!env->charsetId && env->ncharsetId) {
if (dpiOci__nlsEnvironmentVariableGet(DPI_OCI_NLS_CHARSET_ID,
&env->charsetId, error) < 0)
return DPI_FAILURE;
}
if (dpiOci__envNlsCreate(&env->handle, createMode | DPI_OCI_OBJECT,
env->charsetId, env->ncharsetId, error) < 0)
return DPI_FAILURE;
}
if (dpiHandlePool__create(&env->errorHandles, error) < 0)
return DPI_FAILURE;
error->env = env;
if (createMode & DPI_OCI_THREADED)
dpiMutex__initialize(env->mutex);
if (dpiEnv__getCharacterSetIdAndName(env, DPI_OCI_ATTR_CHARSET_ID,
&env->charsetId, env->encoding, error) < 0)
return DPI_FAILURE;
if (dpiEnv__getCharacterSetIdAndName(env, DPI_OCI_ATTR_NCHARSET_ID,
&env->ncharsetId, env->nencoding, error) < 0)
return DPI_FAILURE;
if (dpiOci__nlsNumericInfoGet(env->handle, &env->maxBytesPerCharacter,
DPI_OCI_NLS_CHARSET_MAXBYTESZ, error) < 0)
return DPI_FAILURE;
if (env->ncharsetId == env->charsetId)
env->nmaxBytesPerCharacter = env->maxBytesPerCharacter;
else env->nmaxBytesPerCharacter = 4;
if (createMode & DPI_MODE_CREATE_THREADED)
env->threaded = 1;
if (createMode & DPI_MODE_CREATE_EVENTS)
env->events = 1;
if (params->sodaMetadataCache) {
if (dpiUtils__checkClientVersionMulti(env->versionInfo, 19, 11, 21, 3,
error) < 0)
return DPI_FAILURE;
temp = 1;
if (dpiOci__attrSet(env->handle, DPI_OCI_HTYPE_ENV, &temp, 0,
DPI_OCI_ATTR_SODA_METADATA_CACHE, "set SODA metadata cache",
error) < 0)
return DPI_FAILURE;
}
return DPI_SUCCESS;
}