NCBI C++ ToolKit
connection.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: connection.cpp 100655 2023-08-23 18:19:24Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Vladimir Soussov
27  *
28  * File Description: ODBC connection
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbiapp.hpp>
35 #include <dbapi/driver/types.hpp>
36 #include <dbapi/error_codes.hpp>
37 #include <stdio.h>
38 #include <string.h>
39 
40 #ifdef HAVE_ODBCSS_H
41 // #include <odbcss.h>
42 #include <msodbcsql.h>
43 #endif
44 
45 #include "odbc_utils.hpp"
46 
47 // #define DEFAULT_ODBC_DRIVER_NAME "SQL Server"
48 #define DEFAULT_ODBC_DRIVER_NAME "ODBC Driver 18 for SQL Server"
49 
50 #define NCBI_USE_ERRCODE_X Dbapi_Odbc_Conn
51 
52 #undef NCBI_DATABASE_THROW
53 #define NCBI_DATABASE_THROW(ex_class, message, err_code, severity) \
54  NCBI_ODBC_THROW(ex_class, message, err_code, severity)
55 // No use of NCBI_DATABASE_RETHROW or DATABASE_DRIVER_*_EX here.
56 
57 // Accommodate all the code of the form
58 // string err_message = "..." + GetDbgInfo();
59 // DATABASE_DRIVER_ERROR(err_message, ...);
60 // which will still pick up the desired context due to
61 // NCBI_DATABASE_THROW's above redefinition.
62 #define GetDbgInfo() 0
63 
65 
66 bool IsBCPCapable(void)
67 {
68  return true;
69 }
70 
72  CDB_BlobDescriptor& descr_in,
73  SQLLEN size,
74  bool is_text,
75  bool logit,
76  SQLPOINTER id,
77  SQLLEN* ph);
78 
80  SQLPOINTER* id);
81 
82 ////////////////////////////////////////////////////////////////////////////////
84  const CDBConnParams& params) :
86  cntx,
87  params,
88  IsBCPCapable()
89  ),
90  m_Link(NULL),
91  m_ActiveStmt(NULL),
92  m_Reporter(0, SQL_HANDLE_DBC, NULL, this, &cntx.GetReporter()),
93  m_query_timeout(cntx.GetTimeout()),
94  m_cancel_timeout(cntx.GetCancelTimeout())
95 {
97 
98  SQLRETURN rc;
99 
100  {{
101  CWriteLockGuard guard(cntx.x_GetCtxLock());
103  cntx.GetODBCContext(),
104  const_cast<SQLHDBC*>(&m_Link));
105 
106  if (rc != SQL_SUCCESS) {
107  cntx.GetReporter().ReportErrors();
108  }
109  if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
110  DATABASE_DRIVER_ERROR( "Cannot allocate a connection handle.",
111  100011 );
112  }
113  }}
114 
115  // This might look strange, but in current design all errors related to
116  // opening of a connection to a database are reported by a DriverContext.
117  // Have fun.
118  // cntx.SetupErrorReporter(params);
119  CODBC_Reporter opening_reporter(&params.GetOpeningMsgHandlers(),
120  SQL_HANDLE_DBC, m_Link, this,
121  &cntx.GetReporter());
122 
123  x_SetupErrorReporter(params);
124 
125  x_SetConnAttributesBefore(cntx, params);
126 
127  x_Connect(cntx, params, opening_reporter);
128 }
129 
130 
131 void
133 {
134  _ASSERT(m_Link);
135 
140 }
141 
143  CODBCContext& cntx,
144  const CDBConnParams& params,
145  const CODBC_Reporter& opening_reporter) const
146 {
147  SQLRETURN rc;
148  string server_name;
149 
150  if (params.GetHost()) {
151  server_name = impl::ConvertN2A(params.GetHost());
152  } else {
153  server_name = params.GetServerName();
154  }
155 
157 
158  if(!cntx.GetUseDSN()) {
159  string connect_str;
160  string conn_str_suffix = ";SERVER=" + server_name;
161 
162  if (params.GetHost() && params.GetPort()) {
163  conn_str_suffix +=
164  ";ADDRESS=" + server_name +
165  "," + NStr::IntToString(params.GetPort()) +
166  ";NETWORK=DBMSSOCN"
167  ;
168  }
169  conn_str_suffix +=
170  ";UID=" + params.GetUserName() +
171  ";PWD=" + params.GetPassword() +
172  ";TrustServerCertificate=yes"
173  ;
174 
176 
177  // Connection strings for SQL Native Client 2005.
178  // string connect_str("DRIVER={SQL Native Client};MultipleActiveResultSets=true;SERVER=");
179  // string connect_str("DRIVER={SQL Native Client};SERVER=");
180 
181  if (app) {
182  const string driver_name = x_GetDriverName(app->GetConfig());
183 
184  connect_str = "DRIVER={" + driver_name + "}";
185  } else {
186  connect_str = "DRIVER={" DEFAULT_ODBC_DRIVER_NAME "}";
187  }
188 
189  connect_str += conn_str_suffix;
190 
191  TSqlString connect_str_ss = x_MakeTSqlString(connect_str, enc);
192 
194  0,
195  const_cast<TSqlChar*>(connect_str_ss.data()),
196  connect_str_ss.size(),
197  0,
198  0,
199  0,
201  }
202  else {
203  TSqlString server_name_ss = x_MakeTSqlString(server_name, enc);
204  TSqlString username_ss = x_MakeTSqlString(params.GetUserName(), enc);
205  TSqlString password_ss = x_MakeTSqlString(params.GetPassword(), enc);
206  rc = SQLConnect(m_Link,
207  const_cast<TSqlChar*>(server_name_ss.data()),
208  server_name_ss.size(),
209  const_cast<TSqlChar*>(username_ss.data()),
210  username_ss.size(),
211  const_cast<TSqlChar*>(password_ss.data()),
212  password_ss.size());
213  }
214 
215  if (!cntx.CheckSIE(rc, m_Link, opening_reporter)) {
216  string err;
217 
218  err += "Cannot connect to the server '" + server_name;
219  err += "' as user '" + params.GetUserName() + "'";
220  DATABASE_DRIVER_ERROR( err, 100011 );
221  }
222 }
223 
224 
225 void
227  const CODBCContext& cntx,
228  const CDBConnParams& params)
229 {
230  SQLULEN timeout, login_timeout;
231  NStr::StringToNumeric(params.GetParam("timeout"), &timeout);
232  NStr::StringToNumeric(params.GetParam("login_timeout"), &login_timeout);
234  0);
236  (SQLPOINTER)login_timeout, 0);
237 
238  if(cntx.GetPacketSize()) {
242  0);
243  }
244 
245 #ifdef SQL_COPT_SS_BCP
246  // Always enable BCP ...
248  SQL_COPT_SS_BCP,
249  (SQLPOINTER) SQL_BCP_ON,
251 #endif
252 }
253 
254 
255 string
257 {
258  enum EState {eStInitial, eStSingleQuote};
259  vector<string> driver_names;
260  const string odbc_driver_name =
261  registry.GetString("ODBC", "DRIVER_NAME",
262  "'" DEFAULT_ODBC_DRIVER_NAME "'");
263 
264  NStr::Split(odbc_driver_name, " ", driver_names,
266  EState state = eStInitial;
267  string driver_name;
268 
269  ITERATE(vector<string>, it, driver_names) {
270  bool complete_deriver_name = false;
271  const string cur_str(*it);
272 
273  // Check for quotes ...
274  if (state == eStInitial) {
275  if (cur_str[0] == '\'') {
276  if (cur_str[cur_str.size() - 1] == '\'') {
277  // Skip quote ...
278  driver_name = it->substr(1, cur_str.size() - 2);
279  complete_deriver_name = true;
280  } else {
281  // Skip quote ...
282  driver_name = it->substr(1);
283  state = eStSingleQuote;
284  }
285  } else {
286  driver_name = cur_str;
287  complete_deriver_name = true;
288  }
289  } else if (state == eStSingleQuote) {
290  if (cur_str[cur_str.size() - 1] == '\'') {
291  // Final quote ...
292  driver_name += " " + cur_str.substr(0, cur_str.size() - 1);
293  state = eStInitial;
294  complete_deriver_name = true;
295  } else {
296  driver_name += " " + cur_str;
297  }
298  }
299 
300  if (complete_deriver_name) {
301  return driver_name;
302  }
303  }
304 
305  return driver_name;
306 }
307 
308 
310 {
311  string str_version = "TDS_Version=";
312 
313  switch ( version )
314  {
315  case 42:
316  str_version += "4.2;Port=2158";
317  break;
318  case 46:
319  str_version += "4.6";
320  break;
321  case 50:
322  str_version += "5.0;Port=2158";
323  break;
324  case 70:
325  str_version += "7.0";
326  break;
327  //case 80:
328  // str_version += "8.0";
329  // break;
330  default:
331  // DATABASE_DRIVER_ERROR( "Invalid TDS version with the FreeTDS driver.", 100000 );
332  //str_version += "8.0";
333  //break;
334  return string();
335  }
336 
337  return str_version;
338 }
339 
340 
342 {
343  if (m_Link) {
344  SQLINTEGER status;
346 
347  return ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (status == SQL_CD_FALSE));
348  }
349 
350  return (m_Link != NULL);
351 }
352 
353 
354 CODBC_LangCmd* CODBC_Connection::xLangCmd(const string& lang_query)
355 {
356  CODBC_LangCmd* lcmd = new CODBC_LangCmd(*this, lang_query);
357  return lcmd;
358 }
359 
360 CDB_LangCmd* CODBC_Connection::LangCmd(const string& lang_query)
361 {
362  return Create_LangCmd(*(xLangCmd(lang_query)));
363 }
364 
365 
366 CDB_RPCCmd* CODBC_Connection::RPC(const string& rpc_name)
367 {
368  CODBC_RPCCmd* rcmd = new CODBC_RPCCmd(*this, rpc_name);
369  return Create_RPCCmd(*rcmd);
370 }
371 
372 
374 {
375  if ( !IsBCPable() ) {
376  string err_message = "No bcp on this connection." + GetDbgInfo();
377  DATABASE_DRIVER_ERROR( err_message, 410003 );
378  }
379 
380  CODBC_BCPInCmd* bcmd = new CODBC_BCPInCmd(*this, m_Link, table_name);
381  return Create_BCPInCmd(*bcmd);
382 }
383 
384 
385 CDB_CursorCmd* CODBC_Connection::Cursor(const string& cursor_name,
386  const string& query,
387  unsigned int batch_size)
388 {
389 #if 1
390  CODBC_CursorCmdExpl* ccmd = new CODBC_CursorCmdExpl(*this,
391  cursor_name,
392  query);
393 #else
394  CODBC_CursorCmd* ccmd = new CODBC_CursorCmd(*this,
395  cursor_name,
396  query);
397 #endif
398 
399  return Create_CursorCmd(*ccmd);
400 }
401 
402 
404  size_t data_size,
405  bool log_it,
406  bool dump_results)
407 {
408  CODBC_SendDataCmd* sd_cmd =
409  new CODBC_SendDataCmd(*this,
410  (CDB_BlobDescriptor&)descr_in,
411  data_size,
412  log_it,
413  dump_results);
414  return Create_SendDataCmd(*sd_cmd);
415 }
416 
417 
419  bool log_it)
420 {
421  CStatementBase stmt(*this, kEmptyStr);
422 
423  SQLPOINTER p = (SQLPOINTER)2;
424  SQLLEN s = lob.Size();
425  SQLLEN ph;
426 
429 
431  desc_type = CDB_BlobDescriptor::eBinary;
432  } else {
433  desc_type = CDB_BlobDescriptor::eText;
434  }
435 
437  stmt,
438  (CDB_BlobDescriptor&)desc,
439  s,
440  (desc_type == CDB_BlobDescriptor::eText),
441  log_it,
442  p,
443  &ph
444  )) ||
445  (!ODBC_xSendDataGetId(stmt, &p ))) {
446  string err_message = "Cannot prepare a command." + GetDbgInfo();
447  DATABASE_DRIVER_ERROR( err_message, 410035 );
448  }
449 
450  return x_SendData(desc_type, stmt, lob);
451 
452 }
453 
454 
456 {
457  // close all commands first
459 
460  return IsAlive();
461 }
462 
463 
465 {
467  if ( IsBCPable() ) {
469  }
470  if ( HasSecureLogin() ) {
472  }
473  return mode;
474 }
475 
476 
478 {
479  try {
480  Close();
481 
483  ReportErrors();
484  }
485  }
487  if (m_ActiveStmt) {
488  m_ActiveStmt->m_IsActive = false;
489  }
490 }
491 
492 
494 {
496  MarkClosed();
497  return false;
498 }
499 
501 {
502  if (Refresh()) {
503  switch(SQLDisconnect(m_Link)) {
505  case SQL_ERROR:
506  ReportErrors();
507  case SQL_SUCCESS:
508  break;
509  default:
510  {
511  string err_message = "SQLDisconnect failed (memory corruption suspected)." + GetDbgInfo();
512  DATABASE_DRIVER_ERROR( err_message, 410009 );
513  }
514  }
515 
516  MarkClosed();
517 
518  return true;
519  }
520 
521  return false;
522 }
523 
524 void CODBC_Connection::SetTimeout(size_t nof_secs)
525 {
526  m_query_timeout = nof_secs;
527 }
528 
530 {
531  m_cancel_timeout = nof_secs;
532 }
533 
535 {
536  string name = GetCDriverContext().GetDriverName();
537 #ifdef SQL_DRIVER_NAME
538  TSqlChar buffer[256];
539  SQLSMALLINT length = sizeof(buffer);
541  &length))
542  && length > 0 && buffer[0] != _T_NCBI_ODBC('\0')) {
543  TSqlString name2(buffer, length);
544  name2.erase(name2.find(_T_NCBI_ODBC('\0')));
545  name += '(' + CUtf8::AsUTF8(name2) + ')';
546  }
547 #endif
548  return name;
549 }
550 
551 static
552 bool
554 {
555  switch(rc) {
557  stmt.ReportErrors();
558  case SQL_SUCCESS: break;
559  case SQL_ERROR:
560  default:
561  stmt.ReportErrors();
562  return false;
563  }
564 
565  return true;
566 }
567 
569  CDB_BlobDescriptor& descr_in,
570  SQLLEN size,
571  bool is_text,
572  bool logit,
573  SQLPOINTER id,
574  SQLLEN* ph)
575 {
576  string q = "update ";
577  q += descr_in.TableName();
578  q += " set ";
579  q += descr_in.ColumnName();
580  q += "= ? where ";
581  q += descr_in.SearchConditions();
582  //q+= " ;\nset rowcount 0";
583 
584 #if defined(SQL_TEXTPTR_LOGGING)
585  if(!logit) {
586  switch(SQLSetStmtAttr(stmt.GetHandle(), SQL_TEXTPTR_LOGGING, /*SQL_SOPT_SS_TEXTPTR_LOGGING,*/
587  (SQLPOINTER)SQL_TL_OFF, SQL_IS_INTEGER)) {
589  case SQL_ERROR:
590  stmt.ReportErrors();
591  default:
592  break;
593  }
594  }
595 #endif
596 
597 
598  CDB_BlobDescriptor::ETDescriptorType descr_type = descr_in.GetColumnType();
599  if (descr_type == CDB_BlobDescriptor::eUnknown) {
600  if (is_text) {
601  descr_type = CDB_BlobDescriptor::eText;
602  } else {
603  descr_type = CDB_BlobDescriptor::eBinary;
604  }
605  }
606 
607  *ph = SQL_LEN_DATA_AT_EXEC(size);
608 
609  int c_type = 0;
610  int sql_type = 0;
611 
612  if (descr_type == CDB_BlobDescriptor::eText) {
613  // New code ...
614  if (stmt.IsMultibyteClientEncoding()) {
615  c_type = SQL_C_WCHAR;
616  sql_type = SQL_WLONGVARCHAR;
617  *ph = SQL_DATA_AT_EXEC;
618  } else {
619  c_type = SQL_C_CHAR;
620  sql_type = SQL_LONGVARCHAR;
621  }
622  // End of new code ...
623  // Old code ...
624 // #if defined(UNICODE)
625 // c_type = SQL_C_WCHAR;
626 // sql_type = SQL_WLONGVARCHAR;
627 // #else
628 // c_type = SQL_C_CHAR;
629 // sql_type = SQL_LONGVARCHAR;
630 // #endif
631  } else {
632  c_type = SQL_C_BINARY;
633  sql_type = SQL_LONGVARBINARY;
634  }
635 
636  // Do not use SQLDescribeParam. It is not implemented with the odbc driver
637  // from FreeTDS.
638 
640  stmt.GetHandle(),
641  1,
643  c_type,
644  sql_type,
645  size,
646  0,
647  id,
648  0,
649  ph),
650  stmt)) {
651  return false;
652  }
653 
654  TSqlString ss = x_MakeTSqlString(q, stmt.GetClientEncoding());
655  if (!ODBC_xCheckSIE(SQLPrepare(stmt.GetHandle(),
656  const_cast<TSqlChar*>(ss.data()),
657  ss.size()),
658  stmt)) {
659  return false;
660  }
661 
662  switch(SQLExecute(stmt.GetHandle())) {
663  case SQL_NEED_DATA:
664  return true;
666  case SQL_ERROR:
667  stmt.ReportErrors();
668  default:
669  return false;
670  }
671 }
672 
674  SQLPOINTER* id)
675 {
676  switch(SQLParamData(stmt.GetHandle(), id)) {
677  case SQL_NEED_DATA:
678  return true;
680  case SQL_ERROR:
681  stmt.ReportErrors();
682  default:
683  return false;
684  }
685 }
686 
687 bool
690  CDB_Stream& stream)
691 {
692  char buff[1800];
693 
694  int rc;
695 
696  size_t len = 0;
697  size_t invalid_len = 0;
698 
699  while(( len = stream.Read(buff + invalid_len, sizeof(buff) - invalid_len - 1)) != 0 ) {
700  len += invalid_len;
701  // New code ...
702 // size_t valid_len = len;
703 //
704 // if (stmt.GetClientEncoding() == eEncoding_UTF8 &&
705 // descr_type == CDB_BlobDescriptor::eText) {
706 //
707 // valid_len = CStringUTF8::GetValidBytesCount(buff, len);
708 // invalid_len = len - valid_len;
709 // }
710 //
711 // {
712 // TSqlString ss = x_MakeTSqlString(CTempString(buff, valid_len),
713 // stmt.GetClientEncoding());
714 // odbc::TChar* tchar_str = const_cast<odbc::TChar*>(ss.data());
715 //
716 // rc = SQLPutData(stmt.GetHandle(),
717 // static_cast<SQLPOINTER>(tchar_str),
718 // static_cast<SQLINTEGER>(ss.byte_count())
719 // );
720 // }
721 //
722 // if (stmt.GetClientEncoding() == eEncoding_UTF8 &&
723 // descr_type == CDB_BlobDescriptor::eText) {
724 //
725 // if (valid_len < len) {
726 // memmove(buff, buff + valid_len, invalid_len);
727 // }
728 // }
729  // End of new code ...
730 
731 
732  // Old code ...
733  if (stmt.GetClientEncoding() == eEncoding_UTF8 &&
734  descr_type == CDB_BlobDescriptor::eText) {
735 
736  size_t valid_len = impl::GetValidUTF8Len(CTempString(buff, len));
737  invalid_len = len - valid_len;
738 
739  // Encoding is always eEncoding_UTF8 in here.
740  TSqlString ss = x_MakeTSqlString(CTempString(buff, valid_len),
742  odbc::TChar* tchar_str = const_cast<odbc::TChar*>(ss.c_str());
743 
744  rc = SQLPutData(stmt.GetHandle(),
745  static_cast<SQLPOINTER>(tchar_str),
746  static_cast<SQLINTEGER>(ss.byte_count())
747  );
748 
749  if (valid_len < len) {
750  memmove(buff, buff + valid_len, invalid_len);
751  }
752  } else {
753  // Experimental code ...
754 // size_t valid_len = len;
755 //
756 // TSqlString ss = x_MakeTSqlString(CTempString(buff, valid_len),
757 // stmt.GetClientEncoding());
758 // odbc::TChar* tchar_str = const_cast<odbc::TChar*>(ss.data());
759 //
760 // rc = SQLPutData(stmt.GetHandle(),
761 // static_cast<SQLPOINTER>(tchar_str),
762 // static_cast<SQLINTEGER>(ss.byte_count())
763 // );
764  rc = SQLPutData(stmt.GetHandle(),
765  static_cast<SQLPOINTER>(buff),
766  static_cast<SQLINTEGER>(len) // Number of bytes ...
767  );
768  }
769  // End of old code ...
770 
771  switch( rc ) {
773  stmt.ReportErrors();
774  case SQL_NEED_DATA:
775  continue;
776  case SQL_NO_DATA:
777  return true;
778  case SQL_SUCCESS:
779  break;
780  case SQL_ERROR:
781  stmt.ReportErrors();
782  default:
783  return false;
784  }
785  }
786 
787  if (invalid_len > 0) {
788  DATABASE_DRIVER_ERROR( "Invalid encoding of a text string." + GetDbgInfo(), 410055 );
789  }
790 
791  switch(SQLParamData(stmt.GetHandle(), (SQLPOINTER*)&len)) {
792  case SQL_SUCCESS_WITH_INFO: stmt.ReportErrors();
793  case SQL_SUCCESS: break;
794  case SQL_NO_DATA: return true;
795  case SQL_NEED_DATA:
796  {
797  string err_message = "Not all the data were sent." + GetDbgInfo();
798  DATABASE_DRIVER_ERROR( err_message, 410044 );
799  }
800  case SQL_ERROR: stmt.ReportErrors();
801  default:
802  {
803  string err_message = "SQLParamData failed." + GetDbgInfo();
804  DATABASE_DRIVER_ERROR( err_message, 410045 );
805  }
806  }
807 
808  for(;;) {
809  switch(SQLMoreResults( stmt.GetHandle() )) {
810  case SQL_SUCCESS_WITH_INFO: stmt.ReportErrors();
811  case SQL_SUCCESS: continue;
812  case SQL_NO_DATA: break;
813  case SQL_ERROR:
814  {
815  stmt.ReportErrors();
816  string err_message = "SQLMoreResults failed." + GetDbgInfo();
817  DATABASE_DRIVER_ERROR( err_message, 410014 );
818  }
819  default:
820  {
821  string err_message = "SQLMoreResults failed (memory corruption suspected)." + GetDbgInfo();
822  DATABASE_DRIVER_ERROR( err_message, 410015 );
823  }
824  }
825  break;
826  }
827 
828  return true;
829 }
830 
831 
832 /////////////////////////////////////////////////////////////////////////////
834  impl::CBaseCmd(conn, query),
835  m_RowCount(-1),
836  m_Reporter(&conn.GetMsgHandlers(), SQL_HANDLE_STMT, NULL, &conn,
837  &conn.m_Reporter),
838  m_IsActive(true)
839 {
840  x_Init();
841 }
842 
844  const string& cursor_name,
845  const string& query) :
846  impl::CBaseCmd(conn, cursor_name, query),
847  m_RowCount(-1),
848  m_Reporter(&conn.GetMsgHandlers(), SQL_HANDLE_STMT, NULL, &conn,
849  &conn.m_Reporter),
850  m_IsActive(true)
851 {
852  x_Init();
853 }
854 
855 void
857 {
858  if (GetConnection().m_ActiveStmt) {
860  }
861  GetConnection().m_ActiveStmt = this;
862 
863  SQLRETURN rc
865 
866  if(rc == SQL_ERROR) {
868  }
870 
871  SQLUINTEGER query_timeout
872  = static_cast<SQLUINTEGER>(GetConnection().GetTimeout());
873  switch(SQLSetStmtAttr(GetHandle(),
875  (SQLPOINTER)static_cast<uintptr_t>(query_timeout),
876  0))
877  {
879  case SQL_ERROR:
880  case SQL_INVALID_HANDLE:
881  ReportErrors();
882  break;
883  default: // SQL_SUCCESS
884  break;
885  };
886 }
887 
889 {
890  try {
892  if(rc != SQL_SUCCESS) {
893  ReportErrors();
894  }
895  }
897  if (m_IsActive) {
899  }
900 }
901 
902 bool
904 {
905  switch (rc)
906  {
907  case SQL_SUCCESS:
908  return true;
910  case SQL_ERROR:
911  ReportErrors();
912  break;
913  case SQL_INVALID_HANDLE:
914  {
915  string err_message = "Invalid handle." + GetDbgInfo();
916  DATABASE_DRIVER_ERROR( err_message, 0 );
917  }
918  break;
919  }
920 
921  return false;
922 }
923 
924 int
925 CStatementBase::CheckSIE(int rc, const char* msg, unsigned int msg_num) const
926 {
927  switch( rc ) {
929  ReportErrors();
930 
931  case SQL_SUCCESS:
932  break;
933 
934  case SQL_ERROR:
935  ReportErrors();
936  {
937  string err_message = msg + GetDbgInfo();
938  DATABASE_DRIVER_ERROR( err_message, msg_num );
939  }
940  default:
941  {
942  string err_message;
943 
944  err_message.append(msg);
945  err_message.append(" (memory corruption suspected).");
946 
947  DATABASE_DRIVER_ERROR( err_message, 420001 );
948  }
949  }
950 
951  return rc;
952 }
953 
954 int
955 CStatementBase::CheckSIENd(int rc, const char* msg, unsigned int msg_num) const
956 {
957  switch( rc ) {
959  ReportErrors();
960 
961  case SQL_SUCCESS:
962  break;
963 
964  case SQL_ERROR:
965  ReportErrors();
966  {
967  string err_message = msg + GetDbgInfo();
968  DATABASE_DRIVER_ERROR( err_message, msg_num );
969  }
970  default:
971  {
972  string err_message;
973 
974  err_message.append(msg);
975  err_message.append(" (memory corruption suspected).");
976 
977  DATABASE_DRIVER_ERROR( err_message, 420001 );
978  }
979  }
980 
981  return rc;
982 }
983 
984 
985 string
987 {
988  string type_str;
989 
990  switch (param.GetType()) {
991  case eDB_Bit:
992  type_str = "bit";
993  break;
994  case eDB_Int:
995  type_str = "int";
996  break;
997  case eDB_SmallInt:
998  type_str = "smallint";
999  break;
1000  case eDB_TinyInt:
1001  type_str = "tinyint";
1002  break;
1003  case eDB_BigInt:
1004  type_str = "numeric";
1005  break;
1006  case eDB_Char:
1007  case eDB_VarChar:
1008  // New code ...
1009  if (IsMultibyteClientEncoding()) {
1010  type_str = "nvarchar(4000)";
1011  } else {
1012  type_str = "varchar(8000)";
1013  }
1014  // End of new code ...
1015  // Old code ...
1016 // if (IsMultibyteClientEncoding()) {
1017 // type_str = "nvarchar(255)";
1018 // } else {
1019 // type_str = "varchar(255)";
1020 // }
1021  break;
1022  case eDB_LongChar:
1023  if (IsMultibyteClientEncoding()) {
1024  type_str = "nvarchar(4000)";
1025  } else {
1026  type_str = "varchar(8000)";
1027  }
1028  break;
1029  case eDB_Binary:
1030  case eDB_VarBinary:
1031  // New code ...
1032  type_str = "varbinary(8000)";
1033  // Old code ...
1034 // type_str = "varbinary(255)";
1035  break;
1036  case eDB_LongBinary:
1037  type_str = "varbinary(8000)";
1038  break;
1039  case eDB_Float:
1040  type_str = "real";
1041  break;
1042  case eDB_Double:
1043  type_str = "float";
1044  break;
1045  case eDB_SmallDateTime:
1046  type_str = "smalldatetime";
1047  break;
1048  case eDB_DateTime:
1049  type_str = "datetime";
1050  break;
1051  case eDB_BigDateTime:
1052  type_str = ((CDB_BigDateTime&)param)
1053  .GetSQLTypeName(CDB_BigDateTime::eSyntax_Microsoft
1054  /* GetConnection().GetDateTimeSyntax() */);
1055  break;
1056  case eDB_Text:
1057  if (IsMultibyteClientEncoding()) {
1058  type_str = "ntext";
1059  } else {
1060  type_str = "text";
1061  }
1062  case eDB_Image:
1063  type_str = "image";
1064  break;
1065  case eDB_VarCharMax:
1066  if (IsMultibyteClientEncoding()) {
1067  type_str = "nvarchar(max)";
1068  } else {
1069  type_str = "varchar(max)";
1070  }
1071  break;
1072  case eDB_VarBinaryMax:
1073  type_str = "varbinary(max)";
1074  break;
1075  default:
1076  break;
1077  }
1078 
1079  return type_str;
1080 }
1081 
1082 bool
1084  CMemPot& bind_guard,
1085  SQLLEN* indicator_base,
1086  unsigned int pos) const
1087 {
1088  SQLRETURN rc = 0;
1089 
1090  EDB_Type data_type = param.GetType();
1091 
1092  switch (data_type) {
1093  case eDB_Text:
1094  case eDB_Image:
1095  case eDB_Bit:
1096  case eDB_Numeric:
1097  case eDB_UnsupportedType:
1098  return false;
1099  default:
1100  break;
1101  }
1102 
1103  SQLSMALLINT scale;
1104  switch (data_type) {
1105  case eDB_DateTime: scale = 3; break;
1106  case eDB_BigDateTime: scale = 7; break;
1107  default: scale = 0; break;
1108  }
1109 
1110  indicator_base[pos] = x_GetIndicator(param);
1111 
1112  rc = SQLBindParameter(GetHandle(),
1113  pos + 1,
1115  x_GetCType(param),
1116  x_GetSQLType(param),
1117  x_GetMaxDataSize(param),
1118  scale,
1119  x_GetData(param, bind_guard),
1120  x_GetCurDataSize(param),
1121  indicator_base + pos);
1122 
1123  CheckSIE(rc, "SQLBindParameter failed", 420066);
1124 
1125  return true;
1126 }
1127 
1128 
1131 {
1132  SQLSMALLINT type = 0;
1133 
1134  switch (param.GetType()) {
1135  case eDB_Int:
1136  type = SQL_C_SLONG;
1137  break;
1138  case eDB_SmallInt:
1139  type = SQL_C_SSHORT;
1140  break;
1141  case eDB_TinyInt:
1142  type = SQL_C_UTINYINT;
1143  break;
1144  case eDB_BigInt:
1145  type = SQL_C_SBIGINT;
1146  break;
1147  case eDB_Char:
1148  case eDB_VarChar:
1149  case eDB_LongChar:
1150  case eDB_VarCharMax:
1151  // New code ...
1152  if (IsMultibyteClientEncoding()) {
1153  type = SQL_C_WCHAR;
1154  } else {
1155  type = SQL_C_CHAR;
1156  }
1157  // End of new code ...
1158  // Old code ...
1159 // #ifdef UNICODE
1160 // type = SQL_C_WCHAR;
1161 // #else
1162 // type = SQL_C_CHAR;
1163 // #endif
1164  break;
1165  case eDB_Binary:
1166  case eDB_VarBinary:
1167  case eDB_LongBinary:
1168  case eDB_VarBinaryMax:
1169  type = SQL_C_BINARY;
1170  break;
1171  case eDB_Float:
1172  type = SQL_C_FLOAT;
1173  break;
1174  case eDB_Double:
1175  type = SQL_C_DOUBLE;
1176  break;
1177  case eDB_SmallDateTime:
1178  case eDB_DateTime:
1179  case eDB_BigDateTime:
1181  break;
1182  default:
1183  break;
1184  }
1185 
1186  return type;
1187 }
1188 
1189 
1192 {
1194 
1195  switch (param.GetType()) {
1196  case eDB_Int:
1197  type = SQL_INTEGER;
1198  break;
1199  case eDB_SmallInt:
1200  type = SQL_SMALLINT;
1201  break;
1202  case eDB_TinyInt:
1203  type = SQL_TINYINT;
1204  break;
1205  case eDB_BigInt:
1206  type = SQL_NUMERIC;
1207  break;
1208  case eDB_Char:
1209  case eDB_VarChar:
1210  // New code ...
1211  if (IsMultibyteClientEncoding()) {
1212  type = SQL_WVARCHAR;
1213  } else {
1214  type = SQL_VARCHAR;
1215  }
1216  // End of new code ...
1217  // Old code ...
1218 // #ifdef UNICODE
1219 // type = SQL_WVARCHAR;
1220 // #else
1221 // type = SQL_VARCHAR;
1222 // #endif
1223  break;
1224  case eDB_LongChar:
1225  case eDB_VarCharMax:
1226  // New code ...
1227  if (IsMultibyteClientEncoding()) {
1229  } else {
1231  }
1232  // End of new code ...
1233  // Old code ...
1234 // #ifdef UNICODE
1235 // type = SQL_WLONGVARCHAR;
1236 // #else
1237 // type = SQL_LONGVARCHAR;
1238 // #endif
1239  break;
1240  case eDB_Binary:
1241  case eDB_VarBinary:
1242  case eDB_LongBinary:
1243  type = SQL_VARBINARY;
1244  break;
1245  case eDB_VarBinaryMax:
1247  break;
1248  case eDB_Float:
1249  type = SQL_REAL;
1250  break;
1251  case eDB_Double:
1252  type = SQL_FLOAT;
1253  break;
1254  case eDB_SmallDateTime:
1255  case eDB_DateTime:
1256  case eDB_BigDateTime:
1258  break;
1259  default:
1260  break;
1261  }
1262 
1263  return type;
1264 }
1265 
1266 
1267 SQLULEN
1269 {
1270  SQLULEN size = 0;
1271 
1272  switch (param.GetType()) {
1273  case eDB_Int:
1274  size = 4;
1275  break;
1276  case eDB_SmallInt:
1277  size = 2;
1278  break;
1279  case eDB_TinyInt:
1280  size = 1;
1281  break;
1282  case eDB_BigInt:
1283  size = 18;
1284  break;
1285  case eDB_Char:
1286  case eDB_VarChar:
1287  // New code ...
1288  if (IsMultibyteClientEncoding()) {
1289  size = 8000 / sizeof(odbc::TChar);
1290  } else {
1291  size = 8000;
1292  }
1293  // End of new code ...
1294 
1295  // Old code ...
1296 // size = 255;
1297  break;
1298  case eDB_LongChar:
1299  // New code ...
1300  if (IsMultibyteClientEncoding()) {
1301  size = 8000 / sizeof(odbc::TChar);
1302  } else {
1303  size = 8000;
1304  }
1305  // End of new code ...
1306 
1307  // Old code ...
1308 // size = 8000 / sizeof(odbc::TChar);
1309  break;
1310  case eDB_Binary:
1311  case eDB_VarBinary:
1312  size = 8000;
1313  break;
1314  case eDB_LongBinary:
1315  size = 8000;
1316  break;
1317  case eDB_Float:
1318  size = 4;
1319  break;
1320  case eDB_Double:
1321  size = 8;
1322  break;
1323  case eDB_SmallDateTime:
1324  size = 16;
1325  break;
1326  case eDB_DateTime:
1327  size = 23;
1328  break;
1329  case eDB_BigDateTime:
1330  size = 27;
1331  break;
1332  case eDB_VarCharMax:
1333 #if 0
1334  if (IsMultibyteClientEncoding()) {
1335  size = kMax_UInt / sizeof(odbc::TChar);
1336  } else {
1337  size = kMax_UInt;
1338  }
1339 #else
1340  size = static_cast<const CDB_VarCharMax&>(param).Size();
1341  if (size == 0) {
1342  size = 1;
1343  }
1344 #endif
1345  break;
1346  case eDB_VarBinaryMax:
1347 #if 0
1348  size = kMax_UInt;
1349 #else
1350  size = static_cast<const CDB_VarBinaryMax&>(param).Size();
1351  if (size == 0) {
1352  size = 1;
1353  }
1354 #endif
1355  break;
1356  default:
1357  break;
1358  }
1359 
1360  return size;
1361 }
1362 
1363 
1364 SQLLEN
1366 {
1367  SQLLEN size = 0;
1368 
1369  switch (param.GetType()) {
1370  case eDB_Int:
1371  case eDB_SmallInt:
1372  case eDB_TinyInt:
1373  case eDB_BigInt:
1374  case eDB_Binary:
1375  case eDB_VarBinary:
1376  case eDB_Float:
1377  case eDB_Double:
1378  size = x_GetMaxDataSize(param);
1379  break;
1380  case eDB_Char:
1381  case eDB_VarChar:
1382  case eDB_LongChar:
1383  size = dynamic_cast<const CDB_String&>(param).Size() * sizeof(odbc::TChar);
1384  break;
1385  case eDB_LongBinary:
1386  size = dynamic_cast<const CDB_LongBinary&>(param).Size();
1387  break;
1388  case eDB_SmallDateTime:
1389  case eDB_DateTime:
1390  case eDB_BigDateTime:
1391  size = sizeof(SQL_TIMESTAMP_STRUCT);
1392  break;
1393  case eDB_VarCharMax:
1394  size = dynamic_cast<const CDB_VarCharMax&>(param).Size()
1395  * sizeof(odbc::TChar);
1396  break;
1397  case eDB_VarBinaryMax:
1398  size = dynamic_cast<const CDB_VarBinaryMax&>(param).Size();
1399  break;
1400  default:
1401  break;
1402  }
1403 
1404  return size;
1405 }
1406 
1407 
1408 SQLLEN
1410 {
1411  if (param.IsNULL()) {
1412  return SQL_NULL_DATA;
1413  }
1414 
1415  switch (param.GetType()) {
1416  case eDB_Char:
1417  case eDB_VarChar:
1418  case eDB_LongChar:
1419  return dynamic_cast<const CDB_String&>(param).Size()
1420  * sizeof(TSqlChar);
1421  case eDB_Binary:
1422  return dynamic_cast<const CDB_Binary&>(param).Size();
1423  case eDB_VarBinary:
1424  return dynamic_cast<const CDB_VarBinary&>(param).Size();
1425  case eDB_LongBinary:
1426  return dynamic_cast<const CDB_LongBinary&>(param).DataSize();
1427  case eDB_SmallDateTime:
1428  case eDB_DateTime:
1429  case eDB_BigDateTime:
1430  return sizeof(SQL_TIMESTAMP_STRUCT);
1431  break;
1432  case eDB_VarCharMax:
1433  return dynamic_cast<const CDB_VarCharMax&>(param).Size()
1434  * sizeof(TSqlChar);
1435  case eDB_VarBinaryMax:
1436  return dynamic_cast<const CDB_VarBinaryMax&>(param).Size();
1437  default:
1438  break;
1439  }
1440 
1441  return x_GetMaxDataSize(param);
1442 }
1443 
1444 
1445 SQLPOINTER
1447  CMemPot& bind_guard) const
1448 {
1449  SQLPOINTER data = NULL;
1450 
1451  switch (param.GetType()) {
1452  case eDB_Int:
1453  data = dynamic_cast<const CDB_Int&>(param).BindVal();
1454  break;
1455  case eDB_SmallInt:
1456  data = dynamic_cast<const CDB_SmallInt&>(param).BindVal();
1457  break;
1458  case eDB_TinyInt:
1459  data = dynamic_cast<const CDB_TinyInt&>(param).BindVal();
1460  break;
1461  case eDB_BigInt:
1462  data = dynamic_cast<const CDB_BigInt&>(param).BindVal();
1463  break;
1464  case eDB_Char:
1465  case eDB_VarChar:
1466  case eDB_LongChar:
1467 #ifdef UNICODE
1468  data = const_cast<wchar_t *>(dynamic_cast<const CDB_String&>(param)
1469  .AsWString(GetClientEncoding()).data());
1470 #else
1471  data = const_cast<char *>(dynamic_cast<const CDB_String&>(param)
1472  .Data());
1473 #endif
1474  break;
1475  case eDB_Binary:
1476  data = const_cast<void *>(dynamic_cast<const CDB_Binary&>(param).Value());
1477  break;
1478  case eDB_VarBinary:
1479  data = const_cast<void *>(dynamic_cast<const CDB_VarBinary&>(param).Value());
1480  break;
1481  case eDB_LongBinary:
1482  data = const_cast<void *>(dynamic_cast<const CDB_LongBinary&>(param).Value());
1483  break;
1484  case eDB_Float:
1485  data = dynamic_cast<const CDB_Float&>(param).BindVal();
1486  break;
1487  case eDB_Double:
1488  data = dynamic_cast<const CDB_Double&>(param).BindVal();
1489  break;
1490  case eDB_SmallDateTime:
1491  if(!param.IsNULL()) {
1492  SQL_TIMESTAMP_STRUCT* ts = NULL;
1493 
1494  ts = (SQL_TIMESTAMP_STRUCT*)bind_guard.Alloc(sizeof(SQL_TIMESTAMP_STRUCT));
1495  const CTime& t = dynamic_cast<const CDB_SmallDateTime&>(param).Value();
1496  ts->year = t.Year();
1497  ts->month = t.Month();
1498  ts->day = t.Day();
1499  ts->hour = t.Hour();
1500  ts->minute = t.Minute();
1501 
1502  ts->second = 0;
1503  ts->fraction = 0;
1504 
1505  data = ts;
1506  }
1507  break;
1508  case eDB_DateTime:
1509  if(!param.IsNULL()) {
1510  SQL_TIMESTAMP_STRUCT* ts = NULL;
1511 
1512  ts = (SQL_TIMESTAMP_STRUCT*)bind_guard.Alloc(sizeof(SQL_TIMESTAMP_STRUCT));
1513  const CTime& t = dynamic_cast<const CDB_DateTime&>(param).Value();
1514  ts->year = t.Year();
1515  ts->month = t.Month();
1516  ts->day = t.Day();
1517  ts->hour = t.Hour();
1518  ts->minute = t.Minute();
1519 
1520  ts->second = t.Second();
1521  ts->fraction = t.NanoSecond()/1000000;
1522  ts->fraction *= 1000000; /* MSSQL has a bug - it cannot handle fraction of msecs */
1523 
1524  data = ts;
1525  }
1526  break;
1527  case eDB_BigDateTime:
1528  if( !param.IsNULL() ) {
1529  SQL_TIMESTAMP_STRUCT* ts = NULL;
1530 
1531  ts = (SQL_TIMESTAMP_STRUCT*)bind_guard.Alloc
1532  (sizeof(SQL_TIMESTAMP_STRUCT));
1533  const CTime& t = ((const CDB_BigDateTime&)param).GetCTime();
1534  ts->year = t.Year();
1535  ts->month = t.Month();
1536  ts->day = t.Day();
1537  ts->hour = t.Hour();
1538  ts->minute = t.Minute();
1539 
1540  ts->second = t.Second();
1541  ts->fraction = t.NanoSecond() / 100 * 100;
1542 
1543  data = ts;
1544  }
1545  break;
1546  case eDB_VarCharMax:
1547 #ifdef UNICODE
1548  if( !param.IsNULL() ) {
1549  CDB_Stream& par = static_cast<CDB_Stream&>
1550  (const_cast<CDB_Object&>(param));
1551  size_t n = par.Size();
1552  AutoArray<char> raw_data(n);
1553  par.MoveTo(0);
1554  _VERIFY(par.Read(raw_data.get(), n) == n);
1555  CStringUTF8 utf_data
1556  = CUtf8::AsUTF8(CTempString(raw_data.get(), n),
1557  GetClientEncoding());
1558  raw_data.reset();
1559  wstring wdata = CUtf8::AsBasicString<TSqlChar>(utf_data);
1560  utf_data.clear();
1561  n = wdata.size() * sizeof(TSqlChar);
1562  data = bind_guard.Alloc(n);
1563  memcpy(data, wdata.data(), n);
1564  }
1565  break;
1566 // else fall through
1567 #endif
1568  case eDB_VarBinaryMax:
1569  if( !param.IsNULL() ) {
1570  CDB_Stream& par = static_cast<CDB_Stream&>
1571  (const_cast<CDB_Object&>(param));
1572  size_t n = par.Size();
1573  data = bind_guard.Alloc(n);
1574  par.MoveTo(0);
1575  _VERIFY(par.Read(data, n) == n);
1576  }
1577  break;
1578  default:
1579  break;
1580  }
1581 
1582  return data;
1583 }
1584 
1585 
1586 int
1588 {
1589  return static_cast<int>(m_RowCount);
1590 }
1591 
1592 bool
1594 {
1595  SQLUINTEGER cancel_timeout
1596  = static_cast<SQLUINTEGER>(GetConnection().GetCancelTimeout());
1599  (SQLPOINTER)static_cast<uintptr_t>(cancel_timeout),
1600  0);
1601  try {
1603  SQLUINTEGER query_timeout
1604  = static_cast<SQLUINTEGER>(GetConnection().GetTimeout());
1607  (SQLPOINTER)static_cast<uintptr_t>(query_timeout),
1608  0);
1609  return result;
1610  }
1611  catch (CDB_Exception&) {
1612  SQLUINTEGER query_timeout
1613  = static_cast<SQLUINTEGER>(GetConnection().GetTimeout());
1616  (SQLPOINTER)static_cast<uintptr_t>(query_timeout),
1617  0);
1618  throw;
1619  }
1620 }
1621 
1622 
1623 /////////////////////////////////////////////////////////////////////////////
1624 //
1625 // CODBC_SendDataCmd::
1626 //
1627 
1629  CDB_BlobDescriptor& descr,
1630  size_t nof_bytes,
1631  bool logit,
1632  bool dump_results) :
1634  impl::CSendDataCmd(conn, nof_bytes),
1635  m_DescrType(descr.GetColumnType() == CDB_BlobDescriptor::eText ?
1637  m_Res(NULL),
1638  m_HasMoreResults(false),
1639  m_DumpResults(dump_results)
1640 {
1641  SQLPOINTER p = (SQLPOINTER)1;
1642  if((!ODBC_xSendDataPrepare(*this, descr, (SQLINTEGER)nof_bytes,
1643  false, logit, p, &m_ParamPH)) ||
1644  (!ODBC_xSendDataGetId(*this, &p))) {
1645 
1646  string err_message = "Cannot prepare a command." + GetDbgInfo();
1647  DATABASE_DRIVER_ERROR( err_message, 410035 );
1648  }
1649 }
1650 
1651 size_t CODBC_SendDataCmd::SendChunk(const void* chunk_ptr, size_t nof_bytes)
1652 {
1653  if(nof_bytes > GetBytes2Go()) nof_bytes= GetBytes2Go();
1654  if(nof_bytes < 1) return 0;
1655 
1656  int rc;
1657 
1658 
1659  // New code ...
1660 // size_t valid_len = nof_bytes;
1661 //
1662 // if (GetClientEncoding() == eEncoding_UTF8 &&
1663 // m_DescrType == CDB_BlobDescriptor::eText) {
1664 //
1665 // valid_len = CStringUTF8::GetValidBytesCount(static_cast<const char*>(chunk_ptr),
1666 // nof_bytes);
1667 //
1668 // if (valid_len == 0) {
1669 // DATABASE_DRIVER_ERROR( "Invalid encoding of a text string." + GetDbgInfo(), 410055 );
1670 // }
1671 //
1672 // nof_bytes = valid_len;
1673 // }
1674 //
1675 // {
1676 // TSqlString ss = x_MakeTSqlString(CTempString(chunk_ptr, valid_len),
1677 // GetClientEncoding());
1678 // odbc::TChar* tchar_str = const_cast<odbc::TChar*>(ss.data());
1679 //
1680 // rc = SQLPutData(GetHandle(),
1681 // static_cast<SQLPOINTER>(tchar_str),
1682 // static_cast<SQLINTEGER>(ss.byte_count())
1683 // );
1684 // }
1685  // End of new code ...
1686 
1687  // Old code ...
1688  if (GetClientEncoding() == eEncoding_UTF8 &&
1690  size_t valid_len = 0;
1691 
1692  valid_len = impl::GetValidUTF8Len(
1693  CTempString(static_cast<const char*>(chunk_ptr),nof_bytes));
1694 
1695  if (valid_len < nof_bytes) {
1696  DATABASE_DRIVER_ERROR( "Invalid encoding of a text string." + GetDbgInfo(), 410055 );
1697  }
1698 
1699  // Encoding is always eEncoding_UTF8 in here.
1701  (CTempString(static_cast<const char*>(chunk_ptr), valid_len),
1702  eEncoding_UTF8);
1703  odbc::TChar* tchar_str = const_cast<odbc::TChar*>(ss.data());
1704  nof_bytes = valid_len;
1705 
1706  rc = SQLPutData(GetHandle(),
1707  static_cast<SQLPOINTER>(tchar_str),
1708  static_cast<SQLINTEGER>(ss.byte_count())
1709  );
1710  } else {
1711  rc = SQLPutData(GetHandle(),
1712  const_cast<SQLPOINTER>(chunk_ptr),
1713  static_cast<SQLINTEGER>(nof_bytes)
1714  );
1715  }
1716  // End of old code ...
1717 
1718 
1719  switch( rc ) {
1720  case SQL_SUCCESS_WITH_INFO:
1721  ReportErrors();
1722  case SQL_NEED_DATA:
1723  case SQL_NO_DATA:
1724  case SQL_SUCCESS:
1725  SetBytes2Go(GetBytes2Go() - nof_bytes);
1726  if(GetBytes2Go() == 0) break;
1727  return nof_bytes;
1728  case SQL_ERROR:
1729  ReportErrors();
1730  default:
1731  return 0;
1732  }
1733 
1734  SQLPOINTER s= (SQLPOINTER)1;
1735  switch(SQLParamData(GetHandle(), (SQLPOINTER*)&s)) {
1737  case SQL_SUCCESS: break;
1738  case SQL_NO_DATA: break;
1739  case SQL_NEED_DATA:
1740  {
1741  string err_message = "Not all the data were sent." + GetDbgInfo();
1742  DATABASE_DRIVER_ERROR( err_message, 410044 );
1743  }
1744  case SQL_ERROR: ReportErrors();
1745  default:
1746  {
1747  string err_message = "SQLParamData failed." + GetDbgInfo();
1748  DATABASE_DRIVER_ERROR( err_message, 410045 );
1749  }
1750  }
1751 
1752  for(;;) {
1753  switch(SQLMoreResults(GetHandle())) {
1755  case SQL_SUCCESS: continue;
1756  case SQL_NO_DATA: break;
1757  case SQL_ERROR:
1758  {
1759  ReportErrors();
1760  string err_message = "SQLMoreResults failed." + GetDbgInfo();
1761  DATABASE_DRIVER_ERROR( err_message, 410014 );
1762  }
1763  default:
1764  {
1765  string err_message = "SQLMoreResults failed (memory corruption suspected)." + GetDbgInfo();
1766  DATABASE_DRIVER_ERROR( err_message, 410015 );
1767  }
1768  }
1769  break;
1770  }
1771 
1772  return nof_bytes;
1773 }
1774 
1776 {
1777  if (GetBytes2Go() > 0) {
1778  xCancel();
1779  SetBytes2Go(0);
1780  return true;
1781  }
1782 
1783  return false;
1784 }
1785 
1787 {
1788  try {
1790 
1792 
1793  Cancel();
1794  }
1796 }
1797 
1799 {
1800  if ( !Close() ) {
1801  return;
1802  }
1803  ResetParams();
1804 }
1805 
1807 {
1808  if (m_Res) {
1809  delete m_Res;
1810  m_Res = 0;
1812  }
1813 
1814  if ( !CStatementBase::WasSent() ) {
1815  string err_message = "A command has to be sent first." + GetDbgInfo();
1816  DATABASE_DRIVER_ERROR( err_message, 420010 );
1817  }
1818 
1819  if(!m_HasMoreResults) {
1821  return 0;
1822  }
1823 
1824  while(m_HasMoreResults) {
1825  SQLSMALLINT nof_cols= 0;
1826  CheckSIE(SQLNumResultCols(GetHandle(), &nof_cols),
1827  "SQLNumResultCols failed", 420011);
1828 
1829  if(nof_cols < 1) { // no data in this result set
1830  SQLLEN rc;
1831 
1832  CheckSIE(SQLRowCount(GetHandle(), &rc),
1833  "SQLRowCount failed", 420013);
1834 
1835  m_RowCount = rc;
1837  continue;
1838  }
1839 
1840  m_Res = new CODBC_RowResult(*this, nof_cols, &m_RowCount);
1841  return Create_Result(*m_Res);
1842  }
1843 
1845  return 0;
1846 }
1847 
1849 {
1850  return m_HasMoreResults;
1851 }
1852 
1854 {
1855  // int rc = CheckSIE(SQLMoreResults(GetHandle()), "SQLBindParameter failed", 420066);
1856  //
1857  // return (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS);
1858 
1859  switch(SQLMoreResults(GetHandle())) {
1861  case SQL_SUCCESS: return true;
1862  case SQL_NO_DATA: return false;
1863  case SQL_ERROR:
1864  {
1865  ReportErrors();
1866 
1867  string err_message = "SQLMoreResults failed." + GetDbgInfo();
1868  DATABASE_DRIVER_ERROR( err_message, 420014 );
1869  }
1870  default:
1871  {
1872  string err_message = "SQLMoreResults failed (memory corruption suspected)." + GetDbgInfo();
1873  DATABASE_DRIVER_ERROR( err_message, 420015 );
1874  }
1875  }
1876 }
1877 
1879 
1880 
1881 
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
CDBConnParams::
Definition: interfaces.hpp:258
CDB_Exception –.
Definition: exception.hpp:118
Convenience extension of basic_string, supporting implicit conversion to const TChar* in most situati...
Definition: types.hpp:99
void * Alloc(size_t nof_bytes)
static CNcbiApplication * Instance(void)
Singleton method.
Definition: ncbiapp.cpp:244
SQLHENV GetODBCContext(void) const
Definition: interfaces.hpp:196
bool GetUseDSN(void) const
Definition: interfaces.hpp:209
const CODBC_Reporter & GetReporter(void) const
Definition: interfaces.hpp:200
SQLUINTEGER GetPacketSize(void) const
Definition: interfaces.hpp:191
bool CheckSIE(int rc, SQLHDBC con, const CODBC_Reporter &opening_reporter)
Definition: context.cpp:456
virtual CDB_CursorCmd * Cursor(const string &cursor_name, const string &query, unsigned int batch_size=1)
Cursor.
Definition: connection.cpp:385
friend class CODBC_RPCCmd
Definition: interfaces.hpp:257
virtual I_DriverContext::TConnectionMode ConnectMode(void) const
Get the bitmask for the connection mode (BCP, secure login, ...)
Definition: connection.cpp:464
CODBC_LangCmd * xLangCmd(const string &lang_query)
Definition: connection.cpp:354
size_t m_cancel_timeout
Definition: interfaces.hpp:354
size_t GetCancelTimeout() const
Definition: interfaces.hpp:310
friend class CODBC_LangCmd
Definition: interfaces.hpp:256
virtual bool IsAlive(void)
Check out if connection is alive (this function doesn't ping the server, it just checks the status of...
Definition: connection.cpp:341
void x_Connect(CODBCContext &cntx, const CDBConnParams &params, const CODBC_Reporter &opening_reporter) const
Definition: connection.cpp:142
friend class CODBC_CursorCmdExpl
Definition: interfaces.hpp:261
virtual string GetDriverName(void) const
Definition: connection.cpp:534
const SQLHDBC m_Link
Definition: interfaces.hpp:350
size_t m_query_timeout
Definition: interfaces.hpp:353
static string x_GetDriverName(const IRegistry &registry)
Definition: connection.cpp:256
virtual CDB_SendDataCmd * SendDataCmd(I_BlobDescriptor &desc, size_t data_size, bool log_it=true, bool dump_results=true)
"Send-data" command
Definition: connection.cpp:403
friend class CODBC_BCPInCmd
Definition: interfaces.hpp:258
bool x_SendData(CDB_BlobDescriptor::ETDescriptorType descr_type, CStatementBase &stmt, CDB_Stream &stream)
Definition: connection.cpp:688
virtual CDB_RPCCmd * RPC(const string &rpc_name)
Remote procedure call.
Definition: connection.cpp:366
virtual void SetTimeout(size_t nof_secs)
Definition: connection.cpp:524
friend class CODBC_SendDataCmd
Definition: interfaces.hpp:259
const TDbgInfo & GetDbgInfo(void) const
Definition: interfaces.hpp:321
virtual bool Abort(void)
abort the connection Attention: it is not recommended to use this method unless you absolutely have t...
Definition: connection.cpp:493
virtual bool Refresh(void)
Reset the connection to the "ready" state (cancel all active commands)
Definition: connection.cpp:455
CODBC_Reporter m_Reporter
Definition: interfaces.hpp:352
static string x_MakeFreeTDSVersion(int version)
Definition: connection.cpp:309
virtual void SetCancelTimeout(size_t nof_secs)
Definition: connection.cpp:529
void x_SetConnAttributesBefore(const CODBCContext &cntx, const CDBConnParams &params)
Definition: connection.cpp:226
CStatementBase * m_ActiveStmt
Definition: interfaces.hpp:351
void x_SetupErrorReporter(const CDBConnParams &params)
Definition: connection.cpp:132
size_t GetTimeout() const
Definition: interfaces.hpp:305
virtual ~CODBC_Connection(void)
Definition: connection.cpp:477
void ReportErrors(void)
Definition: interfaces.hpp:326
CODBC_Connection(CODBCContext &cntx, const CDBConnParams &params)
Definition: connection.cpp:83
virtual CDB_LangCmd * LangCmd(const string &lang_query)
These methods: LangCmd(), RPC(), BCPIn(), Cursor() and SendDataCmd() create and return a "command" ob...
Definition: connection.cpp:360
friend class CODBC_CursorCmd
Definition: interfaces.hpp:260
virtual bool SendData(I_BlobDescriptor &desc, CDB_Stream &lob, bool log_it=true)
Shortcut to send text and image to the server without using the "Send-data" command (SendDataCmd)
Definition: connection.cpp:418
virtual bool Close(void)
Close an open connection.
Definition: connection.cpp:500
virtual CDB_BCPInCmd * BCPIn(const string &table_name)
"Bulk copy in" command
Definition: connection.cpp:373
void SetHandlerStack(impl::CDBHandlerStack &hs)
Definition: interfaces.hpp:118
void SetServerName(const string &server_name)
Definition: interfaces.hpp:133
void ReportErrors(void) const
Definition: context.cpp:198
void SetHandle(SQLHANDLE h)
Definition: interfaces.hpp:121
void SetUserName(const string &username)
Definition: interfaces.hpp:136
virtual bool HasMoreResults(void) const
bool xCheck4MoreResults(void)
virtual ~CODBC_SendDataCmd(void)
virtual CDB_Result * Result(void)
Get result set.
CODBC_RowResult * m_Res
Definition: interfaces.hpp:714
CODBC_SendDataCmd(CODBC_Connection &conn, CDB_BlobDescriptor &descr, size_t nof_bytes, bool logit, bool dump_results)
void xCancel(void)
const CDB_BlobDescriptor::ETDescriptorType m_DescrType
Definition: interfaces.hpp:713
virtual bool Cancel(void)
virtual size_t SendChunk(const void *chunk_ptr, size_t nof_bytes)
Send chunk of data to the server.
const CODBC_Connection::TDbgInfo & GetDbgInfo(void) const
Definition: interfaces.hpp:387
bool CheckRC(int rc) const
Definition: connection.cpp:903
bool x_BindParam_ODBC(const CDB_Object &param, CMemPot &bind_guard, SQLLEN *indicator_base, unsigned int pos) const
virtual int RowCount(void) const
Get the number of rows affected by the command Special case: negative on error or if there is no way ...
CODBC_Reporter m_Reporter
Definition: interfaces.hpp:462
bool IsMultibyteClientEncoding(void) const
Definition: interfaces.hpp:430
SQLULEN x_GetMaxDataSize(const CDB_Object &param) const
bool Close(void) const
string Type2String(const CDB_Object &param) const
Definition: connection.cpp:986
SQLHSTMT GetHandle(void) const
Definition: interfaces.hpp:368
void x_Init(void)
Definition: connection.cpp:856
SQLSMALLINT x_GetCType(const CDB_Object &param) const
SQLLEN x_GetIndicator(const CDB_Object &param) const
SQLLEN x_GetCurDataSize(const CDB_Object &param) const
CStatementBase(CODBC_Connection &conn, const string &query)
Definition: connection.cpp:833
SQLHSTMT m_Cmd
Definition: interfaces.hpp:461
int CheckSIE(int rc, const char *msg, unsigned int msg_num) const
Definition: connection.cpp:925
bool ResetParams(void) const
Definition: interfaces.hpp:425
~CStatementBase(void)
Definition: connection.cpp:888
EEncoding GetClientEncoding(void) const
Definition: interfaces.hpp:434
SQLSMALLINT x_GetSQLType(const CDB_Object &param) const
CODBC_Connection & GetConnection(void)
Definition: interfaces.hpp:372
int CheckSIENd(int rc, const char *msg, unsigned int msg_num) const
Definition: connection.cpp:955
SQLPOINTER x_GetData(const CDB_Object &param, CMemPot &bind_guard) const
void ReportErrors(void) const
Definition: interfaces.hpp:392
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTime –.
Definition: ncbitime.hpp:296
IRegistry –.
Definition: ncbireg.hpp:73
I_BlobDescriptor::
Definition: interfaces.hpp:369
void SetWasSent(bool flag=true)
bool WasSent(void) const
static CDB_Result * Create_Result(CResult &result)
bool IsBCPable(void) const
const CDBHandlerStack & GetMsgHandlers(void) const
CDB_CursorCmd * Create_CursorCmd(CBaseCmd &cursor_cmd)
CDB_RPCCmd * Create_RPCCmd(CBaseCmd &rpc_cmd)
void DropCmd(impl::CCommand &cmd)
void SetServerType(CDBConnParams::EServerType type)
bool HasSecureLogin(void) const
CDB_SendDataCmd * Create_SendDataCmd(CSendDataCmd &senddata_cmd)
CDriverContext & GetCDriverContext(void)
CDB_BCPInCmd * Create_BCPInCmd(CBaseCmd &bcpin_cmd)
CDB_LangCmd * Create_LangCmd(CBaseCmd &lang_cmd)
These methods to allow the children of CConnection to create various command-objects.
EEncoding GetClientEncoding(void) const
virtual CRWLock & x_GetCtxLock(void) const
void DetachSendDataIntf(void)
void SetBytes2Go(size_t value)
size_t GetBytes2Go(void) const
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
SQLCHAR TSqlChar
Definition: interfaces.hpp:76
char TChar
Definition: interfaces.hpp:78
static int type
Definition: getdata.c:31
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
element_type * get(void) const
Get pointer.
Definition: ncbimisc.hpp:581
void reset(element_type *p=0)
Reset will delete the old pointer, set content to the new value, and assume the ownership upon the ne...
Definition: ncbimisc.hpp:598
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define DATABASE_DRIVER_ERROR(message, err_code)
Definition: exception.hpp:740
virtual const impl::CDBHandlerStack & GetOpeningMsgHandlers(void) const =0
virtual string GetPassword(void) const =0
virtual string GetDriverName(void) const
Definition: interfaces.cpp:342
virtual Uint4 GetHost(void) const =0
virtual string GetServerName(void) const =0
virtual Uint2 GetPort(void) const =0
virtual string GetUserName(void) const =0
virtual string GetParam(const string &key) const =0
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
const string & SearchConditions() const
Definition: public.hpp:993
ETDescriptorType GetColumnType(void) const
Definition: public.hpp:996
const string & ColumnName() const
Definition: public.hpp:991
const string & TableName() const
Definition: public.hpp:989
EDB_Type
Definition: types.hpp:52
static EBlobType GetBlobType(EDB_Type db_type)
Definition: types.hpp:1216
@ eBlobType_Binary
Definition: types.hpp:81
size_type byte_count(void) const
Definition: types.hpp:111
virtual EDB_Type GetType() const =0
virtual bool MoveTo(size_t byte_number)
Definition: types.cpp:2008
virtual size_t Read(void *buff, size_t nof_bytes)
Definition: types.cpp:1987
virtual size_t Size() const
Definition: types.cpp:2014
bool IsNULL() const
Definition: types.hpp:303
@ eDB_Bit
Definition: types.hpp:68
@ eDB_Char
Definition: types.hpp:58
@ eDB_UnsupportedType
Definition: types.hpp:75
@ eDB_SmallDateTime
Definition: types.hpp:65
@ eDB_VarChar
Definition: types.hpp:57
@ eDB_TinyInt
Definition: types.hpp:55
@ eDB_LongChar
Definition: types.hpp:70
@ eDB_Double
Definition: types.hpp:62
@ eDB_Image
Definition: types.hpp:67
@ eDB_Float
Definition: types.hpp:61
@ eDB_Int
Definition: types.hpp:53
@ eDB_VarCharMax
Definition: types.hpp:72
@ eDB_Numeric
Definition: types.hpp:69
@ eDB_BigInt
Definition: types.hpp:56
@ eDB_BigDateTime
Definition: types.hpp:64
@ eDB_Binary
Definition: types.hpp:60
@ eDB_Text
Definition: types.hpp:66
@ eDB_SmallInt
Definition: types.hpp:54
@ eDB_DateTime
Definition: types.hpp:63
@ eDB_LongBinary
Definition: types.hpp:71
@ eDB_VarBinary
Definition: types.hpp:59
@ eDB_VarBinaryMax
Definition: types.hpp:73
#define _VERIFY(expr)
Definition: ncbidbg.hpp:161
#define NCBI_CURRENT_FUNCTION
Get current function name.
Definition: ncbidiag.hpp:142
#define NCBI_CATCH_ALL_X(err_subcode, message)
Definition: ncbiexpt.hpp:619
unsigned int uintptr_t
Definition: ncbitype.h:197
#define kMax_UInt
Definition: ncbi_limits.h:185
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
std::string CStringUTF8
Definition: ncbistl.hpp:254
EEncoding
Definition: ncbistr.hpp:199
#define kEmptyStr
Definition: ncbistr.hpp:123
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3457
static TNumeric StringToNumeric(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to a numeric value.
Definition: ncbistr.hpp:330
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
static CStringUTF8 AsUTF8(const CTempString &src, EEncoding encoding, EValidate validate=eNoValidate)
Convert into UTF8 from a C/C++ string.
Definition: ncbistr.hpp:3888
@ eEncoding_UTF8
Definition: ncbistr.hpp:201
@ fSplit_Truncate
Definition: ncbistr.hpp:2501
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2498
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
yy_size_t n
int len
@ eText
Definition: map_control.hpp:50
static int version
Definition: mdb_load.c:29
string ConvertN2A(Uint4 host)
SIZE_TYPE GetValidUTF8Len(const CTempString &ts)
mdb_mode_t mode
Definition: lmdb++.h:38
const struct ncbi::grid::netcache::search::fields::SIZE size
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2107
EIPRangeType t
Definition: ncbi_localip.c:101
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define DEFAULT_ODBC_DRIVER_NAME
Definition: connection.cpp:48
static bool ODBC_xSendDataGetId(CStatementBase &stmt, SQLPOINTER *id)
Definition: connection.cpp:673
static bool ODBC_xCheckSIE(int rc, CStatementBase &stmt)
Definition: connection.cpp:553
bool IsBCPCapable(void)
Definition: connection.cpp:66
static bool ODBC_xSendDataPrepare(CStatementBase &stmt, CDB_BlobDescriptor &descr_in, SQLLEN size, bool is_text, bool logit, SQLPOINTER id, SQLLEN *ph)
Definition: connection.cpp:568
static const char table_name[]
Definition: bcp.c:249
#define SQLSetConnectAttr(h, n, p, t)
Definition: odbc.c:50
#define SQLULEN
Definition: odbc.h:49
#define SQLLEN
Definition: odbc.h:52
TSqlString x_MakeTSqlString(const CTempString &s, EEncoding enc)
Definition: odbc_utils.hpp:107
#define _T_NCBI_ODBC(x)
Definition: odbc_utils.hpp:101
#define memmove(a, b, c)
static pcre_uint8 * buffer
Definition: pcretest.c:1051
static HSTMT stmt
Definition: rebindpar.c:12
#define SQL_REAL
Definition: sql.h:173
SQLRETURN SQLRowCount(SQLHSTMT StatementHandle, SQLINTEGER *RowCount)
SQLRETURN SQLPutData(SQLHSTMT StatementHandle, SQLPOINTER Data, SQLINTEGER StrLen_or_Ind)
#define SQL_FLOAT
Definition: sql.h:172
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength)
Definition: odbc_export.h:848
#define SQL_HANDLE_STMT
Definition: sql.h:66
SQLRETURN SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3)
Definition: odbc_export.h:488
SQLRETURN SQLGetInfo(SQLHDBC ConnectionHandle, SQLUSMALLINT InfoType, SQLPOINTER InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength)
SQLRETURN SQLExecute(SQLHSTMT StatementHandle)
Definition: odbc.c:3558
#define SQL_SUCCESS
Definition: sql.h:31
#define SQL_DATA_AT_EXEC
Definition: sql.h:30
SQLRETURN SQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option)
Definition: odbc.c:4237
#define SQL_UNKNOWN_TYPE
Definition: sql.h:166
#define SQL_TYPE_TIMESTAMP
Definition: sql.h:184
#define SQL_SMALLINT
Definition: sql.h:171
#define SQL_NEED_DATA
Definition: sql.h:39
SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
#define SQL_NUMERIC
Definition: sql.h:168
#define SQL_INTEGER
Definition: sql.h:170
SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)
#define SQL_INVALID_HANDLE
Definition: sql.h:37
#define SQL_SUCCESS_WITH_INFO
Definition: sql.h:32
SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle)
Definition: odbc.c:2313
SQLRETURN SQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount)
#define SQL_NULL_DATA
Definition: sql.h:29
SQLRETURN SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
#define SQL_SUCCEEDED(rc)
Definition: sql.h:40
SQLRETURN SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength)
Definition: odbc_export.h:1020
SQLRETURN SQLParamData(SQLHSTMT StatementHandle, SQLPOINTER *Value)
#define SQL_HANDLE_DBC
Definition: sql.h:65
#define SQL_VARCHAR
Definition: sql.h:178
#define SQL_ERROR
Definition: sql.h:36
#define SQL_CLOSE
Definition: sql.h:253
#define SQL_NO_DATA
Definition: sql.h:34
#define SQL_ATTR_CONNECTION_TIMEOUT
Definition: sqlext.h:125
#define SQL_PARAM_INPUT
Definition: sqlext.h:1852
#define SQL_DRIVER_NAME
Definition: sqlext.h:775
#define SQL_C_DOUBLE
Definition: sqlext.h:515
#define SQL_C_TYPE_TIMESTAMP
Definition: sqlext.h:531
SQLRETURN SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLUINTEGER cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLINTEGER cbValueMax, SQLINTEGER *pcbValue)
#define SQL_LONGVARBINARY
Definition: sqlext.h:435
#define SQL_LEN_DATA_AT_EXEC(length)
Definition: sqlext.h:618
#define SQL_LONGVARCHAR
Definition: sqlext.h:432
#define SQL_ATTR_LOGIN_TIMEOUT
Definition: sqlext.h:130
#define SQL_C_SLONG
Definition: sqlext.h:553
#define SQL_C_BINARY
Definition: sqlext.h:546
#define SQL_ATTR_CONNECTION_DEAD
Definition: sqlext.h:141
#define SQL_ATTR_QUERY_TIMEOUT
Definition: sqlext.h:271
#define SQL_C_FLOAT
Definition: sqlext.h:514
#define SQL_ATTR_PACKET_SIZE
Definition: sqlext.h:132
#define SQL_CD_FALSE
Definition: sqlext.h:217
#define SQL_TINYINT
Definition: sqlext.h:437
#define SQL_C_SSHORT
Definition: sqlext.h:554
SQLRETURN SQLMoreResults(SQLHSTMT hstmt)
Definition: odbc.c:865
#define SQL_VARBINARY
Definition: sqlext.h:434
#define SQL_C_UTINYINT
Definition: sqlext.h:558
#define SQL_C_SBIGINT
Definition: sqlext.h:549
#define SQL_IS_INTEGER
Definition: sqlext.h:307
#define SQL_C_CHAR
Definition: sqlext.h:511
#define SQL_DRIVER_NOPROMPT
Definition: sqlext.h:1785
SQLRETURN SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut, SQLUSMALLINT fDriverCompletion)
unsigned long SQLUINTEGER
Definition: sqltypes.h:177
void * SQLPOINTER
Definition: sqltypes.h:195
SQLHANDLE SQLHDBC
Definition: sqltypes.h:215
long SQLINTEGER
Definition: sqltypes.h:176
signed short int SQLSMALLINT
Definition: sqltypes.h:201
TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT
Definition: sqltypes.h:316
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
#define SQL_WVARCHAR
Definition: sqlucode.h:15
#define SQL_C_WCHAR
Definition: sqlucode.h:17
#define SQL_WLONGVARCHAR
Definition: sqlucode.h:16
static string query
SQLUSMALLINT hour
Definition: sqltypes.h:309
SQLUINTEGER fraction
Definition: sqltypes.h:312
SQLUSMALLINT second
Definition: sqltypes.h:311
SQLSMALLINT year
Definition: sqltypes.h:306
SQLUSMALLINT month
Definition: sqltypes.h:307
SQLUSMALLINT day
Definition: sqltypes.h:308
SQLUSMALLINT minute
Definition: sqltypes.h:310
Definition: type.c:6
#define _ASSERT
else result
Definition: token2.c:20
Modified on Sat Dec 02 09:19:30 2023 by modify_doxy.py rev. 669887