ObjectVar.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //-----------------------------------------------------------------------------
  2. // ObjectVar.c
  3. // Defines the routines for handling Oracle object variables.
  4. //-----------------------------------------------------------------------------
  5. #include "ObjectType.c"
  6. #include "ExternalObjectVar.c"
  7. //-----------------------------------------------------------------------------
  8. // Object type
  9. //-----------------------------------------------------------------------------
  10. typedef struct {
  11. Variable_HEAD
  12. dvoid **data;
  13. dvoid **objectIndicator;
  14. udt_Connection *connection;
  15. udt_ObjectType *objectType;
  16. } udt_ObjectVar;
  17. //-----------------------------------------------------------------------------
  18. // Declaration of object variable functions.
  19. //-----------------------------------------------------------------------------
  20. static int ObjectVar_Initialize(udt_ObjectVar*, udt_Cursor*);
  21. static void ObjectVar_Finalize(udt_ObjectVar*);
  22. static PyObject *ObjectVar_GetValue(udt_ObjectVar*, unsigned);
  23. static int ObjectVar_PreDefine(udt_ObjectVar*, OCIParam*);
  24. static int ObjectVar_PostDefine(udt_ObjectVar*);
  25. static int ObjectVar_IsNull(udt_ObjectVar*, unsigned);
  26. //-----------------------------------------------------------------------------
  27. // declaration of members for Oracle objects
  28. //-----------------------------------------------------------------------------
  29. static PyMemberDef g_ObjectVarMembers[] = {
  30. { "type", T_OBJECT, offsetof(udt_ObjectVar, objectType), READONLY },
  31. { NULL }
  32. };
  33. //-----------------------------------------------------------------------------
  34. // Python type declarations
  35. //-----------------------------------------------------------------------------
  36. static PyTypeObject g_ObjectVarType = {
  37. PyVarObject_HEAD_INIT(NULL, 0)
  38. "cx_Oracle.OBJECTVAR", // tp_name
  39. sizeof(udt_ObjectVar), // tp_basicsize
  40. 0, // tp_itemsize
  41. 0, // tp_dealloc
  42. 0, // tp_print
  43. 0, // tp_getattr
  44. 0, // tp_setattr
  45. 0, // tp_compare
  46. 0, // tp_repr
  47. 0, // tp_as_number
  48. 0, // tp_as_sequence
  49. 0, // tp_as_mapping
  50. 0, // tp_hash
  51. 0, // tp_call
  52. 0, // tp_str
  53. 0, // tp_getattro
  54. 0, // tp_setattro
  55. 0, // tp_as_buffer
  56. Py_TPFLAGS_DEFAULT, // tp_flags
  57. 0, // tp_doc
  58. 0, // tp_traverse
  59. 0, // tp_clear
  60. 0, // tp_richcompare
  61. 0, // tp_weaklistoffset
  62. 0, // tp_iter
  63. 0, // tp_iternext
  64. 0, // tp_methods
  65. g_ObjectVarMembers // tp_members
  66. };
  67. //-----------------------------------------------------------------------------
  68. // variable type declarations
  69. //-----------------------------------------------------------------------------
  70. static udt_VariableType vt_Object = {
  71. (InitializeProc) ObjectVar_Initialize,
  72. (FinalizeProc) ObjectVar_Finalize,
  73. (PreDefineProc) ObjectVar_PreDefine,
  74. (PostDefineProc) ObjectVar_PostDefine,
  75. (PreFetchProc) NULL,
  76. (IsNullProc) ObjectVar_IsNull,
  77. (SetValueProc) NULL,
  78. (GetValueProc) ObjectVar_GetValue,
  79. (GetBufferSizeProc) NULL,
  80. &g_ObjectVarType, // Python type
  81. SQLT_NTY, // Oracle type
  82. SQLCS_IMPLICIT, // charset form
  83. sizeof(dvoid*), // element length
  84. 0, // is character data
  85. 0, // is variable length
  86. 0, // can be copied
  87. 0 // can be in array
  88. };
  89. //-----------------------------------------------------------------------------
  90. // ObjectVar_Initialize()
  91. // Initialize the variable.
  92. //-----------------------------------------------------------------------------
  93. static int ObjectVar_Initialize(
  94. udt_ObjectVar *self, // variable to initialize
  95. udt_Cursor *cursor) // cursor to use
  96. {
  97. int i;
  98. Py_INCREF(cursor->connection);
  99. self->connection = cursor->connection;
  100. self->objectType = NULL;
  101. self->objectIndicator =
  102. PyMem_Malloc(self->allocatedElements * sizeof(dvoid*));
  103. if (!self->objectIndicator) {
  104. PyErr_NoMemory();
  105. return -1;
  106. }
  107. for (i = 0; i < self->allocatedElements; i++) {
  108. self->data[i] = NULL;
  109. self->objectIndicator[i] = NULL;
  110. }
  111. return 0;
  112. }
  113. //-----------------------------------------------------------------------------
  114. // ObjectVar_Finalize()
  115. // Prepare for variable destruction.
  116. //-----------------------------------------------------------------------------
  117. static void ObjectVar_Finalize(
  118. udt_ObjectVar *self) // variable to free
  119. {
  120. int i;
  121. for (i = 0; i < self->allocatedElements; i++) {
  122. if (self->data[i])
  123. OCIObjectFree(self->environment->handle,
  124. self->environment->errorHandle, self->data[i],
  125. OCI_OBJECTFREE_FORCE);
  126. }
  127. Py_DECREF(self->connection);
  128. Py_XDECREF(self->objectType);
  129. if (self->objectIndicator)
  130. PyMem_Free(self->objectIndicator);
  131. }
  132. //-----------------------------------------------------------------------------
  133. // ObjectVar_PreDefine()
  134. // Performs additional steps required for defining objects.
  135. //-----------------------------------------------------------------------------
  136. static int ObjectVar_PreDefine(
  137. udt_ObjectVar *self, // variable to set up
  138. OCIParam *param) // parameter being defined
  139. {
  140. self->objectType = ObjectType_New(self->connection, param,
  141. OCI_ATTR_TYPE_NAME);
  142. if (!self->objectType)
  143. return -1;
  144. return 0;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // ObjectVar_PostDefine()
  148. // Performs additional steps required for defining objects.
  149. //-----------------------------------------------------------------------------
  150. static int ObjectVar_PostDefine(
  151. udt_ObjectVar *self) // variable to set up
  152. {
  153. sword status;
  154. status = OCIDefineObject(self->defineHandle,
  155. self->environment->errorHandle, self->objectType->tdo, self->data,
  156. 0, self->objectIndicator, 0);
  157. return Environment_CheckForError(self->environment, status,
  158. "ObjectVar_PostDefine(): define object");
  159. }
  160. //-----------------------------------------------------------------------------
  161. // ObjectVar_IsNull()
  162. // Returns a boolean indicating if the variable is null or not.
  163. //-----------------------------------------------------------------------------
  164. static int ObjectVar_IsNull(
  165. udt_ObjectVar *self, // variable to set up
  166. unsigned pos) // position to check
  167. {
  168. if (!self->objectIndicator[pos])
  169. return 1;
  170. return (*((OCIInd*) self->objectIndicator[pos]) == OCI_IND_NULL);
  171. }
  172. //-----------------------------------------------------------------------------
  173. // ObjectVar_GetValue()
  174. // Returns the value stored at the given array position.
  175. //-----------------------------------------------------------------------------
  176. static PyObject *ObjectVar_GetValue(
  177. udt_ObjectVar *self, // variable to determine value for
  178. unsigned pos) // array position
  179. {
  180. PyObject *var;
  181. // only allowed to get the value once (for now)
  182. if (!self->data[pos]) {
  183. PyErr_SetString(g_ProgrammingErrorException,
  184. "variable value can only be acquired once");
  185. return NULL;
  186. }
  187. // for collections, return the list rather than the object
  188. if (self->objectType->isCollection)
  189. return ExternalObjectVar_ConvertCollection(self->environment,
  190. self->data[pos], (PyObject*) self, self->objectType);
  191. // for objects, return a representation of the object
  192. var = ExternalObjectVar_New((PyObject*) self, self->objectType,
  193. self->data[pos], self->objectIndicator[pos], 1);
  194. if (!var)
  195. return NULL;
  196. self->data[pos] = NULL;
  197. self->objectIndicator[pos] = NULL;
  198. return var;
  199. }