diff --git a/include/sqlpp11/connection_pool.h b/include/sqlpp11/connection_pool.h index 11eaf0c7..2c90c924 100644 --- a/include/sqlpp11/connection_pool.h +++ b/include/sqlpp11/connection_pool.h @@ -42,196 +42,196 @@ namespace sqlpp { - namespace connection_validator - { - struct automatic - { - template - void validate(Connection* connection) - { - if (!connection->is_valid()) - { - try - { - connection->reconnect(); - } - catch (const sqlpp::exception&) - { - throw sqlpp::exception("Failed to reconnect to database."); - } - } - } + namespace connection_validator + { + struct automatic + { + template + void validate(Connection* connection) + { + if (!connection->is_valid()) + { + try + { + connection->reconnect(); + } + catch (const sqlpp::exception&) + { + throw sqlpp::exception("Failed to reconnect to database."); + } + } + } - template - void deregister(Connection* connection) {} - }; + template + void deregister(Connection* connection) {} + }; - using namespace std::chrono_literals; - class periodic - { - private: - std::chrono::seconds revalidate_interval; - std::unordered_map> last_checked; + using namespace std::chrono_literals; + class periodic + { + private: + std::chrono::seconds revalidate_interval; + std::unordered_map> last_checked; - public: - periodic(const std::chrono::seconds r = 28800s) //default wait_timeout in MySQL - : revalidate_interval(r), last_checked() {} + public: + periodic(const std::chrono::seconds r = 28800s) //default wait_timeout in MySQL + : revalidate_interval(r), last_checked() {} - template - void validate(Connection* connection) - { - auto last = last_checked.find(connection); - auto now = std::chrono::system_clock::now(); - if (last == last_checked.end()) - { - last_checked.emplace_hint(last, connection, now); - } + template + void validate(Connection* connection) + { + auto last = last_checked.find(connection); + auto now = std::chrono::system_clock::now(); + if (last == last_checked.end()) + { + last_checked.emplace_hint(last, connection, now); + } - if (now - last->second < revalidate_interval) - { - return; - } - - if (!connection->is_valid()) - { - try - { - connection->reconnect(); - } - catch (const sqlpp::exception& e) - { - throw sqlpp::exception("Failed to reconnect to database."); - } - } + if (now - last->second < revalidate_interval) + { + return; + } - last = now; - } + if (!connection->is_valid()) + { + try + { + connection->reconnect(); + } + catch (const sqlpp::exception& e) + { + throw sqlpp::exception("Failed to reconnect to database."); + } + } - template - void deregister(Connection* con) - { - auto itr = last_checked.find(con); - if(itr != last_checked.end()) - { - last_checked.erase(itr); - } - } - }; + last = now; + } - struct none - { - template - void validate(Connection*) {} + template + void deregister(Connection* con) + { + auto itr = last_checked.find(con); + if (itr != last_checked.end()) + { + last_checked.erase(itr); + } + } + }; - template - void deregister(Connection*) {} - }; - } + struct none + { + template + void validate(Connection*) {} - template ::value, Connection_config::connection>::type> - class connection_pool - { - friend pool_connection; + template + void deregister(Connection*) {} + }; + } - private: - std::mutex connection_pool_mutex; - const std::shared_ptr config; - size_t maximum_pool_size = 0; - std::stack> free_connections; - Connection_validator connection_validator; + template ::value, Connection_config::connection>::type> + class connection_pool + { + friend pool_connection; - void free_connection(std::unique_ptr& connection) - { - std::lock_guard lock(connection_pool_mutex); - if (free_connections.size() >= maximum_pool_size) - { - // Exceeds default size, deregister left over info in the connection_validator and let connection self destroy. - connection_validator.deregister(connection.get()); - } - else - { - if (connection.get()) - { - free_connections.push(std::move(connection)); - } - else - { - throw sqlpp::exception("Trying to free an empty connection."); - } - } - } + private: + std::mutex connection_pool_mutex; + const std::shared_ptr config; + size_t maximum_pool_size = 0; + std::stack> free_connections; + Connection_validator connection_validator; - public: - connection_pool(const std::shared_ptr& config, size_t pool_size) - : config(config), maximum_pool_size(pool_size), connection_validator(Connection_validator()) {} - ~connection_pool() = default; - connection_pool(const connection_pool&) = delete; - connection_pool(connection_pool&& other) - : config(std::move(other.config)), maximum_pool_size(std::move(other.maximum_pool_size)), - connection_validator(std::move(other.connection_validator)) {} - connection_pool& operator=(const connection_pool&) = delete; - connection_pool& operator=(connection_pool&&) = delete; + void free_connection(std::unique_ptr& connection) + { + std::lock_guard lock(connection_pool_mutex); + if (free_connections.size() >= maximum_pool_size) + { + // Exceeds default size, deregister left over info in the connection_validator and let connection self destroy. + connection_validator.deregister(connection.get()); + } + else + { + if (connection.get()) + { + free_connections.push(std::move(connection)); + } + else + { + throw sqlpp::exception("Trying to free an empty connection."); + } + } + } - pool_connection get_connection() - { - std::lock_guard lock(connection_pool_mutex); - while (true) - { - try - { - if (!free_connections.empty()) - { - auto connection = std::move(free_connections.top()); - free_connections.pop(); - connection_validator.validate(connection.get()); + public: + connection_pool(const std::shared_ptr& config, size_t pool_size) + : config(config), maximum_pool_size(pool_size), connection_validator(Connection_validator()) {} + ~connection_pool() = default; + connection_pool(const connection_pool&) = delete; + connection_pool(connection_pool&& other) + : config(std::move(other.config)), maximum_pool_size(std::move(other.maximum_pool_size)), + connection_validator(std::move(other.connection_validator)) {} + connection_pool& operator=(const connection_pool&) = delete; + connection_pool& operator=(connection_pool&&) = delete; - return pool_connection(std::move(connection), this); - } - else - { - break; - } - } - catch (const sqlpp::exception&) - { - throw sqlpp::exception("Failed to retrieve a valid connection."); - } - } + auto get_connection() + -> pool_connection + { + std::lock_guard lock(connection_pool_mutex); + while (true) + { + try + { + if (!free_connections.empty()) + { + auto connection = std::move(free_connections.top()); + free_connections.pop(); + connection_validator.validate(connection.get()); - try - { - return pool_connection(std::move(std::make_unique(config)), this); - } - catch (const sqlpp::exception&) - { - throw sqlpp::exception("Failed to spawn a new connection."); - } - } + return pool_connection(std::move(connection), this); + } + else + { + break; + } + } + catch (const sqlpp::exception&) + { + throw sqlpp::exception("Failed to retrieve a valid connection."); + } + } - template - void operator()(Query query, Lambda callback) - { - query_task(*this, query, callback)(); - } + try + { + return pool_connection(std::move(std::make_unique(config)), this); + } + catch (const sqlpp::exception&) + { + throw sqlpp::exception("Failed to spawn a new connection."); + } + } - template - void operator()(Query query) - { - operator()(query, [](){}); - } - }; + template + void operator()(Query query, Lambda callback) + { + query_task(*this, query, callback)(); + } - template::value,Connection_config::connection>::type> - connection_pool make_connection_pool( - const std::shared_ptr& config, - size_t max_pool_size) - { - return connection_pool(config, max_pool_size); - } + template + void operator()(Query query) + { + operator()(query, []() {}); + } + }; + + template::value, Connection_config::connection>::type> + auto make_connection_pool(const std::shared_ptr& config, size_t max_pool_size) + -> connection_pool + { + return connection_pool(config, max_pool_size); + } } #endif diff --git a/include/sqlpp11/pool_connection.h b/include/sqlpp11/pool_connection.h index b05bfe52..f4eea7dc 100644 --- a/include/sqlpp11/pool_connection.h +++ b/include/sqlpp11/pool_connection.h @@ -32,63 +32,67 @@ namespace sqlpp { - template > - struct pool_connection : public sqlpp::connection - { - private: - std::unique_ptr _impl; - Connection_pool* origin; + template > + struct pool_connection : public sqlpp::connection + { + private: + std::unique_ptr _impl; + Connection_pool* origin; - public: - pool_connection() : _impl(nullptr), origin(nullptr) {} + public: + pool_connection() : _impl(nullptr), origin(nullptr) + { + } - pool_connection(std::unique_ptr& connection, Connection_pool* origin) - : _impl(std::move(connection)), origin(origin) {} + pool_connection(std::unique_ptr& connection, Connection_pool* origin) : _impl(std::move(connection)), origin(origin) + { + } - ~pool_connection() - { - if (_impl.get()) - { - origin->free_connection(_impl); - } - } + ~pool_connection() + { + if (_impl.get()) + { + origin->free_connection(_impl); + } + } - template - auto operator()(Args&&... args) -> decltype(_impl->args(std::forward(args)...)) - { - return _impl->args(std::forward(args)...); - } + template + auto operator()(Args&&... args) -> decltype(_impl->args(std::forward(args)...)) + { + return _impl->args(std::forward(args)...); + } - template - auto operator()(const T& t) -> decltype(_impl->run(t)) - { - return _impl->run(t); - } + template + auto operator()(const T& t) -> decltype(_impl->run(t)) + { + return _impl->run(t); + } - template - auto execute(const T& t) -> decltype(_impl->execute(t)) - { - return _impl->execute(t); - } + template + auto execute(const T& t) -> decltype(_impl->execute(t)) + { + return _impl->execute(t); + } - template - auto prepare(const T& t) -> decltype(_impl->prepare(t)) - { - return _impl->prepare(t); - } + template + auto prepare(const T& t) -> decltype(_impl->prepare(t)) + { + return _impl->prepare(t); + } - pool_connection(const pool_connection&) = delete; - pool_connection(pool_connection&& other) - : _impl(std::move(other._impl)), origin(other.origin) {} - pool_connection& operator=(const pool_connection&) = delete; - pool_connection& operator=(pool_connection&& other) - { - _impl = std::move(other._impl); - origin = other.origin; - return *this; - } - }; + pool_connection(const pool_connection&) = delete; + pool_connection(pool_connection&& other) : _impl(std::move(other._impl)), origin(other.origin) + { + } + pool_connection& operator=(const pool_connection&) = delete; + pool_connection& operator=(pool_connection&& other) + { + _impl = std::move(other._impl); + origin = other.origin; + return *this; + } + }; } #endif