PageRenderTime 51ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/Error.c

https://bitbucket.org/glenwalker/cx_oracle
C | 153 lines | 109 code | 16 blank | 28 comment | 8 complexity | b392d5542636eb0d1c2dcf904fe2bac3 MD5 | raw file
  1. //-----------------------------------------------------------------------------
  2. // Error.c
  3. // Error handling.
  4. //-----------------------------------------------------------------------------
  5. //-----------------------------------------------------------------------------
  6. // structure for the Python type
  7. //-----------------------------------------------------------------------------
  8. typedef struct {
  9. PyObject_HEAD
  10. sb4 code;
  11. ub4 offset;
  12. PyObject *message;
  13. const char *context;
  14. } udt_Error;
  15. //-----------------------------------------------------------------------------
  16. // forward declarations
  17. //-----------------------------------------------------------------------------
  18. static void Error_Free(udt_Error*);
  19. static PyObject *Error_Str(udt_Error*);
  20. //-----------------------------------------------------------------------------
  21. // declaration of members
  22. //-----------------------------------------------------------------------------
  23. static PyMemberDef g_ErrorMembers[] = {
  24. { "code", T_INT, offsetof(udt_Error, code), READONLY },
  25. { "offset", T_INT, offsetof(udt_Error, offset), READONLY },
  26. { "message", T_OBJECT, offsetof(udt_Error, message), READONLY },
  27. { "context", T_STRING, offsetof(udt_Error, context), READONLY },
  28. { NULL }
  29. };
  30. //-----------------------------------------------------------------------------
  31. // declaration of Python type
  32. //-----------------------------------------------------------------------------
  33. static PyTypeObject g_ErrorType = {
  34. PyVarObject_HEAD_INIT(NULL, 0)
  35. "cx_Oracle._Error", // tp_name
  36. sizeof(udt_Error), // tp_basicsize
  37. 0, // tp_itemsize
  38. (destructor) Error_Free, // tp_dealloc
  39. 0, // tp_print
  40. 0, // tp_getattr
  41. 0, // tp_setattr
  42. 0, // tp_compare
  43. 0, // tp_repr
  44. 0, // tp_as_number
  45. 0, // tp_as_sequence
  46. 0, // tp_as_mapping
  47. 0, // tp_hash
  48. 0, // tp_call
  49. (reprfunc) Error_Str, // tp_str
  50. 0, // tp_getattro
  51. 0, // tp_setattro
  52. 0, // tp_as_buffer
  53. Py_TPFLAGS_DEFAULT, // tp_flags
  54. 0, // tp_doc
  55. 0, // tp_traverse
  56. 0, // tp_clear
  57. 0, // tp_richcompare
  58. 0, // tp_weaklistoffset
  59. 0, // tp_iter
  60. 0, // tp_iternext
  61. 0, // tp_methods
  62. g_ErrorMembers, // tp_members
  63. 0 // tp_getset
  64. };
  65. //-----------------------------------------------------------------------------
  66. // Error_New()
  67. // Create a new error object.
  68. //-----------------------------------------------------------------------------
  69. static udt_Error *Error_New(
  70. udt_Environment *environment, // environment object
  71. const char *context, // context in which error occurred
  72. int retrieveError) // retrieve error from OCI?
  73. {
  74. char errorText[4096];
  75. udt_Error *self;
  76. ub4 handleType;
  77. dvoid *handle;
  78. sword status;
  79. #if PY_MAJOR_VERSION >= 3
  80. Py_ssize_t len;
  81. #endif
  82. self = (udt_Error*) g_ErrorType.tp_alloc(&g_ErrorType, 0);
  83. if (!self)
  84. return NULL;
  85. self->context = context;
  86. if (retrieveError) {
  87. if (environment->errorHandle) {
  88. handle = environment->errorHandle;
  89. handleType = OCI_HTYPE_ERROR;
  90. } else {
  91. handle = environment->handle;
  92. handleType = OCI_HTYPE_ENV;
  93. }
  94. status = OCIErrorGet(handle, 1, 0, &self->code,
  95. (unsigned char*) errorText, sizeof(errorText), handleType);
  96. if (status != OCI_SUCCESS) {
  97. Py_DECREF(self);
  98. PyErr_SetString(g_InternalErrorException, "No Oracle error?");
  99. return NULL;
  100. }
  101. #if PY_MAJOR_VERSION < 3
  102. self->message = PyBytes_FromString(errorText);
  103. #else
  104. len = strlen(errorText);
  105. self->message = PyUnicode_Decode(errorText, len, environment->encoding,
  106. NULL);
  107. #endif
  108. if (!self->message) {
  109. Py_DECREF(self);
  110. return NULL;
  111. }
  112. }
  113. return self;
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Error_Free()
  117. // Deallocate the environment, disconnecting from the database if necessary.
  118. //-----------------------------------------------------------------------------
  119. static void Error_Free(
  120. udt_Error *self) // error object
  121. {
  122. Py_CLEAR(self->message);
  123. PyObject_Del(self);
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Error_Str()
  127. // Return a string representation of the error variable.
  128. //-----------------------------------------------------------------------------
  129. static PyObject *Error_Str(
  130. udt_Error *self) // variable to return the string for
  131. {
  132. if (self->message) {
  133. Py_INCREF(self->message);
  134. return self->message;
  135. }
  136. return cxString_FromAscii("");
  137. }