//----------------------------------------------------------------------------- // NumberVar_PreDefine() // Set the type of value (integer, float or string) that will be returned // when values are fetched from this variable. //----------------------------------------------------------------------------- static int NumberVar_PreDefine( udt_NumberVar *var, // variable to initialize OCIParam *param) // parameter handle { static int maxLongSafeDigits = sizeof(long) >= 8 ? 18 : 9; sb2 precision; sword status; sb1 scale; // if the return type has not already been specified, check to see if the // number can fit inside an integer by looking at the precision and scale if (var->type == &vt_Float) { scale = 0; precision = 0; status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &scale, 0, OCI_ATTR_SCALE, var->environment->errorHandle); if (Environment_CheckForError(var->environment, status, "NumberVar_PreDefine(): scale") < 0) return -1; status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &precision, 0, OCI_ATTR_PRECISION, var->environment->errorHandle); if (Environment_CheckForError(var->environment, status, "NumberVar_PreDefine(): precision") < 0) return -1; if (scale == 0 || (scale == -127 && precision == 0)) { var->type = &vt_LongInteger; if (precision > 0 && precision <= maxLongSafeDigits) var->type = &vt_Integer; } } return 0; }
//----------------------------------------------------------------------------- // LobVar_PreFetch() // Free temporary LOBs prior to fetch. //----------------------------------------------------------------------------- static int LobVar_PreFetch( udt_LobVar *var) // variable to free { boolean isTemporary; sword status; ub4 i; for (i = 0; i < var->allocatedElements; i++) { if (var->data[i]) { status = OCILobIsTemporary(var->environment->handle, var->environment->errorHandle, var->data[i], &isTemporary); if (Environment_CheckForError(var->environment, status, "LobVar_PreFetch(): is temporary LOB?") < 0) return -1; if (isTemporary) { Py_BEGIN_ALLOW_THREADS status = OCILobFreeTemporary(var->connection->handle, var->environment->errorHandle, var->data[i]); Py_END_ALLOW_THREADS if (Environment_CheckForError(var->environment, status, "LobVar_PreFetch(): free temporary LOB") < 0) return -1; } } }
//----------------------------------------------------------------------------- // NumberVar_GetValue() // Returns the value stored at the given array position. //----------------------------------------------------------------------------- static PyObject *NumberVar_GetValue( udt_NumberVar *var, // variable to determine value for unsigned pos) // array position { PyObject *result, *stringObj; char stringValue[200]; long integerValue; ub4 stringLength; sword status; if (var->type == &vt_Boolean || var->type == &vt_Integer) { status = OCINumberToInt(var->environment->errorHandle, &var->data[pos], sizeof(long), OCI_NUMBER_SIGNED, (dvoid*) &integerValue); if (Environment_CheckForError(var->environment, status, "NumberVar_GetValue(): as integer") < 0) return NULL; if (var->type == &vt_Boolean) return PyBool_FromLong(integerValue); #if PY_MAJOR_VERSION >= 3 return PyLong_FromLong(integerValue); #else return PyInt_FromLong(integerValue); #endif } if (var->type == &vt_NumberAsString || var->type == &vt_LongInteger) { stringLength = sizeof(stringValue); status = OCINumberToText(var->environment->errorHandle, &var->data[pos], (text*) var->environment->numberToStringFormatBuffer.ptr, var->environment->numberToStringFormatBuffer.size, NULL, 0, &stringLength, (unsigned char*) stringValue); if (Environment_CheckForError(var->environment, status, "NumberVar_GetValue(): as string") < 0) return NULL; stringObj = cxString_FromEncodedString(stringValue, stringLength, var->environment->encoding); if (!stringObj) return NULL; if (var->type == &vt_NumberAsString) return stringObj; #if PY_MAJOR_VERSION >= 3 result = PyNumber_Long(stringObj); #else result = PyNumber_Int(stringObj); #endif Py_DECREF(stringObj); if (result || !PyErr_ExceptionMatches(PyExc_ValueError)) return result; PyErr_Clear(); } return OracleNumberToPythonFloat(var->environment, &var->data[pos]); }
//----------------------------------------------------------------------------- // NumberVar_SetValueFromLong() // Set the value of the variable from a Python long. //----------------------------------------------------------------------------- static int NumberVar_SetValueFromLong( udt_NumberVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { udt_Buffer textBuffer; PyObject *textValue; sword status; textValue = PyObject_Str(value); if (!textValue) return -1; if (cxBuffer_FromObject(&textBuffer, textValue, var->environment->encoding) < 0) return -1; status = OCINumberFromText(var->environment->errorHandle, (text*) textBuffer.ptr, textBuffer.size, (text*) var->environment->numberFromStringFormatBuffer.ptr, var->environment->numberFromStringFormatBuffer.size, NULL, 0, &var->data[pos]); cxBuffer_Clear(&textBuffer); Py_DECREF(textValue); return Environment_CheckForError(var->environment, status, "NumberVar_SetValueFromLong()"); }
//----------------------------------------------------------------------------- // ObjectVar_PostDefine() // Performs additional steps required for defining objects. //----------------------------------------------------------------------------- static int ObjectVar_PostDefine( udt_ObjectVar *self) // variable to set up { sword status; status = OCIDefineObject(self->defineHandle, self->environment->errorHandle, self->objectType->tdo, self->data, 0, self->objectIndicator, 0); return Environment_CheckForError(self->environment, status, "ObjectVar_PostDefine(): define object"); }
//----------------------------------------------------------------------------- // TimestampVar_SetValue() // Set the value of the variable. //----------------------------------------------------------------------------- static int TimestampVar_SetValue( udt_TimestampVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { sword status; uword valid; // make sure a timestamp is being bound if (!PyDateTime_Check(value)) { PyErr_SetString(PyExc_TypeError, "expecting timestamp data"); return -1; } // store a copy of the value status = OCIDateTimeConstruct(var->environment->handle, var->environment->errorHandle, var->data[pos], (sb2) PyDateTime_GET_YEAR(value), PyDateTime_GET_MONTH(value), PyDateTime_GET_DAY(value), PyDateTime_DATE_GET_HOUR(value), PyDateTime_DATE_GET_MINUTE(value), PyDateTime_DATE_GET_SECOND(value), PyDateTime_DATE_GET_MICROSECOND(value) * 1000, NULL, 0); if (Environment_CheckForError(var->environment, status, "TimestampVar_SetValue(): create structure") < 0) return -1; status = OCIDateTimeCheck(var->environment->handle, var->environment->errorHandle, var->data[pos], &valid); if (Environment_CheckForError(var->environment, status, "TimestampVar_SetValue()") < 0) return -1; if (valid != 0) { PyErr_SetString(g_DataErrorException, "invalid date"); return -1; } return 0; }
//----------------------------------------------------------------------------- // NumberVar_SetValueFromFloat() // Set the value of the variable from a Python float. //----------------------------------------------------------------------------- static int NumberVar_SetValueFromFloat( udt_NumberVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { double doubleValue; sword status; doubleValue = PyFloat_AS_DOUBLE(value); status = OCINumberFromReal(var->environment->errorHandle, &doubleValue, sizeof(double), &var->data[pos]); return Environment_CheckForError(var->environment, status, "NumberVar_SetValueFromFloat()"); }
//----------------------------------------------------------------------------- // NumberVar_SetValueFromInteger() // Set the value of the variable from a Python integer. //----------------------------------------------------------------------------- static int NumberVar_SetValueFromInteger( udt_NumberVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { long integerValue; sword status; integerValue = PyInt_AS_LONG(value); status = OCINumberFromInt(var->environment->errorHandle, &integerValue, sizeof(long), OCI_NUMBER_SIGNED, &var->data[pos]); return Environment_CheckForError(var->environment, status, "NumberVar_SetValueFromInteger()"); }
//----------------------------------------------------------------------------- // StringVar_PostDefine() // Set the character set information when values are fetched from this // variable. //----------------------------------------------------------------------------- static int StringVar_PostDefine( udt_StringVar *var) // variable to initialize { sword status; status = OCIAttrSet(var->defineHandle, OCI_HTYPE_DEFINE, &var->type->charsetForm, 0, OCI_ATTR_CHARSET_FORM, var->environment->errorHandle); if (Environment_CheckForError(var->environment, status, "StringVar_PostDefine(): setting charset form") < 0) return -1; return 0; }
//----------------------------------------------------------------------------- // TimestampVar_Initialize() // Initialize the variable. //----------------------------------------------------------------------------- static int TimestampVar_Initialize( udt_TimestampVar *var, // variable to initialize udt_Cursor *cursor) // cursor variable associated with { sword status; ub4 i; // initialize the LOB locators for (i = 0; i < var->allocatedElements; i++) { status = OCIDescriptorAlloc(var->environment->handle, (dvoid**) &var->data[i], OCI_DTYPE_TIMESTAMP, 0, 0); if (Environment_CheckForError(var->environment, status, "TimestampVar_Initialize()") < 0) return -1; } return 0; }
//----------------------------------------------------------------------------- // ExternalLobVar_InternalRead() // Return the size of the LOB variable for internal comsumption. //----------------------------------------------------------------------------- static int ExternalLobVar_InternalRead( udt_ExternalLobVar *var, // variable to return the size of char *buffer, // buffer in which to put data ub4 bufferSize, // size of buffer ub4 *length, // length of data (IN/OUT) int offset) // offset { sword status; if (var->lobVar->isFile) { Py_BEGIN_ALLOW_THREADS status = OCILobFileOpen(var->lobVar->connection->handle, var->lobVar->environment->errorHandle, var->lobVar->data[var->pos], OCI_FILE_READONLY); Py_END_ALLOW_THREADS if (Environment_CheckForError(var->lobVar->environment, status, "ExternalLobVar_FileOpen()") < 0) return -1; }
//----------------------------------------------------------------------------- // LobVar_Initialize() // Initialize the variable. //----------------------------------------------------------------------------- static int LobVar_Initialize( udt_LobVar *var, // variable to initialize udt_Cursor *cursor) // cursor created by { sword status; ub4 i; ub4 length; // initialize members Py_INCREF(cursor->connection); var->connection = cursor->connection; var->isFile = (var->type == &vt_BFILE); // initialize the LOB locators for (i = 0; i < var->allocatedElements; i++) { status = OCIDescriptorAlloc(var->environment->handle, (dvoid**) &var->data[i], OCI_DTYPE_LOB, 0, 0); if (Environment_CheckForError(var->environment, status, "LobVar_Initialize()") < 0) return -1; PySys_WriteStderr("LobVar_Initialize(env=%p, i=%d, lob=%p)\n", var->environment->handle, i, var->data[i]); /* Py_BEGIN_ALLOW_THREADS status = OCILobGetLength(var->connection->handle, var->environment->errorHandle, var->data[i], &length); Py_END_ALLOW_THREADS if (Environment_CheckForError(var->environment, status, "LobVar_InternalSize()") < 0) return -1; PySys_WriteStderr("LobVar_Initialize(lob=%p length=%d)\n", var->data[i], length); */ } return 0; }
//----------------------------------------------------------------------------- // NumberVar_SetValueFromDecimal() // Set the value of the variable from a Python decimal.Decimal object. //----------------------------------------------------------------------------- static int NumberVar_SetValueFromDecimal( udt_NumberVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { PyObject *textValue, *format, *tupleValue; udt_Buffer textBuffer, formatBuffer; sword status; tupleValue = PyObject_CallMethod(value, "as_tuple", NULL); if (!tupleValue) return -1; if (NumberVar_GetFormatAndTextFromDecimal(tupleValue, &textValue, &format) < 0) { Py_DECREF(tupleValue); return -1; } Py_DECREF(tupleValue); if (cxBuffer_FromObject(&textBuffer, textValue, var->environment->encoding) < 0) return -1; if (cxBuffer_FromObject(&formatBuffer, format, var->environment->encoding) < 0) { cxBuffer_Clear(&textBuffer); return -1; } status = OCINumberFromText(var->environment->errorHandle, (text*) textBuffer.ptr, textBuffer.size, (text*) formatBuffer.ptr, formatBuffer.size, var->environment->nlsNumericCharactersBuffer.ptr, var->environment->nlsNumericCharactersBuffer.size, &var->data[pos]); cxBuffer_Clear(&textBuffer); cxBuffer_Clear(&formatBuffer); Py_DECREF(textValue); Py_DECREF(format); return Environment_CheckForError(var->environment, status, "NumberVar_SetValueFromDecimal()"); }
//----------------------------------------------------------------------------- // LobVar_Initialize() // Initialize the variable. //----------------------------------------------------------------------------- static int LobVar_Initialize( udt_LobVar *var, // variable to initialize udt_Cursor *cursor) // cursor created by { sword status; ub4 i; // initialize members Py_INCREF(cursor->connection); var->connection = cursor->connection; var->isFile = (var->type == &vt_BFILE); // initialize the LOB locators for (i = 0; i < var->allocatedElements; i++) { status = OCIDescriptorAlloc(var->environment->handle, (dvoid**) &var->data[i], OCI_DTYPE_LOB, 0, 0); if (Environment_CheckForError(var->environment, status, "LobVar_Initialize()") < 0) return -1; } return 0; }
//----------------------------------------------------------------------------- // NumberVar_GetValue() // Returns the value stored at the given array position. //----------------------------------------------------------------------------- static PyObject *NumberVar_GetValue( udt_NumberVar *var, // variable to determine value for unsigned pos) // array position { PyObject *result, *stringObj; char stringValue[200]; long integerValue; ub4 stringLength; sword status; #if PY_MAJOR_VERSION < 3 if (var->type == &vt_Integer || var->type == &vt_Boolean) { #else if (var->type == &vt_Boolean) { #endif status = OCINumberToInt(var->environment->errorHandle, &var->data[pos], sizeof(long), OCI_NUMBER_SIGNED, (dvoid*) &integerValue); if (Environment_CheckForError(var->environment, status, "NumberVar_GetValue(): as integer") < 0) return NULL; #if PY_MAJOR_VERSION < 3 if (var->type == &vt_Integer) return PyInt_FromLong(integerValue); #endif return PyBool_FromLong(integerValue); } if (var->type == &vt_NumberAsString || var->type == &vt_LongInteger) { stringLength = sizeof(stringValue); status = OCINumberToText(var->environment->errorHandle, &var->data[pos], (text*) var->environment->numberToStringFormatBuffer.ptr, var->environment->numberToStringFormatBuffer.size, NULL, 0, &stringLength, (unsigned char*) stringValue); if (Environment_CheckForError(var->environment, status, "NumberVar_GetValue(): as string") < 0) return NULL; stringObj = cxString_FromEncodedString(stringValue, stringLength, var->environment->encoding); if (!stringObj) return NULL; if (var->type == &vt_NumberAsString) return stringObj; #if PY_MAJOR_VERSION >= 3 result = PyNumber_Long(stringObj); #else result = PyNumber_Int(stringObj); #endif Py_DECREF(stringObj); if (result || !PyErr_ExceptionMatches(PyExc_ValueError)) return result; PyErr_Clear(); } return OracleNumberToPythonFloat(var->environment, &var->data[pos]); } #ifdef SQLT_BFLOAT //----------------------------------------------------------------------------- // NativeFloatVar_GetValue() // Returns the value stored at the given array position as a float. //----------------------------------------------------------------------------- static PyObject *NativeFloatVar_GetValue( udt_NativeFloatVar *var, // variable to determine value for unsigned pos) // array position { return PyFloat_FromDouble(var->data[pos]); } //----------------------------------------------------------------------------- // NativeFloatVar_SetValue() // Set the value of the variable which should be a native double. //----------------------------------------------------------------------------- static int NativeFloatVar_SetValue( udt_NativeFloatVar *var, // variable to set value for unsigned pos, // array position to set PyObject *value) // value to set { if (!PyFloat_Check(value)) { PyErr_SetString(PyExc_TypeError, "expecting float"); return -1; } var->data[pos] = PyFloat_AS_DOUBLE(value); return 0; }