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

Go to the SVN repository for this file.

1 /* $Id: dbapi_impl_context.cpp 98945 2023-01-25 18:36:58Z 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: Sergey Sikorskiy
27 *
28 */
29 
30 #include <ncbi_pch.hpp>
31 
37 #include <dbapi/error_codes.hpp>
38 
40 #include <corelib/ncbifile.hpp>
41 
42 #include <algorithm>
43 #include <set>
44 
45 
46 #if defined(NCBI_OS_MSWIN)
47 # include <winsock2.h>
48 #endif
49 
50 
52 
53 #define NCBI_USE_ERRCODE_X Dbapi_DrvrContext
54 
55 
57 
58 
59 namespace impl
60 {
61 
62 inline
63 static bool s_Matches(CConnection* conn, const string& pool_name,
64  const string& server_name)
65 {
66  if (pool_name.empty()) {
67  // There is no server name check here. We assume that a connection
68  // pool contains connections with appropriate server names only.
69  return conn->ServerName() == server_name
70  || conn->GetRequestedServer() == server_name;
71  } else {
72  return conn->PoolName() == pool_name;
73  }
74 }
75 
76 ///////////////////////////////////////////////////////////////////////////
77 // CDriverContext::
78 //
79 
81  m_PoolSem(0, 1),
82  m_LoginTimeout(0),
83  m_Timeout(0),
84  m_CancelTimeout(0),
85  m_MaxBlobSize(0),
86  m_ClientEncoding(eEncoding_ISO8859_1)
87 {
90 }
91 
93 {
94  try {
95  DeleteAllConn();
96  } STD_CATCH_ALL("CDriverContext::DeleteAllConn");
97 }
98 
99 void
100 CDriverContext::SetApplicationName(const string& app_name)
101 {
102  CWriteLockGuard guard(x_GetCtxLock());
103 
104  m_AppName = app_name;
105 }
106 
107 string
109 {
110  CReadLockGuard guard(x_GetCtxLock());
111 
112  return m_AppName;
113 }
114 
115 void
116 CDriverContext::SetHostName(const string& host_name)
117 {
118  CWriteLockGuard guard(x_GetCtxLock());
119 
120  m_HostName = host_name;
121 }
122 
123 string
125 {
126  CReadLockGuard guard(x_GetCtxLock());
127 
128  return m_HostName;
129 }
130 
131 unsigned int CDriverContext::GetLoginTimeout(void) const
132 {
133  CReadLockGuard guard(x_GetCtxLock());
134 
135  return m_LoginTimeout;
136 }
137 
138 bool CDriverContext::SetLoginTimeout (unsigned int nof_secs)
139 {
140  CWriteLockGuard guard(x_GetCtxLock());
141 
142  m_LoginTimeout = nof_secs;
143 
144  return true;
145 }
146 
147 unsigned int CDriverContext::GetTimeout(void) const
148 {
149  CReadLockGuard guard(x_GetCtxLock());
150 
151  return m_Timeout;
152 }
153 
154 bool CDriverContext::SetTimeout(unsigned int nof_secs)
155 {
156  bool success = true;
157  CWriteLockGuard guard(x_GetCtxLock());
158 
159  try {
160  m_Timeout = nof_secs;
161 
162  // We do not have to update query/connection timeout in context
163  // any more. Each connection can be updated explicitly now.
164  // UpdateConnTimeout();
165  } catch (...) {
166  success = false;
167  }
168 
169  return success;
170 }
171 
172 unsigned int CDriverContext::GetCancelTimeout(void) const
173 {
174  CReadLockGuard guard(x_GetCtxLock());
175 
176  return m_CancelTimeout;
177 }
178 
179 bool CDriverContext::SetCancelTimeout(unsigned int nof_secs)
180 {
181  bool success = true;
182  CWriteLockGuard guard(x_GetCtxLock());
183 
184  try {
185  m_CancelTimeout = nof_secs;
186  } catch (...) {
187  success = false;
188  }
189 
190  return success;
191 }
192 
193 bool CDriverContext::SetMaxBlobSize(size_t nof_bytes)
194 {
195  CWriteLockGuard guard(x_GetCtxLock());
196 
197  m_MaxBlobSize = nof_bytes;
198 
200 
201  return true;
202 }
203 
205  EOwnership ownership)
206 {
207  CWriteLockGuard guard(x_GetCtxLock());
208  m_CntxHandlers.Push(h, ownership);
209 }
210 
212 {
213  CWriteLockGuard guard(x_GetCtxLock());
214  m_CntxHandlers.Pop(h);
215 }
216 
218  EOwnership ownership)
219 {
220  CWriteLockGuard guard(x_GetCtxLock());
221  m_ConnHandlers.Push(h, ownership);
222 }
223 
225 {
226  CWriteLockGuard guard(x_GetCtxLock());
227  m_ConnHandlers.Pop(h);
228 
229  // Remove this handler from all connections
232  con = *it;
233  con->PopMsgHandler(h);
234  }
235 
236  ITERATE(TConnPool, it, m_InUse) {
237  con = *it;
238  con->PopMsgHandler(h);
239  }
240 }
241 
242 
244 {
245  DEFINE_STATIC_MUTEX(env_mtx);
246 
247  CMutexGuard mg(env_mtx);
249 
250  // If user forces his own Sybase client path using $RESET_SYBASE
251  // and $SYBASE -- use that unconditionally.
252  try {
253  if (env.Get("LC_ALL") == "POSIX") {
254  // Canonicalize, since locales.dat might list C but not POSIX.
255  env.Set("LC_ALL", "C");
256  }
257  if (!env.Get("SYBASE").empty()) {
258  string reset = env.Get("RESET_SYBASE");
259  if ( !reset.empty() && NStr::StringToBool(reset)) {
260  return;
261  }
262  }
263  // ...else try hardcoded paths
264  } catch (const CStringException&) {
265  // Conversion error -- try hardcoded paths too
266  }
267 
268  // User-set or default hardcoded path
269  if ( CDir(NCBI_GetSybasePath()).CheckAccess(CDirEntry::fRead) ) {
270  env.Set("SYBASE", NCBI_GetSybasePath());
271  return;
272  }
273 
274  // If NCBI_SetSybasePath() was used to set up the Sybase path, and it is
275  // not right, then use the very Sybase client against which the code was
276  // compiled
279  env.Set("SYBASE", NCBI_GetDefaultSybasePath());
280  }
281 
282  // Else, well, use whatever $SYBASE there is
283 }
284 
285 
286 void CDriverContext::x_Recycle(CConnection* conn, bool conn_reusable)
287 {
289 
290  TConnPool::iterator it = find(m_InUse.begin(), m_InUse.end(), conn);
291 
292  if (it != m_InUse.end()) {
293  m_InUse.erase(it);
294  }
295 
296 #ifdef NCBI_THREADS
297  CConnection** recipient = nullptr;
298  for (auto &consumer : m_PoolSemConsumers) {
299  if ( !consumer.selected
300  && (consumer.subject_is_pool
301  ? conn->PoolName() == consumer.subject
302  : s_Matches(conn, kEmptyStr, consumer.subject))) {
303  consumer.selected = true;
304  recipient = &consumer.conn;
305  // probably redundant, but ensures Post will work
306  m_PoolSem.TryWait();
307  m_PoolSem.Post();
308  break;
309  }
310  }
311 #endif
312 
313  bool keep = false;
314  if (conn_reusable && conn->IsOpeningFinished() && conn->IsValid()) {
315  keep = true;
316  // Tentatively; account for temporary overflow below, bearing
317  // in mind that that conn is already gone from m_InUse and not
318  // yet in m_NotInUse, and as such uncounted.
319  if (conn->m_PoolMaxSize <= m_InUse.size() + m_NotInUse.size()) {
320  unsigned int n;
321  if (conn->m_Pool.empty()) {
322  n = NofConnections(conn->m_RequestedServer);
323  } else {
324  n = NofConnections(kEmptyStr, conn->m_Pool);
325  }
326  if (n >= conn->m_PoolMaxSize) {
327  keep = false;
328  }
329  }
330 
331  if (keep && conn->m_ReuseCount + 1 > conn->m_PoolMaxConnUse) {
332  // CXX-4420: limit the number of time the connection is reused
333  keep = false;
334  }
335  }
336 
337  if (keep) {
338  if (conn->m_PoolIdleTimeParam.GetSign() != eNegative) {
339  CTime now(CTime::eCurrent);
340  conn->m_CleanupTime = now + conn->m_PoolIdleTimeParam;
341  }
342  m_NotInUse.push_back(conn);
343 #ifdef NCBI_THREADS
344  if (recipient != nullptr) {
345  *recipient = conn;
346  }
347 #endif
348  } else {
349  x_AdjustCounts(conn, -1);
350  delete conn;
351  }
352 
354 }
355 
356 
358 {
359  if (delta != 0 && conn->IsReusable()) {
361  string server_name = conn->GetServerName();
362  if (conn->Host() != 0 && server_name.find('@') == NPOS) {
363  server_name += '@' + ConvertN2A(conn->Host());
364  if (conn->Port() != 0) {
365  server_name += ':' + NStr::NumericToString(conn->Port());
366  }
367  }
368  _DEBUG_ARG(unsigned int pool_count =)
369  m_CountsByPool[conn->PoolName()][server_name] += delta;
370  _DEBUG_ARG(unsigned int service_count =)
371  m_CountsByService[conn->GetRequestedServer()][server_name] += delta;
372  _TRACE(server_name << " count += " << delta << " for pool "
373  << conn->PoolName() << " (" << pool_count << ") and service "
374  << conn->GetRequestedServer() << " (" << service_count << ')');
375  }
376 }
377 
378 
380  const string& name, TCounts* counts) const
381 {
382  CReadLockGuard guard(m_PoolLock);
383  auto it = main_map.find(name);
384  if (it == main_map.end()) {
385  counts->clear();
386  } else {
387  *counts = it->second;
388  }
389 }
390 
391 
392 void CDriverContext::CloseUnusedConnections(const string& srv_name,
393  const string& pool_name,
394  unsigned int max_closings)
395 {
397 
399 
400  // close all connections first
402  con = *it;
403 
404  if ( !srv_name.empty() && srv_name != con->ServerName()
405  && srv_name != con->GetRequestedServer() )
406  continue;
407  if((!pool_name.empty()) && pool_name.compare(con->PoolName())) continue;
408 
409  it = m_NotInUse.erase(it);
410  x_AdjustCounts(con, -1);
411  delete con;
412  if (--max_closings == 0) {
413  break;
414  }
415  }
416 }
417 
418 unsigned int CDriverContext::NofConnections(const TSvrRef& svr_ref,
419  const string& pool_name) const
420 {
421  CReadLockGuard guard(m_PoolLock);
422 
423  if ((!svr_ref || !svr_ref->IsValid()) && pool_name.empty()) {
424  return static_cast<unsigned int>(m_InUse.size() + m_NotInUse.size());
425  }
426 
427  string server;
428  Uint4 host = 0;
429  Uint2 port = 0;
430  if (svr_ref) {
431  host = svr_ref->GetHost();
432  port = svr_ref->GetPort();
433  if (host == 0)
434  server = svr_ref->GetName();
435  }
436 
437  const TConnPool* pools[] = {&m_NotInUse, &m_InUse};
438  int n = 0;
439  for (size_t i = 0; i < ArraySize(pools); ++i) {
440  ITERATE(TConnPool, it, (*pools[i])) {
441  TConnPool::value_type con = *it;
442  if(!server.empty()) {
443  if (server != con->ServerName()
444  && server != con->GetRequestedServer())
445  continue;
446  }
447  else if (host != 0) {
448  if (host != con->Host() || port != con->Port())
449  continue;
450  }
451  if((!pool_name.empty()) && pool_name.compare(con->PoolName())) continue;
452  ++n;
453  }
454  }
455 
456  return n;
457 }
458 
459 unsigned int CDriverContext::NofConnections(const string& srv_name,
460  const string& pool_name) const
461 {
462  TSvrRef svr_ref(new CDBServer(srv_name, 0, 0));
463  return NofConnections(svr_ref, pool_name);
464 }
465 
467  int delta)
468 {
469  connection->m_CleanupTime.Clear();
471  m_InUse.push_back(connection);
472  x_AdjustCounts(connection, delta);
473 
474  return new CDB_Connection(connection);
475 }
476 
479 {
480  if (params.GetParam("is_pooled") == "true") {
482 
483  string pool_name (params.GetParam("pool_name")),
484  server_name(params.GetServerName());
485 
487  CConnection* t_con(*it);
488  if (s_Matches(t_con, pool_name, server_name)) {
489  it = m_NotInUse.erase(it);
490  CDB_Connection* dbcon = MakeCDBConnection(t_con, 0);
491  if (dbcon->Refresh()) {
492  /* Future development ...
493  if (!params.GetDatabaseName().empty()) {
494  return SetDatabase(dbcon, params);
495  } else {
496  return dbcon;
497  }
498  */
499 
500  return dbcon;
501  }
502  else {
503  x_AdjustCounts(t_con, -1);
504  t_con->m_Reusable = false;
505  delete dbcon;
506  }
507  }
508  }
509 
510  // Connection should be created, but we can have limit on number of
511  // connections in the pool.
512  string pool_max_str(params.GetParam("pool_maxsize"));
513  if (!pool_max_str.empty() && pool_max_str != "default") {
514  int pool_max = NStr::StringToInt(pool_max_str);
515  if (pool_max != 0) {
516  int total_cnt = 0;
517  ITERATE(TConnPool, it, m_InUse) {
518  CConnection* t_con(*it);
519  if (s_Matches(t_con, pool_name, server_name)) {
520  ++total_cnt;
521  }
522  }
523  if (total_cnt >= pool_max) {
524 #ifdef NCBI_THREADS
525  string timeout_str(params.GetParam("pool_wait_time"));
526  double timeout_val = 0.0;
527  if ( !timeout_str.empty() && timeout_str != "default") {
528  timeout_val = NStr::StringToDouble(timeout_str);
529  }
530  CDeadline deadline{CTimeout(timeout_val)};
532  if (pool_name.empty()) {
533  subject = server_name;
534  } else {
535  subject = pool_name;
536  }
537  auto target = (m_PoolSemConsumers
538  .emplace(m_PoolSemConsumers.end(),
539  subject, !pool_name.empty()));
540  guard.Release();
541  bool timed_out = true;
542  bool relocked = false;
543  while (m_PoolSem.TryWait(deadline.GetRemainingTime())) {
544  guard.Guard(m_PoolLock);
545  relocked = true;
546  if (target->selected) {
547  timed_out = false;
548  for (const auto &it : m_PoolSemConsumers) {
549  if (&it != &*target && it.selected) {
550  m_PoolSem.TryWait();
551  m_PoolSem.Post();
552  break;
553  }
554  }
555  } else {
556  m_PoolSem.TryWait();
557  m_PoolSem.Post();
558  relocked = false;
559  guard.Release();
560  continue;
561  }
562  CConnection* t_con = NULL;
564  if (*it == target->conn) {
565  t_con = target->conn;
566  m_NotInUse.erase((++it).base());
567  break;
568  }
569  }
570  if (t_con != NULL) {
571  m_PoolSemConsumers.erase(target);
572  return MakeCDBConnection(t_con, 0);
573  }
574  break;
575  }
576  if ( !relocked ) {
577  guard.Guard(m_PoolLock);
578  }
579  m_PoolSemConsumers.erase(target);
580  if (timed_out)
581 #endif
582  if (params.GetParam("pool_allow_temp_overflow")
583  != "true") {
584  string msg = FORMAT("Connection pool full (size "
585  << pool_max << ") for "
586  << (pool_name.empty() ? server_name
587  : pool_name));
588  DATABASE_DRIVER_ERROR(msg, 200011);
589  }
590  }
591  }
592  }
593  }
594 
595  if (params.GetParam("do_not_connect") == "true") {
596  return NULL;
597  }
598 
599  // Precondition check.
600  if (!TDbapi_CanUseKerberos::GetDefault()
601  && (params.GetUserName().empty()
602  || params.GetPassword().empty()))
603  {
604  string err_msg("Insufficient credentials to connect.");
605 
606  if (params.GetUserName().empty()) {
607  err_msg += " User name has not been set.";
608  }
609  if (params.GetPassword().empty()) {
610  err_msg += " Password has not been set.";
611  }
612 
613  DATABASE_DRIVER_ERROR( err_msg, 200010 );
614  }
615 
616  CConnection* t_con = MakeIConnection(params);
617 
618  return MakeCDBConnection(t_con, 1);
619 }
620 
621 void
623 {
625  // close all connections first
627  x_AdjustCounts(*it, -1);
628  delete *it;
629  }
630  m_NotInUse.clear();
631 
632  ITERATE(TConnPool, it, m_InUse) {
633  (*it)->Close();
634  }
635 }
636 
637 void
639 {
641  // close all connections first
643  x_AdjustCounts(*it, -1);
644  delete *it;
645  }
646  m_NotInUse.clear();
647 
648  ITERATE(TConnPool, it, m_InUse) {
649  x_AdjustCounts(*it, -1);
650  delete *it;
651  }
652  m_InUse.clear();
653 }
654 
655 
657 {
658 public:
660  : m_Other(other)
661  {
662  // Override what is set in CDBConnParamsBase constructor
663  SetParam("secure_login", kEmptyStr);
664  SetParam("is_pooled", kEmptyStr);
665  SetParam("do_not_connect", kEmptyStr);
666  }
667 
669  {}
670 
671  virtual Uint4 GetProtocolVersion(void) const
672  {
673  return m_Other.GetProtocolVersion();
674  }
675 
676  virtual EEncoding GetEncoding(void) const
677  {
678  return m_Other.GetEncoding();
679  }
680 
681  virtual string GetServerName(void) const
682  {
684  }
685 
686  virtual string GetDatabaseName(void) const
687  {
689  }
690 
691  virtual string GetUserName(void) const
692  {
694  }
695 
696  virtual string GetPassword(void) const
697  {
699  }
700 
701  virtual EServerType GetServerType(void) const
702  {
703  return m_Other.GetServerType();
704  }
705 
706  virtual Uint4 GetHost(void) const
707  {
708  return m_Other.GetHost();
709  }
710 
711  virtual Uint2 GetPort(void) const
712  {
713  return m_Other.GetPort();
714  }
715 
717  {
718  return m_Other.GetConnValidator();
719  }
720 
721  virtual string GetParam(const string& key) const
722  {
724  if (result.empty())
725  return m_Other.GetParam(key);
726  else
727  return result;
728  }
729 
735 
736 private:
738 };
739 
740 
742 {
743  string server_name;
744  string user_name;
745  string db_name;
746  string password;
747 
748  SLoginData(const string& sn, const string& un,
749  const string& dn, const string& pass)
750  : server_name(sn), user_name(un), db_name(dn), password(pass)
751  {}
752 
753  bool operator< (const SLoginData& right) const
754  {
755  if (server_name != right.server_name)
756  return server_name < right.server_name;
757  else if (user_name != right.user_name)
758  return user_name < right.user_name;
759  else if (db_name != right.db_name)
760  return db_name < right.db_name;
761  else
762  return password < right.password;
763  }
764 };
765 
766 
767 static void
768 s_TransformLoginData(string& server_name, string& user_name,
769  string& db_name, string& password)
770 {
771  if (!TDbapi_ConnUseEncryptData::GetDefault())
772  return;
773 
774  string app_name = CNcbiApplication::Instance()->GetProgramDisplayName();
775  set<SLoginData> visited;
777 
778  visited.insert(SLoginData(server_name, user_name, db_name, password));
779  for (;;) {
780  string res_name = app_name;
781  if (!user_name.empty()) {
782  res_name += "/";
783  res_name += user_name;
784  }
785  if (!server_name.empty()) {
786  res_name += "@";
787  res_name += server_name;
788  }
789  if (!db_name.empty()) {
790  res_name += ":";
791  res_name += db_name;
792  }
793  const CNcbiResourceInfo& info
794  = res_file.GetResourceInfo(res_name, password);
795  if (!info)
796  break;
797 
798  password = info.GetValue();
799  typedef CNcbiResourceInfo::TExtraValuesMap TExtraMap;
800  typedef TExtraMap::const_iterator TExtraMapIt;
801  const TExtraMap& extra = info.GetExtraValues().GetPairs();
802 
803  TExtraMapIt it = extra.find("server");
804  if (it != extra.end())
805  server_name = it->second;
806  it = extra.find("username");
807  if (it != extra.end())
808  user_name = it->second;
809  it = extra.find("database");
810  if (it != extra.end())
811  db_name = it->second;
812 
813  if (!visited.insert(
814  SLoginData(server_name, user_name, db_name, password)).second)
815  {
817  "Circular dependency inside resources info file.", 100012);
818  }
819  }
820 }
821 
822 
823 void
825 {
826  flags = 0;
827  server.clear();
828  port.clear();
829  database.clear();
830  username.clear();
831  password.clear();
832  login_timeout.clear();
833  io_timeout.clear();
834  single_server.clear();
835  is_pooled.clear();
836  pool_name.clear();
837  pool_maxsize.clear();
838  pool_idle_time.clear();
839  pool_wait_time.clear();
840  pool_allow_temp_overflow.clear();
841  pool_max_conn_use.clear();
842  args.clear();
843 }
844 
845 void
846 CDriverContext::ReadDBConfParams(const string& service_name,
847  SDBConfParams* params)
848 {
849  params->Clear();
850  if (service_name.empty())
851  return;
852 
854  if (!app)
855  return;
856 
857  const IRegistry& reg = app->GetConfig();
858  string section_name(service_name);
859  section_name.append(1, '.');
860  section_name.append("dbservice");
861  if (!reg.HasEntry(section_name, kEmptyStr))
862  return;
863 
864  if (reg.HasEntry(section_name, "service", IRegistry::fCountCleared)) {
865  params->flags += SDBConfParams::fServerSet;
866  params->server = reg.Get(section_name, "service");
867  }
868  if (reg.HasEntry(section_name, "port", IRegistry::fCountCleared)) {
869  params->flags += SDBConfParams::fPortSet;
870  params->port = reg.Get(section_name, "port");
871  }
872  if (reg.HasEntry(section_name, "database", IRegistry::fCountCleared)) {
874  params->database = reg.Get(section_name, "database");
875  }
876  if (reg.HasEntry(section_name, "username", IRegistry::fCountCleared)) {
878  params->username = reg.Get(section_name, "username");
879  }
880  if (reg.HasEntry(section_name, "password_key", IRegistry::fCountCleared)) {
882  params->password_key_id = reg.Get(section_name, "password_key");
883  }
884  if (reg.HasEntry(section_name, "password", IRegistry::fCountCleared)) {
886  params->password = reg.Get(section_name, "password");
887  if (CNcbiEncrypt::IsEncrypted(params->password)) {
888  try {
889  params->password = CNcbiEncrypt::Decrypt(params->password);
890  } NCBI_CATCH("Password decryption for " + service_name);
891  } else if (params->password_key_id.empty()) {
893  << "Using unencrypted password for " + service_name);
894  }
895  }
896  if (reg.HasEntry(section_name, "password_file",
898  // password and password_file are mutually exclusive, but only SDBAPI
899  // actually honors the latter, so it will take care of throwing
900  // exceptions as necessary.
902  params->password_file = reg.Get(section_name, "password_file");
903  }
904  if (reg.HasEntry(section_name, "login_timeout", IRegistry::fCountCleared)) {
906  params->login_timeout = reg.Get(section_name, "login_timeout");
907  }
908  if (reg.HasEntry(section_name, "io_timeout", IRegistry::fCountCleared)) {
910  params->io_timeout = reg.Get(section_name, "io_timeout");
911  }
912  if (reg.HasEntry(section_name, "cancel_timeout", IRegistry::fCountCleared)) {
914  params->cancel_timeout = reg.Get(section_name, "cancel_timeout");
915  }
916  if (reg.HasEntry(section_name, "exclusive_server", IRegistry::fCountCleared)) {
918  params->single_server = reg.Get(section_name, "exclusive_server");
919  }
920  if (reg.HasEntry(section_name, "use_conn_pool", IRegistry::fCountCleared)) {
922  params->is_pooled = reg.Get(section_name, "use_conn_pool");
923  params->pool_name = section_name;
924  params->pool_name.append(1, '.');
925  params->pool_name.append("pool");
926  }
927  if (reg.HasEntry(section_name, "conn_pool_name", IRegistry::fCountCleared)) {
928  // params->flags += SDBConfParams::fPoolNameSet;
929  params->pool_name = reg.Get(section_name, "conn_pool_name");
930  }
931  if (reg.HasEntry(section_name, "conn_pool_minsize", IRegistry::fCountCleared)) {
933  params->pool_minsize = reg.Get(section_name, "conn_pool_minsize");
934  }
935  if (reg.HasEntry(section_name, "conn_pool_maxsize", IRegistry::fCountCleared)) {
937  params->pool_maxsize = reg.Get(section_name, "conn_pool_maxsize");
938  }
939  if (reg.HasEntry(section_name, "conn_pool_idle_time",
942  params->pool_idle_time = reg.Get(section_name, "conn_pool_idle_time");
943  }
944  if (reg.HasEntry(section_name, "conn_pool_wait_time",
947  params->pool_wait_time = reg.Get(section_name, "conn_pool_wait_time");
948  }
949  if (reg.HasEntry(section_name, "conn_pool_allow_temp_overflow",
953  = reg.Get(section_name, "conn_pool_allow_temp_overflow");
954  }
955  if (reg.HasEntry(section_name, "continue_after_raiserror",
959  = reg.Get(section_name, "continue_after_raiserror");
960  }
961  if (reg.HasEntry(section_name, "conn_pool_max_conn_use",
964  params->pool_max_conn_use
965  = reg.Get(section_name, "conn_pool_max_conn_use");
966  }
967  if (reg.HasEntry(section_name, "log_minor_messages",
970  params->log_minor_messages
971  = reg.Get(section_name, "log_minor_messages");
972  }
973  if (reg.HasEntry(section_name, "args", IRegistry::fCountCleared)) {
974  params->flags += SDBConfParams::fArgsSet;
975  params->args = reg.Get(section_name, "args");
976  }
977 }
978 
979 bool
981 {
983 
984  string pool_min_str = params.GetParam("pool_minsize");
985  if (pool_min_str.empty() || pool_min_str == "default")
986  return true;
987  int pool_min = NStr::StringToInt(pool_min_str);
988  if (pool_min <= 0)
989  return true;
990 
991  string pool_name = params.GetParam("pool_name"),
992  server_name = params.GetServerName();
993  int total_cnt = 0;
994  ITERATE(TConnPool, it, m_InUse) {
995  CConnection* t_con(*it);
996  if (t_con->IsReusable() && s_Matches(t_con, pool_name, server_name)
997  && t_con->IsValid() && t_con->IsAlive())
998  {
999  ++total_cnt;
1000  }
1001  }
1002  ITERATE(TConnPool, it, m_NotInUse) {
1003  CConnection* t_con(*it);
1004  if (t_con->IsReusable() && s_Matches(t_con, pool_name, server_name)
1005  && t_con->IsAlive())
1006  {
1007  ++total_cnt;
1008  }
1009  }
1010  guard.Release();
1011  vector< AutoPtr<CDB_Connection> > conns(pool_min);
1012  for (int i = total_cnt; i < pool_min; ++i) {
1013  try {
1014  conns.push_back(MakeConnection(params));
1015  }
1016  catch (CDB_Exception& ex) {
1017  ERR_POST_X(1, "Error filling connection pool: " << ex);
1018  return false;
1019  }
1020  }
1021  return true;
1022 }
1023 
1026 {
1027  CMakeConnActualParams act_params(params);
1028 
1029  SDBConfParams conf_params;
1030  conf_params.Clear();
1031  if (params.GetParam("do_not_read_conf") != "true") {
1032  ReadDBConfParams(params.GetServerName(), &conf_params);
1033  }
1034 
1035  unique_ptr<CDB_Connection> t_con;
1036  {
1037  string server_name = (conf_params.IsServerSet()? conf_params.server:
1038  params.GetServerName());
1039  string user_name = (conf_params.IsUsernameSet()? conf_params.username:
1040  params.GetUserName());
1041  string db_name = (conf_params.IsDatabaseSet()? conf_params.database:
1042  params.GetDatabaseName());
1043  string password = (conf_params.IsPasswordSet()? conf_params.password:
1044  params.GetPassword());
1047  auto cfactory
1048  = dynamic_cast<const CDBConnectionFactory*>(
1049  factory.GetPointerOrNull());
1050  unsigned int timeout;
1051  if (cfactory != nullptr) {
1052  timeout = cfactory->GetLoginTimeout();
1053  } else if (conf_params.IsLoginTimeoutSet()) {
1054  if (conf_params.login_timeout.empty()) {
1055  timeout = 0;
1056  } else {
1057  NStr::StringToNumeric(conf_params.login_timeout, &timeout);
1058  }
1059  } else {
1060  string value(params.GetParam("login_timeout"));
1061  if (value == "default") {
1062  timeout = 0;
1063  } else if (!value.empty()) {
1064  NStr::StringToNumeric(value, &timeout);
1065  } else {
1066  timeout = GetLoginTimeout();
1067  }
1068  }
1069  if (timeout == 0 && cfactory != nullptr) {
1070  timeout = 30;
1071  }
1072  act_params.SetParam("login_timeout", NStr::NumericToString(timeout));
1073 
1074  if (conf_params.IsIOTimeoutSet()) {
1075  if (conf_params.io_timeout.empty()) {
1076  timeout = 0;
1077  } else {
1078  NStr::StringToNumeric(conf_params.io_timeout, &timeout);
1079  }
1080  } else {
1081  string value(params.GetParam("timeout"));
1082  if (value == "default") {
1083  timeout = 0;
1084  } else if (!value.empty()) {
1085  NStr::StringToNumeric(value, &timeout);
1086  } else {
1087  timeout = GetTimeout();
1088  }
1089  }
1090  if (cfactory != nullptr) {
1091  auto validation_timeout = cfactory->GetConnectionTimeout();
1092  if (validation_timeout == 0) {
1093  validation_timeout = timeout ? timeout : 30;
1094  }
1095  act_params.SetParam("timeout",
1096  NStr::NumericToString(validation_timeout));
1097  } else {
1098  act_params.SetParam("timeout", NStr::NumericToString(timeout));
1099  }
1100  if (conf_params.IsCancelTimeoutSet()) {
1101  if (conf_params.cancel_timeout.empty()) {
1102  SetCancelTimeout(0);
1103  }
1104  else {
1106  }
1107  }
1108  else {
1109  string value(params.GetParam("cancel_timeout"));
1110  if (value == "default") {
1111  SetCancelTimeout(10);
1112  }
1113  else if (!value.empty()) {
1115  }
1116  }
1117  if (conf_params.IsSingleServerSet()) {
1118  if (conf_params.single_server.empty()) {
1119  act_params.SetParam("single_server", "true");
1120  }
1121  else {
1122  act_params.SetParam("single_server",
1124  conf_params.single_server)));
1125  }
1126  }
1127  else if (params.GetParam("single_server") == "default") {
1128  act_params.SetParam("single_server", "true");
1129  }
1130  if (conf_params.IsPooledSet()) {
1131  if (conf_params.is_pooled.empty()) {
1132  act_params.SetParam("is_pooled", "false");
1133  }
1134  else {
1135  act_params.SetParam("is_pooled",
1137  conf_params.is_pooled)));
1138  act_params.SetParam("pool_name", conf_params.pool_name);
1139  }
1140  }
1141  else if (params.GetParam("is_pooled") == "default") {
1142  act_params.SetParam("is_pooled", "false");
1143  }
1144  if (conf_params.IsPoolMinSizeSet())
1145  act_params.SetParam("pool_minsize", conf_params.pool_minsize);
1146  else if (params.GetParam("pool_minsize") == "default") {
1147  act_params.SetParam("pool_minsize", "0");
1148  }
1149  if (conf_params.IsPoolMaxSizeSet())
1150  act_params.SetParam("pool_maxsize", conf_params.pool_maxsize);
1151  else if (params.GetParam("pool_maxsize") == "default") {
1152  act_params.SetParam("pool_maxsize", "");
1153  }
1154  if (conf_params.IsPoolIdleTimeSet())
1155  act_params.SetParam("pool_idle_time", conf_params.pool_idle_time);
1156  else if (params.GetParam("pool_idle_time") == "default") {
1157  act_params.SetParam("pool_idle_time", "");
1158  }
1159  if (conf_params.IsPoolWaitTimeSet())
1160  act_params.SetParam("pool_wait_time", conf_params.pool_wait_time);
1161  else if (params.GetParam("pool_wait_time") == "default") {
1162  act_params.SetParam("pool_wait_time", "0");
1163  }
1164  if (conf_params.IsPoolAllowTempOverflowSet()) {
1165  if (conf_params.pool_allow_temp_overflow.empty()) {
1166  act_params.SetParam("pool_allow_temp_overflow", "false");
1167  }
1168  else {
1169  act_params.SetParam
1170  ("pool_allow_temp_overflow",
1173  conf_params.pool_allow_temp_overflow)));
1174  }
1175  }
1176  else if (params.GetParam("pool_allow_temp_overflow") == "default") {
1177  act_params.SetParam("pool_allow_temp_overflow", "false");
1178  }
1179  if (conf_params.IsPoolMaxConnUseSet())
1180  act_params.SetParam("pool_max_conn_use",
1181  conf_params.pool_max_conn_use);
1182  else if (params.GetParam("pool_max_conn_use") == "default") {
1183  act_params.SetParam("pool_max_conn_use", "0");
1184  }
1185  if (conf_params.IsContinueAfterRaiserrorSet()) {
1186  if (conf_params.continue_after_raiserror.empty()) {
1187  act_params.SetParam("continue_after_raiserror", "false");
1188  }
1189  else {
1190  act_params.SetParam
1191  ("continue_after_raiserror",
1194  conf_params.continue_after_raiserror)));
1195  }
1196  }
1197  else if (params.GetParam("continue_after_raiserror") == "default") {
1198  act_params.SetParam("continue_after_raiserror", "false");
1199  }
1200  if (conf_params.IsLogMinorMessagesSet()) {
1201  if (conf_params.log_minor_messages.empty()) {
1202  act_params.SetParam("log_minor_messages", "false");
1203  }
1204  else {
1205  act_params.SetParam
1206  ("log_minor_messages",
1209  conf_params.log_minor_messages)));
1210  }
1211  }
1212  else if (params.GetParam("log_minor_messages") == "default") {
1213  act_params.SetParam("log_minor_messages", "false");
1214  }
1215 
1216  s_TransformLoginData(server_name, user_name, db_name, password);
1217  act_params.SetServerName(server_name);
1218  act_params.SetUserName(user_name);
1219  act_params.SetDatabaseName(db_name);
1220  act_params.SetPassword(password);
1221 
1223  t_con.reset(factory->MakeDBConnection(*this, act_params, expts));
1224 
1225  if (t_con.get() == NULL) {
1226  if (act_params.GetParam("do_not_connect") == "true") {
1227  return NULL;
1228  }
1229 
1230  string err;
1231  err += "Cannot connect to the server '" + act_params.GetServerName();
1232  err += "' as user '" + act_params.GetUserName() + "'";
1233 
1234  CDB_ClientEx ex(DIAG_COMPILE_INFO, NULL, err, eDiag_Error, 100011);
1235  ex.SetRetriable(eRetriable_No);
1237  {
1238  ex.AddPrevious(*it);
1239  }
1240  throw ex;
1241  }
1242 
1243  t_con->SetTimeout(timeout);
1244  // Set database ...
1245  t_con->SetDatabaseName(act_params.GetDatabaseName());
1246 
1247  }
1248 
1249  return t_con.release();
1250 }
1251 
1252 size_t CDriverContext::CloseConnsForPool(const string& pool_name,
1253  Uint4 keep_host_ip, Uint2 keep_port)
1254 {
1255  size_t invalidated_count = 0;
1256  CWriteLockGuard guard(m_PoolLock);
1257 
1258  ITERATE(TConnPool, it, m_InUse) {
1259  CConnection* t_con(*it);
1260  if (t_con->IsReusable() && pool_name == t_con->PoolName()) {
1261  if (t_con->Host() != keep_host_ip || t_con->Port() != keep_port) {
1262  t_con->Invalidate();
1263  ++invalidated_count;
1264  }
1265  }
1266  }
1268  CConnection* t_con(*it);
1269  if (t_con->IsReusable() && pool_name == t_con->PoolName()) {
1270  if (t_con->Host() != keep_host_ip || t_con->Port() != keep_port) {
1271  m_NotInUse.erase(it);
1272  x_AdjustCounts(t_con, -1);
1273  delete t_con;
1274  }
1275  }
1276  }
1277  return invalidated_count;
1278 }
1279 
1280 
1281 void CDriverContext::CloseOldIdleConns(unsigned int max_closings,
1282  const string& pool_name)
1283 {
1284  CWriteLockGuard guard(m_PoolLock);
1285  if (max_closings == 0) {
1286  return;
1287  }
1288 
1289  set<string> at_min_by_pool, at_min_by_server;
1290  CTime now(CTime::eCurrent);
1292  const string& pool_name_2 = (*it)->PoolName();
1293  set<string>& at_min
1294  = pool_name_2.empty() ? at_min_by_server : at_min_by_pool;
1295  if (pool_name_2.empty()) {
1296  if ( !pool_name.empty()
1297  || at_min.find((*it)->GetRequestedServer()) != at_min.end()) {
1298  continue;
1299  }
1300  } else if (( !pool_name.empty() && pool_name != pool_name_2)
1301  || at_min.find(pool_name_2) != at_min.end()) {
1302  continue;
1303  }
1304  if ((*it)->m_CleanupTime.IsEmpty() || (*it)->m_CleanupTime > now) {
1305  continue;
1306  }
1307  unsigned int n;
1308  if (pool_name_2.empty()) {
1309  n = NofConnections((*it)->GetRequestedServer());
1310  } else {
1311  n = NofConnections(TSvrRef(), pool_name_2);
1312  }
1313  if (n > (*it)->m_PoolMinSize) {
1314  x_AdjustCounts(*it, -1);
1315  delete *it;
1316  m_NotInUse.erase(it);
1317  if (--max_closings == 0) {
1318  break;
1319  }
1320  } else {
1321  at_min.insert(pool_name_2);
1322  }
1323  }
1324 }
1325 
1326 
1328 {
1329  if (impl) {
1330  impl->ReleaseInterface();
1331  x_Recycle(impl, impl->IsReusable());
1332  }
1333 }
1334 
1335 void CDriverContext::SetClientCharset(const string& charset)
1336 {
1337  CWriteLockGuard guard(x_GetCtxLock());
1338 
1339  m_ClientCharset = charset;
1341 
1342  if (NStr::CompareNocase(charset, "UTF-8") == 0 ||
1343  NStr::CompareNocase(charset, "UTF8") == 0) {
1345  } else if (NStr::CompareNocase(charset, "Ascii") == 0) {
1347  } else if (NStr::CompareNocase(charset, "ISO8859_1") == 0 ||
1348  NStr::CompareNocase(charset, "ISO8859-1") == 0
1349  ) {
1351  } else if (NStr::CompareNocase(charset, "Windows_1252") == 0 ||
1352  NStr::CompareNocase(charset, "Windows-1252") == 0) {
1354  }
1355 }
1356 
1358 {
1359  // Do not protect this method. It is already protected.
1360 
1361  ITERATE(TConnPool, it, m_NotInUse) {
1362  CConnection* t_con = *it;
1363  if (!t_con) continue;
1364 
1365  t_con->SetTimeout(GetTimeout());
1366  }
1367 
1368  ITERATE(TConnPool, it, m_InUse) {
1369  CConnection* t_con = *it;
1370  if (!t_con) continue;
1371 
1372  t_con->SetTimeout(GetTimeout());
1373  }
1374 }
1375 
1376 
1378 {
1379  // Do not protect this method. It is protected.
1380 
1381  ITERATE(TConnPool, it, m_NotInUse) {
1382  CConnection* t_con = *it;
1383  if (!t_con) continue;
1384 
1385  t_con->SetBlobSize(GetMaxBlobSize());
1386  }
1387 
1388  ITERATE(TConnPool, it, m_InUse) {
1389  CConnection* t_con = *it;
1390  if (!t_con) continue;
1391 
1392  t_con->SetBlobSize(GetMaxBlobSize());
1393  }
1394 }
1395 
1396 
1397 ///////////////////////////////////////////////////////////////////////////
1399 {
1400 #if defined(NCBI_OS_MSWIN)
1401  WSADATA wsaData;
1402  if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
1403  {
1404  DATABASE_DRIVER_ERROR( "winsock initialization failed", 200001 );
1405  }
1406 #endif
1407 }
1408 
1410 {
1411 #if defined(NCBI_OS_MSWIN)
1412  WSACleanup();
1413 #endif
1414 }
1415 
1416 } // namespace impl
1417 
1419 
1420 
CDBConnParams::
Definition: interfaces.hpp:258
unsigned int GetLoginTimeout(void) const
IDBServiceMapper.
Uint2 GetPort(void) const
const string & GetName(void) const
bool IsValid(void) const
Uint4 GetHost(void) const
CDB_Exception –.
Definition: exception.hpp:118
CRef< IDBConnectionFactory > GetConnectionFactory(void) const
Retrieve a connection factory.
static CDbapiConnMgr & Instance(void)
Get access to the class instance.
CDeadline.
Definition: ncbitime.hpp:1830
CDir –.
Definition: ncbifile.hpp:1695
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
static CNcbiApplication * Instance(void)
Singleton method.
Definition: ncbiapp.cpp:244
static bool IsEncrypted(const string &data)
Check if the string contains valid encrypted data.
static string Decrypt(const string &encrypted_string)
Decrypt a string using the matching key found in the NCBI keys files.
CNcbiEnvironment –.
Definition: ncbienv.hpp:104
Class for handling resource info files.
static string GetDefaultFileName(void)
Get default resource info file location (/etc/ncbi/.info).
const CNcbiResourceInfo & GetResourceInfo(const string &res_name, const string &pwd) const
Get read-only resource info for the given name.
Class for storing encrypted resource information.
CStringException –.
Definition: ncbistr.hpp:4505
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
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
virtual CDB_Connection * MakeDBConnection(I_DriverContext &ctx, const CDBConnParams &params, CDB_UserHandler::TExceptions &exceptions)=0
Create new connection object for the given context and connection attributes.
IRegistry –.
Definition: ncbireg.hpp:73
virtual void SetTimeout(size_t nof_secs)=0
virtual void SetBlobSize(size_t nof_bytes)
bool IsReusable(void) const
Check if this connection is a reusable one.
virtual bool IsAlive(void)=0
Check out if connection is alive (this function doesn't ping the server, it just checks the status of...
const string & PoolName(void) const
Find out which connection pool this connection belongs to.
impl::CDBConnParamsBase::
virtual string GetPassword(void) const
virtual string GetDatabaseName(void) const
virtual string GetUserName(void) const
void SetUserName(const string &name)
virtual string GetParam(const string &key) const
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
void SetParam(const string &key, const string &value)
void SetServerName(const string &name)
void SetPassword(const string &passwd)
virtual string GetServerName(void) const
void SetDatabaseName(const string &name)
void Pop(CDB_UserHandler *h, bool last=true)
void Push(CDB_UserHandler *h, EOwnership ownership=eNoOwnership)
virtual void PopDefConnMsgHandler(CDB_UserHandler *h)
Remove `per-connection' mess. handler "h" and all above it in the stack.
virtual void PushDefConnMsgHandler(CDB_UserHandler *h, EOwnership ownership=eNoOwnership)
Add `per-connection' err.message handler "h" to the stack of default handlers which are inherited by ...
CDBHandlerStack m_ConnHandlers
Stacks of `per-connection' err.message handlers.
void x_AdjustCounts(const CConnection *conn, int delta)
virtual CDB_Connection * MakeConnection(const CDBConnParams &params)
Create connection object using Load Balancer / connection factory.
size_t CloseConnsForPool(const string &pool_name, Uint4 keep_host_ip=0, Uint2 keep_port=0)
virtual void SetHostName(const string &host_name)
Set host name.
virtual void PushCntxMsgHandler(CDB_UserHandler *h, EOwnership ownership=eNoOwnership)
Add message handler "h" to process 'context-wide' (not bound to any particular connection) error mess...
list< SConsumer > m_PoolSemConsumers
void ReadDBConfParams(const string &service_name, SDBConfParams *params)
size_t GetMaxBlobSize(void) const
CDBHandlerStack m_CntxHandlers
Stack of `per-context' err.message handlers.
virtual string GetHostName(void) const
Get host name.
bool SatisfyPoolMinimum(const CDBConnParams &params)
void x_Recycle(CConnection *conn, bool conn_reusable)
Return unused connection "conn" to the driver context for future reuse (if "conn_reusable" is TRUE) o...
virtual unsigned int GetCancelTimeout(void) const
virtual unsigned int NofConnections(const string &srv_name="", const string &pool_name="") const
Return number of currently open connections in this context.
virtual bool SetTimeout(unsigned int nof_secs=0)
Set connection timeout.
static void ResetEnvSybase(void)
void UpdateConnMaxBlobSize(void) const
TConnPool m_NotInUse
Unused(reserve) connections.
virtual string GetApplicationName(void) const
Return application name.
virtual void PopCntxMsgHandler(CDB_UserHandler *h)
Remove message handler "h" and all handlers above it in the stack.
CDB_Connection * MakePooledConnection(const CDBConnParams &params)
Create connection object WITHOUT using of Load Balancer / connection factory.
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
void CloseOldIdleConns(unsigned int max_closings, const string &pool_name=kEmptyStr)
virtual unsigned int GetLoginTimeout(void) const
Get login timeout.
virtual CConnection * MakeIConnection(const CDBConnParams &params)=0
virtual void SetApplicationName(const string &app_name)
Set application name.
virtual bool SetLoginTimeout(unsigned int nof_secs=0)
Set login timeout.
CDB_Connection * MakeCDBConnection(CConnection *connection, int delta)
TConnPool m_InUse
Used connections.
virtual unsigned int GetTimeout(void) const
Get connection timeout.
void UpdateConnTimeout(void) const
void x_GetCounts(const TCountsMap &main_map, const string &name, TCounts *counts) const
void CloseUnusedConnections(const string &srv_name=kEmptyStr, const string &pool_name=kEmptyStr, unsigned int max_closings=kMax_UInt)
close reusable deleted connections for specified server and/or pool
void DestroyConnImpl(CConnection *impl)
list< CConnection * > TConnPool
virtual bool SetCancelTimeout(unsigned int nof_secs)
virtual string GetUserName(void) const
virtual Uint4 GetProtocolVersion(void) const
virtual CRef< IConnValidator > GetConnValidator(void) const
virtual string GetDatabaseName(void) const
virtual string GetPassword(void) const
virtual Uint2 GetPort(void) const
void SetUserName(const string &name)
virtual EEncoding GetEncoding(void) const
virtual string GetParam(const string &key) const
Parameters, which are not listed above explicitly, should be retrieved via SetParam() method.
void SetParam(const string &key, const string &value)
virtual string GetServerName(void) const
virtual Uint4 GetHost(void) const
virtual EServerType GetServerType(void) const
void SetServerName(const string &name)
CMakeConnActualParams(const CDBConnParams &other)
void SetPassword(const string &passwd)
void SetDatabaseName(const string &name)
const_iterator end() const
Definition: map.hpp:152
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: set.hpp:45
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
bool empty() const
Definition: set.hpp:133
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
char value[7]
Definition: config.c:431
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
NCBI_PARAM_DEF_EX(bool, dbapi, conn_use_encrypt_data, false, eParam_NoThread, NULL)
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
constexpr size_t ArraySize(const Element(&)[Size])
Definition: ncbimisc.hpp:1532
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define ERASE_ITERATE(Type, Var, Cont)
Non-constant version with ability to erase current element, if container permits.
Definition: ncbimisc.hpp:843
const string & GetProgramDisplayName(void) const
Get the application's "display" name.
#define NON_CONST_REVERSE_ITERATE(Type, Var, Cont)
Non constant version of REVERSE_ITERATE macro.
Definition: ncbimisc.hpp:834
@ eRetriable_No
It makes no sense to retry the action.
Definition: ncbimisc.hpp:168
@ eNegative
Value is negative.
Definition: ncbimisc.hpp:121
@ eTakeOwnership
An object can take ownership of another.
Definition: ncbi_types.h:136
#define NULL
Definition: ncbistd.hpp:225
void SetDatabaseName(const string &d)
Definition: exception.hpp:208
#define DATABASE_DRIVER_ERROR(message, err_code)
Definition: exception.hpp:740
static CDB_UserHandler & GetDefault(void)
Definition: exception.cpp:628
deque< CDB_Exception * > TExceptions
Exception container type.
Definition: exception.hpp:574
virtual EEncoding GetEncoding(void) const =0
virtual EServerType GetServerType(void) const =0
virtual string GetPassword(void) const =0
virtual Uint4 GetProtocolVersion(void) const =0
virtual Uint4 GetHost(void) const =0
virtual string GetServerName(void) const =0
virtual Uint2 GetPort(void) const =0
virtual string GetDatabaseName(void) const =0
virtual CRef< IConnValidator > GetConnValidator(void) const =0
conn_use_encrypt_data
Definition: interfaces.hpp:796
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.
virtual bool Refresh()
Reset the connection to the "ready" state (cancel all active commands)
Definition: public.cpp:414
#define _TRACE(message)
Definition: ncbidbg.hpp:122
#define _DEBUG_ARG(arg)
Definition: ncbidbg.hpp:134
#define DIAG_COMPILE_INFO
Make compile time diagnostic information object to use in CNcbiDiag and CException.
Definition: ncbidiag.hpp:170
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
#define NCBI_CATCH(message)
Catch CExceptions as well This macro is deprecated - use *_X or *_XX variant instead of it.
Definition: ncbiexpt.hpp:580
#define STD_CATCH_ALL(message)
Standard handling of "exception"-derived exceptions; catches non-standard exceptions and generates "u...
Definition: ncbiexpt.hpp:570
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
#define FORMAT(message)
Format message using iostreams library.
Definition: ncbiexpt.hpp:672
@ fRead
Read permission.
Definition: ncbifile.hpp:1153
TObjectType * GetPointerOrNull(void) THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:986
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
uint16_t Uint2
2-byte (16-bit) unsigned integer
Definition: ncbitype.h:101
virtual const string & Get(const string &section, const string &name, TFlags flags=0) const
Get the parameter value.
Definition: ncbireg.cpp:262
virtual bool HasEntry(const string &section, const string &name=kEmptyStr, TFlags flags=0) const
Definition: ncbireg.cpp:290
@ fCountCleared
Let explicitly cleared entries stand.
Definition: ncbireg.hpp:94
#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 bool StringToBool(const CTempString str)
Convert string to bool.
Definition: ncbistr.cpp:2819
EEncoding
Definition: ncbistr.hpp:199
#define kEmptyStr
Definition: ncbistr.hpp:123
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
Definition: ncbistr.cpp:219
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
#define NPOS
Definition: ncbistr.hpp:133
static TNumeric StringToNumeric(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to a numeric value.
Definition: ncbistr.hpp:330
static const string BoolToString(bool value)
Convert bool to string.
Definition: ncbistr.cpp:2813
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static bool Equal(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Test for equality of a substring with another string.
Definition: ncbistr.hpp:5383
@ eEncoding_Windows_1252
Definition: ncbistr.hpp:207
@ eEncoding_Ascii
Definition: ncbistr.hpp:202
@ eEncoding_ISO8859_1
Note: From the point of view of the C++.
Definition: ncbistr.hpp:203
@ eEncoding_UTF8
Definition: ncbistr.hpp:201
@ eEncoding_Unknown
Definition: ncbistr.hpp:200
#define DEFINE_STATIC_MUTEX(id)
Define static mutex and initialize it.
Definition: ncbimtx.hpp:512
bool TryWait(unsigned int timeout_sec=0, unsigned int timeout_nsec=0)
Timed wait.
Definition: ncbimtx.cpp:1844
void Post(unsigned int count=1)
Increment the semaphore by "count".
Definition: ncbimtx.cpp:1971
CTime & Clear(void)
Make the time "empty",.
Definition: ncbitime.cpp:1998
@ eCurrent
Use current time. See also CCurrentTime.
Definition: ncbitime.hpp:300
enum ENcbiOwnership EOwnership
Ownership relations between objects.
Definition of all error codes used in dbapi libraries (dbapi_driver.lib and others).
int i
yy_size_t n
static MDB_envinfo info
Definition: mdb_load.c:37
string ConvertN2A(Uint4 host)
static bool s_Matches(CConnection *conn, const string &pool_name, const string &server_name)
static void s_TransformLoginData(string &server_name, string &user_name, string &db_name, string &password)
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
const struct ncbi::grid::netcache::search::fields::KEY key
CRef< CDBServer > TSvrRef
const char * NCBI_GetDefaultSybasePath(void)
Get default Sybase client installation path.
const char * NCBI_GetSybasePath(void)
Get Sybase client installation path.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
Int4 delta(size_t dimension_, const Int4 *score_)
Defines NCBI C++ secure resources API.
static string subject
bool IsContinueAfterRaiserrorSet(void)
bool IsPoolAllowTempOverflowSet(void)
bool operator<(const SLoginData &right) const
SLoginData(const string &sn, const string &un, const string &dn, const string &pass)
else result
Definition: token2.c:20
static HENV env
Definition: transaction2.c:38
Modified on Sat Dec 09 04:48:49 2023 by modify_doxy.py rev. 669887