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

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 <stdio.h>
  14. #include "OdbcData.hpp"
  15. #include "DiagArea.hpp"
  16. // DiagSpec
  17. static const DiagSpec
  18. diag_spec_list[] = {
  19.     {   Diag_pos_header,
  20. SQL_DIAG_CURSOR_ROW_COUNT,
  21. OdbcData::Integer,
  22. Odbc_handle_stmt
  23.     },
  24.     {   Diag_pos_header,
  25. SQL_DIAG_DYNAMIC_FUNCTION,
  26. OdbcData::Sqlchar,
  27. Odbc_handle_stmt
  28.     },
  29.     {   Diag_pos_header,
  30. SQL_DIAG_DYNAMIC_FUNCTION_CODE,
  31. OdbcData::Integer,
  32. Odbc_handle_stmt
  33.     },
  34.     {   Diag_pos_header,
  35. SQL_DIAG_NUMBER,
  36. OdbcData::Integer,
  37. Odbc_handle_all
  38.     },
  39.     {   Diag_pos_header,
  40. SQL_DIAG_RETURNCODE,
  41. OdbcData::Smallint,
  42. Odbc_handle_all
  43.     },
  44.     {   Diag_pos_header,
  45. SQL_DIAG_ROW_COUNT,
  46. OdbcData::Integer,
  47. Odbc_handle_stmt
  48.     },
  49.     {   Diag_pos_status,
  50. SQL_DIAG_CLASS_ORIGIN,
  51. OdbcData::Sqlchar,
  52. Odbc_handle_all
  53.     },
  54.     {   Diag_pos_status,
  55. SQL_DIAG_COLUMN_NUMBER,
  56. OdbcData::Integer,
  57. Odbc_handle_all
  58.     },
  59.     {   Diag_pos_status,
  60. SQL_DIAG_CONNECTION_NAME,
  61. OdbcData::Sqlchar,
  62. Odbc_handle_all
  63.     },
  64.     {   Diag_pos_status,
  65. SQL_DIAG_MESSAGE_TEXT,
  66. OdbcData::Sqlchar,
  67. Odbc_handle_all
  68.     },
  69.     {   Diag_pos_status,
  70. SQL_DIAG_NATIVE,
  71. OdbcData::Integer,
  72. Odbc_handle_all
  73.     },
  74.     {   Diag_pos_status,
  75. SQL_DIAG_ROW_NUMBER,
  76. OdbcData::Integer,
  77. Odbc_handle_all
  78.     },
  79.     {   Diag_pos_status,
  80. SQL_DIAG_SERVER_NAME,
  81. OdbcData::Sqlchar,
  82. Odbc_handle_all
  83.     },
  84.     {   Diag_pos_status,
  85. SQL_DIAG_SQLSTATE,
  86. OdbcData::Sqlchar,
  87. Odbc_handle_all
  88.     },
  89.     {   Diag_pos_status,
  90. SQL_DIAG_SUBCLASS_ORIGIN,
  91. OdbcData::Sqlchar,
  92. Odbc_handle_all
  93.     },
  94.     {   Diag_pos_end,
  95.         0,
  96. OdbcData::Undef,
  97. 0
  98.     }
  99. };
  100. const DiagSpec&
  101. DiagSpec::find(int id)
  102. {
  103.     const DiagSpec* p;
  104.     for (p = diag_spec_list; p->m_pos != Diag_pos_end; p++) {
  105. if (p->m_id == id)
  106.     break;
  107.     }
  108.     return *p;
  109. }
  110. // DiagField
  111. // DiagRec
  112. void
  113. DiagRec::setField(int id, const OdbcData& data)
  114. {
  115.     Fields::iterator iter;
  116.     iter = m_fields.find(id);
  117.     if (iter != m_fields.end()) {
  118. DiagField& field = (*iter).second;
  119. field.setData(data);
  120. return;
  121.     }
  122.     const DiagSpec& spec = DiagSpec::find(id);
  123.     if (spec.m_pos != Diag_pos_end) {
  124. DiagField field(spec, data);
  125. m_fields.insert(Fields::value_type(id, field));
  126. return;
  127.     }
  128.     ctx_assert(false);
  129. }
  130. void
  131. DiagRec::getField(Ctx& ctx, int id, OdbcData& data)
  132. {
  133.     Fields::iterator iter;
  134.     iter = m_fields.find(id);
  135.     if (iter != m_fields.end()) {
  136. DiagField& field = (*iter).second;
  137. data.setValue(field.getData());
  138. return;
  139.     }
  140.     const DiagSpec& spec = DiagSpec::find(id);
  141.     if (spec.m_pos != Diag_pos_end) {
  142. // success and undefined value says the MS doc
  143. data.setValue();
  144. return;
  145.     }
  146.     ctx_assert(false);
  147. }
  148. // DiagArea
  149. DiagArea::DiagArea() :
  150.     m_recs(1), // add header
  151.     m_code(SQL_SUCCESS),
  152.     m_recNumber(0)
  153. {
  154.     setHeader(SQL_DIAG_NUMBER, (SQLINTEGER)0);
  155. }
  156. DiagArea::~DiagArea() {
  157. }
  158. unsigned
  159. DiagArea::numStatus()
  160. {
  161.     ctx_assert(m_recs.size() > 0);
  162.     return m_recs.size() - 1;
  163. }
  164. void
  165. DiagArea::pushStatus()
  166. {
  167.     ctx_assert(m_recs.size() > 0);
  168.     DiagRec rec;
  169.     m_recs.push_back(rec);
  170.     SQLINTEGER diagNumber = m_recs.size() - 1;
  171.     setHeader(SQL_DIAG_NUMBER, diagNumber);
  172. }
  173. void
  174. DiagArea::setHeader(int id, const OdbcData& data)
  175. {
  176.     ctx_assert(m_recs.size() > 0);
  177.     getHeader().setField(id, data);
  178. }
  179. // set status
  180. void
  181. DiagArea::setStatus(int id, const OdbcData& data)
  182. {
  183.     getStatus().setField(id, data);
  184. }
  185. void
  186. DiagArea::setStatus(const Sqlstate& state)
  187. {
  188.     getStatus().setField(SQL_DIAG_SQLSTATE, state);
  189.     setCode(state.getCode(m_code));
  190. }
  191. void
  192. DiagArea::setStatus(const Error& error)
  193. {
  194.     BaseString message("");
  195.     // bracketed prefixes
  196.     message.append(NDB_ODBC_COMPONENT_VENDOR);
  197.     message.append(NDB_ODBC_COMPONENT_DRIVER);
  198.     if (! error.driverError())
  199. message.append(NDB_ODBC_COMPONENT_DATABASE);
  200.     // native error code
  201.     char nativeString[20];
  202.     sprintf(nativeString, "%02d%02d%04d",
  203.      (unsigned)error.m_status % 100,
  204. (unsigned)error.m_classification % 100,
  205. (unsigned)error.m_code % 10000);
  206.     SQLINTEGER native = atoi(nativeString);
  207.     message.appfmt("NDB-%s", nativeString);
  208.     // message text
  209.     message.append(" ");
  210.     message.append(error.m_message);
  211.     if (error.m_sqlFunction != 0)
  212. message.appfmt(" (in %s)", error.m_sqlFunction);
  213.     // set diag fields
  214.     setStatus(error.m_sqlstate);
  215.     setStatus(SQL_DIAG_NATIVE, native);
  216.     setStatus(SQL_DIAG_MESSAGE_TEXT, message.c_str());
  217. }
  218. // push status
  219. void
  220. DiagArea::pushStatus(const Error& error)
  221. {
  222.     pushStatus();
  223.     setStatus(error);
  224. }
  225. // record access
  226. DiagRec&
  227. DiagArea::getHeader()
  228. {
  229.     ctx_assert(m_recs.size() > 0);
  230.     return m_recs[0];
  231. }
  232. DiagRec&
  233. DiagArea::getStatus()
  234. {
  235.     ctx_assert(m_recs.size() > 1);
  236.     return m_recs.back();
  237. }
  238. DiagRec&
  239. DiagArea::getRecord(unsigned num)
  240. {
  241.     ctx_assert(num < m_recs.size());
  242.     return m_recs[num];
  243. }
  244. void
  245. DiagArea::getRecord(Ctx& ctx, unsigned num, int id, OdbcData& data)
  246. {
  247.     DiagRec& rec = getRecord(num);
  248.     rec.getField(ctx, id, data);
  249. }
  250. void
  251. DiagArea::setCode(SQLRETURN code)
  252. {
  253.     m_code = code;
  254.     getHeader().setField(SQL_DIAG_RETURNCODE, (SQLSMALLINT)code);
  255. }