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

Go to the SVN repository for this file.

1 /* $Id: context.cpp 99071 2023-02-09 17:00:30Z 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: Driver for CTLib client library
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include "ctlib_utils.hpp"
35 
37 #include <corelib/ncbi_param.hpp>
38 
39 // DO NOT DELETE this include !!!
41 
46 #include <dbapi/error_codes.hpp>
47 
48 #include <algorithm>
49 
50 #if defined(NCBI_OS_MSWIN)
51 # include <winsock2.h>
52 # include "../ncbi_win_hook.hpp"
53 #else
54 # include <unistd.h>
55 #endif
56 
57 #ifdef FTDS_IN_USE
58 # include "config.h"
59 # include <ctlib.h>
60 #endif
61 
62 #define NCBI_USE_ERRCODE_X Dbapi_CTLib_Context
63 
64 
66 
67 #ifdef FTDS_IN_USE
68 #define ftdsVER NCBI_AS_STRING(NCBI_FTDS_VERSION_NAME(ftds))
69 
70 namespace NCBI_NS_FTDS_CTLIB
71 {
72 #endif
73 
74 /////////////////////////////////////////////////////////////////////////////
75 inline
77 {
78  return CDiagCompileInfo();
79 }
80 
81 
82 #ifdef FTDS_IN_USE
83 # define s_CTLCtxLock s_TDSCtxLock
84 #endif
85 
86 /// Static lock which will guard all thread-unsafe operations on most ctlib
87 /// contexts and a handful of ctlib-scale operations such as cs_init and
88 /// cs_ctx_*. It is added because several CTLibContext classes can share one
89 /// global underlying context handle, so there is no other way to synchronize
90 /// them but some global lock. Use of non-global context handles considered
91 /// to be very rare so the impact on using it through global lock can be
92 /// treated as insignificant.
94 
95 
96 /////////////////////////////////////////////////////////////////////////////
97 //
98 // CTLibContextRegistry (Singleton)
99 //
100 
102 {
103 public:
104  static CTLibContextRegistry& Instance(void);
105 
106  void Add(CTLibContext* ctx);
107  void Remove(CTLibContext* ctx);
108  void ClearAll(void);
109  static void StaticClearAll(void);
110 
111  bool ExitProcessIsPatched(void) const
112  {
113  return m_ExitProcessPatched;
114  }
115 
116 private:
117  CTLibContextRegistry(void);
118  ~CTLibContextRegistry(void) throw();
119 
120  mutable CMutex m_Mutex;
121  vector<CTLibContext*> m_Registry;
122  bool m_ExitProcessPatched;
123 
125 };
126 
127 
128 /////////////////////////////////////////////////////////////////////////////
130 m_ExitProcessPatched(false)
131 {
132 #if defined(NCBI_OS_MSWIN) && defined(NCBI_DLL_BUILD)
133 
134  try {
137  } catch (const NWinHook::CWinHookException&) {
138  // Just in case ...
139  m_ExitProcessPatched = false;
140  }
141 
142 #endif
143 }
144 
146 {
147  try {
148  ClearAll();
149  }
151 }
152 
155 {
156  static CSafeStatic<CTLibContextRegistry> instance;
157 
158  return instance.Get();
159 }
160 
161 void
163 {
164  CMutexGuard mg(m_Mutex);
165 
166  vector<CTLibContext*>::iterator it = find(m_Registry.begin(),
167  m_Registry.end(),
168  ctx);
169  if (it == m_Registry.end()) {
170  m_Registry.push_back(ctx);
171  }
172 }
173 
174 void
176 {
177  CMutexGuard mg(m_Mutex);
178 
179  vector<CTLibContext*>::iterator it = find(m_Registry.begin(),
180  m_Registry.end(),
181  ctx);
182 
183  if (it != m_Registry.end()) {
184  m_Registry.erase(it);
185  ctx->x_SetRegistry(NULL);
186  }
187 }
188 
189 
190 void
192 {
193  if (!m_Registry.empty())
194  {
195  CWriteLockGuard ctx_guard(*s_CTLCtxLock);
196  CMutexGuard mg(m_Mutex);
197 
198  while ( !m_Registry.empty() ) {
199  // x_Close will unregister and remove handler from the registry.
200  m_Registry.back()->x_Close(false);
201  }
202  }
203 }
204 
205 void
207 {
209 }
210 
211 
212 /////////////////////////////////////////////////////////////////////////////
213 namespace ctlib
214 {
215 
217  CTL_Connection& ctl_conn)
218 : m_CTL_Context(&context)
219 , m_CTL_Conn(&ctl_conn)
220 , m_Handle(NULL)
221 , m_IsAllocated(false)
222 , m_IsOpen(false)
223 , m_IsDead(false)
224 {
225  if (CheckWhileOpening(ct_con_alloc(GetCTLContext().CTLIB_GetContext(),
226  &m_Handle)) != CS_SUCCEED) {
227  DATABASE_DRIVER_ERROR( "Cannot allocate a connection handle.", 100011 );
228  }
229  m_IsAllocated = true;
230 }
231 
232 
234 {
235  try {
236  if (m_IsAllocated) {
237  // Connection must be closed before it is allowed to be dropped.
238  Close();
239  Drop();
240  }
241  }
243 }
244 
245 
247 {
248  // Connection must be dropped always, even if it is dead.
249  if (m_IsAllocated) {
251  m_IsAllocated = false;
252  m_IsOpen = false;
253  }
254 
255  return !m_IsAllocated;
256 }
257 
258 
259 const CTL_Connection&
261 {
262  if (!m_CTL_Conn) {
263  DATABASE_DRIVER_ERROR( "CTL_Connection wasn't assigned.", 100011 );
264  }
265 
266  return *m_CTL_Conn;
267 }
268 
269 
272 {
273  if (!m_CTL_Conn) {
274  DATABASE_DRIVER_ERROR( "CTL_Connection wasn't assigned.", 100011 );
275  }
276 
277  return *m_CTL_Conn;
278 }
279 
280 
281 bool Connection::Open(const CDBConnParams& params)
282 {
283  if (!IsOpen() || Close()) {
285 
286  CS_RETCODE rc;
287 
288  string server_name;
289 
290 #if defined(FTDS_IN_USE)
291  if (params.GetHost()) {
292  if (params.GetUserName().empty()) {
293  // Kerberos authentication needs a hostname to get appropriate
294  // service tickets
295  server_name = params.GetServerName();
296  } else {
297  server_name = impl::ConvertN2A(params.GetHost());
298  }
299  if (params.GetPort()) {
300  server_name += ":" + NStr::IntToString(params.GetPort());
301  }
302  } else {
303  server_name = params.GetServerName();
304  }
305 
307  const_cast<char*>(server_name.data()),
308  static_cast<CS_INT>(server_name.size())));
309 #else
310 #if defined(CS_SERVERADDR)
311  if (params.GetHost()) {
312  server_name = impl::ConvertN2A(params.GetHost());
313  if (params.GetPort()) {
314  server_name += " " + NStr::IntToString(params.GetPort());
315  }
316 
318  CS_SET,
320  const_cast<char*>(server_name.data()),
321  static_cast<CS_INT>(server_name.size()),
322  NULL));
323 
324  // It's strange but at least after one type of error inside
325  // ct_connect (when client encoding is unrecognized) and thus
326  // after throwing an exception from Check one should make
327  // mandatory call to ct_close().
329  NULL,
330  CS_UNUSED));
331  } else {
332  server_name = params.GetServerName();
333 
334  // See comment above
336  const_cast<char*>(server_name.data()),
337  static_cast<CS_INT>(server_name.size())));
338  }
339 #else
340  server_name = params.GetServerName();
341 
342  // See comment above
344  const_cast<char*>(server_name.data()),
345  server_name.size()));
346 
347 #endif
348 #endif
349 
350  if (rc == CS_SUCCEED) {
351  m_IsOpen = true;
352  }
353  else {
354  m_IsOpen = false;
355  }
356  }
357 
358  return IsOpen();
359 }
360 
361 
363 {
364  if (IsOpen()) {
365  if (IsDead() || !IsAlive()) {
367  m_IsOpen = false;
368  }
369  } else {
371  m_IsOpen = false;
372  }
373  }
374  }
375 
376  return !IsOpen();
377 }
378 
379 
381 {
382  if (IsOpen()) {
383  if (!IsAlive()) {
384  return false;
385  }
386 
387  if (GetCTLConn().Check(ct_cancel(
388  GetNativeHandle(),
389  NULL,
390  CS_CANCEL_ALL) != CS_SUCCEED)) {
391  return false;
392  }
393  }
394 
395  return true;
396 }
397 
398 
400 {
401  CS_INT status;
403  GetNativeHandle(),
404  CS_GET,
406  &status,
407  CS_UNUSED,
408  0)) != CS_SUCCEED) {
409  return false;
410  }
411 
412  return
413  (status & CS_CONSTAT_CONNECTED) != 0 &&
414  (status & CS_CONSTAT_DEAD ) == 0;
415 }
416 
417 
419 {
420  CS_INT is_logged = CS_TRUE;
421 
422 #if !defined(FTDS_IN_USE)
424  GetNativeHandle(),
425  CS_GET,
427  (CS_VOID*)&is_logged,
428  CS_UNUSED,
429  NULL)
430  );
431 #endif
432 
433  return is_logged == CS_TRUE;
434 }
435 
436 
437 ////////////////////////////////////////////////////////////////////////////////
439 : m_CTL_Conn(&ctl_conn)
440 , m_Handle(NULL)
441 , m_IsAllocated(false)
442 , m_IsOpen(false)
443 {
445  GetCTLConn().GetNativeConnection().GetNativeHandle(),
446  &m_Handle
447  )) != CS_SUCCEED) {
448  DATABASE_DRIVER_ERROR("Cannot allocate a command handle.", 100011);
449  }
450 
451  m_IsAllocated = true;
452 }
453 
454 
456 {
457  try {
458  Close();
459  Drop();
460  }
462 }
463 
464 
465 bool
466 Command::Open(CS_INT type, CS_INT option, const string& arg)
467 {
468  _ASSERT(!m_IsOpen);
469 
470  if (!m_IsOpen) {
472  type,
473  const_cast<CS_CHAR*>(
474  arg.data()),
475  static_cast<CS_INT>(
476  arg.size()),
477  option)) == CS_SUCCEED);
478  }
479 
480  return m_IsOpen;
481 }
482 
483 
484 bool
486 {
487  return (GetCTLConn().Check(ct_data_info(
488  m_Handle,
489  CS_GET,
490  CS_UNUSED,
491  &desc)) == CS_SUCCEED);
492 }
493 
494 
495 bool
497 {
498  return (GetCTLConn().Check(ct_send_data(
499  m_Handle,
500  buff,
501  buff_len)) == CS_SUCCEED);
502 }
503 
504 
505 bool
507 {
508  return (GetCTLConn().Check(ct_send(
509  m_Handle)) == CS_SUCCEED);
510 }
511 
512 
515 {
516  return GetCTLConn().Check(ct_results(m_Handle, &res_type));
517 }
518 
519 
522 {
523  return GetCTLConn().Check(ct_fetch(
524  m_Handle,
525  CS_UNUSED,
526  CS_UNUSED,
527  CS_UNUSED,
528  0));
529 }
530 
531 
532 void
534 {
535  if (m_IsAllocated) {
537  m_Handle = NULL;
538  m_IsAllocated = false;
539  }
540 }
541 
542 
543 void
545 {
546  if (m_IsOpen) {
548  m_IsOpen = false;
549  }
550 }
551 
552 
553 } // namespace ctlib
554 
555 
556 /////////////////////////////////////////////////////////////////////////////
557 //
558 // CTLibContext::
559 //
560 
562  m_Context(NULL),
563  m_Locale(NULL),
564  m_PacketSize(2048),
565  m_LoginRetryCount(0),
566  m_LoginLoopDelay(0),
567  m_TDSVersion(version),
568  m_Registry(NULL),
569  m_ReusingContext(reuse_context)
570 {
571 #ifdef FTDS_IN_USE
572  switch (version) {
573  case 40:
574  case 42:
575  case 46:
576  case CS_VERSION_100:
577  DATABASE_DRIVER_ERROR("FTDS driver does not support TDS protocol "
578  "version other than 5.0 or 7.x.",
579  300011 );
580  break;
581  }
582 #endif
583 
585 
586  ResetEnvSybase();
587 
588  CS_RETCODE r = reuse_context ? Check(cs_ctx_global(version, &m_Context)) :
590  if (r != CS_SUCCEED) {
591  m_Context = 0;
592  DATABASE_DRIVER_ERROR( "Cannot allocate a context", 100001 );
593  }
594 
595 
597  if (r != CS_SUCCEED) {
598  m_Locale = NULL;
599  }
600 
601  CS_VOID* cb;
602  CS_INT outlen;
603  CPointerPot* p_pot = 0;
604 
605  // check if cs message callback is already installed
607  if (r != CS_SUCCEED) {
608  m_Context = 0;
609  DATABASE_DRIVER_ERROR( "cs_config failed", 100006 );
610  }
611 
612  if (cb == (CS_VOID*) CTLIB_cserr_handler) {
613  // we did use this context already
615  (CS_VOID*) &p_pot, (CS_INT) sizeof(p_pot), &outlen));
616  if (r != CS_SUCCEED) {
617  m_Context = 0;
618  DATABASE_DRIVER_ERROR( "cs_config failed", 100006 );
619  }
620  }
621  else {
622  // this is a brand new context
625  if (r != CS_SUCCEED) {
627  m_Context = 0;
628  DATABASE_DRIVER_ERROR( "Cannot install the cslib message callback", 100005 );
629  }
630 
631  p_pot = new CPointerPot;
633  (CS_VOID*) &p_pot, (CS_INT) sizeof(p_pot), NULL));
634  if (r != CS_SUCCEED) {
636  m_Context = 0;
637  delete p_pot;
638  DATABASE_DRIVER_ERROR( "Cannot install the user data", 100007 );
639  }
640 
642  if (r != CS_SUCCEED) {
644  m_Context = 0;
645  delete p_pot;
646  DATABASE_DRIVER_ERROR( "ct_init failed", 100002 );
647  }
648 
651  if (r != CS_SUCCEED) {
654  m_Context = 0;
655  delete p_pot;
656  DATABASE_DRIVER_ERROR( "Cannot install the client message callback", 100003 );
657  }
658 
661  if (r != CS_SUCCEED) {
664  m_Context = 0;
665  delete p_pot;
666  DATABASE_DRIVER_ERROR( "Cannot install the server message callback", 100004 );
667  }
668  // PushCntxMsgHandler();
669  }
670 
671 
672 #if defined(FTDS_IN_USE) && NCBI_FTDS_VERSION >= 95
673  FIntHandler& int_handler = m_Context->tds_ctx->int_handler;
674  static FIntHandler s_DefaultIntHandler;
675  if (int_handler == &CTL_Connection::x_IntHandler) {
676  m_OrigIntHandler = s_DefaultIntHandler;
677  } else {
678  if (s_DefaultIntHandler == nullptr) {
679  s_DefaultIntHandler = int_handler;
680  }
681  m_OrigIntHandler = int_handler;
682  int_handler = &CTL_Connection::x_IntHandler;
683  }
684 #endif
685 
686  if ( p_pot ) {
687  p_pot->Add((TPotItem) this);
688  }
689 
691  x_AddToRegistry();
692 }
693 
694 
696 {
698 
699  try {
700  x_Close();
701 
702  if (m_Locale) {
704  m_Locale = NULL;
705  }
706  }
708 }
709 
710 
713 {
716 
717  return rc;
718 }
719 
720 
721 void
723 {
724  if (m_Registry) {
725  m_Registry->Add(this);
726  }
727 }
728 
729 void
731 {
732  if (m_Registry) {
733  m_Registry->Remove(this);
734  }
735 }
736 
737 void
739 {
741 }
742 
743 bool CTLibContext::SetLoginTimeout(unsigned int nof_secs)
744 {
746 
747  CWriteLockGuard guard(x_GetCtxLock());
748 
749  int sec = (nof_secs == 0 ? CS_NO_LIMIT : static_cast<int>(nof_secs));
750 
752  CS_SET,
754  &sec,
755  CS_UNUSED,
756  NULL)) == CS_SUCCEED;
757 }
758 
759 
760 bool CTLibContext::SetTimeout(unsigned int nof_secs)
761 {
762  bool success = impl::CDriverContext::SetTimeout(nof_secs);
763 
764  CWriteLockGuard guard(x_GetCtxLock());
765 
766  int sec = (nof_secs == 0 ? CS_NO_LIMIT : static_cast<int>(nof_secs));
767 
769  CS_SET,
770  CS_TIMEOUT,
771  &sec,
772  CS_UNUSED,
773  NULL)) == CS_SUCCEED
774  ) {
775  return success;
776  }
777 
778  return false;
779 }
780 
781 
782 bool CTLibContext::SetMaxBlobSize(size_t nof_bytes)
783 {
785 
786  CWriteLockGuard guard(x_GetCtxLock());
787 
788  CS_INT ti_size = (CS_INT) GetMaxBlobSize();
790  CS_SET,
791  CS_TEXTLIMIT,
792  &ti_size,
793  CS_UNUSED,
794  NULL)) == CS_SUCCEED;
795 }
796 
797 
799 {
800  string app_name = GetApplicationName();
801  if (app_name.empty()) {
802  CWriteLockGuard guard(x_GetCtxLock());
803  if ( !GetApplicationName().empty() ) {
804  return;
805  }
806  app_name = GetDiagContext().GetAppName();
807  if (app_name.empty()) {
808 #ifdef FTDS_IN_USE
809  app_name = "DBAPI-" ftdsVER;
810 #else
811  app_name = "DBAPI-ctlib";
812 #endif
813  }
814  app_name = NStr::PrintableString(app_name);
815  SetApplicationName(app_name);
816  }
817 }
818 
819 unsigned int
821 {
822  {
823  CReadLockGuard guard(x_GetCtxLock());
824 
825  CS_INT t_out = 0;
826 
828  CS_GET,
830  &t_out,
831  CS_UNUSED,
832  NULL)) == CS_SUCCEED) {
833  if (t_out == -1 || t_out == CS_NO_LIMIT) {
834  return 0;
835  } else {
836  return t_out;
837  }
838  }
839  }
840 
842 }
843 
844 
845 unsigned int CTLibContext::GetTimeout(void) const
846 {
847  {
848  CReadLockGuard guard(x_GetCtxLock());
849 
850  CS_INT t_out = 0;
851 
853  CS_GET,
854  CS_TIMEOUT,
855  &t_out,
856  CS_UNUSED,
857  NULL)) == CS_SUCCEED)
858  {
859  if (t_out == -1 || t_out == CS_NO_LIMIT)
860  return 0;
861  else
862  return t_out;
863  }
864  }
865 
867 }
868 
869 
870 string CTLibContext::GetDriverName(void) const
871 {
872 #if FTDS_IN_USE
873  return "ftds";
874 #else
875  return "ctlib";
876 #endif
877 }
878 
879 
882 {
884  CReadLockGuard guard(x_GetCtxLock());
885  CTL_Connection* ctl_conn = new CTL_Connection(*this, params);
886 #if defined(FTDS_IN_USE) && NCBI_FTDS_VERSION >= 95
887  ctl_conn->m_OrigIntHandler = m_OrigIntHandler;
888 #endif
889  return ctl_conn;
890 }
891 
892 
894 {
897 }
898 
899 
901 {
902  switch(cpb) {
903  case eBcp:
906  return true;
907  default:
908  break;
909  }
910 
911  return false;
912 }
913 
914 
915 bool
917 {
919 
921  CS_SET,
923  (CS_VOID*)&num,
924  CS_UNUSED,
925  NULL)) == CS_SUCCEED;
926 }
927 
928 
929 unsigned int
931 {
932  CReadLockGuard guard(x_GetCtxLock());
933 
934  unsigned int num = 0;
935 
937  CS_GET,
939  (CS_VOID*)&num,
940  CS_UNUSED,
941  NULL)) != CS_SUCCEED) {
942  return 0;
943  }
944 
945  return num;
946 }
947 
948 
949 void
950 CTLibContext::x_Close(bool delete_conn)
951 {
952  if ( CTLIB_GetContext() ) {
953  if (x_SafeToFinalize()) {
954  if (delete_conn) {
955  DeleteAllConn();
956  } else {
957  CloseAllConn();
958  }
959  }
960 
961  CS_INT outlen;
962  CPointerPot* p_pot = 0;
963 
965  CS_GET,
966  CS_USERDATA,
967  (void*) &p_pot,
968  (CS_INT) sizeof(p_pot),
969  &outlen)) == CS_SUCCEED
970  && p_pot != 0) {
971  p_pot->Remove(this);
972  if (p_pot->NofItems() == 0) {
973  if (x_SafeToFinalize()) {
975  CS_UNUSED)) != CS_SUCCEED) {
977  CS_FORCE_EXIT));
978  }
979 
980  // This is a last driver for this context
981  // Clean context user data ...
982  {
983  CPointerPot* p_pot_tmp = NULL;
985  CS_SET,
986  CS_USERDATA,
987  (CS_VOID*) &p_pot_tmp,
988  (CS_INT) sizeof(p_pot_tmp),
989  NULL
990  )
991  );
992 
993  delete p_pot;
994  }
995 
996 #if defined(FTDS_IN_USE) && NCBI_FTDS_VERSION >= 95
997  m_Context->tds_ctx->int_handler = m_OrigIntHandler;
998 #endif
999 
1001  }
1002  }
1003  }
1004 
1005  m_Context = NULL;
1007  } else {
1008  if (delete_conn && x_SafeToFinalize()) {
1009  DeleteAllConn();
1010  }
1011  }
1012 }
1013 
1015 {
1016 #if defined(NCBI_OS_MSWIN) && defined(NCBI_DLL_BUILD)
1017  if (m_Registry) {
1018  return m_Registry->ExitProcessIsPatched();
1019  }
1020 #endif
1021 
1022  return true;
1023 }
1024 
1025 void CTLibContext::CTLIB_SetApplicationName(const string& a_name)
1026 {
1027  SetApplicationName( a_name );
1028 }
1029 
1030 
1031 void CTLibContext::CTLIB_SetHostName(const string& host_name)
1032 {
1033  SetHostName( host_name );
1034 }
1035 
1036 
1038 {
1039  m_PacketSize = packet_size;
1040 }
1041 
1042 
1044 {
1045  m_LoginRetryCount = n;
1046 }
1047 
1048 
1050 {
1051  m_LoginLoopDelay = nof_sec;
1052 }
1053 
1054 
1056 {
1057  return m_Context;
1058 }
1059 
1060 
1062 {
1063  CPointerPot* p_pot = NULL;
1064  CTLibContext* ctl_ctx = NULL;
1065  CS_INT outlen;
1066 
1067  try {
1068  CReadLockGuard guard(*s_CTLCtxLock);
1069 
1070  if (cs_config(context,
1071  CS_GET,
1072  CS_USERDATA,
1073  (void*) &p_pot,
1074  (CS_INT) sizeof(p_pot),
1075  &outlen ) == CS_SUCCEED &&
1076  p_pot != 0 && p_pot->NofItems() > 0)
1077  {
1078  ctl_ctx = (CTLibContext*) p_pot->Get(0);
1079  if (ctl_ctx != nullptr && !ctl_ctx->m_ReusingContext) {
1080  guard.Guard(ctl_ctx->x_GetCtxLock());
1081  }
1082  }
1083  if (ctl_ctx
1084  && ctl_ctx->GetCtxHandlerStack().HandleMessage(
1085  msg->severity, msg->msgnumber, msg->msgstring))
1086  {
1087  return CS_SUCCEED;
1088  }
1089 
1090  EDiagSev sev = eDiag_Error;
1091 
1092  if (msg->severity == CS_SV_INFORM) {
1093  sev = eDiag_Info;
1094  }
1095  else if (msg->severity == CS_SV_FATAL) {
1096  sev = eDiag_Critical;
1097  }
1098 
1099 
1100 #ifdef FTDS_IN_USE
1101  if ((msg->msgnumber & 0xFF) == 25) {
1102  unique_ptr<CDB_Exception> ex(new CDB_TruncateEx(
1104  0,
1105  msg->msgstring,
1106  msg->msgnumber));
1107 
1108  ex->SetSybaseSeverity(msg->severity);
1111  return CS_SUCCEED;
1112  }
1113 #endif
1114 
1115  unique_ptr<CDB_Exception> ex(new CDB_ClientEx(DIAG_COMPILE_INFO,
1116  0, msg->msgstring,
1117  sev, msg->msgnumber));
1118 
1119  ex->SetSybaseSeverity(msg->severity);
1120 
1122  if (msg->severity == CS_SV_INFORM)
1124  else
1125  // Otherwise the final severity is detected as error or critical
1127  } catch (...) {
1128  return CS_FAIL;
1129  }
1130 
1131  return CS_SUCCEED;
1132 }
1133 
1134 
1135 static
1136 void PassException(unique_ptr<CDB_Exception>& ex,
1137  const string& server_name,
1138  const string& user_name,
1139  CS_INT severity,
1140  const CDBParams* params,
1141  ERetriable retriable,
1142  unsigned int rows_in_batch = 0
1143  )
1144 {
1145  ex->SetServerName(server_name);
1146  ex->SetUserName(user_name);
1147  ex->SetSybaseSeverity(severity);
1148  ex->SetParams(params);
1149  ex->SetRowsInBatch(rows_in_batch);
1150 
1152  ex_storage.Accept(ex);
1153  ex_storage.SetRetriable(retriable);
1154 }
1155 
1156 
1157 static
1158 CS_RETCODE
1160  CS_CLIENTMSG* msg,
1161  const string& server_name,
1162  const string& user_name
1163  )
1164 {
1165  if(conn) {
1166  CS_INT login_status = 0;
1167 
1168  if( ct_con_props(conn,
1169  CS_GET,
1171  (CS_VOID*)&login_status,
1172  CS_UNUSED,
1173  NULL) != CS_SUCCEED) {
1174  return CS_FAIL;
1175  }
1176 
1177  if (login_status) {
1179 
1180  switch(rc){
1181  case CS_SUCCEED:
1182  return CS_SUCCEED;
1183 #if !defined(FTDS_IN_USE)
1184  case CS_TRYING: {
1185  unique_ptr<CDB_Exception> ex(
1186  new CDB_TimeoutEx(
1188  0,
1189  "Got timeout on ct_cancel(CS_CANCEL_ALL)",
1190  msg->msgnumber));
1191 
1192  PassException(ex, server_name, user_name, msg->severity, NULL,
1193  eRetriable_No);
1194  }
1195 #endif
1196  default:
1197  return CS_FAIL;
1198  }
1199  }
1200  }
1201 
1202  return CS_FAIL;
1203 }
1204 
1205 
1207  CS_CONNECTION* con,
1208  CS_CLIENTMSG* msg
1209  )
1210 {
1211  CS_INT outlen;
1212  CPointerPot* p_pot = NULL;
1213  CTL_Connection* ctl_conn = NULL;
1214  CTLibContext* ctl_ctx = NULL;
1215  string server_name;
1216  string user_name;
1217 
1219 
1220  try {
1221  CReadLockGuard guard(*s_CTLCtxLock);
1222 
1223  // Ignoring "The connection has been marked dead" from connection's
1224  // Close() method.
1225  if (msg->msgnumber == 16843058
1226  && GetCTLExceptionStorage().IsClosingConnect())
1227  {
1228  return CS_SUCCEED;
1229  }
1230  message.message = msg->msgstring;
1231 
1232  // Retrieve CDBHandlerStack ...
1233  if (con != NULL &&
1234  ct_con_props(con,
1235  CS_GET,
1236  CS_USERDATA,
1237  (void*) &ctl_conn,
1238  (CS_INT) sizeof(ctl_conn),
1239  &outlen ) == CS_SUCCEED && ctl_conn != 0)
1240  {
1241  guard.Release();
1242  if (ctl_conn->ServerName().size() < 127 && ctl_conn->UserName().size() < 127) {
1243  server_name = ctl_conn->ServerName();
1244  user_name = ctl_conn->UserName();
1245  } else {
1246  ERR_POST_X(1, Error << "Invalid value of ServerName." << CStackTrace());
1247  }
1248  }
1249  else if (cs_config(context,
1250  CS_GET,
1251  CS_USERDATA,
1252  (void*) &p_pot,
1253  (CS_INT) sizeof(p_pot),
1254  &outlen ) == CS_SUCCEED &&
1255  p_pot != 0 && p_pot->NofItems() > 0)
1256  {
1257  ctl_ctx = (CTLibContext*) p_pot->Get(0);
1258  if (ctl_ctx != nullptr && !ctl_ctx->m_ReusingContext) {
1259  guard.Guard(ctl_ctx->x_GetCtxLock());
1260  }
1261  }
1262  else {
1263  guard.Release();
1264  if (msg->severity != CS_SV_INFORM) {
1265  CNcbiOstrstream err_str;
1266 
1267  // nobody can be informed, let's put it in stderr
1268  err_str << "CTLIB error handler detects the following error" << endl
1269  << "Severity:" << msg->severity
1270  << " Msg # " << msg->msgnumber << endl
1271  << msg->msgstring << endl;
1272 
1273  if (msg->osstringlen > 1) {
1274  err_str << "OS # " << msg->osnumber
1275  << " OS msg " << msg->osstring << endl;
1276  }
1277 
1278  if (msg->sqlstatelen > 1 &&
1279  (msg->sqlstate[0] != 'Z' || msg->sqlstate[1] != 'Z')) {
1280  err_str << "SQL: " << msg->sqlstate << endl;
1281  }
1282 
1283  ERR_POST_X(2, (string)CNcbiOstrstreamToString(err_str));
1284  }
1285 
1286  return CS_SUCCEED;
1287  }
1288 
1289  impl::CDBHandlerStack* handlers = nullptr;
1290  const CDBParams* params = NULL;
1291  unsigned int rows_in_batch = 0;
1292  if (ctl_conn) {
1293  handlers = &ctl_conn->GetMsgHandlers();
1294  message.context.Reset(&ctl_conn->GetDbgInfo());
1295  params = ctl_conn->GetLastParams();
1296  rows_in_batch = ctl_conn->GetRowsInCurrentBatch();
1297  } else if (ctl_ctx != nullptr) {
1298  handlers = &ctl_ctx->GetCtxHandlerStack();
1299  }
1300  if (handlers != nullptr
1301  && handlers->HandleMessage(msg->severity, msg->msgnumber,
1302  msg->msgstring)) {
1303  return CS_SUCCEED;
1304  }
1305 
1306  // In case of timeout ...
1307  /* Experimental. Based on C-Toolkit and code developed by Eugene
1308  * Yaschenko.
1309  if (msg->msgnumber == 16908863) {
1310  return HandleConnStatus(con, msg, server_name, user_name);
1311  }
1312  */
1313 
1314 #ifdef FTDS_IN_USE
1315  if (msg->msgnumber == 20003) {
1316  unique_ptr<CDB_Exception> ex(new CDB_TimeoutEx(
1318  0,
1319  message,
1320  msg->msgnumber));
1321 
1322  PassException(ex, server_name, user_name, msg->severity, params,
1323  eRetriable_Yes, rows_in_batch);
1324  if (ctl_conn != NULL && ctl_conn->IsOpen()) {
1325 #if NCBI_FTDS_VERSION >= 95
1326  if (ctl_conn->GetCancelTimedOut()) {
1327  // This is the case when a cancel request was sent due to a
1328  // timeout but a response to it has not been received
1329  // within one loop over the poll() i.e. 1 sec. So reset the
1330  // flag and return CS_FAIL to break the poll() loop.
1331  ctl_conn->SetCancelTimedOut(false);
1332 
1333  // Inform the exception storage that the connection is not
1334  // in the retriable state
1336  return CS_FAIL;
1337  }
1338 #endif
1339  return CS_SUCCEED;
1340  } else {
1341  return CS_FAIL;
1342  }
1343  } else if ((msg->msgnumber & 0xFF) == 25) {
1344  unique_ptr<CDB_Exception> ex(new CDB_TruncateEx(
1346  0,
1347  message,
1348  msg->msgnumber));
1349 
1350  PassException(ex, server_name, user_name, msg->severity, params,
1351  eRetriable_No, rows_in_batch);
1352  return CS_SUCCEED;
1353  }
1354 #endif
1355 
1356  // Process the message ...
1357  switch (msg->severity) {
1358  case CS_SV_INFORM: {
1359  unique_ptr<CDB_Exception> ex(new CDB_ClientEx(
1361  0,
1362  message,
1363  eDiag_Info,
1364  msg->msgnumber));
1365 
1366  PassException(ex, server_name, user_name, msg->severity, params,
1367  eRetriable_Yes, rows_in_batch);
1368 
1369  break;
1370  }
1371  case CS_SV_RETRY_FAIL: {
1372  unique_ptr<CDB_Exception> ex(new CDB_TimeoutEx(
1374  0,
1375  message,
1376  msg->msgnumber));
1377 
1378  PassException(ex, server_name, user_name, msg->severity, params,
1379  eRetriable_Yes, rows_in_batch);
1380 
1381  return HandleConnStatus(con, msg, server_name, user_name);
1382 
1383  break;
1384  }
1385  case CS_SV_CONFIG_FAIL:
1386  case CS_SV_API_FAIL:
1387  case CS_SV_INTERNAL_FAIL: {
1388  ERetriable retriable = eRetriable_No;
1389  if (msg->severity == CS_SV_INTERNAL_FAIL)
1390  retriable = eRetriable_Unknown;
1391  unique_ptr<CDB_Exception> ex(new CDB_ClientEx(
1393  0,
1394  message,
1395  eDiag_Error,
1396  msg->msgnumber));
1397 
1398  PassException(ex, server_name, user_name, msg->severity, params,
1399  retriable, rows_in_batch);
1400 
1401  break;
1402  }
1403  default: {
1404  unique_ptr<CDB_Exception> ex(new CDB_ClientEx(
1406  0,
1407  message,
1409  msg->msgnumber));
1410 
1411  PassException(ex, server_name, user_name, msg->severity, params,
1412  eRetriable_No, rows_in_batch);
1413 
1414  break;
1415  }
1416  }
1417  } catch (...) {
1418  return CS_FAIL;
1419  }
1420 
1421  return CS_SUCCEED;
1422 }
1423 
1424 
1426  CS_CONNECTION* con,
1427  CS_SERVERMSG* msg
1428  )
1429 {
1430  if (
1431  (msg->severity == 0 && msg->msgnumber == 0
1432  && CTempString(msg->text, msg->textlen)
1433  .find_first_not_of("\t\n\r ") == NPOS) ||
1434  // PubSeqOS sends messages with 0 0 that need to be processed, so
1435  // ignore only those whose text consists entirely of whitespace
1436  // (as MS SQL sends in some cases).
1437  msg->msgnumber == 3621 || // The statement has been terminated.
1438  msg->msgnumber == 3980 || // The request failed to run because the batch is aborted...
1439  msg->msgnumber == 5701 || // Changed database context to ...
1440  msg->msgnumber == 5703 || // Changed language setting to ...
1441  msg->msgnumber == 5704 || // Changed client character set setting to ...
1442  msg->msgnumber == 2401 || // Character set conversion is not available between client character set and server character set
1443  msg->msgnumber == 2411 // No conversions will be done
1444  ) {
1445  return CS_SUCCEED;
1446  }
1447 
1448  CS_INT outlen;
1449  CPointerPot* p_pot = NULL;
1450  CTL_Connection* ctl_conn = NULL;
1451  CTLibContext* ctl_ctx = NULL;
1452  string server_name;
1453  string user_name;
1454 
1456 
1457  try {
1458  CReadLockGuard guard(*s_CTLCtxLock);
1459 
1460  if (con != NULL && ct_con_props(con, CS_GET, CS_USERDATA,
1461  (void*) &ctl_conn, (CS_INT) sizeof(ctl_conn),
1462  &outlen) == CS_SUCCEED &&
1463  ctl_conn != NULL)
1464  {
1465  guard.Release();
1466  if (ctl_conn->ServerName().size() < 127 && ctl_conn->UserName().size() < 127) {
1467  server_name = ctl_conn->ServerName();
1468  user_name = ctl_conn->UserName();
1469  } else {
1470  ERR_POST_X(3, Error << "Invalid value of ServerName." << CStackTrace());
1471  }
1472  }
1473  else if (cs_config(context, CS_GET,
1474  CS_USERDATA,
1475  (void*) &p_pot,
1476  (CS_INT) sizeof(p_pot),
1477  &outlen) == CS_SUCCEED &&
1478  p_pot != 0 && p_pot->NofItems() > 0)
1479  {
1480  if (ctl_ctx != nullptr && !ctl_ctx->m_ReusingContext) {
1481  guard.Guard(ctl_ctx->x_GetCtxLock());
1482  }
1483  ctl_ctx = (CTLibContext*) p_pot->Get(0);
1484  server_name = string(msg->svrname, msg->svrnlen);
1485  }
1486  else {
1487  guard.Release();
1488  CNcbiOstrstream err_str;
1489 
1490  err_str << "Message from the server ";
1491 
1492  if (msg->svrnlen > 0) {
1493  err_str << "<" << msg->svrname << "> ";
1494  }
1495 
1496  err_str << "msg # " << msg->msgnumber
1497  << " severity: " << msg->severity << endl;
1498 
1499  if (msg->proclen > 0) {
1500  err_str << "Proc: " << msg->proc << " line: " << msg->line << endl;
1501  }
1502 
1503  if (msg->sqlstatelen > 1 &&
1504  (msg->sqlstate[0] != 'Z' || msg->sqlstate[1] != 'Z')) {
1505  err_str << "SQL: " << msg->sqlstate << endl;
1506  }
1507 
1508  err_str << msg->text << endl;
1509 
1510  ERR_POST_X(4, (string)CNcbiOstrstreamToString(err_str));
1511 
1512  return CS_SUCCEED;
1513  }
1514 
1515  impl::CDBHandlerStack* handlers;
1516  const CDBParams* params = NULL;
1517  unsigned int rows_in_batch = 0;
1518  if (ctl_conn)
1519  handlers = &ctl_conn->GetMsgHandlers();
1520  else
1521  handlers = &ctl_ctx->GetCtxHandlerStack();
1522  if (handlers->HandleMessage(msg->severity, msg->msgnumber, msg->text))
1523  return CS_SUCCEED;
1524 
1525  message.message = msg->text;
1526  if (ctl_conn) {
1527  message.context.Reset(&ctl_conn->GetDbgInfo());
1528  params = ctl_conn->GetLastParams();
1529  rows_in_batch = ctl_conn->GetRowsInCurrentBatch();
1530  if (ctl_conn->IsCancelInProgress()
1531  && (msg->msgnumber == 3618 /* Transaction has been aborted */
1532  || msg->msgnumber == 4224 /* An interruption occurred */))
1533  {
1534  return CS_SUCCEED;
1535  }
1536  }
1537 
1538  if (msg->msgnumber == 1205 /*DEADLOCK*/) {
1539  unique_ptr<CDB_Exception> ex(new CDB_DeadlockEx(
1541  0,
1542  message));
1543 
1544  PassException(ex, server_name, user_name, msg->severity, params,
1545  eRetriable_Yes, rows_in_batch);
1546  }
1547  else if (msg->msgnumber == 1771 || msg->msgnumber == 1708) {
1548  // "Maximum row size exceeds allowable width. It is being rounded down to 32767 bytes."
1549  // "Row size (32767 bytes) could exceed row size limit, which is 1962 bytes."
1550  // and in ftds
1551  // "The table has been created but its maximum row size exceeds the maximum number of bytes
1552  // per row (8060). INSERT or UPDATE of a row in this table will fail if the resulting row
1553  // length exceeds 8060 bytes."
1554  // Note: MS SQL server 2014 does not report error code 1771 as
1555  // described in the comment; it reports: "Cannot create
1556  // foreign key '%.*ls' because it references object '%.*ls'
1557  // whose clustered index '%.*ls' is disabled."
1558  // However it was decided to keep the code as it is because:
1559  // - it is not clear what (and if) MSSQL2014 reports anything
1560  // instead
1561  // - we still have Sybase servers which may report it
1562  // - there were no complains that MSSQL2014 behaves
1563  // improperly
1564  // - at this point there is no way to tell what server we are
1565  // talking to
1566  ERR_POST_X(11, Warning << message);
1567  }
1568  else {
1569  EDiagSev sev =
1570  msg->severity < 10 ? eDiag_Info :
1571  msg->severity == 10 ? (msg->msgnumber == 0 ? eDiag_Info : eDiag_Warning) :
1572  msg->severity < 16 ? eDiag_Error : eDiag_Critical;
1573 
1574  if (msg->proclen > 0) {
1575  unique_ptr<CDB_Exception> ex(new CDB_RPCEx(
1577  0,
1578  message,
1579  sev,
1580  (int) msg->msgnumber,
1581  msg->proc,
1582  (int) msg->line));
1583 
1584  PassException(ex, server_name, user_name, msg->severity,
1585  params, eRetriable_No, rows_in_batch);
1586  }
1587  else if (msg->sqlstatelen > 1 &&
1588  (msg->sqlstate[0] != 'Z' || msg->sqlstate[1] != 'Z')) {
1589  unique_ptr<CDB_Exception> ex(new CDB_SQLEx(
1591  0,
1592  message,
1593  sev,
1594  (int) msg->msgnumber,
1595  (const char*) msg->sqlstate,
1596  (int) msg->line));
1597 
1598  PassException(ex, server_name, user_name, msg->severity,
1599  params, eRetriable_No, rows_in_batch);
1600  }
1601  else {
1602  unique_ptr<CDB_Exception> ex(new CDB_DSEx(
1604  0,
1605  message,
1606  sev,
1607  (int) msg->msgnumber));
1608 
1609  PassException(ex, server_name, user_name, msg->severity,
1610  params, eRetriable_No, rows_in_batch);
1611  }
1612  }
1613  } catch (...) {
1614  return CS_FAIL;
1615  }
1616 
1617  return CS_SUCCEED;
1618 }
1619 
1620 
1621 void CTLibContext::SetClientCharset(const string& charset)
1622 {
1624 
1625  if ( !GetClientCharset().empty() ) {
1626  CWriteLockGuard guard(x_GetCtxLock());
1627 
1629  CS_SET,
1630  m_Locale,
1632  const_cast<CS_CHAR*>(GetClientCharset().data()),
1633  static_cast<CS_INT>(GetClientCharset().size()),
1634  NULL);
1635  }
1636 }
1637 
1638 // Tunable version of TDS protocol to use
1639 
1640 // NB: normally used only in the absence of CS_CURRENT_VERSION
1641 #if !defined(NCBI_CTLIB_TDS_VERSION)
1642 # define NCBI_CTLIB_TDS_VERSION 125
1643 #endif
1644 
1645 #define NCBI_CTLIB_TDS_FALLBACK_VERSION 110
1646 
1647 
1648 #ifdef FTDS_IN_USE
1649 
1650 NCBI_PARAM_DECL (int, ftds, TDS_VERSION);
1651 NCBI_PARAM_DEF_EX(int, ftds, TDS_VERSION,
1652  0, // default is to auto-detect
1654  FTDS_TDS_VERSION);
1655 typedef NCBI_PARAM_TYPE(ftds, TDS_VERSION) TFtdsTdsVersion;
1656 
1657 #else
1658 
1659 NCBI_PARAM_DECL (int, ctlib, TDS_VERSION);
1660 NCBI_PARAM_DEF_EX(int, ctlib, TDS_VERSION,
1661  NCBI_CTLIB_TDS_VERSION, // default TDS version
1663  CTLIB_TDS_VERSION);
1664 typedef NCBI_PARAM_TYPE(ctlib, TDS_VERSION) TCtlibTdsVersion;
1665 
1666 #endif
1667 
1668 
1669 #ifdef FTDS_IN_USE
1670 # define FTDS_VERSION_ERR_LEVEL Info
1671 #else
1672 # define FTDS_VERSION_ERR_LEVEL Warning
1673 #endif
1674 
1676 {
1677  if (version == 0) {
1678 #ifdef FTDS_IN_USE
1679  return TFtdsTdsVersion::GetDefault();
1680 #elif defined(CS_CURRENT_VERSION)
1681  return CS_CURRENT_VERSION;
1682 #else
1683  version = TCtlibTdsVersion::GetDefault();
1684 #endif
1685  }
1686 
1687  switch ( version ) {
1688  case 42:
1689  case 46:
1690  case 70:
1691  case 71:
1692 #if NCBI_FTDS_VERSION >= 95
1693  case 72:
1694  case 73:
1695 #endif
1696 #if NCBI_FTDS_VERSION >= 100
1697  case 74:
1698 #endif
1699  case 80:
1700  return version;
1701  case 100:
1702  return CS_VERSION_100;
1703  case 110:
1704  return CS_VERSION_110;
1705 #ifdef CS_VERSION_120
1706  case 120:
1707  return CS_VERSION_120;
1708 #endif
1709 #ifdef CS_VERSION_125
1710  case 125:
1711  return CS_VERSION_125;
1712 #endif
1713 #ifdef CS_VERSION_150
1714  case 150:
1715  return CS_VERSION_150;
1716 #endif
1717 #ifdef CS_VERSION_155
1718  case 155:
1719  return CS_VERSION_155;
1720 #endif
1721 #ifdef CS_VERSION_157
1722  case 157:
1723  return CS_VERSION_157;
1724 #endif
1725  }
1726 
1727  int fallback_version = (version == NCBI_CTLIB_TDS_VERSION) ?
1729 
1731  << "The version " << version << " of TDS protocol for "
1732  "the DBAPI CTLib driver is not supported. Falling back to "
1733  "the TDS protocol version " << fallback_version << ".");
1734 
1735  return GetCtlibTdsVersion(fallback_version);
1736 }
1737 
1738 
1739 
1740 ///////////////////////////////////////////////////////////////////////
1741 // Driver manager related functions
1742 //
1743 
1744 ///////////////////////////////////////////////////////////////////////////////
1745 CDbapiCtlibCFBase::CDbapiCtlibCFBase(const string& driver_name)
1746  : TParent( driver_name, 0 )
1747 {
1748  return ;
1749 }
1750 
1752 {
1753  return ;
1754 }
1755 
1758  const string& driver,
1760  const TPluginManagerParamTree* params) const
1761 {
1762  unique_ptr<TImplementation> drv;
1763 
1764  if ( !driver.empty() && driver != m_DriverName ) {
1765  return 0;
1766  }
1767 
1770 
1771  // Mandatory parameters ....
1772 #ifdef FTDS_IN_USE
1773  bool reuse_context = false; // Be careful !!!
1774  int tds_version = 0;
1775 #else
1776  // Previous behahviour was: reuse_context = true
1777  bool reuse_context = false;
1778  int tds_version = 0 /* NCBI_CTLIB_TDS_VERSION */;
1779 #endif
1780 
1781  // Optional parameters ...
1782  CS_INT page_size = 0;
1783  string prog_name;
1784  string host_name;
1785  string client_charset;
1786  unsigned int max_connect = 0;
1787 
1788  if ( params != NULL ) {
1790  typedef TPluginManagerParamTree::TValueType TValue;
1791 
1792  // Get parameters ...
1793  TCIter cit = params->SubNodeBegin();
1794  TCIter cend = params->SubNodeEnd();
1795 
1796  for (; cit != cend; ++cit) {
1797  const TValue& v = (*cit)->GetValue();
1798 
1799  if ( v.id == "reuse_context" ) {
1800  reuse_context = (v.value != "false");
1801  } else if ( v.id == "version" ) {
1802  tds_version = NStr::StringToInt(v.value);
1803  _TRACE("WARNING: user manually set TDS version to " << tds_version);
1804  } else if ( v.id == "packet" ) {
1805  page_size = NStr::StringToInt(v.value);
1806  } else if ( v.id == "prog_name" ) {
1807  prog_name = v.value;
1808  } else if ( v.id == "host_name" ) {
1809  host_name = v.value;
1810  } else if ( v.id == "client_charset" ) {
1811  client_charset = v.value;
1812  } else if ( v.id == "max_connect" ) {
1813  max_connect = NStr::StringToInt(v.value);;
1814  }
1815  }
1816  }
1817 
1818  // Create a driver ...
1819  drv.reset(new CTLibContext(reuse_context,
1821  )
1822  );
1823 
1824  // Set parameters ...
1825  if (page_size) {
1826  drv->CTLIB_SetPacketSize(page_size);
1827  }
1828 
1829  if (!prog_name.empty()) {
1830  drv->SetApplicationName(prog_name);
1831  }
1832 
1833  if (!host_name.empty()) {
1834  drv->SetHostName(host_name);
1835  }
1836 
1837  if (!client_charset.empty()) {
1838  drv->SetClientCharset(client_charset);
1839  }
1840 
1841  if (max_connect && CDbapiConnMgr::Instance().GetMaxConnect() < max_connect) {
1842  CDbapiConnMgr::Instance().SetMaxConnect(max_connect);
1843  }
1844  drv->SetMaxConnect(1000);
1845  }
1846 
1847  return drv.release();
1848 }
1849 
1850 ///////////////////////////////////////////////////////////////////////////////
1851 #if defined(FTDS_IN_USE)
1852 
1853 # define CDbapiCtlibCF_ftdsVER_ctlib \
1854  NCBI_FTDS_VERSION_NAME2(CDbapiCtlibCF_ftds,_ctlib)
1855 # define DBAPI_RegisterDriver_FTDSVER \
1856  NCBI_FTDS_VERSION_NAME(DBAPI_RegisterDriver_FTDS)
1857 
1858 class CDbapiCtlibCF_ftdsVER_ctlib : public CDbapiCtlibCFBase
1859 {
1860 public:
1861  CDbapiCtlibCF_ftdsVER_ctlib(void)
1862  : CDbapiCtlibCFBase(ftdsVER)
1863  {
1864  }
1865 };
1866 
1867 #else
1868 
1870 {
1871 public:
1873  : CDbapiCtlibCFBase("ctlib")
1874  {
1875  }
1876 };
1877 
1878 #endif
1879 
1880 
1881 #ifdef FTDS_IN_USE
1882 } // namespace NCBI_NS_FTDS_CTLIB
1883 #endif
1884 
1885 
1886 ///////////////////////////////////////////////////////////////////////////////
1887 #if defined(FTDS_IN_USE)
1888 
1889 void
1890 NCBI_EntryPoint_xdbapi_ftdsVER(
1893 {
1895 }
1896 
1898 void
1899 DBAPI_RegisterDriver_FTDSVER(void)
1900 {
1901  RegisterEntryPoint<I_DriverContext>(NCBI_EntryPoint_xdbapi_ftdsVER);
1902 }
1903 
1904 
1905 #else // defined(FTDS_IN_USE)
1906 
1907 void
1911 {
1913 }
1914 
1916 void
1918 {
1919  RegisterEntryPoint<I_DriverContext>( NCBI_EntryPoint_xdbapi_ctlib );
1920 }
1921 
1922 
1923 #endif // defined(FTDS_IN_USE)
1924 
1926 
1927 
#define false
Definition: bool.h:36
CDBConnParams::
Definition: interfaces.hpp:258
CDBParams.
Definition: interfaces.hpp:154
static void SetMaxConnect(unsigned int max_connect)
static CDbapiConnMgr & Instance(void)
Get access to the class instance.
~CDbapiCtlibCFBase(void)
Definition: context.cpp:1751
virtual TInterface * CreateInstance(const string &driver=kEmptyStr, CVersionInfo version=NCBI_INTERFACE_VERSION(I_DriverContext), const TPluginManagerParamTree *params=0) const
Create instance of TDriver.
Definition: context.cpp:1757
CDbapiCtlibCFBase(const string &driver_name)
Definition: context.cpp:1745
Incapsulate compile time information such as __FILE__, __LINE__, NCBI_MODULE, current function.
Definition: ncbidiag.hpp:65
void Guard(resource_type &resource)
Manually force the guard to protect some other resource.
Definition: guard.hpp:175
void Release()
Manually force the resource to be released.
Definition: guard.hpp:166
CMutex –.
Definition: ncbimtx.hpp:749
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
int NofItems(void) const
Definition: pointer_pot.hpp:81
void Remove(int n)
Definition: pointer_pot.cpp:75
void Add(const TPotItem item, int check_4_unique=0)
Definition: pointer_pot.cpp:55
CRWLock –.
Definition: ncbimtx.hpp:953
Helper class for object allocation/deallocation.
CSafeStatic<>::
T & Get(void)
Create the variable if not created yet, return the reference.
CS_RETCODE Check(CS_RETCODE rc)
Definition: connection.cpp:458
CTLibContextRegistry(void)
Definition: context.cpp:129
void Remove(CTLibContext *ctx)
Definition: context.cpp:175
vector< CTLibContext * > m_Registry
Definition: context.cpp:121
void ClearAll(void)
Definition: context.cpp:191
static void StaticClearAll(void)
Definition: context.cpp:206
~CTLibContextRegistry(void)
Definition: context.cpp:145
bool ExitProcessIsPatched(void) const
Definition: context.cpp:111
void Add(CTLibContext *ctx)
Definition: context.cpp:162
static CTLibContextRegistry & Instance(void)
Definition: context.cpp:154
virtual bool IsAbleTo(ECapability cpb) const
Check if a driver is acle to provide necessary functionality.
Definition: context.cpp:900
bool m_ReusingContext
Definition: interfaces.hpp:349
virtual void CTLIB_SetLoginLoopDelay(CS_INT nof_sec)
Definition: context.cpp:1049
virtual void CTLIB_SetPacketSize(CS_INT packet_size)
Definition: context.cpp:1037
virtual unsigned int GetLoginTimeout(void) const
Get login timeout.
Definition: context.cpp:820
virtual bool SetLoginTimeout(unsigned int nof_secs=0)
Set login timeout.
Definition: context.cpp:743
CS_RETCODE Check(CS_RETCODE rc) const
Definition: context.cpp:712
virtual void CTLIB_SetHostName(const string &host_name)
Definition: context.cpp:1031
virtual bool SetTimeout(unsigned int nof_secs=0)
Set connection timeout.
Definition: context.cpp:760
unsigned int GetMaxConnect(void)
Definition: context.cpp:930
CTLibContextRegistry * m_Registry
Definition: interfaces.hpp:348
CS_CONTEXT * m_Context
Definition: interfaces.hpp:342
CS_INT m_LoginRetryCount
Definition: interfaces.hpp:345
virtual void CTLIB_SetLoginRetryCount(CS_INT n)
Definition: context.cpp:1043
static CS_RETCODE CS_PUBLIC CTLIB_cterr_handler(CS_CONTEXT *context, CS_CONNECTION *con, CS_CLIENTMSG *msg)
Definition: context.cpp:1206
bool x_SafeToFinalize(void) const
Definition: context.cpp:1014
virtual void CTLIB_SetApplicationName(const string &a_name)
Definition: context.cpp:1025
static CS_RETCODE CS_PUBLIC CTLIB_srverr_handler(CS_CONTEXT *context, CS_CONNECTION *con, CS_SERVERMSG *msg)
Definition: context.cpp:1425
CTLibContext(bool reuse_context=true, CS_INT version=GetCtlibTdsVersion())
Definition: context.cpp:561
virtual void InitApplicationName(void)
Explicitly auto-initialize the application name, if necessary.
Definition: context.cpp:798
virtual bool SetMaxBlobSize(size_t nof_bytes)
Set maximal size for BLOB data.
Definition: context.cpp:782
void x_AddToRegistry(void)
Definition: context.cpp:722
virtual void SetClientCharset(const string &charset)
Definition: context.cpp:1621
virtual ~CTLibContext(void)
Definition: context.cpp:695
void x_RemoveFromRegistry(void)
Definition: context.cpp:730
virtual string GetDriverName(void) const
Definition: context.cpp:870
virtual impl::CConnection * MakeIConnection(const CDBConnParams &params)
Definition: context.cpp:881
CRWLock & x_GetCtxLock(void) const
Definition: context.cpp:893
virtual CS_CONTEXT * CTLIB_GetContext(void) const
Definition: context.cpp:1055
CS_LOCALE * m_Locale
Definition: interfaces.hpp:343
bool SetMaxConnect(unsigned int num)
Set maximal number of open connections.
Definition: context.cpp:916
void x_SetRegistry(CTLibContextRegistry *registry)
Definition: context.cpp:738
void x_Close(bool delete_conn=true)
Definition: context.cpp:950
CS_INT m_PacketSize
Definition: interfaces.hpp:344
static CS_RETCODE CS_PUBLIC CTLIB_cserr_handler(CS_CONTEXT *context, CS_CLIENTMSG *msg)
Definition: context.cpp:1061
CS_INT m_LoginLoopDelay
Definition: interfaces.hpp:346
virtual unsigned int GetTimeout(void) const
Get connection timeout.
Definition: context.cpp:845
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
definition of a Culling tree
Definition: ncbi_tree.hpp:100
CVersionInfo –.
Command(CTL_Connection &ctl_conn)
Definition: context.cpp:438
~Command(void)
Definition: context.cpp:455
CS_COMMAND * m_Handle
Definition: interfaces.hpp:239
void Close(void)
Definition: context.cpp:544
const CTL_Connection & GetCTLConn(void) const
Definition: interfaces.hpp:223
bool Open(CS_INT type, CS_INT option, const string &arg=kEmptyCStr)
Definition: context.cpp:466
bool SendData(CS_VOID *buff, CS_INT buff_len)
Definition: context.cpp:496
CS_COMMAND * GetNativeHandle(void) const
Definition: interfaces.hpp:210
CS_RETCODE Fetch(void)
Definition: context.cpp:521
bool Send(void)
Definition: context.cpp:506
CS_RETCODE GetResults(CS_INT &res_type)
Definition: context.cpp:514
bool GetDataInfo(CS_IODESC &desc)
Definition: context.cpp:485
void Drop(void)
Definition: context.cpp:533
CS_CONNECTION * GetNativeHandle(void) const
Definition: interfaces.hpp:148
bool Drop(void)
Drop allocated connection.
Definition: context.cpp:246
CS_CONNECTION * m_Handle
Definition: interfaces.hpp:196
bool Cancel(void)
Definition: context.cpp:380
bool IsDead(void) const
Definition: interfaces.hpp:165
CS_RETCODE CheckWhileOpening(CS_RETCODE rc)
bool IsOpen_native(void)
Definition: context.cpp:418
bool Close(void)
Definition: context.cpp:362
const CTL_Connection & GetCTLConn(void) const
Definition: context.cpp:260
const CTLibContext & GetCTLContext(void) const
Definition: interfaces.hpp:180
bool IsOpen(void) const
Definition: interfaces.hpp:153
Connection(CTLibContext &context, CTL_Connection &ctl_conn)
Definition: context.cpp:216
bool Open(const CDBConnParams &params)
Definition: context.cpp:281
bool IsAlive(void)
Definition: context.cpp:399
CTLibContext * m_CTL_Context
Definition: interfaces.hpp:194
CTL_Connection * m_CTL_Conn
Definition: interfaces.hpp:195
~Connection(void) noexcept
Definition: context.cpp:233
void Handle(const CDBHandlerStack &handler)
void Accept(unique_ptr< CDB_Exception > &e)
bool HandleMessage(int severity, int msgnum, const string &message) const
const string & GetExtraMsg(void) const
virtual void SetHostName(const string &host_name)
Set host name.
size_t GetMaxBlobSize(void) const
const CDBHandlerStack & GetCtxHandlerStack(void) const
virtual bool SetTimeout(unsigned int nof_secs=0)
Set connection timeout.
static void ResetEnvSybase(void)
virtual string GetApplicationName(void) const
Return application name.
virtual bool SetMaxBlobSize(size_t nof_bytes)
Set maximal size for BLOB data.
virtual void SetClientCharset(const string &charset)
virtual CRWLock & x_GetCtxLock(void) const
virtual unsigned int GetLoginTimeout(void) const
Get login timeout.
const string & GetClientCharset(void) const
virtual void SetApplicationName(const string &app_name)
Set application name.
virtual bool SetLoginTimeout(unsigned int nof_secs=0)
Set login timeout.
virtual unsigned int GetTimeout(void) const
Get connection timeout.
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
#define option
#define CS_SERVERMSG_CB
Definition: cspublic.h:411
CS_RETCODE cs_ctx_alloc(CS_INT version, CS_CONTEXT **ctx)
Definition: cs.c:342
#define CS_FORCE_EXIT
Definition: cspublic.h:458
#define CS_CLIENTMSG_CB
Definition: cspublic.h:412
@ CS_TEXTLIMIT
Definition: cspublic.h:203
@ CS_MAX_CONNECT
Definition: cspublic.h:215
@ CS_SERVERADDR
Definition: cspublic.h:251
@ CS_LOGIN_TIMEOUT
Definition: cspublic.h:211
@ CS_USERDATA
Definition: cspublic.h:199
@ CS_CON_STATUS
Definition: cspublic.h:241
@ CS_LOGIN_STATUS
Definition: cspublic.h:191
@ CS_TIMEOUT
Definition: cspublic.h:213
#define CS_FAIL
Definition: cspublic.h:41
#define CS_FORCE_CLOSE
Definition: cspublic.h:459
#define CS_CANCEL_ATTN
Definition: cspublic.h:467
#define CS_VERSION_120
Definition: cspublic.h:448
#define CS_SV_API_FAIL
Definition: cspublic.h:529
#define CS_CANCEL_ALL
Definition: cspublic.h:466
CS_RETCODE cs_locale(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: cs.c:1024
CS_RETCODE cs_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: cs.c:400
#define CS_SV_INTERNAL_FAIL
Definition: cspublic.h:534
#define CS_SV_FATAL
Definition: cspublic.h:535
#define CS_SV_CONFIG_FAIL
Definition: cspublic.h:532
CS_RETCODE cs_loc_alloc(CS_CONTEXT *ctx, CS_LOCALE **locptr)
Definition: cs.c:997
CS_RETCODE cs_ctx_drop(CS_CONTEXT *ctx)
Definition: cs.c:385
#define CS_SYB_CHARSET
Definition: cspublic.h:510
#define CS_MESSAGE_CB
Definition: cspublic.h:419
#define CS_CONSTAT_CONNECTED
Definition: cspublic.h:308
#define CS_UNUSED
Definition: cspublic.h:425
#define CS_SET
Definition: cspublic.h:429
#define CS_TRUE
Definition: cspublic.h:722
#define CS_NO_LIMIT
Definition: cspublic.h:424
#define CS_SUCCEED
Definition: cspublic.h:40
#define CS_VERSION_110
Definition: cspublic.h:447
CS_RETCODE cs_ctx_global(CS_INT version, CS_CONTEXT **ctx)
Definition: cs.c:367
#define CS_SV_INFORM
Definition: cspublic.h:528
#define CS_VERSION_125
Definition: cspublic.h:449
#define CS_SV_RETRY_FAIL
Definition: cspublic.h:530
#define CS_VERSION_150
Definition: cspublic.h:450
CS_RETCODE cs_loc_drop(CS_CONTEXT *ctx, CS_LOCALE *locale)
Definition: cs.c:1012
#define CS_VERSION_100
Definition: cspublic.h:446
#define CS_GET
Definition: cspublic.h:428
#define CS_CONSTAT_DEAD
Definition: cspublic.h:309
Int4 CS_INT
Definition: cstypes.h:41
void CS_VOID
Definition: cstypes.h:53
CS_INT CS_RETCODE
Definition: cstypes.h:63
char CS_CHAR
Definition: cstypes.h:48
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
CS_CONTEXT * ctx
Definition: t0006.c:12
impl::CDBExceptionStorage & GetCTLExceptionStorage(void)
Definition: ctlib_utils.cpp:41
CS_RETCODE ct_command(CS_COMMAND *cmd, CS_INT type, const CS_VOID *buffer, CS_INT buflen, CS_INT option)
Definition: ct.c:760
CS_RETCODE ct_connect(CS_CONNECTION *con, CS_CHAR *servername, CS_INT snamelen)
Definition: ct.c:633
CS_RETCODE ct_results(CS_COMMAND *cmd, CS_INT *result_type)
Definition: ct.c:1172
CS_RETCODE ct_callback(CS_CONTEXT *ctx, CS_CONNECTION *con, CS_INT action, CS_INT type, CS_VOID *func)
Definition: ct.c:306
CS_RETCODE ct_fetch(CS_COMMAND *cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT *rows_read)
Definition: ct.c:1589
CS_RETCODE ct_cmd_drop(CS_COMMAND *cmd)
Definition: ct.c:1881
CS_RETCODE ct_cmd_alloc(CS_CONNECTION *con, CS_COMMAND **cmd)
Definition: ct.c:728
CS_RETCODE ct_con_alloc(CS_CONTEXT *ctx, CS_CONNECTION **con)
Definition: ct.c:273
CS_RETCODE ct_con_drop(CS_CONNECTION *con)
Definition: ct.c:1934
CS_RETCODE ct_close(CS_CONNECTION *con, CS_INT option)
Definition: ct.c:1923
CS_RETCODE ct_send(CS_COMMAND *cmd)
Definition: ct.c:913
CS_RETCODE ct_data_info(CS_COMMAND *cmd, CS_INT action, CS_INT colnum, CS_IODESC *iodesc)
Definition: ct.c:3051
CS_RETCODE ct_send_data(CS_COMMAND *cmd, CS_VOID *buffer, CS_INT buflen)
Definition: ct.c:2987
CS_RETCODE ct_cancel(CS_CONNECTION *conn, CS_COMMAND *cmd, CS_INT type)
Definition: ct.c:2201
CS_RETCODE ct_con_props(CS_CONNECTION *con, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len)
Definition: ct.c:351
CS_RETCODE ct_init(CS_CONTEXT *ctx, CS_INT version)
Definition: ct.c:260
CS_RETCODE ct_exit(CS_CONTEXT *ctx, CS_INT unused)
Definition: ct.c:252
CS_RETCODE ct_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: ct.c:2540
NCBI_PARAM_DECL(int, ctlib, TDS_VERSION)
CS_INT GetCtlibTdsVersion(int version)
Definition: context.cpp:1675
CDiagCompileInfo GetBlankCompileInfo(void)
Definition: context.cpp:76
NCBI_PARAM_DEF_EX(int, ctlib, TDS_VERSION, 125, eParam_NoThread, CTLIB_TDS_VERSION)
#define FTDS_VERSION_ERR_LEVEL
Definition: context.cpp:1672
static void PassException(unique_ptr< CDB_Exception > &ex, const string &server_name, const string &user_name, CS_INT severity, const CDBParams *params, ERetriable retriable, unsigned int rows_in_batch=0)
Definition: context.cpp:1136
static CS_RETCODE HandleConnStatus(CS_CONNECTION *conn, CS_CLIENTMSG *msg, const string &server_name, const string &user_name)
Definition: context.cpp:1159
#define NCBI_CTLIB_TDS_VERSION
Definition: context.cpp:1642
void NCBI_EntryPoint_xdbapi_ctlib(CPluginManager< I_DriverContext >::TDriverInfoList &info_list, CPluginManager< I_DriverContext >::EEntryPointRequest method)
Definition: context.cpp:1908
#define NCBI_CTLIB_TDS_FALLBACK_VERSION
Definition: context.cpp:1645
static CSafeStatic< CRWLock > s_CTLCtxLock(CSafeStaticLifeSpan::eLifeSpan_Long)
Static lock which will guard all thread-unsafe operations on most ctlib contexts and a handful of ctl...
typedef NCBI_PARAM_TYPE(ctlib, TDS_VERSION) TCtlibTdsVersion
ERetriable
Can the action be retried?
Definition: ncbimisc.hpp:167
@ eRetriable_Unknown
It is unknown if the action can succeed if retried.
Definition: ncbimisc.hpp:169
@ eRetriable_No
It makes no sense to retry the action.
Definition: ncbimisc.hpp:168
@ eRetriable_Yes
It makes sense to try again.
Definition: ncbimisc.hpp:170
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
void DBAPI_RegisterDriver_CTLIB(void)
Definition: context.cpp:1917
CConstRef< SContext > context
Definition: exception.hpp:172
#define DATABASE_DRIVER_ERROR(message, err_code)
Definition: exception.hpp:740
ECapability
Report if the driver supports this functionality.
virtual Uint4 GetHost(void) const =0
virtual string GetServerName(void) const =0
virtual Uint2 GetPort(void) const =0
virtual string GetUserName(void) const =0
#define _TRACE(message)
Definition: ncbidbg.hpp:122
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
#define DIAG_COMPILE_INFO
Make compile time diagnostic information object to use in CNcbiDiag and CException.
Definition: ncbidiag.hpp:170
#define NCBI_CURRENT_FUNCTION
Get current function name.
Definition: ncbidiag.hpp:142
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
const string & GetAppName(void) const
Get application name.
Definition: ncbidiag.cpp:1857
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
@ eDiag_Info
Informational message.
Definition: ncbidiag.hpp:651
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
@ eDiag_Critical
Critical error message.
Definition: ncbidiag.hpp:654
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_CATCH_ALL_X(err_subcode, message)
Definition: ncbiexpt.hpp:619
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
static void NCBI_EntryPointImpl(TDriverInfoList &info_list, EEntryPointRequest method)
Entry point implementation.
#define NCBI_INTERFACE_VERSION(iface)
Macro to construct CVersionInfo class using interface name (relies on CInterfaceVersion class)
list< SDriverInfo > TDriverInfoList
List of driver information.
EEntryPointRequest
Actions performed by the entry point.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static string PrintableString(const CTempString str, TPrintableMode mode=fNewLine_Quote|fNonAscii_Passthru)
Get a printable version of the specified string.
Definition: ncbistr.cpp:3949
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
#define NPOS
Definition: ncbistr.hpp:133
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5083
size_type find_first_not_of(const CTempString match, size_type pos=0) const
Find the first occurrence of any character not in the matching string within the current string,...
Definition: tempstr.hpp:553
TNodeList_CI SubNodeBegin(void) const
Return first const iterator on subnode list.
Definition: ncbi_tree.hpp:160
TNodeList::const_iterator TNodeList_CI
Definition: ncbi_tree.hpp:110
TNodeList_CI SubNodeEnd(void) const
Return last const iterator on subnode list.
Definition: ncbi_tree.hpp:166
TValue TValueType
Definition: ncbi_tree.hpp:102
@ eNonCompatible
major, minor does not match
#define NCBI_DBAPIDRIVER_CTLIB_EXPORT
Definition: ncbi_export.h:400
static COnExitProcess & Instance(void)
bool Add(TFunct funct)
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
if(yy_accept[yy_current_state])
yy_size_t n
static int version
Definition: mdb_load.c:29
constexpr bool empty(list< Ts... >) noexcept
void Check(const string &value)
string ConvertN2A(Uint4 host)
const struct ncbi::grid::netcache::search::fields::SIZE size
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
static int tds_version
Definition: bcp.c:59
void * TPotItem
Definition: pointer_pot.hpp:43
CS_CHAR osstring[1024]
Definition: cstypes.h:191
CS_INT sqlstatelen
Definition: cstypes.h:195
CS_INT severity
Definition: cstypes.h:186
CS_MSGNUM msgnumber
Definition: cstypes.h:187
CS_BYTE sqlstate[8]
Definition: cstypes.h:194
CS_INT osnumber
Definition: cstypes.h:190
CS_CHAR msgstring[1024]
Definition: cstypes.h:188
CS_INT osstringlen
Definition: cstypes.h:192
TDSCONTEXT * tds_ctx
Definition: ctlib.h:107
CS_CHAR proc[132]
Definition: cstypes.h:207
CS_CHAR text[1024]
Definition: cstypes.h:203
CS_MSGNUM msgnumber
Definition: cstypes.h:200
CS_INT line
Definition: cstypes.h:209
CS_INT sqlstatelen
Definition: cstypes.h:212
CS_BYTE sqlstate[8]
Definition: cstypes.h:211
CS_INT svrnlen
Definition: cstypes.h:206
CS_CHAR svrname[132]
Definition: cstypes.h:205
CS_INT severity
Definition: cstypes.h:202
CS_INT proclen
Definition: cstypes.h:208
CS_INT textlen
Definition: cstypes.h:204
int(* int_handler)(void *)
Definition: tds.h:1104
Definition: type.c:6
#define _ASSERT
Modified on Wed Nov 29 02:18:03 2023 by modify_doxy.py rev. 669887