Ctx.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <NdbApi.hpp>
  14. #include <common/common.hpp>
  15. #include "DiagArea.hpp"
  16. // ctor
  17. Ctx::Ctx() :
  18.     m_diagArea(0) // create on demand
  19. {
  20.     const char* p;
  21.     if ((p = getenv("NDB_ODBC_TRACE")) != 0)
  22. m_logLevel = atoi(p);
  23.     if ((p = getenv("NDB_ODBC_TRACE_FILE")) != 0 && *p != 0)
  24. strcpy(m_szTraceFile, p);
  25. }
  26. Ctx::~Ctx()
  27. {
  28.     delete m_diagArea;
  29.     m_diagArea = 0;
  30. }
  31. // handle exceptions
  32. CtxAssert::CtxAssert(const char* file, int line) :
  33.     m_file(file),
  34.     m_line(line)
  35. {
  36.     const char* p;
  37.     if ((p = getenv("NDB_ODBC_DEBUG")) != 0 && atoi(p) != 0) {
  38. char buf[200];
  39. snprintf(buf, sizeof(buf), "%s, line %d: assert failedn", m_file, m_line);
  40. if ((p = getenv("NDB_ODBC_TRACE_FILE")) != 0 && *p != 0) {
  41.     FILE* pFile = fopen(p, "a");
  42.     fprintf(pFile, buf);
  43.     fflush(pFile);
  44.     fclose(pFile);
  45. } else {
  46.     fprintf(stderr, buf);
  47.     fflush(stderr);
  48. }
  49. abort();
  50. exit(1);
  51.     }
  52. }
  53. void
  54. Ctx::handleEx(CtxAssert& ctxAssert)
  55. {
  56.     pushStatus(Sqlstate::_IM001, Error::Gen, "exception at %s line %d", ctxAssert.m_file, ctxAssert.m_line);
  57. }
  58. // logging methods
  59. int Ctx::m_logLevel = 0;
  60. char Ctx::m_szTraceFile[MAX_PATH];
  61. void
  62. Ctx::log(const char* fmt, ...)
  63. {
  64.     va_list ap;
  65.     va_start(ap, fmt);
  66.     if (m_szTraceFile[0]) {
  67. FILE* pFile = fopen(m_szTraceFile, "a");
  68. fprintf(pFile, "[NdbOdbc] ");
  69. vfprintf(pFile, fmt, ap);
  70. fprintf(pFile, "n");
  71. fflush(pFile);
  72. fclose(pFile);
  73.     } else {
  74. printf("[NdbOdbc] ");
  75. vprintf(fmt, ap);
  76. printf("n");
  77. fflush(stdout);
  78.     }
  79.     va_end(ap);
  80. }
  81. void
  82. Ctx::logSqlEnter(const char* sqlFunction)
  83. {
  84.     Ctx& ctx = *this;
  85.     snprintf(m_sqlFunction, sizeof(m_sqlFunction), "%s", sqlFunction);
  86.     ctx_log3(("%s", m_sqlFunction));
  87. }
  88. void
  89. Ctx::logSqlExit()
  90. {
  91.     Ctx& ctx = *this;
  92.     if (m_diagArea == 0) {
  93. ctx_log3(("%s ret=%d", m_sqlFunction, getCode()));
  94. return;
  95.     }
  96.     int logLevel = diagArea().numStatus() != 0 ? 2 : 3;
  97.     ctx_logN(logLevel, ("%s ret=%d diag=%d", m_sqlFunction, diagArea().getCode(), diagArea().numStatus()));
  98.     for (unsigned i = 1; i <= diagArea().numStatus(); i++) {
  99. OdbcData state;
  100. OdbcData message;
  101. diagArea().getRecord(ctx, i, SQL_DIAG_SQLSTATE, state);
  102. diagArea().getRecord(ctx, i, SQL_DIAG_MESSAGE_TEXT, message);
  103. ctx_logN(logLevel, ("diag %u: %s - %s", i, state.sqlstate().state(), message.sqlchar()));
  104.     }
  105. }
  106. void
  107. Ctx::print(const char* fmt, ...)
  108. {
  109.     va_list ap;
  110.     va_start(ap, fmt);
  111.     if (m_szTraceFile[0]) {
  112. FILE* pFile = fopen(m_szTraceFile, "a");
  113. vfprintf(pFile, fmt, ap);
  114. unsigned n = strlen(fmt);
  115. if (n > 0 && fmt[n-1] == 'n')
  116.     fflush(pFile);
  117. fclose(pFile);
  118.     } else {
  119. vprintf(fmt, ap);
  120. unsigned n = strlen(fmt);
  121. if (n > 0 && fmt[n-1] == 'n')
  122.     fflush(stdout);
  123.     }
  124.     va_end(ap);
  125. }
  126. void
  127. Ctx::print(int level, const char* fmt, ...)
  128. {
  129.     if (level > m_logLevel)
  130. return;
  131.     va_list ap;
  132.     va_start(ap, fmt);
  133.     if (m_szTraceFile[0]) {
  134. FILE* pFile = fopen(m_szTraceFile, "a");
  135. vfprintf(pFile, fmt, ap);
  136. unsigned n = strlen(fmt);
  137. if (n > 0 && fmt[n-1] == 'n')
  138.     fflush(pFile);
  139. fclose(pFile);
  140.     } else {
  141. vprintf(fmt, ap);
  142. unsigned n = strlen(fmt);
  143. if (n > 0 && fmt[n-1] == 'n')
  144.     fflush(stdout);
  145.     }
  146.     va_end(ap);
  147. }
  148. // diagnostics
  149. static const unsigned MessageSize = 512;
  150. DiagArea&
  151. Ctx::diagArea() const
  152. {
  153.     ctx_assert(m_diagArea != 0);
  154.     return *m_diagArea;
  155. }
  156. DiagArea&
  157. Ctx::diagArea()
  158. {
  159.     if (m_diagArea == 0)
  160. m_diagArea = new DiagArea;
  161.     return *m_diagArea;
  162. }
  163. SQLRETURN
  164. Ctx::getCode() const
  165. {
  166.     if (m_diagArea == 0)
  167. return SQL_SUCCESS;
  168.     return diagArea().getCode();
  169. }
  170. void
  171. Ctx::setCode(SQLRETURN ret)
  172. {
  173.     diagArea().setCode(ret);
  174. }
  175. void
  176. Ctx::pushStatus(const Sqlstate& state, SQLINTEGER code, const char* fmt, ...)
  177. {
  178.     char message[MessageSize];
  179.     va_list ap;
  180.     va_start(ap, fmt);
  181.     vsnprintf(message, sizeof(message), fmt, ap);
  182.     va_end(ap);
  183.     Error error(state);
  184.     error.m_status = NdbError::PermanentError;
  185.     error.m_classification = NdbError::ApplicationError;
  186.     error.m_code = code;
  187.     error.m_message = message;
  188.     error.m_sqlFunction = m_sqlFunction;
  189.     diagArea().pushStatus(error);
  190. }
  191. void
  192. Ctx::pushStatus(SQLINTEGER code, const char* fmt, ...)
  193. {
  194.     char message[MessageSize];
  195.     va_list ap;
  196.     va_start(ap, fmt);
  197.     vsnprintf(message, sizeof(message), fmt, ap);
  198.     va_end(ap);
  199.     Error error(Sqlstate::_IM000);
  200.     error.m_status = NdbError::PermanentError;
  201.     error.m_classification = NdbError::ApplicationError;
  202.     error.m_code = code;
  203.     error.m_message = message;
  204.     error.m_sqlFunction = m_sqlFunction;
  205.     diagArea().pushStatus(error);
  206. }
  207. void
  208. Ctx::pushStatus(const NdbError& ndbError, const char* fmt, ...)
  209. {
  210.     char message[MessageSize];
  211.     va_list ap;
  212.     va_start(ap, fmt);
  213.     snprintf(message, sizeof(message), "%s", ndbError.message);
  214.     snprintf(message + strlen(message), sizeof(message) - strlen(message), "%s", " - at ");
  215.     vsnprintf(message + strlen(message), sizeof(message) - strlen(message), fmt, ap);
  216.     va_end(ap);
  217.     Error error(Sqlstate::_IM000);
  218.     error.m_status = ndbError.status;
  219.     error.m_classification = ndbError.classification;
  220.     error.m_code = ndbError.code;
  221.     error.m_message = message;
  222.     error.m_sqlFunction = m_sqlFunction;
  223.     diagArea().pushStatus(error);
  224. }
  225. void
  226. Ctx::pushStatus(const Ndb* ndb, const char* fmt, ...)
  227. {
  228.     char message[MessageSize];
  229.     va_list ap;
  230.     va_start(ap, fmt);
  231.     vsnprintf(message, sizeof(message), fmt, ap);
  232.     va_end(ap);
  233.     bool found = false;
  234.     if (ndb != 0) {
  235. const NdbError& ndbError = ndb->getNdbError();
  236. if (ndbError.code != 0) {
  237.     pushStatus(ndbError, "%s", message);
  238.     found = true;
  239. }
  240.     }
  241.     if (! found) {
  242. pushStatus(Error::Gen, "unknown NDB error");
  243.     }
  244. }
  245. void
  246. Ctx::pushStatus(const Ndb* ndb, const NdbConnection* tcon, const NdbOperation* op, const char* fmt, ...)
  247. {
  248.     char message[MessageSize];
  249.     va_list ap;
  250.     va_start(ap, fmt);
  251.     vsnprintf(message, sizeof(message), fmt, ap);
  252.     va_end(ap);
  253.     bool found = false;
  254.     if (op != 0) {
  255. const NdbError& ndbError = op->getNdbError();
  256. if (ndbError.code != 0) {
  257.     pushStatus(ndbError, "%s", message);
  258.     found = true;
  259. }
  260.     }
  261.     if (tcon != 0) {
  262. const NdbError& ndbError = tcon->getNdbError();
  263. if (ndbError.code != 0) {
  264.     pushStatus(ndbError, "%s", message);
  265.     found = true;
  266. }
  267.     }
  268.     if (ndb != 0) {
  269. const NdbError& ndbError = ndb->getNdbError();
  270. if (ndbError.code != 0) {
  271.     pushStatus(ndbError, "%s", message);
  272.     found = true;
  273. }
  274.     }
  275.     if (! found) {
  276. pushStatus(Error::Gen, "unknown NDB error");
  277.     }
  278. }
  279. void
  280. Ctx::pushStatus(const Ndb* ndb, const NdbSchemaCon* scon, const NdbSchemaOp* op, const char* fmt, ...)
  281. {
  282.     char message[MessageSize];
  283.     va_list ap;
  284.     va_start(ap, fmt);
  285.     vsnprintf(message, sizeof(message), fmt, ap);
  286.     va_end(ap);
  287.     bool found = false;
  288.     if (op != 0) {
  289. const NdbError& ndbError = op->getNdbError();
  290. if (ndbError.code != 0) {
  291.     pushStatus(ndbError, "%s", message);
  292.     found = true;
  293. }
  294.     }
  295.     if (scon != 0) {
  296. const NdbError& ndbError = scon->getNdbError();
  297. if (ndbError.code != 0) {
  298.     pushStatus(ndbError, "%s", message);
  299.     found = true;
  300. }
  301.     }
  302.     if (ndb != 0) {
  303. const NdbError& ndbError = ndb->getNdbError();
  304. if (ndbError.code != 0) {
  305.     pushStatus(ndbError, "%s", message);
  306.     found = true;
  307. }
  308.     }
  309.     if (! found) {
  310. pushStatus(Error::Gen, "unknown NDB error");
  311.     }
  312. }
  313. // check for error
  314. bool
  315. Ctx::ok()
  316. {
  317.     if (m_diagArea == 0)
  318. return true;
  319.     if (diagArea().getCode() == SQL_SUCCESS)
  320. return true;
  321.     if (diagArea().getCode() == SQL_SUCCESS_WITH_INFO)
  322. return true;
  323.     return false;
  324. }