StringVar.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //-----------------------------------------------------------------------------
  2. // StringVar.c
  3. // Defines the routines specific to the string type.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // String type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. Variable_HEAD
  10. char *data;
  11. } udt_StringVar;
  12. //-----------------------------------------------------------------------------
  13. // Declaration of string variable functions.
  14. //-----------------------------------------------------------------------------
  15. static int StringVar_Initialize(udt_StringVar*, udt_Cursor*);
  16. static int StringVar_SetValue(udt_StringVar*, unsigned, PyObject*);
  17. static PyObject *StringVar_GetValue(udt_StringVar*, unsigned);
  18. static int StringVar_PostDefine(udt_StringVar*);
  19. static ub4 StringVar_GetBufferSize(udt_StringVar*);
  20. //-----------------------------------------------------------------------------
  21. // Python type declarations
  22. //-----------------------------------------------------------------------------
  23. static PyTypeObject g_StringVarType = {
  24. PyVarObject_HEAD_INIT(NULL, 0)
  25. "cx_Oracle.STRING", // tp_name
  26. sizeof(udt_StringVar), // tp_basicsize
  27. 0, // tp_itemsize
  28. 0, // tp_dealloc
  29. 0, // tp_print
  30. 0, // tp_getattr
  31. 0, // tp_setattr
  32. 0, // tp_compare
  33. 0, // tp_repr
  34. 0, // tp_as_number
  35. 0, // tp_as_sequence
  36. 0, // tp_as_mapping
  37. 0, // tp_hash
  38. 0, // tp_call
  39. 0, // tp_str
  40. 0, // tp_getattro
  41. 0, // tp_setattro
  42. 0, // tp_as_buffer
  43. Py_TPFLAGS_DEFAULT, // tp_flags
  44. 0 // tp_doc
  45. };
  46. static PyTypeObject g_NCharVarType = {
  47. PyVarObject_HEAD_INIT(NULL, 0)
  48. "cx_Oracle.NCHAR", // tp_name
  49. sizeof(udt_StringVar), // tp_basicsize
  50. 0, // tp_itemsize
  51. 0, // tp_dealloc
  52. 0, // tp_print
  53. 0, // tp_getattr
  54. 0, // tp_setattr
  55. 0, // tp_compare
  56. 0, // tp_repr
  57. 0, // tp_as_number
  58. 0, // tp_as_sequence
  59. 0, // tp_as_mapping
  60. 0, // tp_hash
  61. 0, // tp_call
  62. 0, // tp_str
  63. 0, // tp_getattro
  64. 0, // tp_setattro
  65. 0, // tp_as_buffer
  66. Py_TPFLAGS_DEFAULT, // tp_flags
  67. 0 // tp_doc
  68. };
  69. static PyTypeObject g_FixedCharVarType = {
  70. PyVarObject_HEAD_INIT(NULL, 0)
  71. "cx_Oracle.FIXED_CHAR", // tp_name
  72. sizeof(udt_StringVar), // tp_basicsize
  73. 0, // tp_itemsize
  74. 0, // tp_dealloc
  75. 0, // tp_print
  76. 0, // tp_getattr
  77. 0, // tp_setattr
  78. 0, // tp_compare
  79. 0, // tp_repr
  80. 0, // tp_as_number
  81. 0, // tp_as_sequence
  82. 0, // tp_as_mapping
  83. 0, // tp_hash
  84. 0, // tp_call
  85. 0, // tp_str
  86. 0, // tp_getattro
  87. 0, // tp_setattro
  88. 0, // tp_as_buffer
  89. Py_TPFLAGS_DEFAULT, // tp_flags
  90. 0 // tp_doc
  91. };
  92. static PyTypeObject g_FixedNCharVarType = {
  93. PyVarObject_HEAD_INIT(NULL, 0)
  94. "cx_Oracle.FIXED_NCHAR", // tp_name
  95. sizeof(udt_StringVar), // tp_basicsize
  96. 0, // tp_itemsize
  97. 0, // tp_dealloc
  98. 0, // tp_print
  99. 0, // tp_getattr
  100. 0, // tp_setattr
  101. 0, // tp_compare
  102. 0, // tp_repr
  103. 0, // tp_as_number
  104. 0, // tp_as_sequence
  105. 0, // tp_as_mapping
  106. 0, // tp_hash
  107. 0, // tp_call
  108. 0, // tp_str
  109. 0, // tp_getattro
  110. 0, // tp_setattro
  111. 0, // tp_as_buffer
  112. Py_TPFLAGS_DEFAULT, // tp_flags
  113. 0 // tp_doc
  114. };
  115. static PyTypeObject g_RowidVarType = {
  116. PyVarObject_HEAD_INIT(NULL, 0)
  117. "cx_Oracle.ROWID", // tp_name
  118. sizeof(udt_StringVar), // tp_basicsize
  119. 0, // tp_itemsize
  120. 0, // tp_dealloc
  121. 0, // tp_print
  122. 0, // tp_getattr
  123. 0, // tp_setattr
  124. 0, // tp_compare
  125. 0, // tp_repr
  126. 0, // tp_as_number
  127. 0, // tp_as_sequence
  128. 0, // tp_as_mapping
  129. 0, // tp_hash
  130. 0, // tp_call
  131. 0, // tp_str
  132. 0, // tp_getattro
  133. 0, // tp_setattro
  134. 0, // tp_as_buffer
  135. Py_TPFLAGS_DEFAULT, // tp_flags
  136. 0 // tp_doc
  137. };
  138. static PyTypeObject g_BinaryVarType = {
  139. PyVarObject_HEAD_INIT(NULL, 0)
  140. "cx_Oracle.BINARY", // tp_name
  141. sizeof(udt_StringVar), // tp_basicsize
  142. 0, // tp_itemsize
  143. 0, // tp_dealloc
  144. 0, // tp_print
  145. 0, // tp_getattr
  146. 0, // tp_setattr
  147. 0, // tp_compare
  148. 0, // tp_repr
  149. 0, // tp_as_number
  150. 0, // tp_as_sequence
  151. 0, // tp_as_mapping
  152. 0, // tp_hash
  153. 0, // tp_call
  154. 0, // tp_str
  155. 0, // tp_getattro
  156. 0, // tp_setattro
  157. 0, // tp_as_buffer
  158. Py_TPFLAGS_DEFAULT, // tp_flags
  159. 0 // tp_doc
  160. };
  161. //-----------------------------------------------------------------------------
  162. // variable type declarations
  163. //-----------------------------------------------------------------------------
  164. static udt_VariableType vt_String = {
  165. (InitializeProc) StringVar_Initialize,
  166. (FinalizeProc) NULL,
  167. (PreDefineProc) NULL,
  168. (PostDefineProc) NULL,
  169. (PreFetchProc) NULL,
  170. (IsNullProc) NULL,
  171. (SetValueProc) StringVar_SetValue,
  172. (GetValueProc) StringVar_GetValue,
  173. (GetBufferSizeProc) StringVar_GetBufferSize,
  174. &g_StringVarType, // Python type
  175. SQLT_CHR, // Oracle type
  176. SQLCS_IMPLICIT, // charset form
  177. 4000, // element length (default)
  178. 1, // is character data
  179. 1, // is variable length
  180. 1, // can be copied
  181. 1 // can be in array
  182. };
  183. static udt_VariableType vt_NationalCharString = {
  184. (InitializeProc) StringVar_Initialize,
  185. (FinalizeProc) NULL,
  186. (PreDefineProc) NULL,
  187. (PostDefineProc) StringVar_PostDefine,
  188. (PreFetchProc) NULL,
  189. (IsNullProc) NULL,
  190. (SetValueProc) StringVar_SetValue,
  191. (GetValueProc) StringVar_GetValue,
  192. (GetBufferSizeProc) StringVar_GetBufferSize,
  193. &g_NCharVarType, // Python type
  194. SQLT_CHR, // Oracle type
  195. SQLCS_NCHAR, // charset form
  196. 4000, // element length (default)
  197. 1, // is character data
  198. 1, // is variable length
  199. 1, // can be copied
  200. 1 // can be in array
  201. };
  202. static udt_VariableType vt_FixedChar = {
  203. (InitializeProc) StringVar_Initialize,
  204. (FinalizeProc) NULL,
  205. (PreDefineProc) NULL,
  206. (PostDefineProc) NULL,
  207. (PreFetchProc) NULL,
  208. (IsNullProc) NULL,
  209. (SetValueProc) StringVar_SetValue,
  210. (GetValueProc) StringVar_GetValue,
  211. (GetBufferSizeProc) StringVar_GetBufferSize,
  212. &g_FixedCharVarType, // Python type
  213. SQLT_AFC, // Oracle type
  214. SQLCS_IMPLICIT, // charset form
  215. 2000, // element length (default)
  216. 1, // is character data
  217. 1, // is variable length
  218. 1, // can be copied
  219. 1 // can be in array
  220. };
  221. static udt_VariableType vt_FixedNationalChar = {
  222. (InitializeProc) StringVar_Initialize,
  223. (FinalizeProc) NULL,
  224. (PreDefineProc) NULL,
  225. (PostDefineProc) StringVar_PostDefine,
  226. (PreFetchProc) NULL,
  227. (IsNullProc) NULL,
  228. (SetValueProc) StringVar_SetValue,
  229. (GetValueProc) StringVar_GetValue,
  230. (GetBufferSizeProc) StringVar_GetBufferSize,
  231. &g_FixedNCharVarType, // Python type
  232. SQLT_AFC, // Oracle type
  233. SQLCS_NCHAR, // charset form
  234. 2000, // element length (default)
  235. 1, // is character data
  236. 1, // is variable length
  237. 1, // can be copied
  238. 1 // can be in array
  239. };
  240. static udt_VariableType vt_Rowid = {
  241. (InitializeProc) StringVar_Initialize,
  242. (FinalizeProc) NULL,
  243. (PreDefineProc) NULL,
  244. (PostDefineProc) NULL,
  245. (PreFetchProc) NULL,
  246. (IsNullProc) NULL,
  247. (SetValueProc) StringVar_SetValue,
  248. (GetValueProc) StringVar_GetValue,
  249. (GetBufferSizeProc) StringVar_GetBufferSize,
  250. &g_RowidVarType, // Python type
  251. SQLT_CHR, // Oracle type
  252. SQLCS_IMPLICIT, // charset form
  253. 18, // element length (default)
  254. 1, // is character data
  255. 0, // is variable length
  256. 1, // can be copied
  257. 1 // can be in array
  258. };
  259. static udt_VariableType vt_Binary = {
  260. (InitializeProc) StringVar_Initialize,
  261. (FinalizeProc) NULL,
  262. (PreDefineProc) NULL,
  263. (PostDefineProc) NULL,
  264. (PreFetchProc) NULL,
  265. (IsNullProc) NULL,
  266. (SetValueProc) StringVar_SetValue,
  267. (GetValueProc) StringVar_GetValue,
  268. (GetBufferSizeProc) NULL,
  269. &g_BinaryVarType, // Python type
  270. SQLT_BIN, // Oracle type
  271. SQLCS_IMPLICIT, // charset form
  272. 4000, // element length (default)
  273. 0, // is character data
  274. 1, // is variable length
  275. 1, // can be copied
  276. 1 // can be in array
  277. };
  278. //-----------------------------------------------------------------------------
  279. // StringVar_Initialize()
  280. // Initialize the variable.
  281. //-----------------------------------------------------------------------------
  282. static int StringVar_Initialize(
  283. udt_StringVar *var, // variable to initialize
  284. udt_Cursor *cursor) // cursor to use
  285. {
  286. ub4 i;
  287. var->actualLength = (ACTUAL_LENGTH_TYPE *)
  288. PyMem_Malloc(var->allocatedElements * sizeof(ACTUAL_LENGTH_TYPE));
  289. if (!var->actualLength) {
  290. PyErr_NoMemory();
  291. return -1;
  292. }
  293. for (i = 0; i < var->allocatedElements; i++)
  294. var->actualLength[i] = 0;
  295. return 0;
  296. }
  297. //-----------------------------------------------------------------------------
  298. // StringVar_SetValue()
  299. // Set the value of the variable.
  300. //-----------------------------------------------------------------------------
  301. static int StringVar_SetValue(
  302. udt_StringVar *var, // variable to set value for
  303. unsigned pos, // array position to set
  304. PyObject *value) // value to set
  305. {
  306. udt_Buffer buffer;
  307. char *encoding;
  308. // determine which encoding should be used
  309. if (var->type->charsetForm == SQLCS_NCHAR)
  310. encoding = var->environment->nencoding;
  311. else encoding = var->environment->encoding;
  312. // populate the buffer and confirm the maximum size is not exceeded
  313. if (cxBuffer_FromObject(&buffer, value, encoding) < 0)
  314. return -1;
  315. // ensure that the buffer is large enough
  316. if (buffer.size > var->bufferSize) {
  317. if (Variable_Resize( (udt_Variable*) var, buffer.numCharacters) < 0) {
  318. cxBuffer_Clear(&buffer);
  319. return -1;
  320. }
  321. }
  322. // keep a copy of the string
  323. var->actualLength[pos] = (ACTUAL_LENGTH_TYPE) buffer.size;
  324. if (buffer.size)
  325. memcpy(var->data + var->bufferSize * pos, buffer.ptr, buffer.size);
  326. cxBuffer_Clear(&buffer);
  327. return 0;
  328. }
  329. //-----------------------------------------------------------------------------
  330. // StringVar_GetValue()
  331. // Returns the value stored at the given array position.
  332. //-----------------------------------------------------------------------------
  333. static PyObject *StringVar_GetValue(
  334. udt_StringVar *var, // variable to determine value for
  335. unsigned pos) // array position
  336. {
  337. char *data;
  338. data = var->data + pos * var->bufferSize;
  339. if (var->type == &vt_Binary)
  340. return PyBytes_FromStringAndSize(data, var->actualLength[pos]);
  341. if (var->type == &vt_FixedNationalChar
  342. || var->type == &vt_NationalCharString)
  343. return PyUnicode_Decode(data, var->actualLength[pos],
  344. var->environment->nencoding, NULL);
  345. return cxString_FromEncodedString(data, var->actualLength[pos],
  346. var->environment->encoding);
  347. }
  348. //-----------------------------------------------------------------------------
  349. // StringVar_PostDefine()
  350. // Set the character set information when values are fetched from this
  351. // variable.
  352. //-----------------------------------------------------------------------------
  353. static int StringVar_PostDefine(
  354. udt_StringVar *var) // variable to initialize
  355. {
  356. sword status;
  357. status = OCIAttrSet(var->defineHandle, OCI_HTYPE_DEFINE,
  358. &var->type->charsetForm, 0, OCI_ATTR_CHARSET_FORM,
  359. var->environment->errorHandle);
  360. if (Environment_CheckForError(var->environment, status,
  361. "StringVar_PostDefine(): setting charset form") < 0)
  362. return -1;
  363. return 0;
  364. }
  365. //-----------------------------------------------------------------------------
  366. // StringVar_GetBufferSize()
  367. // Returns the buffer size to use for the variable.
  368. //-----------------------------------------------------------------------------
  369. static ub4 StringVar_GetBufferSize(
  370. udt_StringVar* self) // variable to get buffer size for
  371. {
  372. if (self->type->isCharacterData)
  373. return self->size * self->environment->maxBytesPerCharacter;
  374. return self->size;
  375. }