TimestampVar.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //-----------------------------------------------------------------------------
  2. // TimestampVar.c
  3. // Defines the routines for handling timestamp variables.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // Timestamp type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. Variable_HEAD
  10. OCIDateTime **data;
  11. } udt_TimestampVar;
  12. //-----------------------------------------------------------------------------
  13. // Declaration of date/time variable functions.
  14. //-----------------------------------------------------------------------------
  15. static int TimestampVar_Initialize(udt_TimestampVar*, udt_Cursor*);
  16. static void TimestampVar_Finalize(udt_TimestampVar*);
  17. static int TimestampVar_SetValue(udt_TimestampVar*, unsigned, PyObject*);
  18. static PyObject *TimestampVar_GetValue(udt_TimestampVar*, unsigned);
  19. //-----------------------------------------------------------------------------
  20. // Python type declarations
  21. //-----------------------------------------------------------------------------
  22. static PyTypeObject g_TimestampVarType = {
  23. PyVarObject_HEAD_INIT(NULL, 0)
  24. "cx_Oracle.TIMESTAMP", // tp_name
  25. sizeof(udt_TimestampVar), // tp_basicsize
  26. 0, // tp_itemsize
  27. 0, // tp_dealloc
  28. 0, // tp_print
  29. 0, // tp_getattr
  30. 0, // tp_setattr
  31. 0, // tp_compare
  32. 0, // tp_repr
  33. 0, // tp_as_number
  34. 0, // tp_as_sequence
  35. 0, // tp_as_mapping
  36. 0, // tp_hash
  37. 0, // tp_call
  38. 0, // tp_str
  39. 0, // tp_getattro
  40. 0, // tp_setattro
  41. 0, // tp_as_buffer
  42. Py_TPFLAGS_DEFAULT, // tp_flags
  43. 0 // tp_doc
  44. };
  45. //-----------------------------------------------------------------------------
  46. // variable type declarations
  47. //-----------------------------------------------------------------------------
  48. static udt_VariableType vt_Timestamp = {
  49. (InitializeProc) TimestampVar_Initialize,
  50. (FinalizeProc) TimestampVar_Finalize,
  51. (PreDefineProc) NULL,
  52. (PostDefineProc) NULL,
  53. (PreFetchProc) NULL,
  54. (IsNullProc) NULL,
  55. (SetValueProc) TimestampVar_SetValue,
  56. (GetValueProc) TimestampVar_GetValue,
  57. (GetBufferSizeProc) NULL,
  58. &g_TimestampVarType, // Python type
  59. SQLT_TIMESTAMP, // Oracle type
  60. SQLCS_IMPLICIT, // charset form
  61. sizeof(OCIDateTime*), // element length (default)
  62. 0, // is character data
  63. 0, // is variable length
  64. 1, // can be copied
  65. 1 // can be in array
  66. };
  67. //-----------------------------------------------------------------------------
  68. // TimestampVar_Initialize()
  69. // Initialize the variable.
  70. //-----------------------------------------------------------------------------
  71. static int TimestampVar_Initialize(
  72. udt_TimestampVar *var, // variable to initialize
  73. udt_Cursor *cursor) // cursor variable associated with
  74. {
  75. sword status;
  76. ub4 i;
  77. // initialize the LOB locators
  78. for (i = 0; i < var->allocatedElements; i++) {
  79. status = OCIDescriptorAlloc(var->environment->handle,
  80. (dvoid**) &var->data[i], OCI_DTYPE_TIMESTAMP, 0, 0);
  81. if (Environment_CheckForError(var->environment, status,
  82. "TimestampVar_Initialize()") < 0)
  83. return -1;
  84. }
  85. return 0;
  86. }
  87. //-----------------------------------------------------------------------------
  88. // TimestampVar_Finalize()
  89. // Prepare for variable destruction.
  90. //-----------------------------------------------------------------------------
  91. static void TimestampVar_Finalize(
  92. udt_TimestampVar *var) // variable to free
  93. {
  94. ub4 i;
  95. for (i = 0; i < var->allocatedElements; i++) {
  96. if (var->data[i])
  97. OCIDescriptorFree(var->data[i], OCI_DTYPE_TIMESTAMP);
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. // TimestampVar_SetValue()
  102. // Set the value of the variable.
  103. //-----------------------------------------------------------------------------
  104. static int TimestampVar_SetValue(
  105. udt_TimestampVar *var, // variable to set value for
  106. unsigned pos, // array position to set
  107. PyObject *value) // value to set
  108. {
  109. sword status;
  110. uword valid;
  111. // make sure a timestamp is being bound
  112. if (!PyDateTime_Check(value)) {
  113. PyErr_SetString(PyExc_TypeError, "expecting timestamp data");
  114. return -1;
  115. }
  116. // store a copy of the value
  117. status = OCIDateTimeConstruct(var->environment->handle,
  118. var->environment->errorHandle, var->data[pos],
  119. (sb2) PyDateTime_GET_YEAR(value),
  120. PyDateTime_GET_MONTH(value),
  121. PyDateTime_GET_DAY(value),
  122. PyDateTime_DATE_GET_HOUR(value),
  123. PyDateTime_DATE_GET_MINUTE(value),
  124. PyDateTime_DATE_GET_SECOND(value),
  125. PyDateTime_DATE_GET_MICROSECOND(value) * 1000, NULL, 0);
  126. if (Environment_CheckForError(var->environment, status,
  127. "TimestampVar_SetValue(): create structure") < 0)
  128. return -1;
  129. status = OCIDateTimeCheck(var->environment->handle,
  130. var->environment->errorHandle, var->data[pos], &valid);
  131. if (Environment_CheckForError(var->environment, status,
  132. "TimestampVar_SetValue()") < 0)
  133. return -1;
  134. if (valid != 0) {
  135. PyErr_SetString(g_DataErrorException, "invalid date");
  136. return -1;
  137. }
  138. return 0;
  139. }
  140. //-----------------------------------------------------------------------------
  141. // TimestampVar_GetValue()
  142. // Returns the value stored at the given array position.
  143. //-----------------------------------------------------------------------------
  144. static PyObject *TimestampVar_GetValue(
  145. udt_TimestampVar *var, // variable to determine value for
  146. unsigned pos) // array position
  147. {
  148. return OracleTimestampToPythonDate(var->environment, var->data[pos]);
  149. }