ExternalLobVar.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. //-----------------------------------------------------------------------------
  2. // ExternalLobVar.c
  3. // Defines the routines for handling LOB variables external to this module.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // external LOB type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. PyObject_HEAD
  10. udt_LobVar *lobVar;
  11. unsigned pos;
  12. unsigned internalFetchNum;
  13. } udt_ExternalLobVar;
  14. //-----------------------------------------------------------------------------
  15. // Declaration of external LOB variable functions.
  16. //-----------------------------------------------------------------------------
  17. static void ExternalLobVar_Free(udt_ExternalLobVar*);
  18. static PyObject *ExternalLobVar_Str(udt_ExternalLobVar*);
  19. static PyObject *ExternalLobVar_Size(udt_ExternalLobVar*, PyObject*);
  20. static PyObject *ExternalLobVar_Open(udt_ExternalLobVar*, PyObject*);
  21. static PyObject *ExternalLobVar_Close(udt_ExternalLobVar*, PyObject*);
  22. static PyObject *ExternalLobVar_Read(udt_ExternalLobVar*, PyObject*,
  23. PyObject*);
  24. static PyObject *ExternalLobVar_Write(udt_ExternalLobVar*, PyObject*,
  25. PyObject*);
  26. static PyObject *ExternalLobVar_Trim(udt_ExternalLobVar*, PyObject*,
  27. PyObject*);
  28. static PyObject *ExternalLobVar_GetChunkSize(udt_ExternalLobVar*, PyObject*);
  29. static PyObject *ExternalLobVar_IsOpen(udt_ExternalLobVar*, PyObject*);
  30. static PyObject *ExternalLobVar_GetFileName(udt_ExternalLobVar*, PyObject*);
  31. static PyObject *ExternalLobVar_SetFileName(udt_ExternalLobVar*, PyObject*);
  32. static PyObject *ExternalLobVar_FileExists(udt_ExternalLobVar*, PyObject*);
  33. static PyObject *ExternalLobVar_Reduce(udt_ExternalLobVar*);
  34. //-----------------------------------------------------------------------------
  35. // declaration of methods for Python type "ExternalLOBVar"
  36. //-----------------------------------------------------------------------------
  37. static PyMethodDef g_ExternalLobVarMethods[] = {
  38. { "size", (PyCFunction) ExternalLobVar_Size, METH_NOARGS },
  39. { "open", (PyCFunction) ExternalLobVar_Open, METH_NOARGS },
  40. { "close", (PyCFunction) ExternalLobVar_Close, METH_NOARGS },
  41. { "read", (PyCFunction) ExternalLobVar_Read,
  42. METH_VARARGS | METH_KEYWORDS },
  43. { "write", (PyCFunction) ExternalLobVar_Write,
  44. METH_VARARGS | METH_KEYWORDS },
  45. { "trim", (PyCFunction) ExternalLobVar_Trim,
  46. METH_VARARGS | METH_KEYWORDS },
  47. { "getchunksize", (PyCFunction) ExternalLobVar_GetChunkSize, METH_NOARGS },
  48. { "isopen", (PyCFunction) ExternalLobVar_IsOpen, METH_NOARGS },
  49. { "getfilename", (PyCFunction) ExternalLobVar_GetFileName, METH_NOARGS },
  50. { "setfilename", (PyCFunction) ExternalLobVar_SetFileName, METH_VARARGS },
  51. { "fileexists", (PyCFunction) ExternalLobVar_FileExists, METH_NOARGS },
  52. { "__reduce__", (PyCFunction) ExternalLobVar_Reduce, METH_NOARGS },
  53. { NULL, NULL }
  54. };
  55. //-----------------------------------------------------------------------------
  56. // Python type declaration
  57. //-----------------------------------------------------------------------------
  58. static PyTypeObject g_ExternalLobVarType = {
  59. PyVarObject_HEAD_INIT(NULL, 0)
  60. "cx_Oracle.LOB", // tp_name
  61. sizeof(udt_ExternalLobVar), // tp_basicsize
  62. 0, // tp_itemsize
  63. (destructor) ExternalLobVar_Free, // tp_dealloc
  64. 0, // tp_print
  65. 0, // tp_getattr
  66. 0, // tp_setattr
  67. 0, // tp_compare
  68. 0, // tp_repr
  69. 0, // tp_as_number
  70. 0, // tp_as_sequence
  71. 0, // tp_as_mapping
  72. 0, // tp_hash
  73. 0, // tp_call
  74. (reprfunc) ExternalLobVar_Str, // tp_str
  75. 0, // tp_getattro
  76. 0, // tp_setattro
  77. 0, // tp_as_buffer
  78. Py_TPFLAGS_DEFAULT, // tp_flags
  79. 0, // tp_doc
  80. 0, // tp_traverse
  81. 0, // tp_clear
  82. 0, // tp_richcompare
  83. 0, // tp_weaklistoffset
  84. 0, // tp_iter
  85. 0, // tp_iternext
  86. g_ExternalLobVarMethods, // tp_methods
  87. 0, // tp_members
  88. 0, // tp_getset
  89. 0, // tp_base
  90. 0, // tp_dict
  91. 0, // tp_descr_get
  92. 0, // tp_descr_set
  93. 0, // tp_dictoffset
  94. 0, // tp_init
  95. 0, // tp_alloc
  96. 0, // tp_new
  97. 0, // tp_free
  98. 0, // tp_is_gc
  99. 0 // tp_bases
  100. };
  101. //-----------------------------------------------------------------------------
  102. // ExternalLobVar_New()
  103. // Create a new external LOB variable.
  104. //-----------------------------------------------------------------------------
  105. PyObject *ExternalLobVar_New(
  106. udt_LobVar *var, // variable to encapsulate
  107. unsigned pos) // position in array to encapsulate
  108. {
  109. udt_ExternalLobVar *self;
  110. self = (udt_ExternalLobVar*)
  111. g_ExternalLobVarType.tp_alloc(&g_ExternalLobVarType, 0);
  112. if (!self)
  113. return NULL;
  114. self->pos = pos;
  115. self->internalFetchNum = var->internalFetchNum;
  116. Py_INCREF(var);
  117. self->lobVar = var;
  118. return (PyObject*) self;
  119. }
  120. //-----------------------------------------------------------------------------
  121. // ExternalLobVar_Free()
  122. // Free an external LOB variable.
  123. //-----------------------------------------------------------------------------
  124. static void ExternalLobVar_Free(
  125. udt_ExternalLobVar *self) // variable to free
  126. {
  127. Py_CLEAR(self->lobVar);
  128. Py_TYPE(self)->tp_free((PyObject*) self);
  129. }
  130. //-----------------------------------------------------------------------------
  131. // ExternalLobVar_Verify()
  132. // Verify that the external LOB var is still valid.
  133. //-----------------------------------------------------------------------------
  134. static int ExternalLobVar_Verify(
  135. udt_ExternalLobVar *var) // variable to verify
  136. {
  137. if (var->internalFetchNum != var->lobVar->internalFetchNum) {
  138. PyErr_SetString(g_ProgrammingErrorException,
  139. "LOB variable no longer valid after subsequent fetch");
  140. return -1;
  141. }
  142. return 0;
  143. }
  144. //-----------------------------------------------------------------------------
  145. // ExternalLobVar_InternalRead()
  146. // Return the size of the LOB variable for internal comsumption.
  147. //-----------------------------------------------------------------------------
  148. static int ExternalLobVar_InternalRead(
  149. udt_ExternalLobVar *var, // variable to return the size of
  150. char *buffer, // buffer in which to put data
  151. oraub8 bufferSize, // size of buffer
  152. oraub8 *length, // length of data (IN/OUT)
  153. oraub8 offset) // offset
  154. {
  155. oraub8 lengthInBytes, lengthInChars;
  156. ub2 charsetId;
  157. sword status;
  158. if (var->lobVar->type == &vt_NCLOB || var->lobVar->type == &vt_CLOB) {
  159. lengthInBytes = 0;
  160. lengthInChars = *length;
  161. } else {
  162. lengthInChars = 0;
  163. lengthInBytes = *length;
  164. }
  165. if (var->lobVar->isFile) {
  166. Py_BEGIN_ALLOW_THREADS
  167. status = OCILobFileOpen(var->lobVar->connection->handle,
  168. var->lobVar->environment->errorHandle,
  169. var->lobVar->data[var->pos], OCI_FILE_READONLY);
  170. Py_END_ALLOW_THREADS
  171. if (Environment_CheckForError(var->lobVar->environment, status,
  172. "ExternalLobVar_FileOpen()") < 0)
  173. return -1;
  174. }
  175. Py_BEGIN_ALLOW_THREADS
  176. if (var->lobVar->type == &vt_NCLOB)
  177. charsetId = OCI_UTF16ID;
  178. else charsetId = 0;
  179. status = OCILobRead2(var->lobVar->connection->handle,
  180. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  181. &lengthInBytes, &lengthInChars, offset, buffer, bufferSize,
  182. OCI_ONE_PIECE, NULL, NULL, charsetId,
  183. var->lobVar->type->charsetForm);
  184. Py_END_ALLOW_THREADS
  185. if (Environment_CheckForError(var->lobVar->environment, status,
  186. "ExternalLobVar_LobRead()") < 0) {
  187. if (var->lobVar->isFile) {
  188. Py_BEGIN_ALLOW_THREADS
  189. OCILobFileClose(var->lobVar->connection->handle,
  190. var->lobVar->environment->errorHandle,
  191. var->lobVar->data[var->pos]);
  192. Py_END_ALLOW_THREADS
  193. }
  194. return -1;
  195. }
  196. *length = lengthInBytes;
  197. if (var->lobVar->isFile) {
  198. Py_BEGIN_ALLOW_THREADS
  199. status = OCILobFileClose(var->lobVar->connection->handle,
  200. var->lobVar->environment->errorHandle,
  201. var->lobVar->data[var->pos]);
  202. Py_END_ALLOW_THREADS
  203. if (Environment_CheckForError(var->lobVar->environment, status,
  204. "ExternalLobVar_FileClose()") < 0)
  205. return -1;
  206. }
  207. return 0;
  208. }
  209. //-----------------------------------------------------------------------------
  210. // ExternalLobVar_InternalSize()
  211. // Return the size of the LOB variable for internal comsumption.
  212. //-----------------------------------------------------------------------------
  213. static int ExternalLobVar_InternalSize(
  214. udt_ExternalLobVar *var, // variable to return the size of
  215. oraub8 *length) // length to return
  216. {
  217. sword status;
  218. Py_BEGIN_ALLOW_THREADS
  219. status = OCILobGetLength2(var->lobVar->connection->handle,
  220. var->lobVar->environment->errorHandle,
  221. var->lobVar->data[var->pos], length);
  222. Py_END_ALLOW_THREADS
  223. if (Environment_CheckForError(var->lobVar->environment, status,
  224. "ExternalLobVar_InternalSize()") < 0)
  225. return -1;
  226. return 0;
  227. }
  228. //-----------------------------------------------------------------------------
  229. // ExternalLobVar_Value()
  230. // Return a portion (or all) of the data in the external LOB variable.
  231. //-----------------------------------------------------------------------------
  232. static PyObject *ExternalLobVar_Value(
  233. udt_ExternalLobVar *var, // variable to return the size of
  234. oraub8 offset, // offset into LOB
  235. oraub8 amount) // amount to read from LOB
  236. {
  237. oraub8 length, bufferSize;
  238. PyObject *result;
  239. char *buffer;
  240. // modify the arguments
  241. if (amount == (oraub8)(-1)) {
  242. if (ExternalLobVar_InternalSize(var, &amount) < 0)
  243. return NULL;
  244. if (amount >= offset)
  245. amount = amount - offset + 1;
  246. else amount = 1;
  247. }
  248. length = amount;
  249. if (var->lobVar->type == &vt_CLOB)
  250. bufferSize = amount * var->lobVar->environment->maxBytesPerCharacter;
  251. else if (var->lobVar->type == &vt_NCLOB)
  252. bufferSize = amount * 2;
  253. else bufferSize = amount;
  254. // create a string for retrieving the value
  255. buffer = (char*) PyMem_Malloc(bufferSize);
  256. if (!buffer)
  257. return PyErr_NoMemory();
  258. if (ExternalLobVar_InternalRead(var, buffer, bufferSize, &length,
  259. offset) < 0) {
  260. PyMem_Free(buffer);
  261. return NULL;
  262. }
  263. // return the result
  264. if (var->lobVar->type == &vt_CLOB) {
  265. result = cxString_FromEncodedString(buffer, length,
  266. var->lobVar->environment->encoding);
  267. } else if (var->lobVar->type == &vt_NCLOB) {
  268. result = PyUnicode_DecodeUTF16(buffer, length, NULL, NULL);
  269. } else {
  270. result = PyBytes_FromStringAndSize(buffer, length);
  271. }
  272. PyMem_Free(buffer);
  273. return result;
  274. }
  275. //-----------------------------------------------------------------------------
  276. // ExternalLobVar_Size()
  277. // Return the size of the data in the LOB variable.
  278. //-----------------------------------------------------------------------------
  279. static PyObject *ExternalLobVar_Size(
  280. udt_ExternalLobVar *var, // variable to return the size of
  281. PyObject *args) // arguments
  282. {
  283. oraub8 length;
  284. if (ExternalLobVar_Verify(var) < 0)
  285. return NULL;
  286. if (ExternalLobVar_InternalSize(var, &length) < 0)
  287. return NULL;
  288. return PyLong_FromUnsignedLong(length);
  289. }
  290. //-----------------------------------------------------------------------------
  291. // ExternalLobVar_Open()
  292. // Open the LOB to speed further accesses.
  293. //-----------------------------------------------------------------------------
  294. static PyObject *ExternalLobVar_Open(
  295. udt_ExternalLobVar *var, // variable to return the size of
  296. PyObject *args) // arguments
  297. {
  298. sword status;
  299. if (ExternalLobVar_Verify(var) < 0)
  300. return NULL;
  301. Py_BEGIN_ALLOW_THREADS
  302. status = OCILobOpen(var->lobVar->connection->handle,
  303. var->lobVar->environment->errorHandle,
  304. var->lobVar->data[var->pos], OCI_LOB_READWRITE);
  305. Py_END_ALLOW_THREADS
  306. if (Environment_CheckForError(var->lobVar->environment, status,
  307. "ExternalLobVar_Open()") < 0)
  308. return NULL;
  309. Py_INCREF(Py_None);
  310. return Py_None;
  311. }
  312. //-----------------------------------------------------------------------------
  313. // ExternalLobVar_Close()
  314. // Close the LOB.
  315. //-----------------------------------------------------------------------------
  316. static PyObject *ExternalLobVar_Close(
  317. udt_ExternalLobVar *var, // variable to return the size of
  318. PyObject *args) // arguments
  319. {
  320. sword status;
  321. if (ExternalLobVar_Verify(var) < 0)
  322. return NULL;
  323. Py_BEGIN_ALLOW_THREADS
  324. status = OCILobClose(var->lobVar->connection->handle,
  325. var->lobVar->environment->errorHandle,
  326. var->lobVar->data[var->pos]);
  327. Py_END_ALLOW_THREADS
  328. if (Environment_CheckForError(var->lobVar->environment, status,
  329. "ExternalLobVar_Close()") < 0)
  330. return NULL;
  331. Py_INCREF(Py_None);
  332. return Py_None;
  333. }
  334. //-----------------------------------------------------------------------------
  335. // ExternalLobVar_Read()
  336. // Return a portion (or all) of the data in the external LOB variable.
  337. //-----------------------------------------------------------------------------
  338. static PyObject *ExternalLobVar_Read(
  339. udt_ExternalLobVar *var, // variable to return the size of
  340. PyObject *args, // arguments
  341. PyObject *keywordArgs) // keyword arguments
  342. {
  343. static char *keywordList[] = { "offset", "amount", NULL };
  344. oraub8 offset, amount;
  345. // offset and amount are expected, both optional
  346. offset = 1;
  347. amount = (oraub8)(-1);
  348. if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|KK", keywordList,
  349. &offset, &amount))
  350. return NULL;
  351. if (ExternalLobVar_Verify(var) < 0)
  352. return NULL;
  353. return ExternalLobVar_Value(var, offset, amount);
  354. }
  355. //-----------------------------------------------------------------------------
  356. // ExternalLobVar_Str()
  357. // Return all of the data in the external LOB variable.
  358. //-----------------------------------------------------------------------------
  359. static PyObject *ExternalLobVar_Str(
  360. udt_ExternalLobVar *var) // variable to return the string for
  361. {
  362. if (ExternalLobVar_Verify(var) < 0)
  363. return NULL;
  364. return ExternalLobVar_Value(var, 1, (oraub8)(-1));
  365. }
  366. //-----------------------------------------------------------------------------
  367. // ExternalLobVar_Write()
  368. // Write a value to the LOB variable; return the number of bytes written.
  369. //-----------------------------------------------------------------------------
  370. static PyObject *ExternalLobVar_Write(
  371. udt_ExternalLobVar *var, // variable to perform write against
  372. PyObject *args, // arguments
  373. PyObject *keywordArgs) // keyword arguments
  374. {
  375. static char *keywordList[] = { "data", "offset", NULL };
  376. oraub8 amount, offset;
  377. PyObject *dataObj;
  378. // buffer is expected, offset is optional
  379. offset = 1;
  380. if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "O|K", keywordList,
  381. &dataObj, &offset))
  382. return NULL;
  383. // perform the write, if possible
  384. if (ExternalLobVar_Verify(var) < 0)
  385. return NULL;
  386. if (LobVar_Write(var->lobVar, var->pos, dataObj, offset, &amount) < 0)
  387. return NULL;
  388. // return the result
  389. return PyLong_FromUnsignedLong(amount);
  390. }
  391. //-----------------------------------------------------------------------------
  392. // ExternalLobVar_Trim()
  393. // Trim the LOB variable to the specified length.
  394. //-----------------------------------------------------------------------------
  395. static PyObject *ExternalLobVar_Trim(
  396. udt_ExternalLobVar *var, // variable to perform write against
  397. PyObject *args, // arguments
  398. PyObject *keywordArgs) // keyword arguments
  399. {
  400. static char *keywordList[] = { "newSize", NULL };
  401. oraub8 newSize;
  402. sword status;
  403. // buffer and offset are expected, offset is optional
  404. newSize = 0;
  405. if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|K", keywordList,
  406. &newSize))
  407. return NULL;
  408. // create a string for retrieving the value
  409. if (ExternalLobVar_Verify(var) < 0)
  410. return NULL;
  411. Py_BEGIN_ALLOW_THREADS
  412. status = OCILobTrim2(var->lobVar->connection->handle,
  413. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  414. newSize);
  415. Py_END_ALLOW_THREADS
  416. if (Environment_CheckForError(var->lobVar->environment, status,
  417. "ExternalLobVar_Trim()") < 0)
  418. return NULL;
  419. // return the result
  420. Py_INCREF(Py_None);
  421. return Py_None;
  422. }
  423. //-----------------------------------------------------------------------------
  424. // ExternalLobVar_Reduce()
  425. // Method provided for pickling/unpickling of LOB variables.
  426. //-----------------------------------------------------------------------------
  427. static PyObject *ExternalLobVar_Reduce(
  428. udt_ExternalLobVar *self) // variable to dump
  429. {
  430. PyObject *result, *value;
  431. value = ExternalLobVar_Str(self);
  432. if (!value)
  433. return NULL;
  434. result = Py_BuildValue("(O(O))", Py_TYPE(value), value);
  435. Py_DECREF(value);
  436. return result;
  437. }
  438. //-----------------------------------------------------------------------------
  439. // ExternalLobVar_GetChunkSize()
  440. // Return the chunk size that should be used when reading/writing the LOB in
  441. // chunks.
  442. //-----------------------------------------------------------------------------
  443. static PyObject *ExternalLobVar_GetChunkSize(
  444. udt_ExternalLobVar *var, // variable to get chunk size for
  445. PyObject *args) // arguments
  446. {
  447. ub4 chunkSize;
  448. sword status;
  449. if (ExternalLobVar_Verify(var) < 0)
  450. return NULL;
  451. status = OCILobGetChunkSize(var->lobVar->connection->handle,
  452. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  453. &chunkSize);
  454. if (Environment_CheckForError(var->lobVar->environment, status,
  455. "ExternalLobVar_GetChunkSize()") < 0)
  456. return NULL;
  457. return PyInt_FromLong(chunkSize);
  458. }
  459. //-----------------------------------------------------------------------------
  460. // ExternalLobVar_IsOpen()
  461. // Return a boolean indicating if the lob is open or not.
  462. //-----------------------------------------------------------------------------
  463. static PyObject *ExternalLobVar_IsOpen(
  464. udt_ExternalLobVar *var, // variable to get chunk size for
  465. PyObject *args) // arguments
  466. {
  467. boolean isOpen;
  468. sword status;
  469. if (ExternalLobVar_Verify(var) < 0)
  470. return NULL;
  471. Py_BEGIN_ALLOW_THREADS
  472. status = OCILobIsOpen(var->lobVar->connection->handle,
  473. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  474. &isOpen);
  475. Py_END_ALLOW_THREADS
  476. if (Environment_CheckForError(var->lobVar->environment, status,
  477. "ExternalLobVar_IsOpen()") < 0)
  478. return NULL;
  479. return PyBool_FromLong(isOpen);
  480. }
  481. //-----------------------------------------------------------------------------
  482. // ExternalLobVar_GetFileName()
  483. // Return the directory alias and file name for the BFILE lob.
  484. //-----------------------------------------------------------------------------
  485. static PyObject *ExternalLobVar_GetFileName(
  486. udt_ExternalLobVar *var, // variable to get file name for
  487. PyObject *args) // arguments
  488. {
  489. char dirAlias[120], name[1020];
  490. ub2 dirAliasLength, nameLength;
  491. PyObject *result, *temp;
  492. sword status;
  493. // determine the directory alias and name
  494. if (ExternalLobVar_Verify(var) < 0)
  495. return NULL;
  496. nameLength = sizeof(name);
  497. dirAliasLength = sizeof(dirAlias);
  498. status = OCILobFileGetName(var->lobVar->environment->handle,
  499. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  500. (text*) dirAlias, &dirAliasLength, (text*) name, &nameLength);
  501. if (Environment_CheckForError(var->lobVar->environment, status,
  502. "ExternalLobVar_GetFileName()") < 0)
  503. return NULL;
  504. // create the two-tuple for returning
  505. result = PyTuple_New(2);
  506. if (!result)
  507. return NULL;
  508. temp = cxString_FromEncodedString(dirAlias, dirAliasLength,
  509. var->lobVar->environment->encoding);
  510. if (!temp) {
  511. Py_DECREF(result);
  512. return NULL;
  513. }
  514. PyTuple_SET_ITEM(result, 0, temp);
  515. temp = cxString_FromEncodedString(name, nameLength,
  516. var->lobVar->environment->encoding);
  517. if (!temp) {
  518. Py_DECREF(result);
  519. return NULL;
  520. }
  521. PyTuple_SET_ITEM(result, 1, temp);
  522. return result;
  523. }
  524. //-----------------------------------------------------------------------------
  525. // ExternalLobVar_SetFileName()
  526. // Set the directory alias and file name for the BFILE lob.
  527. //-----------------------------------------------------------------------------
  528. static PyObject *ExternalLobVar_SetFileName(
  529. udt_ExternalLobVar *var, // variable to set file name for
  530. PyObject *args) // arguments
  531. {
  532. int dirAliasLength, nameLength;
  533. char *dirAlias, *name;
  534. sword status;
  535. // get the directory alias and name as strings
  536. if (!PyArg_ParseTuple(args, "s#s#", &dirAlias, &dirAliasLength, &name,
  537. &nameLength))
  538. return NULL;
  539. // create a string for retrieving the value
  540. if (ExternalLobVar_Verify(var) < 0)
  541. return NULL;
  542. status = OCILobFileSetName(var->lobVar->environment->handle,
  543. var->lobVar->environment->errorHandle,
  544. &var->lobVar->data[var->pos], (text*) dirAlias,
  545. (ub2) dirAliasLength, (text*) name, (ub2) nameLength);
  546. if (Environment_CheckForError(var->lobVar->environment, status,
  547. "ExternalLobVar_SetFileName()") < 0)
  548. return NULL;
  549. // return the result
  550. Py_INCREF(Py_None);
  551. return Py_None;
  552. }
  553. //-----------------------------------------------------------------------------
  554. // ExternalLobVar_FileExists()
  555. // Return a boolean indicating if the BFIILE lob exists.
  556. //-----------------------------------------------------------------------------
  557. static PyObject *ExternalLobVar_FileExists(
  558. udt_ExternalLobVar *var, // variable to perform write against
  559. PyObject *args) // arguments
  560. {
  561. PyObject *result;
  562. sword status;
  563. boolean flag;
  564. if (ExternalLobVar_Verify(var) < 0)
  565. return NULL;
  566. Py_BEGIN_ALLOW_THREADS
  567. status = OCILobFileExists(var->lobVar->connection->handle,
  568. var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
  569. &flag);
  570. Py_END_ALLOW_THREADS
  571. if (Environment_CheckForError(var->lobVar->environment, status,
  572. "ExternalLobVar_FileExists()") < 0)
  573. return NULL;
  574. // return the result
  575. if (flag)
  576. result = Py_True;
  577. else result = Py_False;
  578. Py_INCREF(result);
  579. return result;
  580. }