| | |
| | | #include "qtl_async.hpp" |
| | | #include <asio/version.hpp> |
| | | #define ASIO_STANDALONE |
| | | #if defined(_MSC_VER) && _WIN32_WINNT<0x0600 |
| | | #define ASIO_ENABLE_CANCELIO 1 |
| | | #if defined(_MSC_VER) && _WIN32_WINNT < 0x0600 |
| | | #define ASIO_ENABLE_CANCELIO 1 |
| | | #endif |
| | | #if ASIO_VERSION < 101200 |
| | | #include <asio/io_service.hpp> |
| | |
| | | #include <asio/steady_timer.hpp> |
| | | |
| | | #if ASIO_VERSION < 100000 |
| | | #error The asio version required by QTL is at least 10.0 |
| | | #error The asio version required by QTL is at least 10.0 |
| | | #endif |
| | | |
| | | namespace qtl |
| | | { |
| | | |
| | | namespace NS_ASIO = ::asio; |
| | | namespace NS_ASIO = ::asio; |
| | | |
| | | namespace asio |
| | | { |
| | | namespace asio |
| | | { |
| | | |
| | | class service |
| | | { |
| | | public: |
| | | class service |
| | | { |
| | | public: |
| | | #if ASIO_VERSION < 101200 |
| | | typedef NS_ASIO::io_service service_type; |
| | | typedef NS_ASIO::io_service service_type; |
| | | #else |
| | | typedef NS_ASIO::io_context service_type; |
| | | typedef NS_ASIO::io_context service_type; |
| | | #endif // ASIO_VERSION |
| | | |
| | | service() NOEXCEPT { } |
| | | explicit service(int concurrency_hint) : _service(concurrency_hint) { } |
| | | service() NOEXCEPT {} |
| | | explicit service(int concurrency_hint) : _service(concurrency_hint) {} |
| | | |
| | | void reset() |
| | | { |
| | | _service.reset(); |
| | | } |
| | | |
| | | void run() |
| | | { |
| | | _service.run(); |
| | | } |
| | | |
| | | void stop() |
| | | { |
| | | _service.stop(); |
| | | } |
| | | |
| | | service_type& context() NOEXCEPT { return _service; } |
| | | |
| | | private: |
| | | |
| | | class event_item : public qtl::event |
| | | { |
| | | public: |
| | | event_item(service& service, qtl::socket_type fd) |
| | | : _service(service), _strand(service.context()), _socket(service.context(), NS_ASIO::ip::tcp::v4(), fd), _timer(service.context()), _busying(false) |
| | | { |
| | | } |
| | | |
| | | NS_ASIO::ip::tcp::socket& next_layer() { return _socket; } |
| | | |
| | | public: // qtl::event |
| | | virtual void set_io_handler(int flags, long timeout, std::function<void(int)>&& handler) override |
| | | { |
| | | if (flags&qtl::event::ef_read) |
| | | void reset() |
| | | { |
| | | _service.reset(); |
| | | } |
| | | |
| | | void run() |
| | | { |
| | | _service.run(); |
| | | } |
| | | |
| | | void stop() |
| | | { |
| | | _service.stop(); |
| | | } |
| | | |
| | | service_type &context() NOEXCEPT { return _service; } |
| | | |
| | | private: |
| | | class event_item : public qtl::event |
| | | { |
| | | public: |
| | | event_item(service &service, qtl::socket_type fd) |
| | | : _service(service), _strand(service.context()), _socket(service.context(), NS_ASIO::ip::tcp::v4(), fd), _timer(service.context()), _busying(false) |
| | | { |
| | | } |
| | | |
| | | NS_ASIO::ip::tcp::socket &next_layer() { return _socket; } |
| | | |
| | | public: // qtl::event |
| | | virtual void set_io_handler(int flags, long timeout, std::function<void(int)> &&handler) override |
| | | { |
| | | if (flags & qtl::event::ef_read) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | _socket.async_read_some(NS_ASIO::null_buffers(), _strand.wrap([this, handler](const NS_ASIO::error_code& ec, size_t bytes_transferred) { |
| | | _socket.async_read_some(NS_ASIO::null_buffers(), _strand.wrap([this, handler](const NS_ASIO::error_code &ec, size_t bytes_transferred) |
| | | { |
| | | #else |
| | | _socket.async_wait(NS_ASIO::socket_base::wait_read, _strand.wrap([this, handler](const NS_ASIO::error_code& ec) { |
| | | _socket.async_wait(NS_ASIO::socket_base::wait_read, _strand.wrap([this, handler](const NS_ASIO::error_code &ec) |
| | | { |
| | | #endif // ASIO_VERSION |
| | | if (!ec) |
| | | handler(qtl::event::ef_read); |
| | |
| | | else |
| | | handler(qtl::event::ef_exception); |
| | | _busying = false; |
| | | _timer.cancel(); |
| | | })); |
| | | _busying = true; |
| | | } |
| | | if (flags&qtl::event::ef_write) |
| | | { |
| | | _timer.cancel(); })); |
| | | _busying = true; |
| | | } |
| | | if (flags & qtl::event::ef_write) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | _socket.async_write_some(NS_ASIO::null_buffers(), _strand.wrap([this, handler](const NS_ASIO::error_code& ec, size_t bytes_transferred) { |
| | | _socket.async_write_some(NS_ASIO::null_buffers(), _strand.wrap([this, handler](const NS_ASIO::error_code &ec, size_t bytes_transferred) |
| | | { |
| | | #else |
| | | _socket.async_wait(NS_ASIO::socket_base::wait_write, _strand.wrap([this, handler](const NS_ASIO::error_code& ec) { |
| | | #endif //ASIO_VERSION |
| | | _socket.async_wait(NS_ASIO::socket_base::wait_write, _strand.wrap([this, handler](const NS_ASIO::error_code &ec) |
| | | { |
| | | #endif // ASIO_VERSION |
| | | if (!ec) |
| | | handler(qtl::event::ef_write); |
| | | else if (ec == NS_ASIO::error::make_error_code(NS_ASIO::error::operation_aborted)) |
| | |
| | | else |
| | | handler(qtl::event::ef_exception); |
| | | _timer.cancel(); |
| | | _busying = false; |
| | | })); |
| | | _busying = true; |
| | | } |
| | | if (timeout > 0) |
| | | { |
| | | _busying = false; })); |
| | | _busying = true; |
| | | } |
| | | if (timeout > 0) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | _timer.expires_from_now(std::chrono::seconds(timeout)); |
| | | _timer.expires_from_now(std::chrono::seconds(timeout)); |
| | | #else |
| | | _timer.expires_after(NS_ASIO::chrono::seconds(timeout)); |
| | | _timer.expires_after(NS_ASIO::chrono::seconds(timeout)); |
| | | #endif // ASIO_VERSION |
| | | _timer.async_wait(_strand.wrap([this, handler](NS_ASIO::error_code ec) { |
| | | _timer.async_wait(_strand.wrap([this, handler](NS_ASIO::error_code ec) |
| | | { |
| | | if (!ec) |
| | | { |
| | | _socket.cancel(ec); |
| | | } })); |
| | | } |
| | | })); |
| | | } |
| | | |
| | | virtual void remove() override |
| | | { |
| | | if (_busying) |
| | | return; |
| | | #if ASIO_VERSION >= 101200 && (!defined(_WIN32) || _WIN32_WINNT >= 0x0603) |
| | | _socket.release(); |
| | | #endif // Windows 8.1 |
| | | _service.remove(this); |
| | | } |
| | | virtual bool is_busying() override |
| | | { |
| | | return _busying; |
| | | } |
| | | |
| | | private: |
| | | service &_service; |
| | | service_type::strand _strand; |
| | | NS_ASIO::ip::tcp::socket _socket; |
| | | NS_ASIO::steady_timer _timer; |
| | | bool _busying; |
| | | }; |
| | | |
| | | public: |
| | | template <typename Connection> |
| | | event_item *add(Connection *connection) |
| | | { |
| | | event_item *item = new event_item(*this, connection->socket()); |
| | | std::lock_guard<std::mutex> lock(_mutex); |
| | | _events.push_back(std::unique_ptr<event_item>(item)); |
| | | return item; |
| | | } |
| | | } |
| | | |
| | | virtual void remove() override |
| | | { |
| | | if (_busying) return; |
| | | #if ASIO_VERSION >= 101200 && (!defined(_WIN32) || _WIN32_WINNT >= 0x0603 ) |
| | | _socket.release(); |
| | | #endif //Windows 8.1 |
| | | _service.remove(this); |
| | | } |
| | | virtual bool is_busying() override |
| | | { |
| | | return _busying; |
| | | } |
| | | private: |
| | | service_type _service; |
| | | std::mutex _mutex; |
| | | std::vector<std::unique_ptr<event_item>> _events; |
| | | |
| | | private: |
| | | service& _service; |
| | | service_type::strand _strand; |
| | | NS_ASIO::ip::tcp::socket _socket; |
| | | NS_ASIO::steady_timer _timer; |
| | | bool _busying; |
| | | }; |
| | | |
| | | public: |
| | | |
| | | template<typename Connection> |
| | | event_item* add(Connection* connection) |
| | | { |
| | | event_item* item = new event_item(*this, connection->socket()); |
| | | std::lock_guard<std::mutex> lock(_mutex); |
| | | _events.push_back(std::unique_ptr<event_item>(item)); |
| | | return item; |
| | | } |
| | | |
| | | private: |
| | | service_type _service; |
| | | std::mutex _mutex; |
| | | std::vector<std::unique_ptr<event_item>> _events; |
| | | |
| | | void remove(event_item* item) |
| | | { |
| | | std::lock_guard<std::mutex> lock(_mutex); |
| | | auto it = std::find_if(_events.begin(), _events.end(), [item](std::unique_ptr<event_item>& v) { |
| | | return item==v.get(); |
| | | }); |
| | | if (it != _events.end()) _events.erase(it); |
| | | } |
| | | }; |
| | | void remove(event_item *item) |
| | | { |
| | | std::lock_guard<std::mutex> lock(_mutex); |
| | | auto it = std::find_if(_events.begin(), _events.end(), [item](std::unique_ptr<event_item> &v) |
| | | { return item == v.get(); }); |
| | | if (it != _events.end()) |
| | | _events.erase(it); |
| | | } |
| | | }; |
| | | |
| | | #if ASIO_VERSION < 101200 |
| | | |
| | | template <typename Handler, typename Signature> |
| | | using async_init_type = NS_ASIO::detail::async_result_init<Handler, Signature>; |
| | | template <typename Handler, typename Signature> |
| | | using async_init_type = NS_ASIO::detail::async_result_init<Handler, Signature>; |
| | | |
| | | template <typename Handler, typename Signature> |
| | | inline typename NS_ASIO::handler_type<Handler, Signature>::type |
| | | get_async_handler(async_init_type<Handler, Signature>& init) |
| | | { |
| | | return init.handler; |
| | | } |
| | | template <typename Handler, typename Signature> |
| | | inline typename NS_ASIO::handler_type<Handler, Signature>::type |
| | | get_async_handler(async_init_type<Handler, Signature> &init) |
| | | { |
| | | return init.handler; |
| | | } |
| | | |
| | | #else |
| | | |
| | | template <typename Handler, typename Signature> |
| | | using async_init_type = NS_ASIO::async_completion<Handler, Signature>; |
| | | template <typename Handler, typename Signature> |
| | | using async_init_type = NS_ASIO::async_completion<Handler, Signature>; |
| | | |
| | | template <typename Handler, typename Signature> |
| | | inline typename async_init_type<Handler, Signature>::completion_handler_type |
| | | get_async_handler(async_init_type<Handler, Signature>& init) |
| | | { |
| | | return init.completion_handler; |
| | | } |
| | | template <typename Handler, typename Signature> |
| | | inline typename async_init_type<Handler, Signature>::completion_handler_type |
| | | get_async_handler(async_init_type<Handler, Signature> &init) |
| | | { |
| | | return init.completion_handler; |
| | | } |
| | | |
| | | #endif // ASIO_VERSION |
| | | |
| | | template<typename Connection, typename OpenHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(OpenHandler, void(typename Connection::exception_type)) |
| | | async_open(service& service, Connection& db, OpenHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename OpenHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(OpenHandler, void(typename Connection::exception_type)) |
| | | async_open(service &service, Connection &db, OpenHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<OpenHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<OpenHandler>(handler)); |
| | | async_init_type<OpenHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<OpenHandler>(handler)); |
| | | #else |
| | | async_init_type<OpenHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<OpenHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.open(service, get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.open(service, get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename CloseHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(CloseHandler, void()) |
| | | async_close(Connection& db, CloseHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename CloseHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(CloseHandler, void()) |
| | | async_close(Connection &db, CloseHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<CloseHandler, |
| | | void()> init(std::forward<CloseHandler>(std::forward<CloseHandler>(handler))); |
| | | async_init_type<CloseHandler, |
| | | void()> |
| | | init(std::forward<CloseHandler>(std::forward<CloseHandler>(handler))); |
| | | #else |
| | | async_init_type<CloseHandler, |
| | | void()> init(std::forward<CloseHandler>(handler)); |
| | | async_init_type<CloseHandler, |
| | | void()> |
| | | init(std::forward<CloseHandler>(handler)); |
| | | #endif |
| | | |
| | | db.close(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.close(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_execute(Connection& db, ExecuteHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_execute(Connection &db, ExecuteHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(std::forward<ExecuteHandler>(handler)); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(std::forward<ExecuteHandler>(handler)); |
| | | #else |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(handler); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.execute(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.execute(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_execute_direct(Connection& db, ExecuteHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_execute_direct(Connection &db, ExecuteHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(std::forward<ExecuteHandler>(handler)); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(std::forward<ExecuteHandler>(handler)); |
| | | #else |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(handler); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.execute_direct(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.execute_direct(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_insert(Connection& db, ExecuteHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_insert(Connection &db, ExecuteHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(std::forward<ExecuteHandler>(handler)); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(std::forward<ExecuteHandler>(handler)); |
| | | #else |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(handler); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.insert(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.insert(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_insert_direct(Connection& db, ExecuteHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename ExecuteHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(ExecuteHandler, void(typename Connection::exception_type, uint64_t)) |
| | | async_insert_direct(Connection &db, ExecuteHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(std::forward<ExecuteHandler>(handler)); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(std::forward<ExecuteHandler>(handler)); |
| | | #else |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> init(handler); |
| | | async_init_type<ExecuteHandler, |
| | | void(typename Connection::exception_type, uint64_t)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.insert_direct(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | db.insert_direct(get_async_handler(init), std::forward<Args>(args)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename FinishHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query(Connection& db, FinishHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename FinishHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query(Connection &db, FinishHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query(std::forward<Args>(args)..., get_async_handler(init)); |
| | | return init.result.get(); |
| | | } |
| | | db.query(std::forward<Args>(args)..., get_async_handler(init)); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename FinishHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_explicit(Connection& db, FinishHandler&& handler, Args&&... args) |
| | | { |
| | | template <typename Connection, typename FinishHandler, typename... Args> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_explicit(Connection &db, FinishHandler &&handler, Args &&...args) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query_explicit(std::forward<Args>(args)..., get_async_handler(init)); |
| | | return init.result.get(); |
| | | } |
| | | db.query_explicit(std::forward<Args>(args)..., get_async_handler(init)); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename A1, typename A2, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi_with_params(Connection& db, A1&& a1, A2&& a2, FinishHandler&& handler, RowHandlers&&... row_handlers) |
| | | { |
| | | template <typename Connection, typename A1, typename A2, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi_with_params(Connection &db, A1 &&a1, A2 &&a2, FinishHandler &&handler, RowHandlers &&...row_handlers) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query_multi_with_params(std::forward<A1>(a1), std::forward<A2>(a2), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | db.query_multi_with_params(std::forward<A1>(a1), std::forward<A2>(a2), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename A1, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi_with_params(Connection& db, A1&& a1, FinishHandler&& handler, RowHandlers&&... row_handlers) |
| | | { |
| | | template <typename Connection, typename A1, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi_with_params(Connection &db, A1 &&a1, FinishHandler &&handler, RowHandlers &&...row_handlers) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query_multi_with_params(std::forward<A1>(a1), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | db.query_multi_with_params(std::forward<A1>(a1), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename A1, typename A2, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi(Connection& db, A1&& a1, A2&& a2, FinishHandler&& handler, RowHandlers&&... row_handlers) |
| | | { |
| | | template <typename Connection, typename A1, typename A2, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi(Connection &db, A1 &&a1, A2 &&a2, FinishHandler &&handler, RowHandlers &&...row_handlers) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query_multi(std::forward<A1>(a1), std::forward<A2>(a2), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | db.query_multi(std::forward<A1>(a1), std::forward<A2>(a2), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | template<typename Connection, typename A1, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi(Connection& db, A1&& a1, FinishHandler&& handler, RowHandlers&&... row_handlers) |
| | | { |
| | | template <typename Connection, typename A1, typename FinishHandler, typename... RowHandlers> |
| | | inline ASIO_INITFN_RESULT_TYPE(FinishHandler, void(typename Connection::exception_type)) |
| | | async_query_multi(Connection &db, A1 &&a1, FinishHandler &&handler, RowHandlers &&...row_handlers) |
| | | { |
| | | #if ASIO_VERSION < 101200 |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(std::forward<FinishHandler>(handler)); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(std::forward<FinishHandler>(handler)); |
| | | #else |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> init(handler); |
| | | async_init_type<FinishHandler, |
| | | void(typename Connection::exception_type)> |
| | | init(handler); |
| | | #endif |
| | | |
| | | db.query_multi(std::forward<A1>(a1), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | db.query_multi(std::forward<A1>(a1), get_async_handler(init), std::forward<RowHandlers>(row_handlers)...); |
| | | return init.result.get(); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | } |
| | | |