| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- //-----------------------------------------------------------------------------
- // LobVar.c
- // Defines the routines for handling LOB variables.
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // LOB type
- //-----------------------------------------------------------------------------
- typedef struct {
- Variable_HEAD
- OCILobLocator **data;
- udt_Connection *connection;
- int isFile;
- } udt_LobVar;
- //-----------------------------------------------------------------------------
- // Declaration of LOB variable functions.
- //-----------------------------------------------------------------------------
- static int LobVar_Initialize(udt_LobVar*, udt_Cursor*);
- static int LobVar_PreFetch(udt_LobVar*);
- static void LobVar_Finalize(udt_LobVar*);
- static PyObject *LobVar_GetValue(udt_LobVar*, unsigned);
- static int LobVar_SetValue(udt_LobVar*, unsigned, PyObject*);
- static int LobVar_Write(udt_LobVar*, unsigned, PyObject*, oraub8, oraub8*);
- //-----------------------------------------------------------------------------
- // Python type declarations
- //-----------------------------------------------------------------------------
- static PyTypeObject g_CLOBVarType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "cx_Oracle.CLOB", // tp_name
- sizeof(udt_LobVar), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0 // tp_doc
- };
- static PyTypeObject g_NCLOBVarType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "cx_Oracle.NCLOB", // tp_name
- sizeof(udt_LobVar), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0 // tp_doc
- };
- static PyTypeObject g_BLOBVarType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "cx_Oracle.BLOB", // tp_name
- sizeof(udt_LobVar), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0 // tp_doc
- };
- static PyTypeObject g_BFILEVarType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "cx_Oracle.BFILE", // tp_name
- sizeof(udt_LobVar), // tp_basicsize
- 0, // tp_itemsize
- 0, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- 0 // tp_doc
- };
- //-----------------------------------------------------------------------------
- // variable type declarations
- //-----------------------------------------------------------------------------
- static udt_VariableType vt_CLOB = {
- (InitializeProc) LobVar_Initialize,
- (FinalizeProc) LobVar_Finalize,
- (PreDefineProc) NULL,
- (PostDefineProc) NULL,
- (PreFetchProc) LobVar_PreFetch,
- (IsNullProc) NULL,
- (SetValueProc) LobVar_SetValue,
- (GetValueProc) LobVar_GetValue,
- (GetBufferSizeProc) NULL,
- &g_CLOBVarType, // Python type
- SQLT_CLOB, // Oracle type
- SQLCS_IMPLICIT, // charset form
- sizeof(OCILobLocator*), // element length
- 1, // is character data
- 0, // is variable length
- 0, // can be copied
- 0 // can be in array
- };
- static udt_VariableType vt_NCLOB = {
- (InitializeProc) LobVar_Initialize,
- (FinalizeProc) LobVar_Finalize,
- (PreDefineProc) NULL,
- (PostDefineProc) NULL,
- (PreFetchProc) LobVar_PreFetch,
- (IsNullProc) NULL,
- (SetValueProc) LobVar_SetValue,
- (GetValueProc) LobVar_GetValue,
- (GetBufferSizeProc) NULL,
- &g_NCLOBVarType, // Python type
- SQLT_CLOB, // Oracle type
- SQLCS_NCHAR, // charset form
- sizeof(OCILobLocator*), // element length
- 1, // is character data
- 0, // is variable length
- 0, // can be copied
- 0 // can be in array
- };
- static udt_VariableType vt_BLOB = {
- (InitializeProc) LobVar_Initialize,
- (FinalizeProc) LobVar_Finalize,
- (PreDefineProc) NULL,
- (PostDefineProc) NULL,
- (PreFetchProc) LobVar_PreFetch,
- (IsNullProc) NULL,
- (SetValueProc) LobVar_SetValue,
- (GetValueProc) LobVar_GetValue,
- (GetBufferSizeProc) NULL,
- &g_BLOBVarType, // Python type
- SQLT_BLOB, // Oracle type
- SQLCS_IMPLICIT, // charset form
- sizeof(OCILobLocator*), // element length
- 0, // is character data
- 0, // is variable length
- 0, // can be copied
- 0 // can be in array
- };
- static udt_VariableType vt_BFILE = {
- (InitializeProc) LobVar_Initialize,
- (FinalizeProc) LobVar_Finalize,
- (PreDefineProc) NULL,
- (PostDefineProc) NULL,
- (PreFetchProc) LobVar_PreFetch,
- (IsNullProc) NULL,
- (SetValueProc) LobVar_SetValue,
- (GetValueProc) LobVar_GetValue,
- (GetBufferSizeProc) NULL,
- &g_BFILEVarType, // Python type
- SQLT_BFILE, // Oracle type
- SQLCS_IMPLICIT, // charset form
- sizeof(OCILobLocator*), // element length
- 0, // is character data
- 0, // is variable length
- 0, // can be copied
- 0 // can be in array
- };
- #include "ExternalLobVar.c"
- //-----------------------------------------------------------------------------
- // 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;
- }
- //-----------------------------------------------------------------------------
- // 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;
- }
- }
- }
- return 0;
- }
- //-----------------------------------------------------------------------------
- // LobVar_Finalize()
- // Prepare for variable destruction.
- //-----------------------------------------------------------------------------
- static void LobVar_Finalize(
- udt_LobVar *var) // variable to free
- {
- boolean isTemporary;
- ub4 i;
- for (i = 0; i < var->allocatedElements; i++) {
- if (var->data[i]) {
- OCILobIsTemporary(var->environment->handle,
- var->environment->errorHandle, var->data[i], &isTemporary);
- if (isTemporary) {
- Py_BEGIN_ALLOW_THREADS
- OCILobFreeTemporary(var->connection->handle,
- var->environment->errorHandle, var->data[i]);
- Py_END_ALLOW_THREADS
- }
- OCIDescriptorFree(var->data[i], OCI_DTYPE_LOB);
- }
- }
- Py_DECREF(var->connection);
- }
- //-----------------------------------------------------------------------------
- // LobVar_Write()
- // Write data to the LOB variable.
- //-----------------------------------------------------------------------------
- static int LobVar_Write(
- udt_LobVar *var, // variable to perform write against
- unsigned position, // position to perform write against
- PyObject *dataObj, // data object to write into LOB
- oraub8 offset, // offset into variable
- oraub8 *amount) // amount to write
- {
- udt_Buffer buffer;
- sword status;
- // verify the data type
- if (var->type == &vt_BFILE) {
- PyErr_SetString(PyExc_TypeError, "BFILEs are read only");
- return -1;
- } else if (var->type == &vt_BLOB) {
- if (cxBuffer_FromObject(&buffer, dataObj,
- var->environment->encoding) < 0)
- return -1;
- *amount = buffer.size;
- #if PY_MAJOR_VERSION < 3
- } else if (var->type == &vt_NCLOB) {
- if (cxBuffer_FromObject(&buffer, dataObj,
- var->environment->nencoding) < 0)
- return -1;
- *amount = buffer.size;
- #endif
- } else {
- if (cxBuffer_FromObject(&buffer, dataObj,
- var->environment->encoding) < 0)
- return -1;
- if (var->environment->fixedWidth
- && var->environment->maxBytesPerCharacter > 1)
- *amount = buffer.size / var->environment->maxBytesPerCharacter;
- else *amount = buffer.size;
- }
- // nothing to do if no data to write
- if (*amount == 0) {
- cxBuffer_Clear(&buffer);
- return 0;
- }
- Py_BEGIN_ALLOW_THREADS
- status = OCILobWrite2(var->connection->handle,
- var->environment->errorHandle, var->data[position], amount, 0,
- offset, (void*) buffer.ptr, buffer.size, OCI_ONE_PIECE, NULL, NULL,
- 0, var->type->charsetForm);
- Py_END_ALLOW_THREADS
- cxBuffer_Clear(&buffer);
- if (Environment_CheckForError(var->environment, status,
- "LobVar_Write()") < 0)
- return -1;
- return 0;
- }
- //-----------------------------------------------------------------------------
- // LobVar_GetValue()
- // Returns the value stored at the given array position.
- //-----------------------------------------------------------------------------
- static PyObject *LobVar_GetValue(
- udt_LobVar *var, // variable to determine value for
- unsigned pos) // array position
- {
- return ExternalLobVar_New(var, pos);
- }
- //-----------------------------------------------------------------------------
- // LobVar_SetValue()
- // Sets the value stored at the given array position.
- //-----------------------------------------------------------------------------
- static int LobVar_SetValue(
- udt_LobVar *var, // variable to determine value for
- unsigned position, // array position
- PyObject *value) // value to set
- {
- boolean isTemporary;
- oraub8 amount;
- sword status;
- ub1 lobType;
- // make sure have temporary LOBs set up
- status = OCILobIsTemporary(var->environment->handle,
- var->environment->errorHandle, var->data[position], &isTemporary);
- if (Environment_CheckForError(var->environment, status,
- "LobVar_SetValue(): is temporary?") < 0)
- return -1;
- if (!isTemporary) {
- if (var->type->oracleType == SQLT_BLOB)
- lobType = OCI_TEMP_BLOB;
- else lobType = OCI_TEMP_CLOB;
- Py_BEGIN_ALLOW_THREADS
- status = OCILobCreateTemporary(var->connection->handle,
- var->environment->errorHandle, var->data[position],
- OCI_DEFAULT, var->type->charsetForm, lobType, FALSE,
- OCI_DURATION_SESSION);
- Py_END_ALLOW_THREADS
- if (Environment_CheckForError(var->environment, status,
- "LobVar_SetValue(): create temporary") < 0)
- return -1;
- }
- // trim the current value
- Py_BEGIN_ALLOW_THREADS
- status = OCILobTrim(var->connection->handle,
- var->environment->errorHandle, var->data[position], 0);
- Py_END_ALLOW_THREADS
- if (Environment_CheckForError(var->environment, status,
- "LobVar_SetValue(): trim") < 0)
- return -1;
- // set the current value
- return LobVar_Write(var, position, value, 1, &amount);
- }
|