4 #include <ozo/type_traits.h>
6 #include <ozo/core/concept.h>
7 #include <ozo/core/recursive.h>
8 #include <ozo/core/none.h>
9 #include <ozo/deadline.h>
10 #include <ozo/pg/handle.h>
12 #include <ozo/detail/bind.h>
13 #include <ozo/detail/functional.h>
15 #include <boost/asio/dispatch.hpp>
16 #include <boost/asio/posix/stream_descriptor.hpp>
34 struct unwrap_connection_impl : unwrap_recursive_impl<T> {};
76 return detail::apply<unwrap_connection_impl>(std::forward<T>(conn));
92 template <
typename O
idMap,
typename Statistics>
106 connection(io_context& io, Statistics statistics);
135 template <
typename Key,
typename Value>
136 void update_statistics(
const Key&,
const Value&) noexcept {
137 static_assert(std::is_void_v<Key>,
"update_statistics is not supperted");
139 const Statistics& statistics() const noexcept {
return statistics_;}
199 template <
typename WaitHandler>
212 template <
typename WaitHandler>
243 bool is_bad() const noexcept;
253 operator
bool () const noexcept {
return !
is_bad();}
265 using stream_type = asio::posix::stream_descriptor;
267 ozo::pg::conn handle_;
268 io_context* io_ =
nullptr;
271 Statistics statistics_;
282 template <
typename,
typename = std::
void_t<>>
285 template <
typename ...Ts>
337 template <
typename T>
339 inline constexpr
auto Connection = is_connection<std::decay_t<decltype(unwrap_connection(std::declval<T>()))>>::value;
357 template <
typename Connection>
368 template <
typename Connection>
379 template <
typename T>
390 template <
typename Connection>
404 template <
typename Connection>
415 template <
typename Connection>
429 template <
typename Connection>
443 template <
typename Connection>
457 template <
typename Connection>
471 template <
typename Connection>
485 template <
typename Connection>
496 template <
typename ConnectionProv
ider,
typename = std::
void_t<>>
497 struct get_connection_type_default {};
499 template <
typename ConnectionProv
ider>
501 std::void_t<typename ConnectionProvider::connection_type>> {
505 template <
typename T>
551 template <
typename ConnectionProv
ider>
553 #ifdef OZO_DOCUMENTATION
555 using type = <implementation defined>;
558 : detail::get_connection_type_default<ConnectionProvider>{};
571 template <
typename T>
574 template <
typename T>
579 struct call_async_get_connection {
580 template <
typename Prov
ider,
typename TimeConstra
int,
typename Handler>
581 static constexpr
auto apply(Provider&& p, TimeConstraint t,
Handler&& h) ->
582 decltype(p.async_get_connection(t, std::forward<Handler>(h))) {
583 static_assert(ozo::TimeConstraint<TimeConstraint>,
"should model TimeConstraint concept");
584 return p.async_get_connection(t, std::forward<Handler>(h));
588 struct forward_connection {
589 template <
typename Conn,
typename TimeConstra
int,
typename Handler>
590 static constexpr
void apply(Conn&& c, TimeConstraint,
Handler&& h) {
591 static_assert(ozo::TimeConstraint<TimeConstraint>,
"should model TimeConstraint concept");
594 asio::dispatch(ex, detail::bind(std::forward<Handler>(h),
error_code{}, std::forward<Conn>(c)));
600 template <
typename Prov
ider,
typename TimeConstra
int>
601 struct async_get_connection_impl : std::conditional_t<Connection<Provider>,
602 detail::forward_connection,
603 detail::call_async_get_connection
608 template <
typename Source,
typename TimeTraits,
typename = std::
void_t<>>
609 struct connection_source_supports_time_traits : std::false_type {};
611 template <
typename Source,
typename TimeTraits>
612 struct connection_source_supports_time_traits<Source, TimeTraits, std::void_t<decltype(
613 std::declval<Source&>()(
614 std::declval<io_context&>(),
615 std::declval<TimeTraits>(),
616 std::declval<handler_signature<Source>>()
618 )>> : std::true_type {};
620 template <
typename T>
621 using connection_source_defined = std::conjunction<
622 typename connection_source_supports_time_traits<T, time_traits::time_point>::type,
623 typename connection_source_supports_time_traits<T, time_traits::duration>::type,
624 typename connection_source_supports_time_traits<T, none_t>::type
628 template <
typename T>
629 using is_connection_source =
typename detail::connection_source_defined<T>::type;
631 template <
typename T>
632 struct connection_source_traits {
633 using type = connection_source_traits;
634 using connection_type =
typename get_connection_type<std::decay_t<T>>::type;
671 template <
typename T>
673 inline constexpr
auto ConnectionSource = is_connection_source<std::decay_t<T>>::value;
676 template <
typename Prov
ider,
typename TimeConstra
int,
typename Handler>
677 constexpr
auto async_get_connection(Provider&& p, TimeConstraint t,
Handler&& h) ->
678 decltype(async_get_connection_impl<std::decay_t<Provider>, TimeConstraint>::
679 apply(std::forward<Provider>(p), t, std::forward<Handler>(h))) {
680 static_assert(ozo::TimeConstraint<TimeConstraint>,
"should model TimeConstraint concept");
681 return async_get_connection_impl<std::decay_t<Provider>, TimeConstraint>::
682 apply(std::forward<Provider>(p), t, std::forward<Handler>(h));
686 template <
typename Prov
ider,
typename TimeConstra
int,
typename = std::
void_t<>>
687 struct connection_provider_supports_time_constraint : std::false_type {};
689 template <
typename Prov
ider,
typename TimeConstra
int>
690 struct connection_provider_supports_time_constraint<Provider, TimeConstraint, std::void_t<decltype(
691 async_get_connection(
692 std::declval<Provider&>(),
693 std::declval<TimeConstraint>(),
694 std::declval<handler_signature<Provider>>()
696 )>> : std::true_type {};
698 template <
typename T>
699 using async_get_connection_defined = std::conjunction<
700 typename connection_provider_supports_time_constraint<T, none_t>::type,
701 typename connection_provider_supports_time_constraint<T, time_traits::duration>::type,
702 typename connection_provider_supports_time_constraint<T, time_traits::time_point>::type
707 template <
typename T>
708 using is_connection_provider =
typename detail::async_get_connection_defined<T>::type;
710 template <
typename T>
711 struct connection_provider_traits {
712 using type = connection_provider_traits;
713 using connection_type =
typename get_connection_type<std::decay_t<T>>::type;
751 template <
typename T>
753 inline constexpr
auto ConnectionProvider = is_connection_provider<std::decay_t<T>>::value;
756 #ifdef OZO_DOCUMENTATION
797 template <
typename T,
typename TimeConstra
int,
typename CompletionToken>
815 template <
typename Initiator>
817 using base =
typename get_connection_op::base;
820 template <
typename T,
typename TimeConstra
int,
typename CompletionToken>
821 decltype(
auto) operator() (T&& provider, TimeConstraint t,
CompletionToken&& token)
const {
823 static_assert(ozo::TimeConstraint<TimeConstraint>,
"should model TimeConstraint concept");
824 return async_initiate<CompletionToken, handler_signature<T>>(
829 template <
typename T,
typename CompletionToken>
830 decltype(
auto) operator() (T&& provider,
CompletionToken&& token)
const {
831 return (*
this)(std::forward<T>(provider),
none, std::forward<CompletionToken>(token));
834 template <
typename OtherInitiator>
835 constexpr
static auto rebind_initiator(
const OtherInitiator& other) {
836 return get_connection_op<OtherInitiator>{other};
841 struct initiate_async_get_connection {
842 template <
typename Prov
ider,
typename Handler,
typename TimeConstra
int>
843 constexpr
void operator()(
Handler&& h, Provider&& p, TimeConstraint t)
const {
844 async_get_connection( std::forward<Provider>(p), t, std::forward<Handler>(h));
849 inline constexpr get_connection_op<detail::initiate_async_get_connection>
get_connection;
866 template <
typename Connection>
890 template <
typename Connection>
892 static_assert(ozo::Connection<Connection>,
"argument should model Connection");
894 auto do_close = [] (
auto conn_ptr) {
900 return std::unique_ptr<
Connection, decltype(do_close)>{conn, do_close};
905 #include <ozo/impl/connection.h>