C++DB is the database layer that was designed to work with C++CMS. This customized version is used within Ye Ol' Pi Shack.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

113 lines
2.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2010-2011 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // Distributed under:
  6. //
  7. // the Boost Software License, Version 1.0.
  8. // (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // or (at your opinion) under:
  12. //
  13. // The MIT License
  14. // (See accompanying file MIT.txt or a copy at
  15. // http://www.opensource.org/licenses/mit-license.php)
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #define CPPDB_SOURCE
  19. #include <cppdb/conn_manager.h>
  20. #include <cppdb/backend.h>
  21. #include <cppdb/pool.h>
  22. #include <cppdb/driver_manager.h>
  23. namespace cppdb {
  24. struct connections_manager::data{};
  25. connections_manager::connections_manager() {}
  26. // Borland erros on hidden destructors in classes without only static methods.
  27. #ifndef __BORLANDC__
  28. connections_manager::~connections_manager() {}
  29. #endif
  30. connections_manager &connections_manager::instance()
  31. {
  32. static connections_manager mgr;
  33. return mgr;
  34. }
  35. namespace {
  36. struct init {
  37. init()
  38. { connections_manager::instance(); }
  39. } initializer;
  40. }
  41. ref_ptr<backend::connection> connections_manager::open(std::string const &cs)
  42. {
  43. ref_ptr<pool> p;
  44. /// seems we may be using pool
  45. if(cs.find("@pool_size")!=std::string::npos) {
  46. mutex::guard l(lock_);
  47. connections_type::iterator pool_ptr = connections_.find(cs);
  48. if(pool_ptr!=connections_.end())
  49. p = pool_ptr->second;
  50. }
  51. if(p) {
  52. return p->open();
  53. }
  54. else {
  55. connection_info ci(cs);
  56. return open(ci);
  57. }
  58. }
  59. ref_ptr<backend::connection> connections_manager::open(connection_info const &ci)
  60. {
  61. if(ci.get("@pool_size",0)==0) {
  62. return driver_manager::instance().connect(ci);
  63. }
  64. ref_ptr<pool> p;
  65. {
  66. mutex::guard l(lock_);
  67. ref_ptr<pool> &ref_p = connections_[ci.connection_string];
  68. if(!ref_p) {
  69. ref_p = pool::create(ci);
  70. }
  71. p=ref_p;
  72. }
  73. return p->open();
  74. }
  75. void connections_manager::gc()
  76. {
  77. std::vector<ref_ptr<pool> > pools_;
  78. pools_.reserve(100);
  79. {
  80. mutex::guard l(lock_);
  81. for(connections_type::iterator p=connections_.begin();p!=connections_.end();++p) {
  82. pools_.push_back(p->second);
  83. }
  84. }
  85. for(unsigned i=0;i<pools_.size();i++) {
  86. pools_[i]->gc();
  87. }
  88. pools_.clear();
  89. {
  90. mutex::guard l(lock_);
  91. for(connections_type::iterator p=connections_.begin();p!=connections_.end();) {
  92. if(p->second->use_count() == 1) {
  93. pools_.push_back(p->second);
  94. connections_type::iterator tmp = p;
  95. ++p;
  96. connections_.erase(tmp);
  97. }
  98. else
  99. ++p;
  100. }
  101. }
  102. pools_.clear();
  103. }
  104. } // cppdb