From 2649db9c65b8faf404cebaa0ae9f5b2e05c8c53f Mon Sep 17 00:00:00 2001 From: "Sergei L. Khandrikov" Date: Sat, 15 Sep 2018 10:46:26 +0300 Subject: [PATCH] Update generated documentation --- docs/howto.md | 2 +- docs/html/annotated.html | 33 +- docs/html/async__connect_8h_source.html | 3 +- docs/html/async__execute_8h_source.html | 2 +- .../binary__deserialization_8h_source.html | 6 +- docs/html/binary__query_8h_source.html | 4 +- .../html/binary__serialization_8h_source.html | 4 +- docs/html/classes.html | 15 +- docs/html/classozo_1_1connection__info.html | 2 +- docs/html/concept_8h_source.html | 8 +- docs/html/connection_8h_source.html | 4 +- docs/html/connection__info_8h_source.html | 4 +- docs/html/connection__pool_8h_source.html | 4 +- docs/html/end__transaction_8h_source.html | 2 +- docs/html/execute_8h_source.html | 5 +- .../group__group-connection-concepts.html | 2 +- .../group__group-connection-functions.html | 8 +- docs/html/group__group-core-concepts.html | 6 +- docs/html/group__group-requests.html | 18 +- docs/html/group__group-requests.js | 2 +- docs/html/group__group-type__system.html | 336 +++++++++++++++++- docs/html/group__group-type__system.js | 12 +- docs/html/hierarchy.html | 25 +- docs/html/impl_2connection_8h_source.html | 4 +- .../impl_2connection__pool_8h_source.html | 3 +- docs/html/io_8h_source.html | 2 +- docs/html/md_docs_howto.html | 2 +- docs/html/namespacemembers.html | 26 +- docs/html/namespacemembers_func.html | 16 +- docs/html/namespacemembers_type.html | 7 +- docs/html/namespacemembers_vars.html | 3 + docs/html/namespaceozo.html | 203 ++--------- docs/html/navtreeindex0.js | 28 +- docs/html/request_8h_source.html | 2 +- docs/html/result_8h_source.html | 5 +- docs/html/search/all_0.js | 2 +- docs/html/search/all_10.js | 2 +- docs/html/search/all_4.js | 4 +- docs/html/search/all_5.js | 1 - docs/html/search/all_8.js | 5 - docs/html/search/all_b.js | 2 + docs/html/search/all_e.js | 1 + docs/html/search/all_f.js | 2 +- docs/html/search/classes_4.js | 2 +- docs/html/search/classes_5.js | 3 +- docs/html/search/classes_6.js | 6 +- docs/html/search/functions_0.js | 2 +- docs/html/search/functions_2.js | 3 +- docs/html/search/functions_7.js | 1 + docs/html/search/functions_8.js | 2 +- docs/html/search/functions_9.js | 2 +- docs/html/search/searchdata.js | 4 +- docs/html/search/typedefs_3.js | 3 +- docs/html/search/variables_6.js | 1 + docs/html/start__transaction_8h_source.html | 2 +- docs/html/structozo_1_1is__built__in.html | 2 +- .../structozo_1_1oid__map__t-members.html | 118 ++++++ docs/html/structozo_1_1oid__map__t.html | 129 +++++++ docs/html/structozo_1_1type__traits.html | 1 + .../structozo_1_1type__traits__helper.html | 3 +- docs/html/transaction_8h_source.html | 2 +- docs/html/type__traits_8h_source.html | 38 +- docs/html/typed__buffer_8h_source.html | 2 +- 63 files changed, 811 insertions(+), 342 deletions(-) create mode 100644 docs/html/structozo_1_1oid__map__t-members.html create mode 100644 docs/html/structozo_1_1oid__map__t.html diff --git a/docs/howto.md b/docs/howto.md index 0271d8bc9..7f96c5e96 100644 --- a/docs/howto.md +++ b/docs/howto.md @@ -40,7 +40,7 @@ int main() { // Request with connection provider, query and callback. // Provider binds how to get connection with io_context. - ozo::request(ozo::make_provider(io, conn_info), query, ozo::into(rows), + ozo::request(ozo::make_connector(io, conn_info), query, ozo::into(rows), [&](ozo::error_code ec, auto conn) { if (ec) { // Here we got an error, so we can get: diff --git a/docs/html/annotated.html b/docs/html/annotated.html index f2f206d18..d2d8cfea1 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -108,24 +108,21 @@  Cbinder  Nimpl  Casync_connect_op - Cfetch_context - Cconnection_infoConnection information - Cconnection_poolConnection pool implementationThis is a simple connection pool implementation which can store up to maximum allowed number of connection to the same database. If all connections are busy client request will be placed into the internal queue to wait for free connection. If where is no free connections but it does not hit the limit of connections the new connection will be created via underlying ConnectionSource being specified in constructor. All operations are timed out. Connection idle life time is timed out as well. Pool is configurable via constructor and operator() - Cconnection_pool_configConnection pool configurationConfiguration of the ozo::connection_pool, e.g. how many connection are in the pool, how many queries can be in wait queue if all connections are used by another queries, and how long to keep connection open - Cconnection_pool_timeoutsTimeouts for the ozo::get_connection() operationTime restrictions to get connection from the ozo::connection_pool - CconnectorDefault implementation of ConnectionProvider - Cget_connection_typeConnection type getter - Cis_array - Cis_built_inCondition indicates if the specified type is built-in for PG - Cis_compositeIndicates if type is a composite.In general we suppose that composite is a type being adapted for introspection via Boost.Fusion or Boost.Hana, including tuples and compile-time sequences - Cis_nullable< boost::optional< T > > - Cis_string - Ctime_traitsTime traits of the library - Ctype_traitsType traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits - Ctype_traits_helperHelper defines the way for the type traits definitions.Type is undefined then Name type is not defined - Nstd - Cdefault_delete< PGconn >Default deleter for PGconn - Cdefault_delete< PGresult >Default deleter for PGresult + Cconnection_infoConnection information + Cconnection_poolConnection pool implementationThis is a simple connection pool implementation which can store up to maximum allowed number of connection to the same database. If all connections are busy client request will be placed into the internal queue to wait for free connection. If where is no free connections but it does not hit the limit of connections the new connection will be created via underlying ConnectionSource being specified in constructor. All operations are timed out. Connection idle life time is timed out as well. Pool is configurable via constructor and operator() + Cconnection_pool_configConnection pool configurationConfiguration of the ozo::connection_pool, e.g. how many connection are in the pool, how many queries can be in wait queue if all connections are used by another queries, and how long to keep connection open + Cconnection_pool_timeoutsTimeouts for the ozo::get_connection() operationTime restrictions to get connection from the ozo::connection_pool + CconnectorDefault implementation of ConnectionProvider + Cget_connection_typeConnection type getter + Cis_built_inCondition indicates if the specified type is built-in for PG + Cis_nullable< boost::optional< T > > + Coid_map_tOidMap implementation type.This type implements OidMap concept based on boost::hana::map + Ctime_traitsTime traits of the library + Ctype_traitsType traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits + Ctype_traits_helperHelper for the type traits definitions + Nstd + Cdefault_delete< PGconn >Default deleter for PGconn + Cdefault_delete< PGresult >Default deleter for PGresult diff --git a/docs/html/async__connect_8h_source.html b/docs/html/async__connect_8h_source.html index 678312cd5..54aa38f77 100644 --- a/docs/html/async__connect_8h_source.html +++ b/docs/html/async__connect_8h_source.html @@ -101,7 +101,7 @@
async_connect.h
-
1 #pragma once
2 
3 #include <ozo/detail/cancel_timer_handler.h>
4 #include <ozo/detail/post_handler.h>
5 #include <ozo/detail/timeout_handler.h>
6 #include <ozo/impl/io.h>
7 #include <ozo/impl/request_oid_map.h>
8 #include <ozo/time_traits.h>
9 #include <ozo/connection.h>
10 
11 #include <boost/asio/bind_executor.hpp>
12 #include <boost/asio/steady_timer.hpp>
13 #include <boost/asio/strand.hpp>
14 #include <boost/asio/post.hpp>
15 
16 namespace ozo {
17 namespace impl {
18 
19 template <typename ConnectionT, typename Handler>
20 struct connect_operation_context {
21  static_assert(Connection<ConnectionT>, "ConnectionT is not a Connection");
22 
23  ConnectionT connection;
24  Handler handler;
25  ozo::strand<decltype(get_io_context(connection))> strand {get_io_context(connection)};
26 
27  connect_operation_context(ConnectionT connection, Handler handler)
28  : connection(std::move(connection)),
29  handler(std::move(handler)) {}
30 };
31 
32 template <typename ... Ts>
33 using connect_operation_context_ptr = std::shared_ptr<connect_operation_context<Ts ...>>;
34 
35 template <typename Connection, typename Handler>
36 auto make_connect_operation_context(Connection&& connection, Handler&& handler) {
37  using context_type = connect_operation_context<std::decay_t<Connection>, std::decay_t<Handler>>;
38  return std::make_shared<context_type>(
39  std::forward<Connection>(connection),
40  std::forward<Handler>(handler)
41  );
42 }
43 
44 template <typename ... Ts>
45 auto& get_connection(const connect_operation_context_ptr<Ts ...>& context) {
46  return context->connection;
47 }
48 
49 template <typename ... Ts>
50 auto& get_handler(const connect_operation_context_ptr<Ts ...>& context) {
51  return context->handler;
52 }
53 
54 template <typename ... Ts>
55 decltype(auto) get_handler_context(const connect_operation_context_ptr<Ts ...>& context) {
56  return std::addressof(context->handler);
57 }
58 
59 template <typename ... Ts>
60 auto& get_executor(const connect_operation_context_ptr<Ts ...>& context) {
61  return context->strand;
62 }
63 
67 template <typename Context>
69  Context context;
70 
71  void perform(const std::string& conninfo, const time_traits::duration& timeout) {
72  if (error_code ec = start_connection(get_connection(context), conninfo)) {
73  return done(ec);
74  }
75 
76  if (connection_bad(get_connection(context))) {
78  }
79 
80  if (error_code ec = assign_socket(get_connection(context))) {
81  return done(ec);
82  }
83 
84  get_timer(get_connection(context)).expires_after(timeout);
85  get_timer(get_connection(context)).async_wait(asio::bind_executor(get_executor(),
86  detail::make_timeout_handler(get_socket(get_connection(context)))));
87 
88  return write_poll(get_connection(context), *this);
89  }
90 
91  void operator () (error_code ec, std::size_t = 0) {
92  if (ec) {
93  set_error_context(get_connection(context), "error while connection polling");
94  return done(ec);
95  }
96 
97  switch (connect_poll(get_connection(context))) {
98  case PGRES_POLLING_OK:
99  return done();
100 
101  case PGRES_POLLING_WRITING:
102  return write_poll(get_connection(context), *this);
103 
104  case PGRES_POLLING_READING:
105  return read_poll(get_connection(context), *this);
106 
107  case PGRES_POLLING_FAILED:
108  case PGRES_POLLING_ACTIVE:
109  break;
110  }
111 
113  }
114 
115  void done(error_code ec = error_code {}) {
116  asio::post(get_executor(),
117  detail::bind(
118  std::move(get_handler(context)),
119  std::move(ec), std::move(get_connection(context))
120  )
121  );
122  }
123 
124  using executor_type = std::decay_t<decltype(impl::get_executor(context))>;
125 
126  auto get_executor() const noexcept {
127  return impl::get_executor(context);
128  }
129 };
130 
131 template <typename Context>
132 inline auto make_async_connect_op(Context&& context) {
133  return async_connect_op<std::decay_t<Context>> {std::forward<Context>(context)};
134 }
135 
136 template <typename Connection, typename Handler>
137 inline void request_oid_map(Connection&& conn, Handler&& handler) {
138  make_async_request_oid_map_op(std::forward<Handler>(handler))
139  .perform(std::forward<Connection>(conn));
140 }
141 
142 template <typename Handler>
143 struct request_oid_map_handler {
144  Handler handler_;
145 
146  template <typename Connection>
147  void operator() (error_code ec, Connection&& conn) {
148  if (ec || empty(get_oid_map(conn))) {
149  handler_(std::move(ec), std::forward<Connection>(conn));
150  } else {
151  request_oid_map(std::forward<Connection>(conn), std::move(handler_));
152  }
153  }
154 };
155 
156 template <typename Handler>
157 inline auto make_request_oid_map_handler(Handler&& handler) {
158  return request_oid_map_handler<std::decay_t<Handler>> {std::forward<Handler>(handler)};
159 }
160 
161 template <typename ConnectionT, typename Handler>
162 inline Require<Connection<ConnectionT>> async_connect(std::string conninfo, const time_traits::duration& timeout,
163  ConnectionT&& connection, Handler&& handler) {
164  make_async_connect_op(
165  make_connect_operation_context(
166  std::forward<ConnectionT>(connection),
167  make_request_oid_map_handler(
168  detail::make_cancel_timer_handler(
169  detail::make_post_handler(std::forward<Handler>(handler))
170  )
171  )
172  )
173  ).perform(conninfo, timeout);
174 }
175 
176 } // namespace impl
177 } // namespace ozo
Definition: async_connect.h:68
+
1 #pragma once
2 
3 #include <ozo/detail/cancel_timer_handler.h>
4 #include <ozo/detail/post_handler.h>
5 #include <ozo/detail/timeout_handler.h>
6 #include <ozo/impl/io.h>
7 #include <ozo/impl/request_oid_map.h>
8 #include <ozo/time_traits.h>
9 #include <ozo/connection.h>
10 
11 #include <boost/asio/bind_executor.hpp>
12 #include <boost/asio/steady_timer.hpp>
13 #include <boost/asio/strand.hpp>
14 #include <boost/asio/post.hpp>
15 
16 namespace ozo {
17 namespace impl {
18 
19 template <typename ConnectionT, typename Handler>
20 struct connect_operation_context {
21  static_assert(Connection<ConnectionT>, "ConnectionT is not a Connection");
22 
23  ConnectionT connection;
24  Handler handler;
25  ozo::strand<decltype(get_io_context(connection))> strand {get_io_context(connection)};
26 
27  connect_operation_context(ConnectionT connection, Handler handler)
28  : connection(std::move(connection)),
29  handler(std::move(handler)) {}
30 };
31 
32 template <typename ... Ts>
33 using connect_operation_context_ptr = std::shared_ptr<connect_operation_context<Ts ...>>;
34 
35 template <typename Connection, typename Handler>
36 auto make_connect_operation_context(Connection&& connection, Handler&& handler) {
37  using context_type = connect_operation_context<std::decay_t<Connection>, std::decay_t<Handler>>;
38  return std::make_shared<context_type>(
39  std::forward<Connection>(connection),
40  std::forward<Handler>(handler)
41  );
42 }
43 
44 template <typename ... Ts>
45 auto& get_connection(const connect_operation_context_ptr<Ts ...>& context) noexcept {
46  return context->connection;
47 }
48 
49 template <typename ... Ts>
50 auto& get_handler(const connect_operation_context_ptr<Ts ...>& context) noexcept {
51  return context->handler;
52 }
53 
54 template <typename ... Ts>
55 decltype(auto) get_handler_context(const connect_operation_context_ptr<Ts ...>& context) noexcept {
56  return std::addressof(context->handler);
57 }
58 
59 template <typename ... Ts>
60 auto& get_executor(const connect_operation_context_ptr<Ts ...>& context) noexcept {
61  return context->strand;
62 }
63 
67 template <typename Context>
69  Context context;
70 
71  void perform(const std::string& conninfo, const time_traits::duration& timeout) {
72  if (error_code ec = start_connection(get_connection(context), conninfo)) {
73  return done(ec);
74  }
75 
76  if (connection_bad(get_connection(context))) {
78  }
79 
80  if (error_code ec = assign_socket(get_connection(context))) {
81  return done(ec);
82  }
83 
84  get_timer(get_connection(context)).expires_after(timeout);
85  get_timer(get_connection(context)).async_wait(asio::bind_executor(get_executor(),
86  detail::make_timeout_handler(get_socket(get_connection(context)))));
87 
88  return write_poll(get_connection(context), *this);
89  }
90 
91  void operator () (error_code ec, std::size_t = 0) {
92  if (ec) {
93  set_error_context(get_connection(context), "error while connection polling");
94  return done(ec);
95  }
96 
97  switch (connect_poll(get_connection(context))) {
98  case PGRES_POLLING_OK:
99  return done();
100 
101  case PGRES_POLLING_WRITING:
102  return write_poll(get_connection(context), *this);
103 
104  case PGRES_POLLING_READING:
105  return read_poll(get_connection(context), *this);
106 
107  case PGRES_POLLING_FAILED:
108  case PGRES_POLLING_ACTIVE:
109  break;
110  }
111 
113  }
114 
115  void done(error_code ec = error_code {}) {
116  asio::post(get_executor(),
117  detail::bind(
118  std::move(get_handler(context)),
119  std::move(ec), std::move(get_connection(context))
120  )
121  );
122  }
123 
124  using executor_type = std::decay_t<decltype(impl::get_executor(context))>;
125 
126  auto get_executor() const noexcept {
127  return impl::get_executor(context);
128  }
129 };
130 
131 template <typename Context>
132 inline auto make_async_connect_op(Context&& context) {
133  return async_connect_op<std::decay_t<Context>> {std::forward<Context>(context)};
134 }
135 
136 template <typename Connection, typename Handler>
137 inline void request_oid_map(Connection&& conn, Handler&& handler) {
138  make_async_request_oid_map_op(std::forward<Handler>(handler))
139  .perform(std::forward<Connection>(conn));
140 }
141 
142 template <typename Handler>
143 struct request_oid_map_handler {
144  Handler handler_;
145 
146  template <typename Connection>
147  void operator() (error_code ec, Connection&& conn) {
148  if (ec || empty(get_oid_map(conn))) {
149  handler_(std::move(ec), std::forward<Connection>(conn));
150  } else {
151  request_oid_map(std::forward<Connection>(conn), std::move(handler_));
152  }
153  }
154 };
155 
156 template <typename Handler>
157 inline auto make_request_oid_map_handler(Handler&& handler) {
158  return request_oid_map_handler<std::decay_t<Handler>> {std::forward<Handler>(handler)};
159 }
160 
161 template <typename ConnectionT, typename Handler>
162 inline Require<Connection<ConnectionT>> async_connect(std::string conninfo, const time_traits::duration& timeout,
163  ConnectionT&& connection, Handler&& handler) {
164  make_async_connect_op(
165  make_connect_operation_context(
166  std::forward<ConnectionT>(connection),
167  make_request_oid_map_handler(
168  detail::make_cancel_timer_handler(
169  detail::make_post_handler(std::forward<Handler>(handler))
170  )
171  )
172  )
173  ).perform(conninfo, timeout);
174 }
175 
176 } // namespace impl
177 } // namespace ozo
Definition: async_connect.h:68
libpq PQconnectPoll function failed
Definition: error.h:54
libpq PQstatus returned CONNECTION_BAD
Definition: error.h:53
Definition: native_conn_handle.h:5
@@ -110,6 +110,7 @@
auto get_connection(T &&provider, CompletionToken &&token)
Get a connection from provider.
Definition: connection.h:851
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
constexpr auto Connection
Database connection concept.
Definition: connection.h:384
+
constexpr bool empty(const oid_map_t< MapImplT > &map) noexcept
Definition: type_traits.h:658
decltype(auto) get_io_context(T &conn) noexcept
IO context for a connection is bound to.
Definition: connection.h:447
decltype(auto) get_oid_map(T &&conn) noexcept
Access to a connection OID map.
Definition: connection.h:572
decltype(auto) get_socket(T &&conn) noexcept
Socket stream object of the connection.
Definition: connection.h:435
diff --git a/docs/html/async__execute_8h_source.html b/docs/html/async__execute_8h_source.html index 4be946f1c..623c2fa85 100644 --- a/docs/html/async__execute_8h_source.html +++ b/docs/html/async__execute_8h_source.html @@ -101,7 +101,7 @@
async_execute.h
-
1 #pragma once
2 
3 #include <ozo/detail/do_nothing.h>
4 #include <ozo/impl/async_request.h>
5 #include <ozo/time_traits.h>
6 
7 namespace ozo {
8 namespace impl {
9 
10 template <typename P, typename Q, typename Handler>
11 void async_execute(P&& provider, Q&& query, const time_traits::duration& timeout, Handler&& handler) {
12  static_assert(ConnectionProvider<P>, "is not a ConnectionProvider");
13  static_assert(Query<Q> || QueryBuilder<Q>, "is neither Query nor QueryBuilder");
14  async_get_connection(std::forward<P>(provider),
15  make_async_request_op(
16  std::forward<Q>(query),
17  timeout,
18  detail::do_nothing {},
19  std::forward<Handler>(handler)
20  )
21  );
22 }
23 
24 template <typename P, typename Q, typename Handler>
25 void async_execute(P&& provider, Q&& query, Handler&& handler) {
26  async_execute(
27  std::forward<P>(provider),
28  std::forward<Q>(query),
29  time_traits::duration::max(),
30  std::forward<Handler>(handler)
31  );
32 }
33 
34 } // namespace impl
35 } // namespace ozo
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
+
1 #pragma once
2 
3 #include <ozo/detail/do_nothing.h>
4 #include <ozo/impl/async_request.h>
5 #include <ozo/time_traits.h>
6 
7 namespace ozo {
8 namespace impl {
9 
10 template <typename P, typename Q, typename Handler>
11 inline void async_execute(P&& provider, Q&& query, const time_traits::duration& timeout, Handler&& handler) {
12  static_assert(ConnectionProvider<P>, "is not a ConnectionProvider");
13  static_assert(Query<Q> || QueryBuilder<Q>, "is neither Query nor QueryBuilder");
14  async_get_connection(std::forward<P>(provider),
15  make_async_request_op(
16  std::forward<Q>(query),
17  timeout,
18  detail::do_nothing {},
19  std::forward<Handler>(handler)
20  )
21  );
22 }
23 
24 } // namespace impl
25 } // namespace ozo
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: asio.h:5
diff --git a/docs/html/binary__deserialization_8h_source.html b/docs/html/binary__deserialization_8h_source.html index 4a5337f6b..deada92b3 100644 --- a/docs/html/binary__deserialization_8h_source.html +++ b/docs/html/binary__deserialization_8h_source.html @@ -101,12 +101,12 @@
binary_deserialization.h
-
1 #pragma once
2 
3 #include <ozo/result.h>
4 #include <ozo/error.h>
5 #include <ozo/type_traits.h>
6 #include <ozo/concept.h>
7 #include <ozo/detail/endian.h>
8 #include <ozo/detail/float.h>
9 #include <ozo/detail/array.h>
10 #include <ozo/istream.h>
11 #include <boost/core/demangle.hpp>
12 #include <boost/hana/for_each.hpp>
13 #include <boost/hana/members.hpp>
14 
15 namespace ozo {
16 template <int... I>
17 constexpr std::tuple<boost::mpl::int_<I>...>
18 make_mpl_index_sequence(std::integer_sequence<int, I...>) {
19  return {};
20 }
21 
22 template <int N>
23 constexpr auto make_index_sequence(boost::mpl::int_<N>) {
24  return make_mpl_index_sequence(
25  std::make_integer_sequence<int, N>{}
26  );
27 }
28 
29 template <typename Adt, typename Index>
30 constexpr decltype(auto) member_name(const Adt&, const Index&) {
31  return fusion::extension::struct_member_name<Adt, Index::value>::call();
32 }
33 
34 template <typename Adt, typename Index>
35 constexpr decltype(auto) member_value(Adt&& v, const Index&) {
36  return fusion::at<Index>(std::forward<Adt>(v));
37 }
38 
39 template <typename Out>
40 bool recv_null(bool is_null, Out& out) {
41  if constexpr (Nullable<Out>) {
42  if (is_null) {
43  reset_nullable(out);
44  return true;
45  }
46  init_nullable(out);
47  } else {
48  if (is_null) {
49  throw std::invalid_argument("unexpected null for type "
50  + boost::core::demangle(typeid(out).name()));
51  }
52  }
53  return false;
54 }
55 
56 template <typename Out, typename = std::void_t<>>
57 struct recv_impl{
58  template <typename M>
59  static istream& apply(istream& in, int32_t size, const oid_map_t<M>&, Out& out) {
60  if constexpr (is_dynamic_size<Out>::value) {
61  out.resize(size);
62  } else {
63  (void)size;
64  }
65  return read(in, out);
66  }
67 };
68 
69 template <typename M, typename Out>
70 inline istream& recv(istream& in, int32_t size, const oid_map_t<M>& oids, Out& out) {
71  if constexpr (!is_dynamic_size<Out>::value) {
72  if (size != static_cast<int32_t>(size_of(out))) {
73  throw std::range_error("data size " + std::to_string(size)
74  + " does not match type size " + std::to_string(size_of(out)));
75  }
76  }
77  return recv_impl<std::decay_t<Out>>::apply(in, size, oids, out);
78 }
79 
80 template <typename T, typename Alloc>
81 struct recv_impl<std::vector<T, Alloc>, Require<!std::is_same_v<T, char>>> {
82  using value_type = std::vector<T, Alloc>;
83 
84  template <typename M>
85  static istream& apply(istream& in, int32_t, const oid_map_t<M>& oids, value_type& out) {
86  detail::pg_array array_header;
87  detail::pg_array_dimension dim_header;
88 
89  read(in, array_header);
90 
91  if (array_header.dimensions_count > 1) {
92  throw std::range_error("multiply dimension count is not supported: "
93  + std::to_string(array_header.dimensions_count));
94  }
95 
96  using item_type = typename value_type::value_type;
97  using unwrapped_item_type = unwrap_nullable_type<item_type>;
98 
99  if (!accepts_oid<unwrapped_item_type>(oids, array_header.elemtype)) {
100  throw system_error(error::oid_type_mismatch,
101  "unexpected oid " + std::to_string(array_header.elemtype)
102  + " for element type of " + boost::core::demangle(typeid(unwrapped_item_type).name()));
103  }
104 
105  if (array_header.dimensions_count < 1) {
106  return in;
107  }
108 
109  read(in, dim_header);
110 
111  if (dim_header.size == 0) {
112  return in;
113  }
114 
115  out.resize(dim_header.size);
116 
117  for (auto& item : out) {
118  int32_t size = 0;
119  read(in, size);
120  const bool is_null = size == -1;
121  if (!recv_null(is_null, item)) {
122  recv(in, size, oids, unwrap_nullable(item));
123  }
124  }
125  return in;
126  }
127 };
128 
129 template <typename T, typename M, typename Out>
130 void recv(const value<T>& in, const oid_map_t<M>& oids, Out& out) {
131  if (recv_null(in.is_null(), out)) {
132  return;
133  }
134 
135  if (!accepts_oid(oids, unwrap_nullable(out), in.oid())) {
136  throw system_error(error::oid_type_mismatch, "unexpected oid "
137  + std::to_string(in.oid()) + " for type "
138  + boost::core::demangle(typeid(unwrap_nullable_type<Out>).name()));
139  }
140 
141  detail::istreambuf_view sbuf(in.data(), in.size());
142  istream s(&sbuf);
143  recv(s, in.size(), oids, unwrap_nullable(out));
144 }
145 
146 template <typename T, typename M, typename Out>
147 Require<!FusionSequence<Out> && !FusionAdaptedStruct<Out>>
148 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
149  if (std::size(in) != 1) {
150  throw std::range_error("row size " + std::to_string(std::size(in))
151  + " does not equal 1 for single column result");
152  }
153 
154  recv(*(in.begin()), oid_map, out);
155 }
156 
157 template <typename T, typename M, typename Out>
158 Require<FusionSequence<Out> && !FusionAdaptedStruct<Out>>
159 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
160 
161  if (static_cast<std::size_t>(fusion::size(out)) != std::size(in)) {
162  throw std::range_error("row size " + std::to_string(std::size(in))
163  + " does not match sequence " + boost::core::demangle(typeid(out).name())
164  + " size " + std::to_string(fusion::size(out)));
165  }
166 
167  auto i = in.begin();
168  fusion::for_each(out, [&](auto& item) {
169  recv(*i, oid_map, item);
170  ++i;
171  });
172 }
173 
174 template <typename T, typename M, typename Out>
175 Require<FusionAdaptedStruct<Out>>
176 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
177 
178  if (static_cast<std::size_t>(fusion::size(out)) != std::size(in)) {
179  throw std::range_error("row size " + std::to_string(std::size(in))
180  + " does not match structure " + boost::core::demangle(typeid(out).name())
181  + " size " + std::to_string(fusion::size(out)));
182  }
183 
184  fusion::for_each(make_index_sequence(fusion::size(out)), [&](auto idx) {
185  auto i = in.find(member_name(out, idx));
186  if (i == in.end()) {
187  throw std::range_error(std::string("row does not contain \"")
188  + member_name(out, idx) + "\" column for "
189  + boost::core::demangle(typeid(out).name()));
190  } else {
191  recv(*i, oid_map, member_value(out, idx));
192  }
193  });
194 }
195 
196 template <typename T, typename M, typename Out>
197 Require<ForwardIterator<Out>, Out>
198 recv_result(const basic_result<T>& in, const oid_map_t<M>& oid_map, Out out) {
199  for (auto row : in) {
200  recv_row(row, oid_map, *out++);
201  }
202  return out;
203 }
204 
205 template <typename T, typename M, typename Out>
206 Require<InsertIterator<Out>, Out>
207 recv_result(const basic_result<T>& in, const oid_map_t<M>& oid_map, Out out) {
208  for (auto row : in) {
209  typename Out::container_type::value_type v{};
210  recv_row(row, oid_map, v);
211  *out++ = std::move(v);
212  }
213  return out;
214 }
215 
216 template <typename T, typename M>
217 basic_result<T>& recv_result(basic_result<T>& in, const oid_map_t<M>&, basic_result<T>& out) {
218  out = std::move(in);
219  return out;
220 }
221 
222 template <typename T, typename M>
223 basic_result<T>& recv_result(basic_result<T>& in, const oid_map_t<M>& oid_map, std::reference_wrapper<basic_result<T>> out) {
224  return recv_result(in, oid_map, out.get());
225 }
226 
227 } // namespace ozo
Definition: native_conn_handle.h:5
+
1 #pragma once
2 
3 #include <ozo/result.h>
4 #include <ozo/error.h>
5 #include <ozo/type_traits.h>
6 #include <ozo/concept.h>
7 #include <ozo/detail/endian.h>
8 #include <ozo/detail/float.h>
9 #include <ozo/detail/array.h>
10 #include <ozo/istream.h>
11 #include <boost/core/demangle.hpp>
12 #include <boost/hana/for_each.hpp>
13 #include <boost/hana/members.hpp>
14 
15 namespace ozo {
16 template <int... I>
17 constexpr std::tuple<boost::mpl::int_<I>...>
18 make_mpl_index_sequence(std::integer_sequence<int, I...>) {
19  return {};
20 }
21 
22 template <int N>
23 constexpr auto make_index_sequence(boost::mpl::int_<N>) {
24  return make_mpl_index_sequence(
25  std::make_integer_sequence<int, N>{}
26  );
27 }
28 
29 template <typename Adt, typename Index>
30 constexpr decltype(auto) member_name(const Adt&, const Index&) {
31  return fusion::extension::struct_member_name<Adt, Index::value>::call();
32 }
33 
34 template <typename Adt, typename Index>
35 constexpr decltype(auto) member_value(Adt&& v, const Index&) {
36  return fusion::at<Index>(std::forward<Adt>(v));
37 }
38 
39 template <typename Out>
40 bool recv_null(bool is_null, Out& out) {
41  if constexpr (Nullable<Out>) {
42  if (is_null) {
43  reset_nullable(out);
44  return true;
45  }
46  init_nullable(out);
47  } else {
48  if (is_null) {
49  throw std::invalid_argument("unexpected null for type "
50  + boost::core::demangle(typeid(out).name()));
51  }
52  }
53  return false;
54 }
55 
56 template <typename Out, typename = std::void_t<>>
57 struct recv_impl{
58  template <typename M>
59  static istream& apply(istream& in, int32_t size, const oid_map_t<M>&, Out& out) {
60  if constexpr (is_dynamic_size<Out>::value) {
61  out.resize(size);
62  } else {
63  (void)size;
64  }
65  return read(in, out);
66  }
67 };
68 
69 template <typename M, typename Out>
70 inline istream& recv(istream& in, int32_t size, const oid_map_t<M>& oids, Out& out) {
71  if constexpr (!is_dynamic_size<Out>::value) {
72  if (size != static_cast<int32_t>(size_of(out))) {
73  throw std::range_error("data size " + std::to_string(size)
74  + " does not match type size " + std::to_string(size_of(out)));
75  }
76  }
77  return recv_impl<std::decay_t<Out>>::apply(in, size, oids, out);
78 }
79 
80 template <typename T, typename Alloc>
81 struct recv_impl<std::vector<T, Alloc>, Require<!std::is_same_v<T, char>>> {
82  using value_type = std::vector<T, Alloc>;
83 
84  template <typename M>
85  static istream& apply(istream& in, int32_t, const oid_map_t<M>& oids, value_type& out) {
86  detail::pg_array array_header;
87  detail::pg_array_dimension dim_header;
88 
89  read(in, array_header);
90 
91  if (array_header.dimensions_count > 1) {
92  throw std::range_error("multiply dimension count is not supported: "
93  + std::to_string(array_header.dimensions_count));
94  }
95 
96  using item_type = typename value_type::value_type;
97  using unwrapped_item_type = unwrap_nullable_type<item_type>;
98 
99  if (!accepts_oid<unwrapped_item_type>(oids, array_header.elemtype)) {
100  throw system_error(error::oid_type_mismatch,
101  "unexpected oid " + std::to_string(array_header.elemtype)
102  + " for element type of " + boost::core::demangle(typeid(unwrapped_item_type).name()));
103  }
104 
105  if (array_header.dimensions_count < 1) {
106  return in;
107  }
108 
109  read(in, dim_header);
110 
111  if (dim_header.size == 0) {
112  return in;
113  }
114 
115  out.resize(dim_header.size);
116 
117  for (auto& item : out) {
118  int32_t size = 0;
119  read(in, size);
120  const bool is_null = size == -1;
121  if (!recv_null(is_null, item)) {
122  recv(in, size, oids, unwrap_nullable(item));
123  }
124  }
125  return in;
126  }
127 };
128 
129 template <>
130 struct recv_impl<pg::name> {
131  template <typename M>
132  static istream& apply(istream& in, int32_t size, const oid_map_t<M>& oid_map, pg::name& out) {
133  return recv_impl<std::string>::apply(in, size, oid_map, out);
134  }
135 };
136 
137 template <typename T, typename M, typename Out>
138 void recv(const value<T>& in, const oid_map_t<M>& oids, Out& out) {
139  if (recv_null(in.is_null(), out)) {
140  return;
141  }
142 
143  if (!accepts_oid(oids, unwrap_nullable(out), in.oid())) {
144  throw system_error(error::oid_type_mismatch, "unexpected oid "
145  + std::to_string(in.oid()) + " for type "
146  + boost::core::demangle(typeid(unwrap_nullable_type<Out>).name()));
147  }
148 
149  detail::istreambuf_view sbuf(in.data(), in.size());
150  istream s(&sbuf);
151  recv(s, in.size(), oids, unwrap_nullable(out));
152 }
153 
154 template <typename T, typename M, typename Out>
155 Require<!FusionSequence<Out> && !FusionAdaptedStruct<Out>>
156 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
157  if (std::size(in) != 1) {
158  throw std::range_error("row size " + std::to_string(std::size(in))
159  + " does not equal 1 for single column result");
160  }
161 
162  recv(*(in.begin()), oid_map, out);
163 }
164 
165 template <typename T, typename M, typename Out>
166 Require<FusionSequence<Out> && !FusionAdaptedStruct<Out>>
167 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
168 
169  if (static_cast<std::size_t>(fusion::size(out)) != std::size(in)) {
170  throw std::range_error("row size " + std::to_string(std::size(in))
171  + " does not match sequence " + boost::core::demangle(typeid(out).name())
172  + " size " + std::to_string(fusion::size(out)));
173  }
174 
175  auto i = in.begin();
176  fusion::for_each(out, [&](auto& item) {
177  recv(*i, oid_map, item);
178  ++i;
179  });
180 }
181 
182 template <typename T, typename M, typename Out>
183 Require<FusionAdaptedStruct<Out>>
184 recv_row(const row<T>& in, const oid_map_t<M>& oid_map, Out& out) {
185 
186  if (static_cast<std::size_t>(fusion::size(out)) != std::size(in)) {
187  throw std::range_error("row size " + std::to_string(std::size(in))
188  + " does not match structure " + boost::core::demangle(typeid(out).name())
189  + " size " + std::to_string(fusion::size(out)));
190  }
191 
192  fusion::for_each(make_index_sequence(fusion::size(out)), [&](auto idx) {
193  auto i = in.find(member_name(out, idx));
194  if (i == in.end()) {
195  throw std::range_error(std::string("row does not contain \"")
196  + member_name(out, idx) + "\" column for "
197  + boost::core::demangle(typeid(out).name()));
198  } else {
199  recv(*i, oid_map, member_value(out, idx));
200  }
201  });
202 }
203 
204 template <typename T, typename M, typename Out>
205 Require<ForwardIterator<Out>, Out>
206 recv_result(const basic_result<T>& in, const oid_map_t<M>& oid_map, Out out) {
207  for (auto row : in) {
208  recv_row(row, oid_map, *out++);
209  }
210  return out;
211 }
212 
213 template <typename T, typename M, typename Out>
214 Require<InsertIterator<Out>, Out>
215 recv_result(const basic_result<T>& in, const oid_map_t<M>& oid_map, Out out) {
216  for (auto row : in) {
217  typename Out::container_type::value_type v{};
218  recv_row(row, oid_map, v);
219  *out++ = std::move(v);
220  }
221  return out;
222 }
223 
224 template <typename T, typename M>
225 basic_result<T>& recv_result(basic_result<T>& in, const oid_map_t<M>&, basic_result<T>& out) {
226  out = std::move(in);
227  return out;
228 }
229 
230 template <typename T, typename M>
231 basic_result<T>& recv_result(basic_result<T>& in, const oid_map_t<M>& oid_map, std::reference_wrapper<basic_result<T>> out) {
232  return recv_result(in, oid_map, out.get());
233 }
234 
235 } // namespace ozo
Definition: native_conn_handle.h:5
decltype(auto) unwrap_nullable(T &&value) noexcept
Dereference Nullable argument or forward it.
Type Require
Concept requirement emulation.
Definition: concept.h:54
no conversion possible from oid to user-supplied type - the type what user expected is not the same a...
Definition: error.h:55
-
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:393
-
bool accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:582
+
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:338
+
bool accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:629
Definition: asio.h:5
diff --git a/docs/html/binary__query_8h_source.html b/docs/html/binary__query_8h_source.html index 2fba9070f..da0d17221 100644 --- a/docs/html/binary__query_8h_source.html +++ b/docs/html/binary__query_8h_source.html @@ -101,9 +101,9 @@
binary_query.h
-
1 #pragma once
2 
3 #include <ozo/binary_serialization.h>
4 #include <ozo/concept.h>
5 #include <ozo/query.h>
6 #include <ozo/type_traits.h>
7 #include <ozo/optional.h>
8 
9 #include <boost/hana/for_each.hpp>
10 #include <boost/hana/tuple.hpp>
11 
12 #include <libpq-fe.h>
13 
14 #include <array>
15 #include <iterator>
16 #include <memory>
17 #include <string_view>
18 #include <vector>
19 
20 namespace ozo {
21 
22 template <class TextT, class ParamsT, class OidMapT, class BufferAllocatorT>
23 class binary_query {
24 public:
25  static_assert(HanaTuple<ParamsT>, "Params must be hana::tuple");
26  static_assert(OidMap<OidMapT>, "OidMapT must be ozo::oid_map_t");
27  static_assert(QueryText<TextT>, "Text must be QueryText concept");
28 
29  using buffer_allocator_type = BufferAllocatorT;
30  using oid_map_type = OidMapT;
31  using text_type = TextT;
32  using params_type = ParamsT;
33 
34  static constexpr auto params_count = decltype(hana::length(std::declval<params_type>()))::value;
35 
36  binary_query(text_type text, const params_type& params, const buffer_allocator_type& buffer_allocator, const oid_map_type& oid_map)
37  : impl(make_impl(std::move(text), params, oid_map, buffer_allocator)) {}
38 
39  constexpr const char* text() const noexcept {
40  return to_const_char(impl->text);
41  }
42 
43  constexpr const ::Oid* types() const noexcept {
44  return std::data(impl->types);
45  }
46 
47  constexpr const int* formats() const noexcept {
48  return std::data(impl->formats);
49  }
50 
51  constexpr const int* lengths() const noexcept {
52  return std::data(impl->lengths);
53  }
54 
55  constexpr const char* const* values() const noexcept {
56  return std::data(impl->values);
57  }
58 
59 private:
60  static constexpr auto binary_format = 1;
61 
62  using buffer_type = std::vector<char, buffer_allocator_type>;
63 
64  struct impl_type {
65  text_type text;
66  buffer_type buffer;
67  std::array<::Oid, params_count> types;
68  std::array<int, params_count> formats;
69  std::array<int, params_count> lengths;
70  std::array<const char*, params_count> values;
71 
72  impl_type(text_type text, const buffer_allocator_type& buffer_allocator)
73  : text(std::move(text)), buffer(buffer_allocator) {}
74 
75  impl_type(const impl_type&) = delete;
76  impl_type(impl_type&&) = delete;
77  };
78 
79  template <std::size_t field>
80  class field_proxy {
81  public:
82  field_proxy(impl_type& result, ostream& os) : result(result), os(os) {}
83 
84  constexpr void set_type(::Oid value) noexcept {
85  result.types[field] = value;
86  }
87 
88  constexpr void set_format(int value) noexcept {
89  result.formats[field] = value;
90  }
91 
92  constexpr void set_length(int value) noexcept {
93  result.lengths[field] = value;
94  }
95 
96  constexpr int stream_pos() noexcept {
97  return int(std::size(result.buffer));
98  }
99 
100  constexpr auto& stream() noexcept {
101  return os;
102  }
103 
104  private:
105  impl_type& result;
106  ozo::ostream& os;
107  };
108 
109  std::shared_ptr<impl_type> impl;
110 
111  static auto make_impl(text_type text, const params_type& params,
112  const oid_map_type& oid_map, const buffer_allocator_type& buffer_allocator) {
113 
114  auto result = std::make_shared<impl_type>(std::move(text), buffer_allocator);
115 
116  ozo::detail::ostreambuf osbuf(result->buffer);
117  ozo::ostream os(&osbuf);
118 
119  const auto range = hana::to<hana::tuple_tag>(
120  hana::make_range(hana::size_c<0>, hana::size_c<params_count>));
121 
122  hana::for_each(range, [&] (auto field) {
123  field_proxy<field> proxy(*result, os);
124  write_meta(oid_map, params[field], proxy);
125  });
126 
127  std::size_t offset = 0;
128  hana::for_each(range, [&] (auto field) {
129  const auto size = result->lengths[field];
130  result->values[field] = size ? std::data(result->buffer) + offset : nullptr;
131  offset += size;
132  }
133  );
134  return result;
135  }
136 
137  template <class T, std::size_t field>
138  static constexpr Require<Nullable<T>> write_meta(const oid_map_type& oid_map, const T& value, field_proxy<field>& result) {
139  if (is_null(value)) {
140  write_null_meta(type_oid<std::decay_t<decltype(*value)>>(oid_map), result);
141  } else {
142  write_meta(oid_map, *value, result);
143  }
144  }
145 
146  template <class T, std::size_t field>
147  static Require<!Nullable<T>> write_meta(const oid_map_type& oid_map, const T& value, field_proxy<field>& result) {
148  using ozo::send;
149  result.set_type(type_oid(oid_map, value));
150  result.set_format(binary_format);
151  const auto start_pos = result.stream_pos();
152  send(result.stream(), oid_map, value);
153  result.set_length(result.stream_pos() - start_pos);
154  }
155 
156  template <class T, std::size_t field>
157  static constexpr Require<!Nullable<T>> write_meta(const oid_map_type& oid_map, const std::reference_wrapper<T>& value, field_proxy<field>& result) {
158  write_meta(oid_map, value.get(), result);
159  }
160 
161  template <class T, std::size_t field>
162  static constexpr void write_meta(const oid_map_type& oid_map, const std::weak_ptr<T>& value, field_proxy<field>& result) {
163  write_meta(oid_map, value.lock(), result);
164  }
165 
166  template <std::size_t field>
167  static constexpr void write_meta(const oid_map_type&, std::nullptr_t, field_proxy<field>& result) noexcept {
168  write_null_meta(null_oid_t::value, result);
169  }
170 
171  template <std::size_t field>
172  static constexpr void write_meta(const oid_map_type&, __OZO_NULLOPT_T, field_proxy<field>& result) noexcept {
173  write_null_meta(null_oid_t::value, result);
174  }
175 
176  template <std::size_t field>
177  static constexpr void write_null_meta(::Oid oid, field_proxy<field>& result) noexcept {
178  result.set_type(oid);
179  result.set_format(binary_format);
180  result.set_length(0);
181  }
182 };
183 
184 template <typename T>
185 struct is_binary_query : std::false_type {};
186 
187 template <typename ... Ts>
188 struct is_binary_query<binary_query<Ts...>> : std::true_type {};
189 
190 template <typename T>
191 constexpr auto BinaryQuery = is_binary_query<std::decay_t<T>>::value;
192 
193 template <class Text, class Params, class M = empty_oid_map, class Alloc = std::allocator<char>,
194  class = Require<QueryText<Text> && HanaTuple<Params>>
195 >
196 auto make_binary_query(Text&& text, const Params& params,
197  const M& oid_map = M{}, const Alloc& buffer_allocator = Alloc{}) {
198  using binary_query_type = binary_query<std::decay_t<Text>, Params, M, Alloc>;
199  return binary_query_type(std::forward<Text>(text), params, buffer_allocator, oid_map);
200 }
201 
202 template <class T, class M = empty_oid_map, class Alloc = std::allocator<char>, class = Require<Query<T>>>
203 auto make_binary_query(const T& query, const M& oid_map = M{}, const Alloc& buffer_allocator = Alloc{}) {
204  return make_binary_query(get_text(query), get_params(query), oid_map, buffer_allocator);
205 }
206 
207 template <class Q, class M, class A>
208 inline Require<BinaryQuery<Q>, Q> make_binary_query(Q query, M&&, A&&) {
209  return std::move(query);
210 }
211 
212 } // namespace ozo
Definition: native_conn_handle.h:5
+
1 #pragma once
2 
3 #include <ozo/binary_serialization.h>
4 #include <ozo/concept.h>
5 #include <ozo/query.h>
6 #include <ozo/type_traits.h>
7 #include <ozo/optional.h>
8 
9 #include <boost/hana/for_each.hpp>
10 #include <boost/hana/tuple.hpp>
11 
12 #include <libpq-fe.h>
13 
14 #include <array>
15 #include <iterator>
16 #include <memory>
17 #include <string_view>
18 #include <vector>
19 
20 namespace ozo {
21 
22 template <class TextT, class ParamsT, class OidMapT, class BufferAllocatorT>
23 class binary_query {
24 public:
25  static_assert(HanaTuple<ParamsT>, "Params must be hana::tuple");
26  static_assert(OidMap<OidMapT>, "OidMapT must be ozo::oid_map_t");
27  static_assert(QueryText<TextT>, "Text must be QueryText concept");
28 
29  using buffer_allocator_type = BufferAllocatorT;
30  using oid_map_type = OidMapT;
31  using text_type = TextT;
32  using params_type = ParamsT;
33 
34  static constexpr auto params_count = decltype(hana::length(std::declval<params_type>()))::value;
35 
36  binary_query(text_type text, const params_type& params, const buffer_allocator_type& buffer_allocator, const oid_map_type& oid_map)
37  : impl(make_impl(std::move(text), params, oid_map, buffer_allocator)) {}
38 
39  constexpr const char* text() const noexcept {
40  return to_const_char(impl->text);
41  }
42 
43  constexpr const ::Oid* types() const noexcept {
44  return std::data(impl->types);
45  }
46 
47  constexpr const int* formats() const noexcept {
48  return std::data(impl->formats);
49  }
50 
51  constexpr const int* lengths() const noexcept {
52  return std::data(impl->lengths);
53  }
54 
55  constexpr const char* const* values() const noexcept {
56  return std::data(impl->values);
57  }
58 
59 private:
60  static constexpr auto binary_format = 1;
61 
62  using buffer_type = std::vector<char, buffer_allocator_type>;
63 
64  struct impl_type {
65  text_type text;
66  buffer_type buffer;
67  std::array<::Oid, params_count> types;
68  std::array<int, params_count> formats;
69  std::array<int, params_count> lengths;
70  std::array<const char*, params_count> values;
71 
72  impl_type(text_type text, const buffer_allocator_type& buffer_allocator)
73  : text(std::move(text)), buffer(buffer_allocator) {}
74 
75  impl_type(const impl_type&) = delete;
76  impl_type(impl_type&&) = delete;
77  };
78 
79  template <std::size_t field>
80  class field_proxy {
81  public:
82  field_proxy(impl_type& result, ostream& os) : result(result), os(os) {}
83 
84  constexpr void set_type(::Oid value) noexcept {
85  result.types[field] = value;
86  }
87 
88  constexpr void set_format(int value) noexcept {
89  result.formats[field] = value;
90  }
91 
92  constexpr void set_length(int value) noexcept {
93  result.lengths[field] = value;
94  }
95 
96  constexpr int stream_pos() noexcept {
97  return int(std::size(result.buffer));
98  }
99 
100  constexpr auto& stream() noexcept {
101  return os;
102  }
103 
104  private:
105  impl_type& result;
106  ozo::ostream& os;
107  };
108 
109  std::shared_ptr<impl_type> impl;
110 
111  static auto make_impl(text_type text, const params_type& params,
112  const oid_map_type& oid_map, const buffer_allocator_type& buffer_allocator) {
113 
114  auto result = std::make_shared<impl_type>(std::move(text), buffer_allocator);
115 
116  ozo::detail::ostreambuf osbuf(result->buffer);
117  ozo::ostream os(&osbuf);
118 
119  const auto range = hana::to<hana::tuple_tag>(
120  hana::make_range(hana::size_c<0>, hana::size_c<params_count>));
121 
122  hana::for_each(range, [&] (auto field) {
123  field_proxy<field> proxy(*result, os);
124  write_meta(oid_map, params[field], proxy);
125  });
126 
127  std::size_t offset = 0;
128  hana::for_each(range, [&] (auto field) {
129  const auto size = result->lengths[field];
130  result->values[field] = size ? std::data(result->buffer) + offset : nullptr;
131  offset += size;
132  }
133  );
134  return result;
135  }
136 
137  template <class T, std::size_t field>
138  static constexpr Require<Nullable<T>> write_meta(const oid_map_type& oid_map, const T& value, field_proxy<field>& result) {
139  if (is_null(value)) {
140  write_null_meta(type_oid<std::decay_t<decltype(*value)>>(oid_map), result);
141  } else {
142  write_meta(oid_map, *value, result);
143  }
144  }
145 
146  template <class T, std::size_t field>
147  static Require<!Nullable<T>> write_meta(const oid_map_type& oid_map, const T& value, field_proxy<field>& result) {
148  using ozo::send;
149  result.set_type(type_oid(oid_map, value));
150  result.set_format(binary_format);
151  const auto start_pos = result.stream_pos();
152  send(result.stream(), oid_map, value);
153  result.set_length(result.stream_pos() - start_pos);
154  }
155 
156  template <class T, std::size_t field>
157  static constexpr Require<!Nullable<T>> write_meta(const oid_map_type& oid_map, const std::reference_wrapper<T>& value, field_proxy<field>& result) {
158  write_meta(oid_map, value.get(), result);
159  }
160 
161  template <class T, std::size_t field>
162  static constexpr void write_meta(const oid_map_type& oid_map, const std::weak_ptr<T>& value, field_proxy<field>& result) {
163  write_meta(oid_map, value.lock(), result);
164  }
165 
166  template <std::size_t field>
167  static constexpr void write_meta(const oid_map_type&, std::nullptr_t, field_proxy<field>& result) noexcept {
168  write_null_meta(null_oid_t::value, result);
169  }
170 
171  template <std::size_t field>
172  static constexpr void write_meta(const oid_map_type&, __OZO_NULLOPT_T, field_proxy<field>& result) noexcept {
173  write_null_meta(null_oid_t::value, result);
174  }
175 
176  template <std::size_t field>
177  static constexpr void write_null_meta(::Oid oid, field_proxy<field>& result) noexcept {
178  result.set_type(oid);
179  result.set_format(binary_format);
180  result.set_length(0);
181  }
182 };
183 
184 template <typename T>
185 struct is_binary_query : std::false_type {};
186 
187 template <typename ... Ts>
188 struct is_binary_query<binary_query<Ts...>> : std::true_type {};
189 
190 template <typename T>
191 constexpr auto BinaryQuery = is_binary_query<std::decay_t<T>>::value;
192 
193 template <class Text, class Params, class M = empty_oid_map, class Alloc = std::allocator<char>,
194  class = Require<QueryText<Text> && HanaTuple<Params>>
195 >
196 auto make_binary_query(Text&& text, const Params& params,
197  const M& oid_map = M{}, const Alloc& buffer_allocator = Alloc{}) {
198  using binary_query_type = binary_query<std::decay_t<Text>, Params, M, Alloc>;
199  return binary_query_type(std::forward<Text>(text), params, buffer_allocator, oid_map);
200 }
201 
202 template <class T, class M = empty_oid_map, class Alloc = std::allocator<char>, class = Require<Query<T>>>
203 auto make_binary_query(const T& query, const M& oid_map = M{}, const Alloc& buffer_allocator = Alloc{}) {
204  return make_binary_query(get_text(query), get_params(query), oid_map, buffer_allocator);
205 }
206 
207 template <class Q, class M, class A>
208 inline Require<BinaryQuery<Q>, Q> make_binary_query(Q query, M&&, A&&) {
209  return std::move(query);
210 }
211 
212 } // namespace ozo
Definition: native_conn_handle.h:5
+
auto type_oid(const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
Definition: type_traits.h:604
Definition: asio.h:5
-
auto type_oid(const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
Definition: type_traits.h:561
diff --git a/docs/html/binary__serialization_8h_source.html b/docs/html/binary__serialization_8h_source.html index ff893cb1c..ebad83093 100644 --- a/docs/html/binary__serialization_8h_source.html +++ b/docs/html/binary__serialization_8h_source.html @@ -101,9 +101,9 @@
binary_serialization.h
-
1 #pragma once
2 
3 #include <ozo/concept.h>
4 #include <ozo/type_traits.h>
5 #include <ozo/ostream.h>
6 #include <ozo/detail/array.h>
7 
8 #include <libpq-fe.h>
9 #include <boost/range/algorithm/for_each.hpp>
10 #include <type_traits>
11 
12 namespace ozo {
13 
14 template <typename In, typename = std::void_t<>>
15 struct send_impl{
16  template <typename M>
17  static ostream& apply(ostream& out, const oid_map_t<M>&, const In& in) {
18  return write(out, in);
19  }
20 };
21 
22 template <class M, class In>
23 inline ostream& send(ostream& out, const oid_map_t<M>& oid_map, const In& in) {
24  return send_impl<In>::apply(out, oid_map, in);
25 }
26 
27 template <typename T, typename Alloc>
28 struct send_impl<std::vector<T, Alloc>, Require<!std::is_same_v<T, char>>> {
29  template <typename M>
30  static ostream& apply(ostream& out, const oid_map_t<M>& oid_map, const std::vector<T, Alloc>& in) {
31  using value_type = std::decay_t<T>;
32  write(out, detail::pg_array {1, 0, ::Oid(type_oid<value_type>(oid_map))});
33  write(out, detail::pg_array_dimension {std::int32_t(std::size(in)), 0});
34  boost::for_each(in,
35  [&] (const auto& v) {
36  write(out, std::int32_t(size_of(v)));
37  send(out, oid_map, v);
38  });
39  return out;
40  }
41 };
42 
43 } // namespace ozo
Definition: native_conn_handle.h:5
+
1 #pragma once
2 
3 #include <ozo/concept.h>
4 #include <ozo/type_traits.h>
5 #include <ozo/ostream.h>
6 #include <ozo/detail/array.h>
7 
8 #include <libpq-fe.h>
9 #include <boost/range/algorithm/for_each.hpp>
10 #include <type_traits>
11 
12 namespace ozo {
13 
14 template <typename In, typename = std::void_t<>>
15 struct send_impl{
16  template <typename M>
17  static ostream& apply(ostream& out, const oid_map_t<M>&, const In& in) {
18  return write(out, in);
19  }
20 };
21 
22 template <class M, class In>
23 inline ostream& send(ostream& out, const oid_map_t<M>& oid_map, const In& in) {
24  return send_impl<In>::apply(out, oid_map, in);
25 }
26 
27 template <typename T, typename Alloc>
28 struct send_impl<std::vector<T, Alloc>, Require<!std::is_same_v<T, char>>> {
29  template <typename M>
30  static ostream& apply(ostream& out, const oid_map_t<M>& oid_map, const std::vector<T, Alloc>& in) {
31  using value_type = std::decay_t<T>;
32  write(out, detail::pg_array {1, 0, ::Oid(type_oid<value_type>(oid_map))});
33  write(out, detail::pg_array_dimension {std::int32_t(std::size(in)), 0});
34  boost::for_each(in,
35  [&] (const auto& v) {
36  write(out, std::int32_t(size_of(v)));
37  send(out, oid_map, v);
38  });
39  return out;
40  }
41 };
42 
43 template <>
44 struct send_impl<pg::name> {
45  template <typename M>
46  static ostream& apply(ostream& out, const oid_map_t<M>& map, const pg::name& in) {
47  return send_impl<std::string>::apply(out, map, in);
48  }
49 };
50 
51 } // namespace ozo
Definition: native_conn_handle.h:5
Type Require
Concept requirement emulation.
Definition: concept.h:54
-
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:393
+
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:338
Definition: asio.h:5
diff --git a/docs/html/classes.html b/docs/html/classes.html index 4c141554a..1cff02a01 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -101,7 +101,7 @@
Class Index
-
a | b | c | d | f | g | i | t
+
a | b | c | d | g | i | o | t
@@ -124,10 +124,6 @@ - - - @@ -135,11 +131,12 @@ - - - + + + @@ -148,7 +145,7 @@
  a  
default_delete< PGconn > (std)   
default_delete< PGresult > (std)   
  f  
-
fetch_context (ozo::impl)   
  g  
  i  
is_array (ozo)   
is_built_in (ozo)   
is_composite (ozo)   
is_nullable< boost::optional< T > > (ozo)   
is_string (ozo)   
  o  
+
oid_map_t (ozo)   
  t  
type_traits_helper (ozo)   
-
a | b | c | d | f | g | i | t
+
a | b | c | d | g | i | o | t
diff --git a/docs/html/classozo_1_1connection__info.html b/docs/html/classozo_1_1connection__info.html index 4708f7dbf..dc0a0914e 100644 --- a/docs/html/classozo_1_1connection__info.html +++ b/docs/html/classozo_1_1connection__info.html @@ -124,7 +124,7 @@

(Note that these are not member functions.)

template<typename OidMap = empty_oid_map, typename Statistics = no_statistics> -auto make_connection_info (std::string conn_str, const OidMap &=OidMap{}, Statistics statistics=Statistics{}) +auto make_connection_info (std::string conn_str, const OidMap &=OidMap{}, Statistics statistics=Statistics{})  Constructs ozo::connection_info ConnectionSource. More...
  diff --git a/docs/html/concept_8h_source.html b/docs/html/concept_8h_source.html index 8e4792601..d7e1e886f 100644 --- a/docs/html/concept_8h_source.html +++ b/docs/html/concept_8h_source.html @@ -101,8 +101,8 @@
concept.h
-
1 #pragma once
2 
3 #ifndef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
4 #error "OZO needs BOOST_HANA_CONFIG_ENABLE_STRING_UDL to be defined"
5 #endif
6 
7 #include <boost/fusion/adapted.hpp>
8 #include <boost/fusion/sequence.hpp>
9 #include <boost/fusion/support/is_sequence.hpp>
10 #include <boost/fusion/include/is_sequence.hpp>
11 #include <boost/hana/core/is_a.hpp>
12 #include <boost/hana/tuple.hpp>
13 #include <boost/hana/string.hpp>
14 #include <typeinfo>
15 #include <type_traits>
16 #include <iterator>
17 
18 namespace ozo {
19 
29 
52 template <bool Condition, typename Type = void>
53 #ifdef OZO_DOCUMENTATION
54 using Require = Type;
55 #else
56 using Require = std::enable_if_t<Condition, Type>;
57 #endif
58 
59 
60 template <typename T, typename = std::void_t<>>
61 struct has_operator_not : std::false_type {};
62 template <typename T>
63 struct has_operator_not<T, std::void_t<decltype(!std::declval<T>())>>
64  : std::true_type {};
65 
73 template <typename T>
74 constexpr auto OperatorNot = has_operator_not<std::decay_t<T>>::value;
75 
76 template <typename T, typename Enable = void>
77 struct is_output_iterator : std::false_type {};
78 
79 template <typename T>
80 struct is_output_iterator<T, typename std::enable_if<
81  std::is_base_of<
82  std::output_iterator_tag,
83  typename std::iterator_traits<T>::iterator_category
84  >::value
85 >::type>
86 : std::true_type {};
87 
95 template <typename T>
96 constexpr auto OutputIterator = is_output_iterator<T>::value;
97 
98 template <typename T, typename Enable = void>
99 struct is_forward_iterator : std::false_type {};
100 
101 template <typename T>
102 struct is_forward_iterator<T, typename std::enable_if<
103  std::is_base_of<
104  std::forward_iterator_tag,
105  typename std::iterator_traits<T>::iterator_category
106  >::value
107 >::type>
108 : std::true_type {};
109 
117 template <typename T>
118 constexpr auto ForwardIterator = is_forward_iterator<T>::value;
119 
120 template <typename T, typename Enable = void>
121 struct is_iterable : std::false_type {};
122 
123 template <typename T>
124 struct is_iterable<T, typename std::enable_if<
125  is_forward_iterator<decltype(begin(std::declval<T>()))>::value &&
126  is_forward_iterator<decltype(end(std::declval<T>()))>::value
127 >::type>
128 : std::true_type {};
129 
137 template <typename T>
138 constexpr auto Iterable = is_iterable<T>::value;
139 
140 template <typename T, typename Enable = void>
141 struct is_insert_iterator : std::false_type {};
142 
143 template <typename T>
144 struct is_insert_iterator<T, typename std::enable_if<
145  is_output_iterator<T>::value && std::is_class<typename T::container_type>::value
146 >::type>
147 : std::true_type {};
148 
156 template <typename T>
157 constexpr auto InsertIterator = is_insert_iterator<T>::value;
158 
166 template <typename T>
167 constexpr auto FusionSequence = boost::fusion::traits::is_sequence<std::decay_t<T>>::value;
168 
176 template <typename T>
177 constexpr auto HanaSequence = boost::hana::Sequence<std::decay_t<T>>::value;
178 
186 template <typename T>
187 constexpr auto HanaStruct = boost::hana::Struct<std::decay_t<T>>::value;
188 
196 template <typename T>
197 constexpr auto HanaString = decltype(boost::hana::is_a<boost::hana::string_tag>(std::declval<T>()))::value;
198 
206 template <typename T>
207 constexpr auto HanaTuple = decltype(boost::hana::is_a<boost::hana::tuple_tag>(std::declval<T>()))::value;
208 
209 
210 template <typename T, typename = std::void_t<>>
211 struct is_fusion_adapted_struct : std::false_type {};
212 
213 template <typename T>
214 struct is_fusion_adapted_struct<T, std::enable_if_t<
215  std::is_same_v<
216  typename boost::fusion::traits::tag_of<T>::type,
217  boost::fusion::struct_tag
218  >
219 >> : std::true_type {};
220 
221 
229 template <typename T>
230 constexpr auto FusionAdaptedStruct = is_fusion_adapted_struct<std::decay_t<T>>::value;
231 
239 template <typename T>
240 constexpr auto Integral = std::is_integral_v<std::decay_t<T>>;
241 
249 template <typename T>
250 constexpr auto FloatingPoint = std::is_floating_point_v<std::decay_t<T>>;
251 
252 template <typename T, typename = std::void_t<>>
253 struct is_raw_data_writable : std::false_type {};
254 
255 template <typename T>
256 struct is_raw_data_writable<T, std::void_t<decltype(std::declval<T&>().data())>> : std::true_type {};
257 
265 template <typename T>
266 constexpr auto RawDataWritable = is_raw_data_writable<std::decay_t<T>>::value;
267 
268 template <typename T, typename = std::void_t<>>
269 struct is_emplaceable : std::false_type {};
270 
271 template <typename T>
272 struct is_emplaceable<T, std::void_t<decltype(std::declval<T&>().emplace())>> : std::true_type {};
273 
281 template <typename T>
282 constexpr auto Emplaceable = is_emplaceable<std::decay_t<T>>::value;
283 
309 #ifdef OZO_DOCUMENTATION
310 template <typename T>
311 constexpr auto CompletionToken = std::false_type;
312 #endif
313 
315 } // namespace ozo
constexpr auto HanaSequence
Boost.Hana Sequence concept.
Definition: concept.h:177
-
constexpr auto RawDataWritable
Raw Data Writable concept.
Definition: concept.h:266
+
1 #pragma once
2 
3 #ifndef BOOST_HANA_CONFIG_ENABLE_STRING_UDL
4 #error "OZO needs BOOST_HANA_CONFIG_ENABLE_STRING_UDL to be defined"
5 #endif
6 
7 #include <boost/fusion/adapted.hpp>
8 #include <boost/fusion/sequence.hpp>
9 #include <boost/fusion/support/is_sequence.hpp>
10 #include <boost/fusion/include/is_sequence.hpp>
11 #include <boost/hana/core/is_a.hpp>
12 #include <boost/hana/tuple.hpp>
13 #include <boost/hana/string.hpp>
14 #include <typeinfo>
15 #include <type_traits>
16 #include <iterator>
17 
18 namespace ozo {
19 
29 
52 template <bool Condition, typename Type = void>
53 #ifdef OZO_DOCUMENTATION
54 using Require = Type;
55 #else
56 using Require = std::enable_if_t<Condition, Type>;
57 #endif
58 
59 
60 template <typename T, typename = std::void_t<>>
61 struct has_operator_not : std::false_type {};
62 template <typename T>
63 struct has_operator_not<T, std::void_t<decltype(!std::declval<T>())>>
64  : std::true_type {};
65 
73 template <typename T>
74 constexpr auto OperatorNot = has_operator_not<std::decay_t<T>>::value;
75 
76 template <typename T, typename Enable = void>
77 struct is_output_iterator : std::false_type {};
78 
79 template <typename T>
80 struct is_output_iterator<T, typename std::enable_if<
81  std::is_base_of<
82  std::output_iterator_tag,
83  typename std::iterator_traits<T>::iterator_category
84  >::value
85 >::type>
86 : std::true_type {};
87 
95 template <typename T>
96 constexpr auto OutputIterator = is_output_iterator<T>::value;
97 
98 template <typename T, typename Enable = void>
99 struct is_forward_iterator : std::false_type {};
100 
101 template <typename T>
102 struct is_forward_iterator<T, typename std::enable_if<
103  std::is_base_of<
104  std::forward_iterator_tag,
105  typename std::iterator_traits<T>::iterator_category
106  >::value
107 >::type>
108 : std::true_type {};
109 
117 template <typename T>
118 constexpr auto ForwardIterator = is_forward_iterator<T>::value;
119 
120 template <typename T, typename Enable = void>
121 struct is_iterable : std::false_type {};
122 
123 template <typename T>
124 struct is_iterable<T, typename std::enable_if<
125  is_forward_iterator<decltype(begin(std::declval<T>()))>::value &&
126  is_forward_iterator<decltype(end(std::declval<T>()))>::value
127 >::type>
128 : std::true_type {};
129 
137 template <typename T>
138 constexpr auto Iterable = is_iterable<T>::value;
139 
140 template <typename T, typename Enable = void>
141 struct is_insert_iterator : std::false_type {};
142 
143 template <typename T>
144 struct is_insert_iterator<T, typename std::enable_if<
145  is_output_iterator<T>::value && std::is_class<typename T::container_type>::value
146 >::type>
147 : std::true_type {};
148 
156 template <typename T>
157 constexpr auto InsertIterator = is_insert_iterator<T>::value;
158 
166 template <typename T>
167 constexpr auto FusionSequence = boost::fusion::traits::is_sequence<std::decay_t<T>>::value;
168 
176 template <typename T>
177 constexpr auto HanaSequence = boost::hana::Sequence<std::decay_t<T>>::value;
178 
186 template <typename T>
187 constexpr auto HanaStruct = boost::hana::Struct<std::decay_t<T>>::value;
188 
196 template <typename T>
197 constexpr auto HanaString = decltype(boost::hana::is_a<boost::hana::string_tag>(std::declval<T>()))::value;
198 
206 template <typename T>
207 constexpr auto HanaTuple = decltype(boost::hana::is_a<boost::hana::tuple_tag>(std::declval<T>()))::value;
208 
209 
210 template <typename T, typename = std::void_t<>>
211 struct is_fusion_adapted_struct : std::false_type {};
212 
213 template <typename T>
214 struct is_fusion_adapted_struct<T, std::enable_if_t<
215  std::is_same_v<
216  typename boost::fusion::traits::tag_of<T>::type,
217  boost::fusion::struct_tag
218  >
219 >> : std::true_type {};
220 
221 
229 template <typename T>
230 constexpr auto FusionAdaptedStruct = is_fusion_adapted_struct<std::decay_t<T>>::value;
231 
239 template <typename T>
240 constexpr auto Integral = std::is_integral_v<std::decay_t<T>>;
241 
249 template <typename T>
250 constexpr auto FloatingPoint = std::is_floating_point_v<std::decay_t<T>>;
251 
252 template <typename T, std::size_t, typename = std::void_t<>>
253 struct has_data : std::false_type {};
254 
255 template <typename T, std::size_t Size>
256 struct has_data<T, Size, std::void_t<decltype(std::declval<T&>().data())>> :
257  std::bool_constant<sizeof(decltype(*std::declval<T&>().data())) == 1> {};
258 
259 template <typename T, std::size_t, typename = std::void_t<>>
260 struct has_friend_data : std::false_type {};
261 
262 template <typename T, std::size_t Size>
263 struct has_friend_data<T, Size, std::void_t<decltype(data(std::declval<T&>()))>> :
264  std::bool_constant<sizeof(decltype(*data(std::declval<T&>()))) == 1> {};
265 
266 template <typename T, typename = std::void_t<>>
267 struct has_size : std::false_type {};
268 
269 template <typename T>
270 struct has_size<T, std::void_t<decltype(std::declval<T&>().size())>> : std::true_type {};
271 
272 template <typename T, typename = std::void_t<>>
273 struct has_friend_size : std::false_type {};
274 
275 template <typename T>
276 struct has_friend_size<T, std::void_t<decltype(size(std::declval<T&>()))>> : std::true_type {};
277 
278 template <typename T>
279 struct is_raw_data_writable : std::bool_constant<
280  (has_data<T, 1>::value && has_size<T>::value) ||
281  (has_friend_data<T, 1>::value && has_friend_size<T>::value)
282 > {};
283 
284 
304 template <typename T>
305 constexpr auto RawDataWritable = is_raw_data_writable<std::decay_t<T>>::value;
306 
307 template <typename T, typename = std::void_t<>>
308 struct is_emplaceable : std::false_type {};
309 
310 template <typename T>
311 struct is_emplaceable<T, std::void_t<decltype(std::declval<T&>().emplace())>> : std::true_type {};
312 
320 template <typename T>
321 constexpr auto Emplaceable = is_emplaceable<std::decay_t<T>>::value;
322 
348 #ifdef OZO_DOCUMENTATION
349 template <typename T>
350 constexpr auto CompletionToken = std::false_type;
351 #endif
352 
354 } // namespace ozo
constexpr auto HanaSequence
Boost.Hana Sequence concept.
Definition: concept.h:177
+
constexpr auto RawDataWritable
RawDataWritable concept.
Definition: concept.h:305
constexpr auto OperatorNot
Operator Not concept.
Definition: concept.h:74
Definition: native_conn_handle.h:5
Type Require
Concept requirement emulation.
Definition: concept.h:54
@@ -115,10 +115,10 @@
constexpr auto HanaStruct
Boost.Hana Structure concept.
Definition: concept.h:187
constexpr auto FloatingPoint
Floating Point concept.
Definition: concept.h:250
constexpr auto Iterable
Iterable concept.
Definition: concept.h:138
-
constexpr auto Emplaceable
Emplaceable concept.
Definition: concept.h:282
+
constexpr auto Emplaceable
Emplaceable concept.
Definition: concept.h:321
Definition: asio.h:5
constexpr auto InsertIterator
Insert Iterator concept.
Definition: concept.h:157
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
constexpr auto FusionAdaptedStruct
Boost.Fusion Adapted Structure concept.
Definition: concept.h:230
diff --git a/docs/html/connection_8h_source.html b/docs/html/connection_8h_source.html index 4fda258b3..590825068 100644 --- a/docs/html/connection_8h_source.html +++ b/docs/html/connection_8h_source.html @@ -118,7 +118,7 @@
decltype(auto) get_statistics(T &&conn) noexcept
Access to a Connection statistics.
Definition: connection.h:586
constexpr auto Connection
Database connection concept.
Definition: connection.h:384
decltype(auto) get_io_context(T &conn) noexcept
IO context for a connection is bound to.
Definition: connection.h:447
-
constexpr auto Nullable
Indicates if type meets nullable requirements.
Definition: type_traits.h:115
+
constexpr auto Nullable
Indicates if type meets nullable requirements.
Definition: type_traits.h:117
error_code rebind_io_context(T &conn, IoContext &io)
Rebinds io_context for the connection.
Definition: connection.h:460
void reset_error_context(T &conn)
Reset connection OZO-related error context.
Definition: connection.h:556
constexpr auto get_connection_error_context(T &&conn)
Get the connection error context object.
@@ -131,7 +131,7 @@
bool connection_bad(const T &conn) noexcept
Indicates if connection state is bad.
Definition: connection.h:474
decltype(auto) get_native_handle(T &&conn) noexcept
PostgreSQL native connection handle.
Definition: connection.h:421
std::string_view error_message(T &&conn)
Gives native libpq error message.
Definition: connection.h:509
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
decltype(auto) get_handle(T &&conn) noexcept
PostgreSQL connection handle.
Definition: connection.h:403
diff --git a/docs/html/connection__info_8h_source.html b/docs/html/connection__info_8h_source.html index bfc2959a4..47d9dc1a2 100644 --- a/docs/html/connection__info_8h_source.html +++ b/docs/html/connection__info_8h_source.html @@ -101,11 +101,13 @@
connection_info.h
-
1 #pragma once
2 
3 #include <ozo/connector.h>
4 #include <ozo/connection.h>
5 #include <ozo/impl/async_connect.h>
6 
7 #include <chrono>
8 
9 namespace ozo {
10 
21 template <
22  typename OidMap = empty_oid_map,
23  typename Statistics = no_statistics>
25  std::string conn_str;
26  Statistics statistics;
27 
28 public:
29  using connection = impl::connection_impl<OidMap, Statistics>;
30  using connection_type = std::shared_ptr<connection>;
31 
32  connection_info(std::string conn_str, Statistics statistics = Statistics{})
33  : conn_str(std::move(conn_str)), statistics(std::move(statistics)) {
34  }
35 
36  template <typename Handler>
37  void operator ()(io_context& io, Handler&& handler,
38  time_traits::duration timeout = time_traits::duration::max()) const {
39  impl::async_connect(
40  conn_str,
41  timeout,
42  std::make_shared<connection>(io, statistics),
43  std::forward<Handler>(handler)
44  );
45  }
46 };
47 
58 template <typename OidMap = empty_oid_map, typename Statistics = no_statistics>
59 inline auto make_connection_info(std::string conn_str, const OidMap& = OidMap{},
60  Statistics statistics = Statistics{}) {
61  return connection_info<OidMap, Statistics>{std::move(conn_str), statistics};
62 }
63 
64 static_assert(ConnectionProvider<connector<connection_info<>>>, "is not a ConnectionProvider");
65 
66 } // namespace ozo
constexpr auto ConnectionProvider
ConnectionProvider concept.
Definition: connection.h:802
+
1 #pragma once
2 
3 #include <ozo/connector.h>
4 #include <ozo/connection.h>
5 #include <ozo/impl/async_connect.h>
6 
7 #include <chrono>
8 
9 namespace ozo {
10 
21 template <
22  typename OidMap = empty_oid_map,
23  typename Statistics = no_statistics>
25  std::string conn_str;
26  Statistics statistics;
27 
28 public:
29  using connection = impl::connection_impl<OidMap, Statistics>;
30  using connection_type = std::shared_ptr<connection>;
31 
32  connection_info(std::string conn_str, Statistics statistics = Statistics{})
33  : conn_str(std::move(conn_str)), statistics(std::move(statistics)) {
34  }
35 
36  template <typename Handler>
37  void operator ()(io_context& io, Handler&& handler,
38  time_traits::duration timeout = time_traits::duration::max()) const {
39  impl::async_connect(
40  conn_str,
41  timeout,
42  std::make_shared<connection>(io, statistics),
43  std::forward<Handler>(handler)
44  );
45  }
46 };
47 
58 template <typename OidMap = empty_oid_map, typename Statistics = no_statistics>
59 inline auto make_connection_info(std::string conn_str, const OidMap& = OidMap{},
60  Statistics statistics = Statistics{}) {
61  return connection_info<OidMap, Statistics>{std::move(conn_str), statistics};
62 }
63 
64 static_assert(ConnectionProvider<connector<connection_info<>>>, "is not a ConnectionProvider");
65 
66 } // namespace ozo
constexpr auto ConnectionProvider
ConnectionProvider concept.
Definition: connection.h:802
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: asio.h:5
auto make_connection_info(std::string conn_str, const OidMap &=OidMap{}, Statistics statistics=Statistics{})
Constructs ozo::connection_info ConnectionSource.
Definition: connection_info.h:59
+
constexpr auto OidMap
Map of C++ types to corresponding PostgreSQL types OIDs.
Definition: type_traits.h:534
Connection information.
Definition: connection_info.h:24
+
std::decay_t< decltype(register_types<>())> empty_oid_map
Type alias for empty OidMap.
Definition: type_traits.h:582
diff --git a/docs/html/connection__pool_8h_source.html b/docs/html/connection__pool_8h_source.html index 760cd545d..cd8a21f3b 100644 --- a/docs/html/connection__pool_8h_source.html +++ b/docs/html/connection__pool_8h_source.html @@ -101,11 +101,11 @@
connection_pool.h
-
1 #pragma once
2 
3 #include <ozo/impl/connection_pool.h>
4 #include <ozo/connection_info.h>
5 #include <ozo/asio.h>
6 
7 namespace ozo {
8 
18  std::size_t capacity = 10;
19  std::size_t queue_capacity = 128;
20  time_traits::duration idle_timeout = std::chrono::seconds(60);
21 };
22 
30  time_traits::duration connect = std::chrono::seconds(10);
31  time_traits::duration queue = std::chrono::seconds(10);
32 };
33 
50 template <typename Source>
52 public:
59  connection_pool(Source source, const connection_pool_config& config)
60  : impl_(config.capacity, config.queue_capacity, config.idle_timeout),
61  source_(std::move(source)) {}
62 
68  using connection_type = impl::pooled_connection_ptr<Source>;
69 
89  template <typename Handler>
90  void operator ()(io_context& io, Handler&& handler,
92  impl_.get_auto_recycle(
93  io,
94  impl::wrap_pooled_connection_handler(
95  io,
96  make_connector(source_, io, timeouts.connect),
97  std::forward<Handler>(handler)
98  ),
99  timeouts.queue
100  );
101  }
102 
103 private:
104  impl::connection_pool<Source> impl_;
105  Source source_;
106 };
107 
108 static_assert(ConnectionProvider<connector<connection_pool<connection_info<>>>>, "is not a ConnectionProvider");
109 
110 template <typename T>
111 struct is_connection_pool : std::false_type {};
112 
113 template <typename ...Args>
114 struct is_connection_pool<connection_pool<Args...>> : std::true_type {};
115 
116 template <typename T>
117 constexpr auto ConnectionPool = is_connection_pool<std::decay_t<T>>::value;
118 
128 template <typename Source>
129 auto make_connection_pool(Source&& source, const connection_pool_config& config) {
130  static_assert(ConnectionSource<Source>, "is not a ConnectionSource");
131  return connection_pool<std::decay_t<Source>>{std::forward<Source>(source), config};
132 }
133 
134 } // namespace ozo
connection_pool(Source source, const connection_pool_config &config)
Construct a new connection pool object.
Definition: connection_pool.h:59
+
1 #pragma once
2 
3 #include <ozo/impl/connection_pool.h>
4 #include <ozo/connection_info.h>
5 #include <ozo/asio.h>
6 
7 namespace ozo {
8 
18  std::size_t capacity = 10;
19  std::size_t queue_capacity = 128;
20  time_traits::duration idle_timeout = std::chrono::seconds(60);
21 };
22 
30  time_traits::duration connect = std::chrono::seconds(10);
31  time_traits::duration queue = std::chrono::seconds(10);
32 };
33 
50 template <typename Source>
52 public:
59  connection_pool(Source source, const connection_pool_config& config)
60  : impl_(config.capacity, config.queue_capacity, config.idle_timeout),
61  source_(std::move(source)) {}
62 
68  using connection_type = impl::pooled_connection_ptr<Source>;
69 
89  template <typename Handler>
90  void operator ()(io_context& io, Handler&& handler,
92  impl_.get_auto_recycle(
93  io,
94  impl::wrap_pooled_connection_handler(
95  io,
96  make_connector(source_, io, timeouts.connect),
97  std::forward<Handler>(handler)
98  ),
99  timeouts.queue
100  );
101  }
102 
103  auto stats() const {
104  return impl_.stats();
105  }
106 
107 private:
108  impl::connection_pool<Source> impl_;
109  Source source_;
110 };
111 
112 static_assert(ConnectionProvider<connector<connection_pool<connection_info<>>>>, "is not a ConnectionProvider");
113 
114 template <typename T>
115 struct is_connection_pool : std::false_type {};
116 
117 template <typename ...Args>
118 struct is_connection_pool<connection_pool<Args...>> : std::true_type {};
119 
120 template <typename T>
121 constexpr auto ConnectionPool = is_connection_pool<std::decay_t<T>>::value;
122 
132 template <typename Source>
133 auto make_connection_pool(Source&& source, const connection_pool_config& config) {
134  static_assert(ConnectionSource<Source>, "is not a ConnectionSource");
135  return connection_pool<std::decay_t<Source>>{std::forward<Source>(source), config};
136 }
137 
138 } // namespace ozo
connection_pool(Source source, const connection_pool_config &config)
Construct a new connection pool object.
Definition: connection_pool.h:59
std::size_t capacity
maximum number of stored connections
Definition: connection_pool.h:18
Definition: native_conn_handle.h:5
constexpr auto ConnectionProvider
ConnectionProvider concept.
Definition: connection.h:802
-
auto make_connection_pool(Source &&source, const connection_pool_config &config)
Connection pool construct helper function.
Definition: connection_pool.h:129
+
auto make_connection_pool(Source &&source, const connection_pool_config &config)
Connection pool construct helper function.
Definition: connection_pool.h:133
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
std::size_t queue_capacity
maximum number of queued requests to get available connection
Definition: connection_pool.h:19
Connection pool configurationConfiguration of the ozo::connection_pool, e.g. how many connection are ...
Definition: connection_pool.h:17
diff --git a/docs/html/end__transaction_8h_source.html b/docs/html/end__transaction_8h_source.html index 1360e3460..36de3df61 100644 --- a/docs/html/end__transaction_8h_source.html +++ b/docs/html/end__transaction_8h_source.html @@ -103,7 +103,7 @@
1 #pragma once
2 
3 #include <ozo/impl/async_end_transaction.h>
4 
5 namespace ozo::impl {
6 
7 template <typename T, typename Query, typename CompletionToken>
8 auto end_transaction(transaction<T>&& transaction, Query&& query,
9  const time_traits::duration& timeout, CompletionToken&& token) {
10  using signature = void (error_code, T);
11 
12  async_completion<CompletionToken, signature> init(token);
13 
14  async_end_transaction(
15  std::move(transaction),
16  std::forward<Query>(query),
17  timeout,
18  init.completion_handler
19  );
20 
21  return init.result.get();
22 }
23 
24 } // namespace ozo::impl
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: async_connect.h:17
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
diff --git a/docs/html/execute_8h_source.html b/docs/html/execute_8h_source.html index 6abc15d34..a94dbed55 100644 --- a/docs/html/execute_8h_source.html +++ b/docs/html/execute_8h_source.html @@ -101,10 +101,11 @@
execute.h
-
1 #pragma once
2 
3 #include <ozo/impl/async_execute.h>
4 
5 namespace ozo {
6 
19 template <typename P, typename Q, typename CompletionToken, typename = Require<ConnectionProvider<P>>>
20 auto execute(P&& provider, Q&& query, CompletionToken&& token) {
21  using signature_t = void (error_code, connection_type<P>);
22  async_completion<CompletionToken, signature_t> init(token);
23 
24  impl::async_execute(std::forward<P>(provider), std::forward<Q>(query), init.completion_handler);
25 
26  return init.result.get();
27 }
28 
29 } // namespace ozo
auto execute(P &&provider, Q &&query, CompletionToken &&token)
Executes query but does not return a resultThis function is same as ozo::request() function except it...
Definition: execute.h:20
+
1 #pragma once
2 
3 #include <ozo/impl/async_execute.h>
4 
5 namespace ozo {
6 
19 template <typename P, typename Q, typename CompletionToken, typename = Require<ConnectionProvider<P>>>
20 inline auto execute(P&& provider, Q&& query, const time_traits::duration& timeout, CompletionToken&& token) {
21  using signature_t = void (error_code, connection_type<P>);
22  async_completion<CompletionToken, signature_t> init(token);
23 
24  impl::async_execute(std::forward<P>(provider), std::forward<Q>(query), timeout, init.completion_handler);
25 
26  return init.result.get();
27 }
28 
29 template <typename P, typename Q, typename CompletionToken, typename = Require<ConnectionProvider<P>>>
30 inline auto execute(P&& provider, Q&& query, CompletionToken&& token) {
31  return execute(
32  std::forward<P>(provider),
33  std::forward<Q>(query),
34  time_traits::duration::max(),
35  std::forward<CompletionToken>(token)
36  );
37 }
38 
39 } // namespace ozo
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
+
auto execute(P &&provider, Q &&query, const time_traits::duration &timeout, CompletionToken &&token)
Executes query but does not return a resultThis function is same as ozo::request() function except it...
Definition: execute.h:20
Definition: asio.h:5
of connection connection_type
Gives exact type of connection which ConnectionProvider or ConnectionSource provide.
Definition: connection.h:658
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
diff --git a/docs/html/group__group-connection-concepts.html b/docs/html/group__group-connection-concepts.html index 45573bc0e..e6546edd8 100644 --- a/docs/html/group__group-connection-concepts.html +++ b/docs/html/group__group-connection-concepts.html @@ -140,7 +140,7 @@

There the oid_map must be a reference or proxy for connection's oid map object, which allows to read and modify it. Object must be created via ozo::register_types() template function or be empty_oid_map in case if no custom types are used with the connection.

+
decltype(auto) oid_map = get_connection_oid_map(unwrap_connection(conn));

There the oid_map must be a reference or proxy for connection's OidMap object, which allows to read and modify it. Object must be created via ozo::register_types() template function or be empty_oid_map in case if no custom types are used with the connection.

decltype(auto) socket = get_connection_socket(unwrap_connection(conn));

Must return reference or proxy for a socket IO stream object which allows to bind the connection to the asio io_context, currently boost::asio::posix::stream_descriptor is suppurted only.

decltype(auto) handle = get_connection_handle(unwrap_connection(conn));

Must return reference or proxy for native_conn_handle object

decltype(auto) timer = get_connection_timer(unwrap_connection(conn));

Must return reference or proxy for timer to plan operations cancel by timeout. Should provide boost::asio::basic_waitable_timer like interface.

diff --git a/docs/html/group__group-connection-functions.html b/docs/html/group__group-connection-functions.html index 04bfec3d3..246c71fa4 100644 --- a/docs/html/group__group-connection-functions.html +++ b/docs/html/group__group-connection-functions.html @@ -197,7 +197,7 @@  Close connection to the database immediately. More...
  template<typename OidMap = empty_oid_map, typename Statistics = no_statistics> -auto make_connection_info (std::string conn_str, const OidMap &=OidMap{}, Statistics statistics=Statistics{}) +auto make_connection_info (std::string conn_str, const OidMap &=OidMap{}, Statistics statistics=Statistics{})  Constructs ozo::connection_info ConnectionSource. More...
  template<typename Source > @@ -481,7 +481,7 @@

Get the connection oid map object.

-

Connection types' OID map getter. This function must be specified for a Connection concept implementation to be conform to. Function must return reference to ozo::oid_map_t template specialization or proxy class object to access connection's types' OID map.

+

Connection types' OID map getter. This function must be specified for a Connection concept implementation to be conform to. Function must return reference to ozo::oid_map_t template specialization or proxy class object to access connection's types' OID map.

Customization Point

This is customization point for Connection concept implementation. To customize it please specialize ozo::get_connection_oid_map_impl template. Default specialization may look like this (for exposition only):

template <typename T, typename = std::void_t<>>
struct get_connection_oid_map_impl {
template <typename Conn>
constexpr static auto apply(Conn&& c) -> decltype((c.oid_map_)) {
return c.oid_map_;
}
};

Function overload works as well, but it is safer to specialize the template.

Parameters
@@ -901,8 +901,8 @@

- - + + diff --git a/docs/html/group__group-core-concepts.html b/docs/html/group__group-core-concepts.html index 8b4ac56bc..24a8a7848 100644 --- a/docs/html/group__group-core-concepts.html +++ b/docs/html/group__group-core-concepts.html @@ -171,7 +171,7 @@ - + @@ -625,8 +625,8 @@

-

Raw Data Writable concept.

-

Indicates if T can be written as a sequence of bytes without endian conversion

Template Parameters
+

RawDataWritable concept.

+

Indicates if T can be written as a sequence of bytes without endian conversion. RawDataWritable<T> is true if for object v of type T applicable one of this code:

auto raw = v.data(); // has_data<T,
static_assert(sizeof(*raw) == 1); // 1>
auto n = v.size(); // has_size<T>

or

auto raw = data(v); // has_friend_data<T,
static_assert(sizeof(*raw) == 1); // 1>
auto n = size(v); // has_friend_size<T>
Template Parameters

const OidMap &  = OidMap{}, const OidMap = OidMap{},
 
template<typename T >
constexpr auto ozo::RawDataWritable
 Raw Data Writable concept. More...
 RawDataWritable concept. More...
 
template<typename T >
constexpr auto ozo::Emplaceable
T- type to examine
diff --git a/docs/html/group__group-requests.html b/docs/html/group__group-requests.html index 7130f95f7..4cf630aac 100644 --- a/docs/html/group__group-requests.html +++ b/docs/html/group__group-requests.html @@ -108,10 +108,10 @@ - - - - + + + +

Functions

template<typename P , typename Q , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
auto ozo::execute (P &&provider, Q &&query, CompletionToken &&token)
 Executes query but does not return a resultThis function is same as ozo::request() function except it does not return any result. It suitable to use with UPDATE INSERT statements, or invoking procedures without result. More...
 
template<typename P , typename Q , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
auto ozo::execute (P &&provider, Q &&query, const time_traits::duration &timeout, CompletionToken &&token)
 Executes query but does not return a resultThis function is same as ozo::request() function except it does not return any result. It suitable to use with UPDATE INSERT statements, or invoking procedures without result. More...
 
template<typename P , typename Q , typename Out , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
auto ozo::request (P &&provider, Q &&query, const time_traits::duration &timeout, Out out, CompletionToken &&token)
 Send request to a database and provides query result (time-out version).
@@ -123,8 +123,8 @@
 

Function Documentation

-
-

◆ execute()

+ +

◆ execute()

@@ -143,6 +143,12 @@

Q &&  query, + + + + const time_traits::duration &  + timeout, + diff --git a/docs/html/group__group-requests.js b/docs/html/group__group-requests.js index 2486370e4..2f3a633a4 100644 --- a/docs/html/group__group-requests.js +++ b/docs/html/group__group-requests.js @@ -1,6 +1,6 @@ var group__group_requests = [ - [ "execute", "group__group-requests.html#ga8883fdec7a4df0150147f8736af47340", null ], + [ "execute", "group__group-requests.html#ga438ed9c31739b1ce13f5f8eae1bbf655", null ], [ "request", "group__group-requests.html#ga3d2edd9e8d3aea4aee843a539d14eb0b", null ], [ "request", "group__group-requests.html#ga748ee23ab6367dcadeec514cd92b8b0e", null ] ]; \ No newline at end of file diff --git a/docs/html/group__group-type__system.html b/docs/html/group__group-type__system.html index 88f82c8dc..b5f451724 100644 --- a/docs/html/group__group-type__system.html +++ b/docs/html/group__group-type__system.html @@ -100,7 +100,9 @@ +Types | +Functions | +Variables

Type system
@@ -110,18 +112,18 @@ - - - - + + + +

Classes

struct  ozo::is_composite< T >
 Indicates if type is a composite.In general we suppose that composite is a type being adapted for introspection via Boost.Fusion or Boost.Hana, including tuples and compile-time sequences. More...
 
struct  ozo::type_traits< T >
 Type traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits. More...
 
struct  ozo::type_traits_helper< T, Name, Oid, Size >
 Helper defines the way for the type traits definitions.Type is undefined then Name type is not defined. More...
 Helper for the type traits definitions. More...
 
struct  ozo::is_built_in< T >
 Condition indicates if the specified type is built-in for PG. More...
 
struct  ozo::oid_map_t< ImplT >
 OidMap implementation type.This type implements OidMap concept based on boost::hana::map. More...
 
@@ -139,6 +141,39 @@ using  + + + +

Macros

ozo::null_oid_t = std::integral_constant< oid_t, 0 >
 Type for non initialized OID.
 
+using ozo::empty_oid_map = std::decay_t< decltype(register_types<>())>
 Type alias for empty OidMap.
 
+ + + + + + + + + + + + + + + + + + + + +

+Functions

template<typename ... T>
decltype(auto) constexpr ozo::register_types () noexcept
 Provides OidMap implementation for user-defined types. More...
 
template<typename T , typename MapImplT >
void ozo::set_type_oid (oid_map_t< MapImplT > &map, oid_t oid) noexcept
 
template<typename T , typename MapImplT >
auto ozo::type_oid (const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
 
template<typename T , typename MapImplT >
bool ozo::accepts_oid (const oid_map_t< MapImplT > &map, oid_t oid) noexcept
 
template<typename T , typename MapImplT >
bool ozo::accepts_oid (const oid_map_t< MapImplT > &map, const T &, oid_t oid) noexcept
 
template<typename MapImplT >
constexpr bool ozo::empty (const oid_map_t< MapImplT > &map) noexcept
 
+ + + + +

+Variables

template<typename T >
constexpr auto ozo::OidMap
 Map of C++ types to corresponding PostgreSQL types OIDs. More...
 

Macro Definition Documentation

@@ -187,7 +222,8 @@

ozo::type_traits specialization. But for a single type you need to define a type, an array of the type, an optional of the type (to support null), shared_ptr... and many other boilerplate. To reduce such things this macro is made.

Note
This macro can be called in the global namespace only
-

E.g. the definition of the uuid type looks like this:

OZO_PG_DEFINE_TYPE_AND_ARRAY(boost::uuids::uuid, "uuid", UUIDOID, 2951, bytes<16>)
Parameters
+

Example

+

E.g. a definition of uuid type looks like this:

OZO_PG_DEFINE_TYPE_AND_ARRAY(boost::uuids::uuid, "uuid", UUIDOID, 2951, bytes<16>)

Definition of user defined composite type may look like this:

BOOST_FUSION_DEFINE_STRUCT((smtp), message,
(std::int64_t, id)
(std::string, from)
(std::vector<std::string>, to)
(std::optional<std::string>, subject)
(std::optional<std::string>, text)
);
//...
OZO_PG_DEFINE_TYPE_AND_ARRAY(smtp::message, "code.message", null_oid, null_oid, dynamic_size)
Parameters
@@ -198,6 +234,294 @@

Function Documentation

+ +

◆ accepts_oid() [1/2]

+ +
+
+
+template<typename T , typename MapImplT >
+
Type— C++ type to be mapped to database type
Name— string with name of database type
+ + + + +
+ + + + + + + + + + + + + + + + + + +
bool ozo::accepts_oid (const oid_map_t< MapImplT > & map,
oid_t oid 
)
+
+noexcept
+
+

Function returns true if type can be obtained from DB response with specified OID.

+
Template Parameters
+ + +
T— type to examine
+
+
+
Parameters
+ + + +
mapOidMap to get type OID from
oid— OID to check for compatibility
+
+
+ +
+ + +

◆ accepts_oid() [2/2]

+ +
+
+
+template<typename T , typename MapImplT >
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool ozo::accepts_oid (const oid_map_t< MapImplT > & map,
const T & ,
oid_t oid 
)
+
+noexcept
+
+

Function returns true if type can be obtained from DB response with specified OID.

+
Parameters
+ + + + +
mapOidMap to get type OID from
constT& — type to examine
oid— OID to check for compatibility
+
+
+ +
+
+ +

◆ empty()

+ +
+
+
+template<typename MapImplT >
+ + + + + +
+ + + + + + + + +
constexpr bool ozo::empty (const oid_map_t< MapImplT > & map)
+
+noexcept
+
+

Checks if OidMap contains no items.

+


+ ### Example

static_assert(empty(ozo::empty_oid_map{}));
Parameters
+ + +
map— OidMap to check
+
+
+
Returns
true if map contains no items, false - if contains.
+ +
+
+ +

◆ register_types()

+ +
+
+
+template<typename ... T>
+ + + + + +
+ + + + + + + +
decltype(auto) constexpr ozo::register_types ()
+
+noexcept
+
+ +

Provides OidMap implementation for user-defined types.

+

This function have to be used to provide information about custom types are being used within requests for a ConnectionSource.

+

Example

+
// User defined type
struct custom_type;
//...
// Providing type information and corresponding database type
OZO_PG_DEFINE_TYPE_AND_ARRAY(custom_type, "code.custom_type", null_oid, null_oid, dynamic_size)
//...
// Creating ConnectionSource for futher requests to a database
const auto conn_source = ozo::make_connection_info("...", regiter_types<custom_type>());
Returns
oid_map_t object.
+ +
+
+ +

◆ set_type_oid()

+ +
+
+
+template<typename T , typename MapImplT >
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void ozo::set_type_oid (oid_map_t< MapImplT > & map,
oid_t oid 
)
+
+noexcept
+
+

Function sets oid for type in OidMap.

+
Template Parameters
+ + +
T— type to set oid for.
+
+
+
Parameters
+ + + +
mapOidMap to modify.
oid— OID to set.
+
+
+ +
+
+ +

◆ type_oid()

+ +
+
+
+template<typename T , typename MapImplT >
+ + + + + +
+ + + + + + + + +
auto ozo::type_oid (const oid_map_t< MapImplT > & map) -> std::enable_if_t<!is_built_in<T>::value, oid_t>
+
+noexcept
+
+

Function returns oid for type from OidMap.

+
Template Parameters
+ + +
T— type to get OID for. &param map — OidMap to get OID from.
+
+
+ +
+
+

Variable Documentation

+ +

◆ OidMap

+ +
+
+
+template<typename T >
+ + + + +
constexpr auto ozo::OidMap
+
+ +

Map of C++ types to corresponding PostgreSQL types OIDs.

+

OidMap is needed to store information about C++ types and corresponding custom database types' OIDs. For PostgreSQL built-in types no mapping is needed since their OIDs are defined in PostgreSQL sources. For custom types their OIDs are defined in a database.

+

OidMap Definition

+

OidMap map is an object for which these next statements are valid:

+
oid_t oid;
//...
set_type_oid<T>(map, oid);

Sets oid for type T in the map.

+
oid_t oid = type_oid<T>(map);

Returns oid value for type T from the map.

+
bool res = empty(map);

Returns true if map has no types OIDs.

+
See also
oid_map_t, register_types(), set_type_oid(), type_oid(), accepts_oid()
+
diff --git a/docs/html/group__group-type__system.js b/docs/html/group__group-type__system.js index 38985473e..c5c307795 100644 --- a/docs/html/group__group-type__system.js +++ b/docs/html/group__group-type__system.js @@ -1,6 +1,5 @@ var group__group_type__system = [ - [ "is_composite", "structozo_1_1is__composite.html", null ], [ "type_traits", "structozo_1_1type__traits.html", [ [ "name", "structozo_1_1type__traits.html#a1d5dbc5e1f0b324f50836a47a80486eb", null ], [ "oid", "structozo_1_1type__traits.html#a188eddb23d740dd449530c45db7993b3", null ], @@ -8,7 +7,16 @@ var group__group_type__system = ] ], [ "type_traits_helper", "structozo_1_1type__traits__helper.html", null ], [ "is_built_in", "structozo_1_1is__built__in.html", null ], + [ "oid_map_t", "structozo_1_1oid__map__t.html", null ], [ "OZO_PG_DEFINE_TYPE_AND_ARRAY", "group__group-type__system.html#ga37e74e6593b00ce3dfda1213bf4b5724", null ], + [ "empty_oid_map", "group__group-type__system.html#gac3359e5eddcb6e0b661a97e33bfcd215", null ], [ "null_oid_t", "group__group-type__system.html#ga6a1c0d23ef107382f509f84757125558", null ], - [ "oid_t", "group__group-type__system.html#ga442ba8c3d090543cf6278acb4fed5e66", null ] + [ "oid_t", "group__group-type__system.html#ga442ba8c3d090543cf6278acb4fed5e66", null ], + [ "accepts_oid", "group__group-type__system.html#ga0082981c9a4ca4163a43b5ac432ae2e6", null ], + [ "accepts_oid", "group__group-type__system.html#gaa3c51f0d200a57fb848dadeb39c79864", null ], + [ "empty", "group__group-type__system.html#ga4ae9202e722b11d284c9d66a1b945838", null ], + [ "register_types", "group__group-type__system.html#gac97d30cda822b83aa3d54f60c658f8f7", null ], + [ "set_type_oid", "group__group-type__system.html#ga078aef0d58433783f8d0cba352732993", null ], + [ "type_oid", "group__group-type__system.html#gabd81e4419a6e16ea9cb416cf8348e35f", null ], + [ "OidMap", "group__group-type__system.html#ga41fff92f9d5a046bcd0654312352e153", null ] ]; \ No newline at end of file diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index 311f8bd18..826db8b97 100644 --- a/docs/html/hierarchy.html +++ b/docs/html/hierarchy.html @@ -112,20 +112,17 @@  Cozo::connector< Base, Args >Default implementation of ConnectionProvider  Cstd::default_delete< PGconn >Default deleter for PGconn  Cstd::default_delete< PGresult >Default deleter for PGresult - Cozo::impl::fetch_context< Connection, Handler > - Cozo::get_connection_type< ConnectionProvider, typename >Connection type getter - Cozo::is_array< T > - Cozo::is_built_in< T >Condition indicates if the specified type is built-in for PG - Cozo::is_composite< T >Indicates if type is a composite.In general we suppose that composite is a type being adapted for introspection via Boost.Fusion or Boost.Hana, including tuples and compile-time sequences - Cozo::is_nullable< boost::optional< T > > - Cozo::is_string< T > - Cozo::time_traitsTime traits of the library - Cozo::type_traits_helper< T, Name, Oid, Size >Helper defines the way for the type traits definitions.Type is undefined then Name type is not defined - Cozo::type_traits_helper< bool, decltype("bool"_s), std::integral_constant< oid_t, BOOLOID >, bytes< 1 > > - Cozo::type_traits_helper< char, decltype("char"_s), std::integral_constant< oid_t, CHAROID >, bytes< 1 > > - Cozo::type_traits_helper< std::vector< char >, decltype("bytea"_s), std::integral_constant< oid_t, BYTEAOID >, dynamic_size > - Cozo::type_traits_helper< T, void > - Cozo::type_traits< T >Type traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits + Cozo::get_connection_type< ConnectionProvider, typename >Connection type getter + Cozo::is_built_in< T >Condition indicates if the specified type is built-in for PG + Cozo::is_nullable< boost::optional< T > > + Cozo::oid_map_t< ImplT >OidMap implementation type.This type implements OidMap concept based on boost::hana::map + Cozo::time_traitsTime traits of the library + Cozo::type_traits_helper< T, Name, Oid, Size >Helper for the type traits definitions + Cozo::type_traits_helper< bool, decltype("bool"_s), std::integral_constant< oid_t, BOOLOID >, bytes< 1 > > + Cozo::type_traits_helper< char, decltype("char"_s), std::integral_constant< oid_t, CHAROID >, bytes< 1 > > + Cozo::type_traits_helper< std::vector< char >, decltype("bytea"_s), std::integral_constant< oid_t, BYTEAOID >, dynamic_size > + Cozo::type_traits_helper< T, void > + Cozo::type_traits< T >Type traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits diff --git a/docs/html/impl_2connection_8h_source.html b/docs/html/impl_2connection_8h_source.html index 1d31fe421..10c497f11 100644 --- a/docs/html/impl_2connection_8h_source.html +++ b/docs/html/impl_2connection_8h_source.html @@ -101,12 +101,14 @@
connection.h
-
1 #pragma once
2 
3 #include <ozo/native_conn_handle.h>
4 #include <ozo/asio.h>
5 
6 #include <boost/algorithm/string/trim.hpp>
7 #include <boost/asio/steady_timer.hpp>
8 #include <boost/asio/posix/stream_descriptor.hpp>
9 
10 #include <string>
11 #include <sstream>
12 
13 namespace ozo {
14 
15 namespace impl {
16 
17 template <typename OidMap, typename Statistics>
18 struct connection_impl {
19  connection_impl(io_context& io, Statistics statistics)
20  : socket_(io), statistics_(std::move(statistics)), timer_(io) {}
21 
22  native_conn_handle handle_;
23  asio::posix::stream_descriptor socket_;
24  OidMap oid_map_;
25  Statistics statistics_; // statistics metatypes to be defined - counter, duration, whatever?
26  std::string error_context_;
27  asio::steady_timer timer_;
28 };
29 
30 inline bool connection_status_bad(PGconn* handle) noexcept {
31  return !handle || PQstatus(handle) == CONNECTION_BAD;
32 }
33 
34 template <typename NativeHandleType>
35 inline auto connection_error_message(NativeHandleType handle) {
36  std::string_view v(PQerrorMessage(handle));
37  auto trim_pos = v.find_last_not_of(' ');
38  if (trim_pos == v.npos) {
39  v.remove_suffix(v.size());
40  } else if (trim_pos < v.size()) {
41  v.remove_suffix(v.size() - trim_pos - 1);
42  }
43  return v;
44 }
45 
46 template <typename Connection, typename IoContext>
47 inline error_code rebind_connection_io_context(Connection& conn, IoContext& io) {
48  if (std::addressof(get_io_context(conn)) != std::addressof(io)) {
49  decltype(auto) socket = get_socket(conn);
50  std::decay_t<decltype(socket)> s{io};
51  error_code ec;
52  s.assign(socket.native_handle(), ec);
53  if (ec) {
54  return ec;
55  }
56  socket.release();
57  socket = std::move(s);
58  }
59  return {};
60 }
61 
62 } // namespace impl
63 } // namespace ozo
Definition: native_conn_handle.h:5
+
1 #pragma once
2 
3 #include <ozo/native_conn_handle.h>
4 #include <ozo/asio.h>
5 
6 #include <boost/algorithm/string/trim.hpp>
7 #include <boost/asio/steady_timer.hpp>
8 #include <boost/asio/posix/stream_descriptor.hpp>
9 
10 #include <string>
11 #include <sstream>
12 
13 namespace ozo {
14 
15 namespace impl {
16 
17 template <typename OidMap, typename Statistics>
18 struct connection_impl {
19  connection_impl(io_context& io, Statistics statistics)
20  : socket_(io), statistics_(std::move(statistics)), timer_(io) {}
21 
22  native_conn_handle handle_;
23  asio::posix::stream_descriptor socket_;
24  OidMap oid_map_;
25  Statistics statistics_; // statistics metatypes to be defined - counter, duration, whatever?
26  std::string error_context_;
27  asio::steady_timer timer_;
28 };
29 
30 inline bool connection_status_bad(PGconn* handle) noexcept {
31  return !handle || PQstatus(handle) == CONNECTION_BAD;
32 }
33 
34 template <typename NativeHandleType>
35 inline auto connection_error_message(NativeHandleType handle) {
36  std::string_view v(PQerrorMessage(handle));
37  auto trim_pos = v.find_last_not_of(' ');
38  if (trim_pos == v.npos) {
39  v.remove_suffix(v.size());
40  } else if (trim_pos < v.size()) {
41  v.remove_suffix(v.size() - trim_pos - 1);
42  }
43  return v;
44 }
45 
46 template <typename Connection, typename IoContext>
47 inline error_code rebind_connection_io_context(Connection& conn, IoContext& io) {
48  if (std::addressof(get_io_context(conn)) != std::addressof(io)) {
49  decltype(auto) socket = get_socket(conn);
50  std::decay_t<decltype(socket)> s{io};
51  error_code ec;
52  s.assign(socket.native_handle(), ec);
53  if (ec) {
54  return ec;
55  }
56  socket.release();
57  socket = std::move(s);
58  get_timer(conn) = std::decay_t<decltype(get_timer(conn))>{io};
59  }
60  return {};
61 }
62 
63 } // namespace impl
64 } // namespace ozo
Definition: native_conn_handle.h:5
+
decltype(auto) get_timer(T &&conn) noexcept
Access to a timer for connection operations.
Definition: connection.h:607
constexpr auto Connection
Database connection concept.
Definition: connection.h:384
decltype(auto) get_io_context(T &conn) noexcept
IO context for a connection is bound to.
Definition: connection.h:447
std::unique_ptr< PGconn > native_conn_handle
libpq PGconn safe RAII representation. libpq PGconn safe RAII representation.
Definition: native_conn_handle.h:30
decltype(auto) get_socket(T &&conn) noexcept
Socket stream object of the connection.
Definition: connection.h:435
Definition: asio.h:5
+
constexpr auto OidMap
Map of C++ types to corresponding PostgreSQL types OIDs.
Definition: type_traits.h:534
diff --git a/docs/html/impl_2connection__pool_8h_source.html b/docs/html/impl_2connection__pool_8h_source.html index a7969dcfd..67fca1256 100644 --- a/docs/html/impl_2connection__pool_8h_source.html +++ b/docs/html/impl_2connection__pool_8h_source.html @@ -101,11 +101,12 @@
connection_pool.h
-
1 #pragma once
2 
3 #include <ozo/connection.h>
4 #include <yamail/resource_pool/async/pool.hpp>
5 #include <ozo/asio.h>
6 
7 namespace ozo::impl {
8 
9 template <typename Source>
10 struct get_connection_pool {
11  using type = yamail::resource_pool::async::pool<
12  std::decay_t<decltype(unwrap_connection(std::declval<connection_type<Source>&>()))>
13  >;
14 };
15 
16 template <typename Source>
17 using connection_pool = typename get_connection_pool<Source>::type;
18 
19 template <typename Source>
20 struct pooled_connection {
21  using handle_type = typename connection_pool<Source>::handle;
22  using underlying_type = typename handle_type::value_type;
23 
24  handle_type handle_;
25 
26  pooled_connection(handle_type&& handle) : handle_(std::move(handle)) {}
27 
28  bool empty() const {return handle_.empty();}
29 
30  void reset(underlying_type&& v) {
31  handle_.reset(std::move(v));
32  }
33 
34  ~pooled_connection() {
35  if (!empty() && connection_bad(*this)) {
36  handle_.waste();
37  }
38  }
39 };
40 template <typename Source>
41 using pooled_connection_ptr = std::shared_ptr<pooled_connection<Source>>;
42 
43 } // namespace ozo::impl
44 namespace ozo {
45 template <typename T>
46 struct unwrap_connection_impl<impl::pooled_connection<T>> {
47  template <typename Conn>
48  static constexpr decltype(auto) apply(Conn&& conn) noexcept {
49  return unwrap_connection(*(conn.handle_));
50  }
51 };
52 } // namespace ozo
53 
54 namespace ozo::impl {
55 
56 template <typename IoContext, typename Provider, typename Handler>
57 struct pooled_connection_wrapper {
58  IoContext& io_;
59  Provider provider_;
60  Handler handler_;
61 
62  using connection = pooled_connection<typename Provider::source_type>;
63  using connection_ptr = pooled_connection_ptr<typename Provider::source_type>;
64 
65  struct wrapper {
66  Handler handler_;
67  connection_ptr conn_;
68 
69  template <typename Conn>
70  void operator () (error_code ec, Conn&& conn) {
71  static_assert(std::is_same_v<connection_type<Provider>, std::decay_t<Conn>>,
72  "Conn must connectiable type of Provider");
73  if (!ec) {
74  conn_->reset(std::move(unwrap_connection(conn)));
75  }
76  handler_(std::move(ec), std::move(conn_));
77  }
78 
79  using executor_type = decltype(asio::get_associated_executor(handler_));
80 
81  auto get_executor() const noexcept {
82  return asio::get_associated_executor(handler_);
83  }
84 
85  template <typename Func>
86  friend void asio_handler_invoke(Func&& f, wrapper* ctx) {
87  using boost::asio::asio_handler_invoke;
88  asio_handler_invoke(std::forward<Func>(f), std::addressof(ctx->handler_));
89  }
90  };
91 
92  template <typename Handle>
93  void operator ()(error_code ec, Handle&& handle) {
94  if (ec) {
95  return handler_(std::move(ec), connection_ptr{});
96  }
97 
98  auto conn = std::make_shared<connection>(std::forward<Handle>(handle));
99  if (!conn->empty() && connection_good(conn)) {
100  ec = rebind_io_context(conn, io_);
101  return handler_(std::move(ec), std::move(conn));
102  }
103 
104  async_get_connection(provider_, wrapper{std::move(handler_), std::move(conn)});
105  }
106 
107  using executor_type = decltype(asio::get_associated_executor(handler_));
108 
109  auto get_executor() const noexcept {
110  return asio::get_associated_executor(handler_);
111  }
112 
113  template <typename Func>
114  friend void asio_handler_invoke(Func&& f, pooled_connection_wrapper* ctx) {
115  using boost::asio::asio_handler_invoke;
116  asio_handler_invoke(std::forward<Func>(f), std::addressof(ctx->handler_));
117  }
118 };
119 
120 template <typename P, typename IoContext, typename Handler>
121 auto wrap_pooled_connection_handler(IoContext& io, P&& provider, Handler&& handler) {
122 
123  static_assert(ConnectionProvider<P>, "is not a ConnectionProvider");
124 
125  return pooled_connection_wrapper<IoContext, std::decay_t<P>, std::decay_t<Handler>> {
126  io, std::forward<P>(provider), std::forward<Handler>(handler)
127  };
128 }
129 
130 static_assert(Connection<pooled_connection_ptr<connection_impl<empty_oid_map, no_statistics>>>,
131  "pooled_connection_ptr is not a Connection concept");
132 
133 static_assert(ConnectionProvider<pooled_connection_ptr<connection_impl<empty_oid_map, no_statistics>>>,
134  "pooled_connection_ptr is not a ConnectionProvider concept");
135 
136 } // namespace ozo::impl
decltype(auto) constexpr unwrap_connection(T &&conn) noexcept
Unwrap connection if wrapped with Nullable.
Definition: connection.h:76
+
1 #pragma once
2 
3 #include <ozo/connection.h>
4 #include <yamail/resource_pool/async/pool.hpp>
5 #include <ozo/asio.h>
6 
7 namespace ozo::impl {
8 
9 template <typename Source>
10 struct get_connection_pool {
11  using type = yamail::resource_pool::async::pool<connection_type<Source>>;
12 };
13 
14 template <typename Source>
15 using connection_pool = typename get_connection_pool<Source>::type;
16 
17 template <typename Source>
18 struct pooled_connection {
19  using handle_type = typename connection_pool<Source>::handle;
20  using underlying_type = typename handle_type::value_type;
21 
22  handle_type handle_;
23 
24  pooled_connection(handle_type&& handle) : handle_(std::move(handle)) {}
25 
26  bool empty() const {return handle_.empty();}
27 
28  void reset(underlying_type&& v) {
29  handle_.reset(std::move(v));
30  }
31 
32  ~pooled_connection() {
33  if (!empty() && connection_bad(*this)) {
34  handle_.waste();
35  }
36  }
37 };
38 template <typename Source>
39 using pooled_connection_ptr = std::shared_ptr<pooled_connection<Source>>;
40 
41 } // namespace ozo::impl
42 namespace ozo {
43 template <typename T>
44 struct unwrap_connection_impl<impl::pooled_connection<T>> {
45  template <typename Conn>
46  static constexpr decltype(auto) apply(Conn&& conn) noexcept {
47  return unwrap_connection(*(conn.handle_));
48  }
49 };
50 } // namespace ozo
51 
52 namespace ozo::impl {
53 
54 template <typename IoContext, typename Provider, typename Handler>
55 struct pooled_connection_wrapper {
56  IoContext& io_;
57  Provider provider_;
58  Handler handler_;
59 
60  using connection = pooled_connection<typename Provider::source_type>;
61  using connection_ptr = pooled_connection_ptr<typename Provider::source_type>;
62 
63  struct wrapper {
64  Handler handler_;
65  connection_ptr conn_;
66 
67  template <typename Conn>
68  void operator () (error_code ec, Conn&& conn) {
69  static_assert(std::is_same_v<connection_type<Provider>, std::decay_t<Conn>>,
70  "Conn must connectiable type of Provider");
71  if (!ec) {
72  conn_->reset(std::move(conn));
73  }
74  handler_(std::move(ec), std::move(conn_));
75  }
76 
77  using executor_type = decltype(asio::get_associated_executor(handler_));
78 
79  auto get_executor() const noexcept {
80  return asio::get_associated_executor(handler_);
81  }
82 
83  template <typename Func>
84  friend void asio_handler_invoke(Func&& f, wrapper* ctx) {
85  using boost::asio::asio_handler_invoke;
86  asio_handler_invoke(std::forward<Func>(f), std::addressof(ctx->handler_));
87  }
88  };
89 
90  template <typename Handle>
91  void operator ()(error_code ec, Handle&& handle) {
92  if (ec) {
93  return handler_(std::move(ec), connection_ptr{});
94  }
95 
96  auto conn = std::make_shared<connection>(std::forward<Handle>(handle));
97  if (!conn->empty() && connection_good(conn)) {
98  ec = rebind_io_context(conn, io_);
99  return handler_(std::move(ec), std::move(conn));
100  }
101 
102  async_get_connection(provider_, wrapper{std::move(handler_), std::move(conn)});
103  }
104 
105  using executor_type = decltype(asio::get_associated_executor(handler_));
106 
107  auto get_executor() const noexcept {
108  return asio::get_associated_executor(handler_);
109  }
110 
111  template <typename Func>
112  friend void asio_handler_invoke(Func&& f, pooled_connection_wrapper* ctx) {
113  using boost::asio::asio_handler_invoke;
114  asio_handler_invoke(std::forward<Func>(f), std::addressof(ctx->handler_));
115  }
116 };
117 
118 template <typename P, typename IoContext, typename Handler>
119 auto wrap_pooled_connection_handler(IoContext& io, P&& provider, Handler&& handler) {
120 
121  static_assert(ConnectionProvider<P>, "is not a ConnectionProvider");
122 
123  return pooled_connection_wrapper<IoContext, std::decay_t<P>, std::decay_t<Handler>> {
124  io, std::forward<P>(provider), std::forward<Handler>(handler)
125  };
126 }
127 
128 static_assert(Connection<pooled_connection_ptr<connection_impl<empty_oid_map, no_statistics>>>,
129  "pooled_connection_ptr is not a Connection concept");
130 
131 static_assert(ConnectionProvider<pooled_connection_ptr<connection_impl<empty_oid_map, no_statistics>>>,
132  "pooled_connection_ptr is not a ConnectionProvider concept");
133 
134 } // namespace ozo::impl
decltype(auto) constexpr unwrap_connection(T &&conn) noexcept
Unwrap connection if wrapped with Nullable.
Definition: connection.h:76
Definition: native_conn_handle.h:5
constexpr auto ConnectionProvider
ConnectionProvider concept.
Definition: connection.h:802
bool connection_good(const T &conn) noexcept
Indicates if connection state is not bad.
Definition: connection.h:494
constexpr auto Connection
Database connection concept.
Definition: connection.h:384
+
constexpr bool empty(const oid_map_t< MapImplT > &map) noexcept
Definition: type_traits.h:658
error_code rebind_io_context(T &conn, IoContext &io)
Rebinds io_context for the connection.
Definition: connection.h:460
Definition: async_connect.h:17
Definition: asio.h:5
diff --git a/docs/html/io_8h_source.html b/docs/html/io_8h_source.html index 85e9db714..6f4163e15 100644 --- a/docs/html/io_8h_source.html +++ b/docs/html/io_8h_source.html @@ -112,7 +112,7 @@
Definition: async_connect.h:17
std::unique_ptr< PGconn > native_conn_handle
libpq PGconn safe RAII representation. libpq PGconn safe RAII representation.
Definition: native_conn_handle.h:30
decltype(auto) get_socket(T &&conn) noexcept
Socket stream object of the connection.
Definition: connection.h:435
-
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:48
+
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:50
std::unique_ptr< PGresult > native_result_handle
libpq PGresult safe RAII representation. libpq PGresult safe RAII representation. ...
Definition: native_result_handle.h:29
decltype(auto) get_native_handle(T &&conn) noexcept
PostgreSQL native connection handle.
Definition: connection.h:421
decltype(auto) get_handle(T &&conn) noexcept
PostgreSQL connection handle.
Definition: connection.h:403
diff --git a/docs/html/md_docs_howto.html b/docs/html/md_docs_howto.html index e74f721e6..37389b2d3 100644 --- a/docs/html/md_docs_howto.html +++ b/docs/html/md_docs_howto.html @@ -105,7 +105,7 @@

How To Make A Very Simple request

E.g. you have very simple table.

CREATE TABLE users_info(
id bigint NOT NULL,
name text,
amount bigint NOT NULL
);

If you want execute just a single query with no custom types or something else then the simplest way for you is:

-
#include <ozo/request.h>
#include <ozo/connection_info.h>
#include <ozo/shortcuts.h>
#include <boost/asio.hpp>
int main() {
// We need io_context for IO, this is alias on boost::asio::io_context
boost::asio::io_context io;
// Rows which accepts integer and nullable string columns in the sequence
// It is an alias on std::vector of std::tuple
ozo::rows_of<std::int64_t, std::optional<std::string>> rows;
// Connection info with host and port to coonect to
ozo::connection_info<> conn_info("host=... port=...");
// For _SQL literal
using namespace ozo::literals;
// Our query statement
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
// Request with connection provider, query and callback.
// Provider binds how to get connection with io_context.
ozo::request(ozo::make_provider(io, conn_info), query, ozo::into(rows),
[&](ozo::error_code ec, auto conn) {
if (ec) {
// Here we got an error, so we can get:
// error code's message
std::cerr << ec.message()
// error message from underlying libpq
<< " | " << error_message(conn)
// and error context from OZO
<< " | " << get_error_context(conn);
return;
};
// Connection must be in good state here,
// typically you do not need to check it manually
assert(ozo::connection_good(conn));
// We got results, let's handle, e.g. print it out
std::cout << "id" << '\t' << "name" << std::endl;
for(auto& row: res) {
std::cout << std::get<0>(row) << '\t'
<< std::get<1>(row) << std::endl;
}
});
io.run();
}

Let's look a little bit closer on this pretty simple asynchronous code.

+
#include <ozo/request.h>
#include <ozo/connection_info.h>
#include <ozo/shortcuts.h>
#include <boost/asio.hpp>
int main() {
// We need io_context for IO, this is alias on boost::asio::io_context
boost::asio::io_context io;
// Rows which accepts integer and nullable string columns in the sequence
// It is an alias on std::vector of std::tuple
ozo::rows_of<std::int64_t, std::optional<std::string>> rows;
// Connection info with host and port to coonect to
ozo::connection_info<> conn_info("host=... port=...");
// For _SQL literal
using namespace ozo::literals;
// Our query statement
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
// Request with connection provider, query and callback.
// Provider binds how to get connection with io_context.
ozo::request(ozo::make_connector(io, conn_info), query, ozo::into(rows),
[&](ozo::error_code ec, auto conn) {
if (ec) {
// Here we got an error, so we can get:
// error code's message
std::cerr << ec.message()
// error message from underlying libpq
<< " | " << error_message(conn)
// and error context from OZO
<< " | " << get_error_context(conn);
return;
};
// Connection must be in good state here,
// typically you do not need to check it manually
assert(ozo::connection_good(conn));
// We got results, let's handle, e.g. print it out
std::cout << "id" << '\t' << "name" << std::endl;
for(auto& row: res) {
std::cout << std::get<0>(row) << '\t'
<< std::get<1>(row) << std::endl;
}
});
io.run();
}

Let's look a little bit closer on this pretty simple asynchronous code.

ozo::rows_of<std::int64_t, std::optional<std::string>> rows;

Here we define result type as we want to see it. Practically ozo::rows_of is an alias on std::vector<std::tuple<...>>. And ozo::into is an alias on std::back_inserter. So request() function will fill this vector of tuples according to the database response rows.

It is very important to preserve the same order of fields in request and types in the tuple (it is a little bit annoying, but there is a way to avoid it via Boost.Hana or Boost.Fusion structure adaptation).

There is std::optional<std::string> at the second position of the tuple. This is because name field of the table can be NULL. Empty optional represens the NULL (learn more about Nullable concept). If you ommit an std::optional then in case of NULL value run-time result deserialization error will happend.

diff --git a/docs/html/namespacemembers.html b/docs/html/namespacemembers.html index 0ca9eefcd..bd989a774 100644 --- a/docs/html/namespacemembers.html +++ b/docs/html/namespacemembers.html @@ -101,7 +101,7 @@

- a -

@@ -145,11 +145,17 @@

- e -

  • Emplaceable : ozo
  • +
  • empty() +: ozo +
  • +
  • empty_oid_map +: ozo +
  • error_message() : ozo
  • execute() -: ozo +: ozo
@@ -239,12 +245,6 @@

- i -

  • Integral : ozo
  • -
  • is_fusion_adapted -: ozo -
  • -
  • is_hana_adapted -: ozo -
  • is_null() : ozo
  • @@ -274,6 +274,9 @@

    - o -

    • oid_t : ozo
    • +
    • OidMap +: ozo +
    • OperatorNot : ozo
    • @@ -290,6 +293,9 @@

      - r -

      • rebind_io_context() : ozo
      • +
      • register_types() +: ozo +
      • request() : ozo
      • @@ -307,7 +313,7 @@

        - s -

          : ozo
        • set_type_oid() -: ozo +: ozo
        • size_of() : ozo @@ -320,7 +326,7 @@

          - t -

          diff --git a/docs/html/namespacemembers_func.html b/docs/html/namespacemembers_func.html index 393005075..0f1ea902b 100644 --- a/docs/html/namespacemembers_func.html +++ b/docs/html/namespacemembers_func.html @@ -101,7 +101,7 @@

          - a -

          @@ -120,11 +120,14 @@

          - c -

            - e -

              +
            • empty() +: ozo +
            • error_message() : ozo
            • execute() -: ozo +: ozo
            @@ -186,8 +189,11 @@

            - r -

            • rebind_io_context() : ozo
            • +
            • register_types() +: ozo +
            • request() -: ozo +: ozo
            • reset_error_context() : ozo @@ -200,7 +206,7 @@

              - s -

                : ozo
              • set_type_oid() -: ozo +: ozo
              • size_of() : ozo @@ -213,7 +219,7 @@

                - t -

                diff --git a/docs/html/namespacemembers_type.html b/docs/html/namespacemembers_type.html index ba2b42d96..b3cf1dab0 100644 --- a/docs/html/namespacemembers_type.html +++ b/docs/html/namespacemembers_type.html @@ -104,11 +104,8 @@
              • connection_type : ozo
              • -
              • is_fusion_adapted -: ozo -
              • -
              • is_hana_adapted -: ozo +
              • empty_oid_map +: ozo
              • native_conn_handle : ozo diff --git a/docs/html/namespacemembers_vars.html b/docs/html/namespacemembers_vars.html index 5072c676a..48900a275 100644 --- a/docs/html/namespacemembers_vars.html +++ b/docs/html/namespacemembers_vars.html @@ -149,6 +149,9 @@
              • Nullable : ozo
              • +
              • OidMap +: ozo +
              • OperatorNot : ozo
              • diff --git a/docs/html/namespaceozo.html b/docs/html/namespaceozo.html index 8b6482e9c..15158cb8e 100644 --- a/docs/html/namespaceozo.html +++ b/docs/html/namespaceozo.html @@ -127,17 +127,13 @@ struct  get_connection_type  Connection type getter. More...
                  -struct  is_array -  struct  is_built_in  Condition indicates if the specified type is built-in for PG. More...
                  -struct  is_composite - Indicates if type is a composite.In general we suppose that composite is a type being adapted for introspection via Boost.Fusion or Boost.Hana, including tuples and compile-time sequences. More...
                -  struct  is_nullable< boost::optional< T > >   -struct  is_string +struct  oid_map_t + OidMap implementation type.This type implements OidMap concept based on boost::hana::map. More...
                  struct  time_traits  Time traits of the library. More...
                @@ -146,7 +142,7 @@  Type traits template forward declaration.Type traits contains information related to it's representation in the database. There are two different kind of traits - built-in types with constant OIDs and custom types with database depent OIDs. The functions below describe neccesary traits. For built-in types traits will be defined there. For custom types user must define traits. More...
                  struct  type_traits_helper - Helper defines the way for the type traits definitions.Type is undefined then Name type is not defined. More...
                + Helper for the type traits definitions. More...
                  - - - - - - + + +

                @@ -175,15 +171,13 @@ using 

                null_oid_t = std::integral_constant< oid_t, 0 >
                 Type for non initialized OID.
                 
                template<typename T >
                using is_fusion_adapted = std::integral_constant< bool, boost::fusion::traits::is_sequence< T >::value >
                 
                template<typename T >
                using is_hana_adapted = std::integral_constant< bool, hana::Sequence< T >::value||hana::Struct< T >::value >
                 
                template<std::size_t n>
                using bytes = std::integral_constant< std::size_t, n >
                 
                +using empty_oid_map = std::decay_t< decltype(register_types<>())>
                 Type alias for empty OidMap.
                 
                @@ -275,10 +269,10 @@ - - - - + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + +

                Functions

                void close_connection (T &&conn)
                 Close connection to the database immediately. More...
                 
                template<typename P , typename Q , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
                auto execute (P &&provider, Q &&query, CompletionToken &&token)
                 Executes query but does not return a resultThis function is same as ozo::request() function except it does not return any result. It suitable to use with UPDATE INSERT statements, or invoking procedures without result. More...
                 
                template<typename P , typename Q , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
                auto execute (P &&provider, Q &&query, const time_traits::duration &timeout, CompletionToken &&token)
                 Executes query but does not return a resultThis function is same as ozo::request() function except it does not return any result. It suitable to use with UPDATE INSERT statements, or invoking procedures without result. More...
                 
                template<typename P , typename Q , typename Out , typename CompletionToken , typename = Require<ConnectionProvider<P>>>
                auto request (P &&provider, Q &&query, const time_traits::duration &timeout, Out out, CompletionToken &&token)
                 Send request to a database and provides query result (time-out version).
                @@ -302,15 +296,25 @@
                template<typename T >
                constexpr auto size_of (T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
                 
                template<typename T , typename MapImplT >
                void set_type_oid (oid_map_t< MapImplT > &map, oid_t oid) noexcept
                 
                template<typename T , typename MapImplT >
                auto type_oid (const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
                 
                template<typename T , typename MapImplT >
                bool accepts_oid (const oid_map_t< MapImplT > &map, oid_t oid) noexcept
                 
                template<typename ... T>
                decltype(auto) constexpr register_types () noexcept
                 Provides OidMap implementation for user-defined types. More...
                 
                template<typename T , typename MapImplT >
                void set_type_oid (oid_map_t< MapImplT > &map, oid_t oid) noexcept
                 
                template<typename T , typename MapImplT >
                auto type_oid (const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
                 
                template<typename T , typename MapImplT >
                bool accepts_oid (const oid_map_t< MapImplT > &map, oid_t oid) noexcept
                 
                template<typename T , typename MapImplT >
                bool accepts_oid (const oid_map_t< MapImplT > &map, const T &, oid_t oid) noexcept
                 
                template<typename MapImplT >
                constexpr bool empty (const oid_map_t< MapImplT > &map) noexcept
                 
                @@ -368,7 +372,7 @@ - + @@ -394,6 +398,10 @@ + + + +

                Variables

                 
                template<typename T >
                constexpr auto RawDataWritable
                 Raw Data Writable concept. More...
                 RawDataWritable concept. More...
                 
                template<typename T >
                constexpr auto Emplaceable
                constexpr auto Nullable
                 Indicates if type meets nullable requirements. More...
                 
                template<typename T >
                constexpr auto OidMap
                 Map of C++ types to corresponding PostgreSQL types OIDs. More...
                 

                Description

                Useful shortcuts for typed unnamed results containers

                @@ -413,121 +421,9 @@

                Helpers to make size trait constant bytes - makes fixed size trait dynamic_size - makes dynamis size trait

                -

                -
- -

◆ is_fusion_adapted

- -
-
-
-template<typename T >
- - - - -
using ozo::is_fusion_adapted = typedef std::integral_constant<bool, boost::fusion::traits::is_sequence<T>::value >
-
-

Indicates if type is adapted for introspection with Boost.Fusion

- -
-
- -

◆ is_hana_adapted

- -
-
-
-template<typename T >
- - - - -
using ozo::is_hana_adapted = typedef std::integral_constant<bool, hana::Sequence<T>::value || hana::Struct<T>::value >
-
-

Indicates if type is adapted for introspection with Boost.Hana

-

Function Documentation

- -

◆ accepts_oid()

- -
-
-
-template<typename T , typename MapImplT >
- - - - - -
- - - - - - - - - - - - - - - - - - -
bool ozo::accepts_oid (const oid_map_t< MapImplT > & map,
oid_t oid 
)
-
-noexcept
-
-

Function returns true if type can be obtained from DB response with specified oid.

- -
-
- -

◆ set_type_oid()

- -
-
-
-template<typename T , typename MapImplT >
- - - - - -
- - - - - - - - - - - - - - - - - - -
void ozo::set_type_oid (oid_map_t< MapImplT > & map,
oid_t oid 
)
-
-noexcept
-
-

Function sets oid for type in oid map.

- -
-

◆ size_of()

@@ -585,35 +481,6 @@

Function returns type name in Postgre SQL. For custom types user must define this name.

-

-
- -

◆ type_oid()

- -
-
-
-template<typename T , typename MapImplT >
- - - - - -
- - - - - - - - -
auto ozo::type_oid (const oid_map_t< MapImplT > & map) -> std::enable_if_t<!is_built_in<T>::value, oid_t>
-
-noexcept
-
-

Function returns oid for type from oid map.

-
diff --git a/docs/html/navtreeindex0.js b/docs/html/navtreeindex0.js index 627d384de..0e214f068 100644 --- a/docs/html/navtreeindex0.js +++ b/docs/html/navtreeindex0.js @@ -90,12 +90,20 @@ var NAVTREEINDEX0 = "group__group-query.html":[2,5], "group__group-requests.html":[2,3], "group__group-requests.html#ga3d2edd9e8d3aea4aee843a539d14eb0b":[2,3,1], +"group__group-requests.html#ga438ed9c31739b1ce13f5f8eae1bbf655":[2,3,0], "group__group-requests.html#ga748ee23ab6367dcadeec514cd92b8b0e":[2,3,2], -"group__group-requests.html#ga8883fdec7a4df0150147f8736af47340":[2,3,0], "group__group-type__system.html":[2,2,3], +"group__group-type__system.html#ga0082981c9a4ca4163a43b5ac432ae2e6":[2,2,3,8], +"group__group-type__system.html#ga078aef0d58433783f8d0cba352732993":[2,2,3,12], "group__group-type__system.html#ga37e74e6593b00ce3dfda1213bf4b5724":[2,2,3,4], -"group__group-type__system.html#ga442ba8c3d090543cf6278acb4fed5e66":[2,2,3,6], -"group__group-type__system.html#ga6a1c0d23ef107382f509f84757125558":[2,2,3,5], +"group__group-type__system.html#ga41fff92f9d5a046bcd0654312352e153":[2,2,3,14], +"group__group-type__system.html#ga442ba8c3d090543cf6278acb4fed5e66":[2,2,3,7], +"group__group-type__system.html#ga4ae9202e722b11d284c9d66a1b945838":[2,2,3,10], +"group__group-type__system.html#ga6a1c0d23ef107382f509f84757125558":[2,2,3,6], +"group__group-type__system.html#gaa3c51f0d200a57fb848dadeb39c79864":[2,2,3,9], +"group__group-type__system.html#gabd81e4419a6e16ea9cb416cf8348e35f":[2,2,3,13], +"group__group-type__system.html#gac3359e5eddcb6e0b661a97e33bfcd215":[2,2,3,5], +"group__group-type__system.html#gac97d30cda822b83aa3d54f60c658f8f7":[2,2,3,11], "index.html":[0], "index.html":[], "md_docs_howto.html":[1], @@ -109,14 +117,14 @@ var NAVTREEINDEX0 = "structozo_1_1connection__pool__timeouts.html#a064ac09df4241f3bd581269a9f27c38e":[2,0,2,3,0], "structozo_1_1connection__pool__timeouts.html#a8dd364f2a64bd2be5271eb4a3d4ac807":[2,0,2,3,1], "structozo_1_1get__connection__type.html":[2,0,2,0], -"structozo_1_1is__built__in.html":[2,2,3,3], -"structozo_1_1is__composite.html":[2,2,3,0], +"structozo_1_1is__built__in.html":[2,2,3,2], +"structozo_1_1oid__map__t.html":[2,2,3,3], "structozo_1_1time__traits.html":[2,2,2,0], "structozo_1_1time__traits.html#a7272c9a4857bf785826771866f18fe67":[2,2,2,0,0], "structozo_1_1time__traits.html#ae4cacabb70251a965ddfbac02da16f72":[2,2,2,0,1], -"structozo_1_1type__traits.html":[2,2,3,1], -"structozo_1_1type__traits.html#a188eddb23d740dd449530c45db7993b3":[2,2,3,1,1], -"structozo_1_1type__traits.html#a1d5dbc5e1f0b324f50836a47a80486eb":[2,2,3,1,0], -"structozo_1_1type__traits.html#ad1a21be06fcb34bf612a7c516159fccd":[2,2,3,1,2], -"structozo_1_1type__traits__helper.html":[2,2,3,2] +"structozo_1_1type__traits.html":[2,2,3,0], +"structozo_1_1type__traits.html#a188eddb23d740dd449530c45db7993b3":[2,2,3,0,1], +"structozo_1_1type__traits.html#a1d5dbc5e1f0b324f50836a47a80486eb":[2,2,3,0,0], +"structozo_1_1type__traits.html#ad1a21be06fcb34bf612a7c516159fccd":[2,2,3,0,2], +"structozo_1_1type__traits__helper.html":[2,2,3,1] }; diff --git a/docs/html/request_8h_source.html b/docs/html/request_8h_source.html index 7665e9eee..45783641f 100644 --- a/docs/html/request_8h_source.html +++ b/docs/html/request_8h_source.html @@ -105,7 +105,7 @@
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: asio.h:5
of connection connection_type
Gives exact type of connection which ConnectionProvider or ConnectionSource provide.
Definition: connection.h:658
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
diff --git a/docs/html/result_8h_source.html b/docs/html/result_8h_source.html index 26f254ad1..d47ea2a4d 100644 --- a/docs/html/result_8h_source.html +++ b/docs/html/result_8h_source.html @@ -101,8 +101,9 @@
result.h
-
1 #pragma once
2 
3 #include <ozo/impl/io.h>
4 #include <ozo/type_traits.h>
5 #include <ozo/native_result_handle.h>
6 
7 #include <libpq-fe.h>
8 
9 #include <boost/iterator/iterator_facade.hpp>
10 #include <memory>
11 #include <vector>
12 
13 
14 namespace ozo {
15 
16 template <typename Result>
17 class value {
18 public:
19  struct coordinates {
20  const Result* res;
21  int row;
22  int col;
23  };
24 
25  value(const coordinates& v) : v_(v) {}
26 
27  oid_t oid() const noexcept {
28  return impl::field_type(res(), column());
29  }
30 
31  bool is_text() const noexcept {
32  return impl::field_format(res(), column()) == impl::result_format::text;
33  }
34 
35  bool is_binary() const noexcept {
36  return impl::field_format(res(), column()) == impl::result_format::binary;
37  }
38 
39  const char* data() const noexcept {
40  return impl::get_value(res(), row(), column());
41  }
42 
43  std::size_t size() const noexcept {
44  return impl::get_length(res(), row(), column());
45  }
46 
47  bool is_null() const noexcept {
48  return impl::get_isnull(res(), row(), column());
49  }
50 
51 private:
52  int column() const noexcept { return v_.col;}
53  int row() const noexcept { return v_.row;}
54  const Result& res() const noexcept { return *(v_.res);}
55 
56  coordinates v_;
57 };
58 
59 template <typename T, typename Result>
60 inline const T* data(const value<Result>& v) {
61  return reinterpret_cast<const T*>(v.data());
62 }
63 
64 template <typename Result>
65 class row {
66 public:
67  using value = ozo::value<Result>;
68  using coordinates = typename value::coordinates;
69 
70  class const_iterator : public boost::iterator_facade<
71  const_iterator,
72  value,
73  boost::random_access_traversal_tag,
74  value,
75  int
76  > {
77  public:
78  const_iterator() = default;
79  const_iterator(const coordinates& v) : v_{v} {}
80 
81  private:
82  value dereference() const noexcept { return {v_}; }
83 
84  bool equal(const const_iterator& rhs) const noexcept {
85  return v_.res == rhs.v_.res && v_.col == rhs.v_.col && v_.row == rhs.v_.row;
86  }
87 
88  void increment() noexcept { advance(1); }
89  void decrement() noexcept { advance(-1); }
90  void advance(int n) noexcept { v_.col += n; }
91 
92  int distance_to(const const_iterator& z) noexcept { return z.col - v_.col; }
93 
94  coordinates v_ {nullptr, 0, 0};
95 
96  friend class boost::iterator_core_access;
97  };
98 
99  using iterator = const_iterator;
100 
101  row(const coordinates& first) : first_(first) {}
102 
103  const_iterator begin() const noexcept { return {first_}; }
104 
105  const_iterator end() const noexcept { return begin() + size(); }
106 
107  const_iterator find(const char* name) const noexcept {
108  int i = impl::field_number(*(first_.res), name);
109  return i == -1 ? end() : begin() + i;
110  }
111 
112  value operator[] (int i) const noexcept { return *(begin() + i); }
113 
114  std::size_t size() const noexcept { return impl::nfields(*(first_.res)); }
115 
116  bool empty() const noexcept { return size() == 0; }
117 
118  value at(int column_index) const {
119  if (column_index < 0 || static_cast<std::size_t>(column_index) >= size()) {
120  throw std::out_of_range("ozo::row::at() column index "
121  + std::to_string(column_index) + " out of range");
122  }
123  return (*this)[column_index];
124  }
125 
126  value at(const char* column_name) const {
127  auto i = find(column_name);
128  if (i == end()) {
129  throw std::out_of_range(std::string("ozo::row::at() no such column name ")
130  + column_name);
131  }
132  return *i;
133  }
134 
135 private:
136  coordinates first_;
137 };
138 
139 template <typename T>
140 class basic_result {
141 public:
142  using handle_type = T;
143  using row = ozo::row<std::decay_t<decltype(*std::declval<handle_type>())>>;
144  using value = typename row::value;
145  using coordinates = typename row::coordinates;
146 
147  class const_iterator : public boost::iterator_facade<
148  const_iterator,
149  row,
150  boost::random_access_traversal_tag,
151  row,
152  int
153  > {
154  public:
155  const_iterator() = default;
156  const_iterator(const coordinates& v) : v_{v} {}
157 
158  private:
159  row dereference() const noexcept { return {v_}; }
160 
161  bool equal(const const_iterator& rhs) const noexcept {
162  return v_.res == rhs.v_.res && v_.row == rhs.v_.row;
163  }
164 
165  void increment() noexcept { advance(1); }
166  void decrement() noexcept { advance(-1); }
167  void advance(int n) noexcept { v_.row += n; }
168 
169  int distance_to(const const_iterator& z) noexcept { return z.row - v_.row; }
170 
171  coordinates v_ {nullptr, 0, 0};
172 
173  friend class boost::iterator_core_access;
174  };
175 
176  using iterator = const_iterator;
177 
178  basic_result() = default;
179  basic_result(handle_type res) : res_(std::move(res)) {}
180 
181  const_iterator begin() const noexcept { return {{std::addressof(*res_), 0, 0}}; }
182 
183  const_iterator end() const noexcept { return begin() + size(); }
184 
185  std::size_t size() const noexcept { return impl::ntuples(*res_);}
186 
187  bool empty() const noexcept { return size() == 0; }
188 
189  row operator[] (int i) const noexcept { return *(begin() + i); }
190 
191  row at(int i) const {
192  if (i < 0 || static_cast<std::size_t>(i) >= size()) {
193  throw std::out_of_range("ozo::result::at() index " + std::to_string(i) + " out of range");
194  }
195  return (*this)[i];
196  }
197 
198  handle_type& handle() {
199  return res_;
200  }
201 
202  const handle_type& handle() const {
203  return res_;
204  }
205 
206 private:
207  handle_type res_;
208 };
209 
210 using result = basic_result<native_result_handle>;
211 
212 template <typename T>
213 auto make_result(T&& handle) {
214  return ozo::basic_result<std::decay_t<T>>(std::forward<T>(handle));
215 }
216 
217 } // namespace ozo
Definition: native_conn_handle.h:5
-
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:48
+
1 #pragma once
2 
3 #include <ozo/impl/io.h>
4 #include <ozo/type_traits.h>
5 #include <ozo/native_result_handle.h>
6 
7 #include <libpq-fe.h>
8 
9 #include <boost/iterator/iterator_facade.hpp>
10 #include <memory>
11 #include <vector>
12 
13 
14 namespace ozo {
15 
16 template <typename Result>
17 class value {
18 public:
19  struct coordinates {
20  const Result* res;
21  int row;
22  int col;
23  };
24 
25  value(const coordinates& v) : v_(v) {}
26 
27  oid_t oid() const noexcept {
28  return impl::field_type(res(), column());
29  }
30 
31  bool is_text() const noexcept {
32  return impl::field_format(res(), column()) == impl::result_format::text;
33  }
34 
35  bool is_binary() const noexcept {
36  return impl::field_format(res(), column()) == impl::result_format::binary;
37  }
38 
39  const char* data() const noexcept {
40  return impl::get_value(res(), row(), column());
41  }
42 
43  std::size_t size() const noexcept {
44  return impl::get_length(res(), row(), column());
45  }
46 
47  bool is_null() const noexcept {
48  return impl::get_isnull(res(), row(), column());
49  }
50 
51 private:
52  int column() const noexcept { return v_.col;}
53  int row() const noexcept { return v_.row;}
54  const Result& res() const noexcept { return *(v_.res);}
55 
56  coordinates v_;
57 };
58 
59 template <typename T, typename Result>
60 inline const T* data(const value<Result>& v) {
61  return reinterpret_cast<const T*>(v.data());
62 }
63 
64 template <typename Result>
65 class row {
66 public:
67  using value = ozo::value<Result>;
68  using coordinates = typename value::coordinates;
69 
70  class const_iterator : public boost::iterator_facade<
71  const_iterator,
72  value,
73  boost::random_access_traversal_tag,
74  value,
75  int
76  > {
77  public:
78  const_iterator() = default;
79  const_iterator(const coordinates& v) : v_{v} {}
80 
81  private:
82  value dereference() const noexcept { return {v_}; }
83 
84  bool equal(const const_iterator& rhs) const noexcept {
85  return v_.res == rhs.v_.res && v_.col == rhs.v_.col && v_.row == rhs.v_.row;
86  }
87 
88  void increment() noexcept { advance(1); }
89  void decrement() noexcept { advance(-1); }
90  void advance(int n) noexcept { v_.col += n; }
91 
92  int distance_to(const const_iterator& z) noexcept { return z.col - v_.col; }
93 
94  coordinates v_ {nullptr, 0, 0};
95 
96  friend class boost::iterator_core_access;
97  };
98 
99  using iterator = const_iterator;
100 
101  row(const coordinates& first) : first_(first) {}
102 
103  const_iterator begin() const noexcept { return {first_}; }
104 
105  const_iterator end() const noexcept { return begin() + size(); }
106 
107  const_iterator find(const char* name) const noexcept {
108  int i = impl::field_number(*(first_.res), name);
109  return i == -1 ? end() : begin() + i;
110  }
111 
112  value operator[] (int i) const noexcept { return *(begin() + i); }
113 
114  std::size_t size() const noexcept { return impl::nfields(*(first_.res)); }
115 
116  bool empty() const noexcept { return size() == 0; }
117 
118  value at(int column_index) const {
119  if (column_index < 0 || static_cast<std::size_t>(column_index) >= size()) {
120  throw std::out_of_range("ozo::row::at() column index "
121  + std::to_string(column_index) + " out of range");
122  }
123  return (*this)[column_index];
124  }
125 
126  value at(const char* column_name) const {
127  auto i = find(column_name);
128  if (i == end()) {
129  throw std::out_of_range(std::string("ozo::row::at() no such column name ")
130  + column_name);
131  }
132  return *i;
133  }
134 
135 private:
136  coordinates first_;
137 };
138 
139 template <typename T>
140 class basic_result {
141 public:
142  using handle_type = T;
143  using row = ozo::row<std::decay_t<decltype(*std::declval<handle_type>())>>;
144  using value = typename row::value;
145  using coordinates = typename row::coordinates;
146 
147  class const_iterator : public boost::iterator_facade<
148  const_iterator,
149  row,
150  boost::random_access_traversal_tag,
151  row,
152  int
153  > {
154  public:
155  const_iterator() = default;
156  const_iterator(const coordinates& v) : v_{v} {}
157 
158  private:
159  row dereference() const noexcept { return {v_}; }
160 
161  bool equal(const const_iterator& rhs) const noexcept {
162  return v_.res == rhs.v_.res && v_.row == rhs.v_.row;
163  }
164 
165  void increment() noexcept { advance(1); }
166  void decrement() noexcept { advance(-1); }
167  void advance(int n) noexcept { v_.row += n; }
168 
169  int distance_to(const const_iterator& z) noexcept { return z.row - v_.row; }
170 
171  coordinates v_ {nullptr, 0, 0};
172 
173  friend class boost::iterator_core_access;
174  };
175 
176  using iterator = const_iterator;
177 
178  basic_result() = default;
179  basic_result(handle_type res) : res_(std::move(res)) {}
180 
181  const_iterator begin() const noexcept { return {{std::addressof(*res_), 0, 0}}; }
182 
183  const_iterator end() const noexcept { return begin() + size(); }
184 
185  std::size_t size() const noexcept { return impl::ntuples(*res_);}
186 
187  bool empty() const noexcept { return size() == 0; }
188 
189  row operator[] (int i) const noexcept { return *(begin() + i); }
190 
191  row at(int i) const {
192  if (i < 0 || static_cast<std::size_t>(i) >= size()) {
193  throw std::out_of_range("ozo::result::at() index " + std::to_string(i) + " out of range");
194  }
195  return (*this)[i];
196  }
197 
198  handle_type& handle() {
199  return res_;
200  }
201 
202  const handle_type& handle() const {
203  return res_;
204  }
205 
206 private:
207  handle_type res_;
208 };
209 
210 using result = basic_result<native_result_handle>;
211 
212 template <typename T>
213 auto make_result(T&& handle) {
214  return ozo::basic_result<std::decay_t<T>>(std::forward<T>(handle));
215 }
216 
217 } // namespace ozo
Definition: native_conn_handle.h:5
+
constexpr bool empty(const oid_map_t< MapImplT > &map) noexcept
Definition: type_traits.h:658
+
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:50
Definition: asio.h:5
diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js index af0b2bd2a..c00d3ec26 100644 --- a/docs/html/search/all_0.js +++ b/docs/html/search/all_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['accepts_5foid',['accepts_oid',['../namespaceozo.html#a0082981c9a4ca4163a43b5ac432ae2e6',1,'ozo']]], + ['accepts_5foid',['accepts_oid',['../group__group-type__system.html#ga0082981c9a4ca4163a43b5ac432ae2e6',1,'ozo::accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept'],['../group__group-type__system.html#gaa3c51f0d200a57fb848dadeb39c79864',1,'ozo::accepts_oid(const oid_map_t< MapImplT > &map, const T &, oid_t oid) noexcept']]], ['async_5fconnect_5fop',['async_connect_op',['../structozo_1_1impl_1_1async__connect__op.html',1,'ozo::impl']]] ]; diff --git a/docs/html/search/all_10.js b/docs/html/search/all_10.js index 9b6976089..8f71a9415 100644 --- a/docs/html/search/all_10.js +++ b/docs/html/search/all_10.js @@ -6,7 +6,7 @@ var searchData= ['time_5fpoint',['time_point',['../structozo_1_1time__traits.html#ae4cacabb70251a965ddfbac02da16f72',1,'ozo::time_traits']]], ['time_5ftraits',['time_traits',['../structozo_1_1time__traits.html',1,'ozo']]], ['type_5fname',['type_name',['../namespaceozo.html#a5d8811b98d595a465352a680d14db8a7',1,'ozo']]], - ['type_5foid',['type_oid',['../namespaceozo.html#abd81e4419a6e16ea9cb416cf8348e35f',1,'ozo']]], + ['type_5foid',['type_oid',['../group__group-type__system.html#gabd81e4419a6e16ea9cb416cf8348e35f',1,'ozo']]], ['type_5ftraits',['type_traits',['../structozo_1_1type__traits.html',1,'ozo']]], ['type_5ftraits_5fhelper',['type_traits_helper',['../structozo_1_1type__traits__helper.html',1,'ozo']]], ['type_5ftraits_5fhelper_3c_20bool_2c_20decltype_28_22bool_22_5fs_29_2c_20std_3a_3aintegral_5fconstant_3c_20oid_5ft_2c_20booloid_20_3e_2c_20bytes_3c_201_20_3e_20_3e',['type_traits_helper< bool, decltype("bool"_s), std::integral_constant< oid_t, BOOLOID >, bytes< 1 > >',['../structozo_1_1type__traits__helper.html',1,'ozo']]], diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js index cd7ff24e0..9276fddf9 100644 --- a/docs/html/search/all_4.js +++ b/docs/html/search/all_4.js @@ -1,8 +1,10 @@ var searchData= [ ['emplaceable',['Emplaceable',['../group__group-core-concepts.html#ga474575596a9253f3aad1f7ff5014425b',1,'ozo']]], + ['empty',['empty',['../group__group-type__system.html#ga4ae9202e722b11d284c9d66a1b945838',1,'ozo']]], + ['empty_5foid_5fmap',['empty_oid_map',['../group__group-type__system.html#gac3359e5eddcb6e0b661a97e33bfcd215',1,'ozo']]], ['error_20codes',['Error codes',['../group__error-codes.html',1,'']]], ['error',['error',['../group__error-codes-errors.html',1,'']]], ['error_5fmessage',['error_message',['../group__group-connection-functions.html#gae1d570854c32a38adcad99baf73e0baa',1,'ozo']]], - ['execute',['execute',['../group__group-requests.html#ga8883fdec7a4df0150147f8736af47340',1,'ozo']]] + ['execute',['execute',['../group__group-requests.html#ga438ed9c31739b1ce13f5f8eae1bbf655',1,'ozo']]] ]; diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js index f18d19d38..373add660 100644 --- a/docs/html/search/all_5.js +++ b/docs/html/search/all_5.js @@ -1,6 +1,5 @@ var searchData= [ - ['fetch_5fcontext',['fetch_context',['../structozo_1_1impl_1_1fetch__context.html',1,'ozo::impl']]], ['floatingpoint',['FloatingPoint',['../group__group-core-concepts.html#ga351423cc3c81ca247a3c8ecea7beabb2',1,'ozo']]], ['forwarditerator',['ForwardIterator',['../group__group-core-concepts.html#ga762b9c7d7a45486c590d33ddb1330e9e',1,'ozo']]], ['fusionadaptedstruct',['FusionAdaptedStruct',['../group__group-core-concepts.html#ga3630bba60dd6977e70781ab0afe0cffd',1,'ozo']]], diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js index ea8d60ff5..4af6b090e 100644 --- a/docs/html/search/all_8.js +++ b/docs/html/search/all_8.js @@ -4,13 +4,8 @@ var searchData= ['idle_5ftimeout',['idle_timeout',['../structozo_1_1connection__pool__config.html#a030e1fbe98cc5d71184d1a63332812b9',1,'ozo::connection_pool_config']]], ['insertiterator',['InsertIterator',['../group__group-core-concepts.html#ga4bca84123276a5399ea63f2e249bd04d',1,'ozo']]], ['integral',['Integral',['../group__group-core-concepts.html#gad66641f2bf2a66458e7a79d5d71806b7',1,'ozo']]], - ['is_5farray',['is_array',['../structozo_1_1is__array.html',1,'ozo']]], ['is_5fbuilt_5fin',['is_built_in',['../structozo_1_1is__built__in.html',1,'ozo']]], - ['is_5fcomposite',['is_composite',['../structozo_1_1is__composite.html',1,'ozo']]], - ['is_5ffusion_5fadapted',['is_fusion_adapted',['../namespaceozo.html#a32551233c932c46a24f162fcf710e7ab',1,'ozo']]], - ['is_5fhana_5fadapted',['is_hana_adapted',['../namespaceozo.html#a1e8ece917416670644622e226e7e4ae6',1,'ozo']]], ['is_5fnull',['is_null',['../group__group-core-functions.html#ga0846e7fca9274b5d6de397590b10f778',1,'ozo']]], ['is_5fnullable_3c_20boost_3a_3aoptional_3c_20t_20_3e_20_3e',['is_nullable< boost::optional< T > >',['../structozo_1_1is__nullable_3_01boost_1_1optional_3_01_t_01_4_01_4.html',1,'ozo']]], - ['is_5fstring',['is_string',['../structozo_1_1is__string.html',1,'ozo']]], ['iterable',['Iterable',['../group__group-core-concepts.html#gaf513c2ac32e89e730a1019c94ec8fb19',1,'ozo']]] ]; diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js index 214b4e857..38d7c45c5 100644 --- a/docs/html/search/all_b.js +++ b/docs/html/search/all_b.js @@ -2,9 +2,11 @@ var searchData= [ ['ozo',['ozo',['../index.html',1,'']]], ['oid',['oid',['../structozo_1_1type__traits.html#a188eddb23d740dd449530c45db7993b3',1,'ozo::type_traits']]], + ['oid_5fmap_5ft',['oid_map_t',['../structozo_1_1oid__map__t.html',1,'ozo']]], ['oid_5frequest_5ffailed',['oid_request_failed',['../group__error-codes-errors.html#ggac6082be94aa8b21e440cab09413a91aca20c118ca7a6401c93d4952603383da0e',1,'ozo::error']]], ['oid_5ft',['oid_t',['../group__group-type__system.html#ga442ba8c3d090543cf6278acb4fed5e66',1,'ozo']]], ['oid_5ftype_5fmismatch',['oid_type_mismatch',['../group__error-codes-errors.html#ggac6082be94aa8b21e440cab09413a91aca5124caadcf0dc20d106092650129a71d',1,'ozo::error']]], + ['oidmap',['OidMap',['../group__group-type__system.html#ga41fff92f9d5a046bcd0654312352e153',1,'ozo']]], ['ok',['ok',['../group__error-codes-errors.html#ggac6082be94aa8b21e440cab09413a91aca6a357773fe2116a5b09686ba8fb9e53a',1,'ozo::error']]], ['operator_28_29',['operator()',['../classozo_1_1connection__pool.html#a4eab0de36606f6de94260f2613dec953',1,'ozo::connection_pool']]], ['operatornot',['OperatorNot',['../group__group-core-concepts.html#gae0a9bc14ebe454c9d0b8f3055839d675',1,'ozo']]], diff --git a/docs/html/search/all_e.js b/docs/html/search/all_e.js index e22070f03..52d422cd8 100644 --- a/docs/html/search/all_e.js +++ b/docs/html/search/all_e.js @@ -4,6 +4,7 @@ var searchData= ['requests',['Requests',['../group__group-requests.html',1,'']]], ['rawdatawritable',['RawDataWritable',['../group__group-core-concepts.html#ga21d1faddb4ee1e9ff5d132885fc03713',1,'ozo']]], ['rebind_5fio_5fcontext',['rebind_io_context',['../group__group-connection-functions.html#ga0814c7ac526064fb9d597ed59a0efe6c',1,'ozo']]], + ['register_5ftypes',['register_types',['../group__group-type__system.html#gac97d30cda822b83aa3d54f60c658f8f7',1,'ozo']]], ['request',['request',['../group__group-requests.html#ga3d2edd9e8d3aea4aee843a539d14eb0b',1,'ozo::request(P &&provider, Q &&query, const time_traits::duration &timeout, Out out, CompletionToken &&token)'],['../group__group-requests.html#ga748ee23ab6367dcadeec514cd92b8b0e',1,'ozo::request(P &&provider, Q &&query, Out out, CompletionToken &&token)']]], ['require',['Require',['../group__group-core-concepts.html#gaec336e235cdaabead728b12ecb63b38a',1,'ozo']]], ['reset_5ferror_5fcontext',['reset_error_context',['../group__group-connection-functions.html#gad4517ffae4244f57bc112d0d3b8f5602',1,'ozo']]], diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js index b24038d66..040329244 100644 --- a/docs/html/search/all_f.js +++ b/docs/html/search/all_f.js @@ -2,7 +2,7 @@ var searchData= [ ['sqlstate',['sqlstate',['../group__error-codes-sqlstate.html',1,'']]], ['set_5ferror_5fcontext',['set_error_context',['../group__group-connection-functions.html#gad57058f0aa7e00df34f027b015b80a1a',1,'ozo']]], - ['set_5ftype_5foid',['set_type_oid',['../namespaceozo.html#a078aef0d58433783f8d0cba352732993',1,'ozo']]], + ['set_5ftype_5foid',['set_type_oid',['../group__group-type__system.html#ga078aef0d58433783f8d0cba352732993',1,'ozo']]], ['size',['size',['../structozo_1_1type__traits.html#ad1a21be06fcb34bf612a7c516159fccd',1,'ozo::type_traits']]], ['size_5fof',['size_of',['../namespaceozo.html#af25063f8ee373256aacd69febdd31517',1,'ozo']]], ['source_5ftype',['source_type',['../classozo_1_1connector.html#a581bd7577c1fbdc2db5ad9d157ee817a',1,'ozo::connector']]] diff --git a/docs/html/search/classes_4.js b/docs/html/search/classes_4.js index 22231df08..640d59f99 100644 --- a/docs/html/search/classes_4.js +++ b/docs/html/search/classes_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['fetch_5fcontext',['fetch_context',['../structozo_1_1impl_1_1fetch__context.html',1,'ozo::impl']]] + ['get_5fconnection_5ftype',['get_connection_type',['../structozo_1_1get__connection__type.html',1,'ozo']]] ]; diff --git a/docs/html/search/classes_5.js b/docs/html/search/classes_5.js index 640d59f99..99a9b351e 100644 --- a/docs/html/search/classes_5.js +++ b/docs/html/search/classes_5.js @@ -1,4 +1,5 @@ var searchData= [ - ['get_5fconnection_5ftype',['get_connection_type',['../structozo_1_1get__connection__type.html',1,'ozo']]] + ['is_5fbuilt_5fin',['is_built_in',['../structozo_1_1is__built__in.html',1,'ozo']]], + ['is_5fnullable_3c_20boost_3a_3aoptional_3c_20t_20_3e_20_3e',['is_nullable< boost::optional< T > >',['../structozo_1_1is__nullable_3_01boost_1_1optional_3_01_t_01_4_01_4.html',1,'ozo']]] ]; diff --git a/docs/html/search/classes_6.js b/docs/html/search/classes_6.js index 1dce03218..43dab3ca1 100644 --- a/docs/html/search/classes_6.js +++ b/docs/html/search/classes_6.js @@ -1,8 +1,4 @@ var searchData= [ - ['is_5farray',['is_array',['../structozo_1_1is__array.html',1,'ozo']]], - ['is_5fbuilt_5fin',['is_built_in',['../structozo_1_1is__built__in.html',1,'ozo']]], - ['is_5fcomposite',['is_composite',['../structozo_1_1is__composite.html',1,'ozo']]], - ['is_5fnullable_3c_20boost_3a_3aoptional_3c_20t_20_3e_20_3e',['is_nullable< boost::optional< T > >',['../structozo_1_1is__nullable_3_01boost_1_1optional_3_01_t_01_4_01_4.html',1,'ozo']]], - ['is_5fstring',['is_string',['../structozo_1_1is__string.html',1,'ozo']]] + ['oid_5fmap_5ft',['oid_map_t',['../structozo_1_1oid__map__t.html',1,'ozo']]] ]; diff --git a/docs/html/search/functions_0.js b/docs/html/search/functions_0.js index 823abcbb3..059869ada 100644 --- a/docs/html/search/functions_0.js +++ b/docs/html/search/functions_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['accepts_5foid',['accepts_oid',['../namespaceozo.html#a0082981c9a4ca4163a43b5ac432ae2e6',1,'ozo']]] + ['accepts_5foid',['accepts_oid',['../group__group-type__system.html#ga0082981c9a4ca4163a43b5ac432ae2e6',1,'ozo::accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept'],['../group__group-type__system.html#gaa3c51f0d200a57fb848dadeb39c79864',1,'ozo::accepts_oid(const oid_map_t< MapImplT > &map, const T &, oid_t oid) noexcept']]] ]; diff --git a/docs/html/search/functions_2.js b/docs/html/search/functions_2.js index d17b288ca..188299329 100644 --- a/docs/html/search/functions_2.js +++ b/docs/html/search/functions_2.js @@ -1,5 +1,6 @@ var searchData= [ + ['empty',['empty',['../group__group-type__system.html#ga4ae9202e722b11d284c9d66a1b945838',1,'ozo']]], ['error_5fmessage',['error_message',['../group__group-connection-functions.html#gae1d570854c32a38adcad99baf73e0baa',1,'ozo']]], - ['execute',['execute',['../group__group-requests.html#ga8883fdec7a4df0150147f8736af47340',1,'ozo']]] + ['execute',['execute',['../group__group-requests.html#ga438ed9c31739b1ce13f5f8eae1bbf655',1,'ozo']]] ]; diff --git a/docs/html/search/functions_7.js b/docs/html/search/functions_7.js index 4eb453a8f..6936723da 100644 --- a/docs/html/search/functions_7.js +++ b/docs/html/search/functions_7.js @@ -1,6 +1,7 @@ var searchData= [ ['rebind_5fio_5fcontext',['rebind_io_context',['../group__group-connection-functions.html#ga0814c7ac526064fb9d597ed59a0efe6c',1,'ozo']]], + ['register_5ftypes',['register_types',['../group__group-type__system.html#gac97d30cda822b83aa3d54f60c658f8f7',1,'ozo']]], ['request',['request',['../group__group-requests.html#ga3d2edd9e8d3aea4aee843a539d14eb0b',1,'ozo::request(P &&provider, Q &&query, const time_traits::duration &timeout, Out out, CompletionToken &&token)'],['../group__group-requests.html#ga748ee23ab6367dcadeec514cd92b8b0e',1,'ozo::request(P &&provider, Q &&query, Out out, CompletionToken &&token)']]], ['reset_5ferror_5fcontext',['reset_error_context',['../group__group-connection-functions.html#gad4517ffae4244f57bc112d0d3b8f5602',1,'ozo']]] ]; diff --git a/docs/html/search/functions_8.js b/docs/html/search/functions_8.js index c4db2bf7c..a478626a8 100644 --- a/docs/html/search/functions_8.js +++ b/docs/html/search/functions_8.js @@ -1,6 +1,6 @@ var searchData= [ ['set_5ferror_5fcontext',['set_error_context',['../group__group-connection-functions.html#gad57058f0aa7e00df34f027b015b80a1a',1,'ozo']]], - ['set_5ftype_5foid',['set_type_oid',['../namespaceozo.html#a078aef0d58433783f8d0cba352732993',1,'ozo']]], + ['set_5ftype_5foid',['set_type_oid',['../group__group-type__system.html#ga078aef0d58433783f8d0cba352732993',1,'ozo']]], ['size_5fof',['size_of',['../namespaceozo.html#af25063f8ee373256aacd69febdd31517',1,'ozo']]] ]; diff --git a/docs/html/search/functions_9.js b/docs/html/search/functions_9.js index bcc9e3a35..4a1a76dba 100644 --- a/docs/html/search/functions_9.js +++ b/docs/html/search/functions_9.js @@ -1,5 +1,5 @@ var searchData= [ ['type_5fname',['type_name',['../namespaceozo.html#a5d8811b98d595a465352a680d14db8a7',1,'ozo']]], - ['type_5foid',['type_oid',['../namespaceozo.html#abd81e4419a6e16ea9cb416cf8348e35f',1,'ozo']]] + ['type_5foid',['type_oid',['../group__group-type__system.html#gabd81e4419a6e16ea9cb416cf8348e35f',1,'ozo']]] ]; diff --git a/docs/html/search/searchdata.js b/docs/html/search/searchdata.js index 91d723b91..2cac97077 100644 --- a/docs/html/search/searchdata.js +++ b/docs/html/search/searchdata.js @@ -1,11 +1,11 @@ var indexSectionsWithContent = { 0: "abcdefghimnopqrstu", - 1: "abcdfgit", + 1: "abcdgiot", 2: "o", 3: "acegimorstu", 4: "cefhinoqrs", - 5: "bcdinorst", + 5: "bcdenorst", 6: "c", 7: "bnopru", 8: "cdeiqrstu", diff --git a/docs/html/search/typedefs_3.js b/docs/html/search/typedefs_3.js index 97e39a721..f58f23a51 100644 --- a/docs/html/search/typedefs_3.js +++ b/docs/html/search/typedefs_3.js @@ -1,5 +1,4 @@ var searchData= [ - ['is_5ffusion_5fadapted',['is_fusion_adapted',['../namespaceozo.html#a32551233c932c46a24f162fcf710e7ab',1,'ozo']]], - ['is_5fhana_5fadapted',['is_hana_adapted',['../namespaceozo.html#a1e8ece917416670644622e226e7e4ae6',1,'ozo']]] + ['empty_5foid_5fmap',['empty_oid_map',['../group__group-type__system.html#gac3359e5eddcb6e0b661a97e33bfcd215',1,'ozo']]] ]; diff --git a/docs/html/search/variables_6.js b/docs/html/search/variables_6.js index dffb8dcd5..b6639c6e8 100644 --- a/docs/html/search/variables_6.js +++ b/docs/html/search/variables_6.js @@ -1,6 +1,7 @@ var searchData= [ ['oid',['oid',['../structozo_1_1type__traits.html#a188eddb23d740dd449530c45db7993b3',1,'ozo::type_traits']]], + ['oidmap',['OidMap',['../group__group-type__system.html#ga41fff92f9d5a046bcd0654312352e153',1,'ozo']]], ['operatornot',['OperatorNot',['../group__group-core-concepts.html#gae0a9bc14ebe454c9d0b8f3055839d675',1,'ozo']]], ['outputiterator',['OutputIterator',['../group__group-core-concepts.html#ga3750f4893911580a5546d11bd5a9ca32',1,'ozo']]] ]; diff --git a/docs/html/start__transaction_8h_source.html b/docs/html/start__transaction_8h_source.html index 7b434dd63..643fb84cb 100644 --- a/docs/html/start__transaction_8h_source.html +++ b/docs/html/start__transaction_8h_source.html @@ -103,7 +103,7 @@
1 #pragma once
2 
3 #include <ozo/impl/async_start_transaction.h>
4 
5 namespace ozo::impl {
6 
7 template <typename T, typename Query, typename CompletionToken,
8  typename = Require<ConnectionProvider<T>>>
9 auto start_transaction(T&& provider, Query&& query,
10  const time_traits::duration& timeout, CompletionToken&& token) {
11  using signature = void (error_code, transaction<connection_type<T>>);
12 
13  async_completion<CompletionToken, signature> init(token);
14 
15  async_start_transaction(
16  std::forward<T>(provider),
17  std::forward<Query>(query),
18  timeout,
19  init.completion_handler
20  );
21 
22  return init.result.get();
23 }
24 
25 } // namespace ozo::impl
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: async_connect.h:17
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
diff --git a/docs/html/structozo_1_1is__built__in.html b/docs/html/structozo_1_1is__built__in.html index e270e61fb..3e5a841c0 100644 --- a/docs/html/structozo_1_1is__built__in.html +++ b/docs/html/structozo_1_1is__built__in.html @@ -115,7 +115,7 @@
-

Inherits integral_constant< bool, !std::is_same_v< type_traits< T >::oid, null_oid_t > >.

+

Inherits bool_constant< !std::is_same_v< type_traits< T >::oid, null_oid_t > >.


The documentation for this struct was generated from the following file: diff --git a/docs/html/structozo_1_1oid__map__t-members.html b/docs/html/structozo_1_1oid__map__t-members.html new file mode 100644 index 000000000..db15889b3 --- /dev/null +++ b/docs/html/structozo_1_1oid__map__t-members.html @@ -0,0 +1,118 @@ + + + + + + + +OZO 「お象」: Member List + + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
OZO 「お象」 +
+
Boost.Asio and libpq based asynchronous PostgreSQL unofficial header-only C++17 client library.
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
ozo::oid_map_t< ImplT > Member List
+
+
+ +

This is the complete list of members for ozo::oid_map_t< ImplT >, including all inherited members.

+ +
+
+ + + + diff --git a/docs/html/structozo_1_1oid__map__t.html b/docs/html/structozo_1_1oid__map__t.html new file mode 100644 index 000000000..db558225e --- /dev/null +++ b/docs/html/structozo_1_1oid__map__t.html @@ -0,0 +1,129 @@ + + + + + + + +OZO 「お象」: ozo::oid_map_t< ImplT > Struct Template Reference + + + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
OZO 「お象」 +
+
Boost.Asio and libpq based asynchronous PostgreSQL unofficial header-only C++17 client library.
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+ +
+
ozo::oid_map_t< ImplT > Struct Template Reference
+
+
+ +

#include <type_traits.h>

+

Description

+

template<typename ImplT>
+struct ozo::oid_map_t< ImplT >

+ +

OidMap implementation type.

+

This type implements OidMap concept based on boost::hana::map.

+

The documentation for this struct was generated from the following file: +
+
+ + + + diff --git a/docs/html/structozo_1_1type__traits.html b/docs/html/structozo_1_1type__traits.html index 4846ec54c..238707851 100644 --- a/docs/html/structozo_1_1type__traits.html +++ b/docs/html/structozo_1_1type__traits.html @@ -118,6 +118,7 @@
+
See also
ozo::type_traits_helper

Inherits ozo::type_traits_helper< T, void >.

diff --git a/docs/html/structozo_1_1type__traits__helper.html b/docs/html/structozo_1_1type__traits__helper.html index e20357b7f..5b5110ee0 100644 --- a/docs/html/structozo_1_1type__traits__helper.html +++ b/docs/html/structozo_1_1type__traits__helper.html @@ -109,8 +109,7 @@

template<typename T, typename Name, typename Oid = null_oid_t, typename Size = dynamic_size>
struct ozo::type_traits_helper< T, Name, Oid, Size >

-

Helper defines the way for the type traits definitions.

-

Type is undefined then Name type is not defined.

+

Helper for the type traits definitions.

Template Parameters
diff --git a/docs/html/transaction_8h_source.html b/docs/html/transaction_8h_source.html index 9bdc4fbc7..51d9cec82 100644 --- a/docs/html/transaction_8h_source.html +++ b/docs/html/transaction_8h_source.html @@ -104,7 +104,7 @@
1 #pragma once
2 
3 #include <ozo/impl/start_transaction.h>
4 #include <ozo/impl/end_transaction.h>
5 
6 namespace ozo {
7 
8 template <typename T, typename CompletionToken, typename = Require<ConnectionProvider<T>>>
9 auto begin(T&& provider, const time_traits::duration& timeout, CompletionToken&& token) {
10  using namespace ozo::literals;
11  return impl::start_transaction(
12  std::forward<T>(provider),
13  "BEGIN"_SQL,
14  timeout,
15  std::forward<CompletionToken>(token)
16  );
17 }
18 
19 template <typename T, typename CompletionToken, typename = Require<ConnectionProvider<T>>>
20 auto begin(T&& provider, CompletionToken&& token) {
21  return begin(
22  std::forward<T>(provider),
23  time_traits::duration::max(),
24  std::forward<CompletionToken>(token)
25  );
26 }
27 
28 template <typename T, typename CompletionToken>
29 auto commit(impl::transaction<T>&& transaction, const time_traits::duration& timeout, CompletionToken&& token) {
30  using namespace ozo::literals;
31  return impl::end_transaction(
32  std::move(transaction),
33  "COMMIT"_SQL,
34  timeout,
35  std::forward<CompletionToken>(token)
36  );
37 }
38 
39 template <typename T, typename CompletionToken>
40 auto commit(impl::transaction<T>&& transaction, CompletionToken&& token) {
41  return commit(
42  std::move(transaction),
43  time_traits::duration::max(),
44  std::forward<CompletionToken>(token)
45  );
46 }
47 
48 template <typename T, typename CompletionToken>
49 auto rollback(impl::transaction<T>&& transaction, const time_traits::duration& timeout, CompletionToken&& token) {
50  using namespace ozo::literals;
51  return impl::end_transaction(
52  std::move(transaction),
53  "ROLLBACK"_SQL,
54  timeout,
55  std::forward<CompletionToken>(token)
56  );
57 }
58 
59 template <typename T, typename CompletionToken>
60 auto rollback(impl::transaction<T>&& transaction, CompletionToken&& token) {
61  return rollback(
62  std::move(transaction),
63  time_traits::duration::max(),
64  std::forward<CompletionToken>(token)
65  );
66 }
67 
68 } // namespace ozo
Definition: query_builder.h:180
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:19
Definition: asio.h:5
-
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:311
+
constexpr auto CompletionToken
Completion token concept.
Definition: concept.h:350
diff --git a/docs/html/type__traits_8h_source.html b/docs/html/type__traits_8h_source.html index d5482e778..712f601a5 100644 --- a/docs/html/type__traits_8h_source.html +++ b/docs/html/type__traits_8h_source.html @@ -101,31 +101,31 @@
type_traits.h
-
1 #pragma once
2 
3 #include <ozo/detail/pg_type.h>
4 #include <ozo/detail/float.h>
5 
6 #include <libpq-fe.h>
7 
8 #include <boost/hana/at_key.hpp>
9 #include <boost/hana/insert.hpp>
10 #include <boost/hana/string.hpp>
11 #include <boost/hana/map.hpp>
12 #include <boost/hana/pair.hpp>
13 #include <boost/hana/type.hpp>
14 #include <boost/uuid/uuid.hpp>
15 #include <boost/optional.hpp>
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/shared_ptr.hpp>
18 #include <boost/make_shared.hpp>
19 #include <boost/weak_ptr.hpp>
20 // Fusion adaptors support
21 #include <boost/fusion/support/is_sequence.hpp>
22 #include <boost/fusion/include/is_sequence.hpp>
23 
24 #include <ozo/concept.h>
25 #include <ozo/optional.h>
26 #include <memory>
27 #include <string>
28 #include <list>
29 #include <vector>
30 #include <set>
31 #include <type_traits>
32 
38 namespace ozo {
39 
40 namespace hana = boost::hana;
41 using namespace hana::literals;
42 
43 namespace fusion = boost::fusion;
48 using oid_t = ::Oid;
49 
54 using null_oid_t = std::integral_constant<oid_t, 0>;
55 constexpr null_oid_t null_oid;
56 
57 template <typename T, typename Enable = void>
58 struct is_nullable : std::false_type {};
59 
63 template <typename T>
64 struct is_nullable<boost::optional<T>> : std::true_type {};
65 
66 #ifdef __OZO_STD_OPTIONAL
67 template <typename T>
68 struct is_nullable<__OZO_STD_OPTIONAL<T>> : std::true_type {};
69 #endif
70 
71 template <typename T>
72 struct is_nullable<boost::scoped_ptr<T>> : std::true_type {};
73 template <typename T, typename Deleter>
74 struct is_nullable<std::unique_ptr<T, Deleter>> : std::true_type {};
75 template <typename T>
76 struct is_nullable<boost::shared_ptr<T>> : std::true_type {};
77 template <typename T>
78 struct is_nullable<std::shared_ptr<T>> : std::true_type {};
79 template <typename T>
80 struct is_nullable<boost::weak_ptr<T>> : std::true_type {};
81 template <typename T>
82 struct is_nullable<std::weak_ptr<T>> : std::true_type {};
83 
114 template <typename T>
115 constexpr auto Nullable = is_nullable<std::decay_t<T>>::value;
116 
117 
118 #ifdef OZO_DOCUMENTATION
119 
128 template <typename T>
129 decltype(auto) unwrap_nullable(T&& value) noexcept;
130 #else
131 template <typename T>
132 inline decltype(auto) unwrap_nullable(T&& t, Require<Nullable<T>>* = 0) noexcept {
133  return *t;
134 }
135 
136 template <typename T>
137 inline decltype(auto) unwrap_nullable(T&& t, Require<!Nullable<T>>* = 0) noexcept {
138  return std::forward<T>(t);
139 }
140 #endif
141 template <typename T>
142 using unwrap_nullable_type = typename std::decay_t<decltype(unwrap_nullable(
143  std::declval<T>()))>;
144 
145 template <typename T>
146 inline auto is_null(const T& v) noexcept -> std::enable_if_t<Nullable<T>, bool> {
147  return !v;
148 }
149 
150 template <typename T>
151 inline auto is_null(const boost::weak_ptr<T>& v) noexcept {
152  return is_null(v.lock());
153 }
154 
155 template <typename T>
156 inline auto is_null(const std::weak_ptr<T>& v) noexcept {
157  return is_null(v.lock());
158 }
159 
160 #ifdef OZO_DOCUMENTATION
161 
171 template <typename T>
172 constexpr auto is_null(const T&) noexcept;
173 #endif
174 
175 template <typename T>
176 constexpr auto is_null(const T&) noexcept -> std::enable_if_t<!Nullable<T>, std::false_type> {
177  return {};
178 }
179 
180 template <typename T, typename = std::void_t<>>
181 struct allocate_nullable_impl {
182  static_assert(Emplaceable<T>, "default implementation uses emplace() method");
183  template <typename Alloc>
184  static void apply(T& out, const Alloc&) {
185  out.emplace();
186  }
187 };
188 
189 template <typename T>
190 struct allocate_nullable_impl<std::unique_ptr<T>> {
191  template <typename Alloc>
192  static void apply(std::unique_ptr<T>& out, const Alloc&) {
193  out = std::make_unique<T>();
194  }
195 };
196 
197 template <typename T>
198 struct allocate_nullable_impl<boost::scoped_ptr<T>> {
199  template <typename Alloc>
200  static void apply(boost::scoped_ptr<T>& out, const Alloc&) {
201  out.reset(new T{});
202  }
203 };
204 
205 template <typename T>
206 struct allocate_nullable_impl<boost::shared_ptr<T>> {
207  template <typename Alloc>
208  static void apply(boost::shared_ptr<T>& out, const Alloc& a) {
209  out = boost::allocate_shared<T, Alloc>(a);
210  }
211 };
212 
213 template <typename T>
214 struct allocate_nullable_impl<std::shared_ptr<T>> {
215  template <typename Alloc>
216  static void apply(std::shared_ptr<T>& out, const Alloc& a) {
217  out = std::allocate_shared<T, Alloc>(a);
218  }
219 };
220 
221 template <typename T, typename Alloc>
222 inline void allocate_nullable(T& out, const Alloc& a) {
223  static_assert(Nullable<T>, "T must be nullable");
224  allocate_nullable_impl<std::decay_t<T>>::apply(out, a);
225 }
226 
227 template <typename T, typename Alloc = std::allocator<char>>
228 inline void init_nullable(T& n, const Alloc& a = Alloc{}) {
229  static_assert(Nullable<T>, "T must be nullable");
230  if (!n) {
231  allocate_nullable(n, a);
232  }
233 }
234 
235 template <typename T>
236 inline void reset_nullable(T& n) {
237  static_assert(Nullable<T>, "T must be nullable");
238  n.reset();
239 }
240 
244 template <typename T>
245 struct is_array : std::false_type {};
246 
247 template <typename T, typename Alloc>
248 struct is_array<std::vector<T, Alloc>> : std::true_type {};
249 template <typename T, typename Alloc>
250 struct is_array<std::list<T, Alloc>> : std::true_type {};
251 
255 template <typename T>
256 struct is_string : std::false_type {};
257 
258 template <typename C, typename T, typename A>
259 struct is_string<std::basic_string<C, T, A>> : std::true_type {};
260 
264 template <typename T>
265 using is_fusion_adapted = std::integral_constant<bool,
266  boost::fusion::traits::is_sequence<T>::value
267 >;
268 
272 template <typename T>
273 using is_hana_adapted = std::integral_constant<bool,
274  hana::Sequence<T>::value ||
275  hana::Struct<T>::value
276 >;
277 
287 #ifdef OZO_DOCUMENTATION
288 template <typename T>
290 #else
291 template <typename T>
292 struct is_composite : std::integral_constant<bool,
293  is_hana_adapted<T>::value ||
294  is_fusion_adapted<T>::value
295 > {};
296 #endif
297 
311 #ifdef OZO_DOCUMENTATION
312 template <typename T>
313 struct type_traits {
314  using name = ;
315  using oid = ;
316  using size = ;
317 };
318 #else
319 template <typename T>
320 struct type_traits;
321 #endif
322 
327 template <std::size_t n>
328 using bytes = std::integral_constant<std::size_t, n>;
329 using dynamic_size = void;
330 
331 template <typename T, typename Size>
332 struct type_size_match : std::integral_constant<bool, sizeof(T) == Size::value> {};
333 
334 template <typename T>
335 struct type_size_match<T, dynamic_size> : std::true_type {};
349 template <typename T, typename Name, typename Oid = null_oid_t, typename Size = dynamic_size>
351  using name = Name;
352  using oid = Oid;
353  using size = Size;
354  static_assert(type_size_match<T, size>::value,
355  "type size does not match to declared size");
356 };
357 
358 template <typename T>
359 struct type_traits : type_traits_helper<T, void> {};
360 
366 template <typename T>
367 struct is_built_in : std::integral_constant<bool,
368  !std::is_same_v<typename type_traits<T>::oid, null_oid_t>> {};
369 
370 template <typename T>
371 using is_dynamic_size = std::is_same<typename type_traits<T>::size, dynamic_size>;
372 
377 template <typename T>
378 constexpr auto type_name() noexcept {
379  static_assert(!std::is_void<typename type_traits<T>::name>::value,
380  "no type_traits found for the type");
381  constexpr auto name = typename type_traits<T>::name{};
382  constexpr char const* retval = hana::to<char const*>(name);
383  return retval;
384 }
385 
386 template <typename T>
387 constexpr auto type_name(const T&) noexcept {return type_name<T>();}
388 
392 template <typename T>
393 constexpr auto size_of(T&&) noexcept -> typename std::enable_if<
394  !is_dynamic_size<std::decay_t<T>>::value,
395  typename type_traits<std::decay_t<T>>::size>::type {
396  return {};
397 }
398 
399 template <typename T>
400 constexpr auto size_of(const T& v) noexcept -> typename std::enable_if<
401  is_dynamic_size<std::decay_t<T>>::value,
402  decltype(std::size(std::declval<T>()))>::type {
403  return std::size(v) ? std::size(v) * size_of(*std::begin(v)) : 0;
404 }
405 
406 } // namespace ozo
407 
408 #define OZO__TYPE_NAME_TYPE(Name) decltype(Name##_s)
409 #define OZO__TYPE_ARRAY_NAME_TYPE(Name) decltype(Name##_s+"[]"_s)
410 
411 #define OZO_PG_DEFINE_TYPE(Type, Name, Oid, Size) \
412  namespace ozo {\
413  template <>\
414  struct type_traits<Type> : type_traits_helper<\
415  Type, \
416  OZO__TYPE_NAME_TYPE(Name), \
417  std::integral_constant<oid_t, Oid>, \
418  Size\
419  >{};\
420  }
421 
422 #define OZO_PG_DEFINE_TYPE_ARRAY(Type, Name, Oid) \
423  namespace ozo {\
424  template <>\
425  struct type_traits<std::vector<Type>> : type_traits_helper<\
426  std::vector<Type>, \
427  OZO__TYPE_ARRAY_NAME_TYPE(Name), \
428  std::integral_constant<oid_t, Oid>, \
429  dynamic_size\
430  >{};\
431  }
432 
433 #ifdef __OZO_STD_OPTIONAL
434 #define OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid) \
435  OZO_PG_DEFINE_TYPE_ARRAY(__OZO_STD_OPTIONAL<Type>, Name, Oid)
436 #else
437 #define OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid)
438 #endif
439 
440 #define OZO_PG_DEFINE_TYPE_ARRAY_NULLABLES(Type, Name, Oid) \
441  OZO_PG_DEFINE_TYPE_ARRAY(boost::optional<Type>, Name, Oid) \
442  OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid) \
443  OZO_PG_DEFINE_TYPE_ARRAY(boost::scoped_ptr<Type>, Name, Oid) \
444  OZO_PG_DEFINE_TYPE_ARRAY(std::unique_ptr<Type>, Name, Oid) \
445  OZO_PG_DEFINE_TYPE_ARRAY(boost::shared_ptr<Type>, Name, Oid) \
446  OZO_PG_DEFINE_TYPE_ARRAY(std::shared_ptr<Type>, Name, Oid)
447 
471 #ifdef OZO_DOCUMENTATION
472 #define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size)
473 #else
474 #define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size) \
475  OZO_PG_DEFINE_TYPE(Type, Name, Oid, Size) \
476  OZO_PG_DEFINE_TYPE_ARRAY(Type, Name, ArrayOid) \
477  OZO_PG_DEFINE_TYPE_ARRAY_NULLABLES(Type, Name, ArrayOid)
478 #endif
479 
480 
481 #define OZO_PG_DEFINE_CUSTOM_TYPE(Type, Name, Size) \
482  namespace ozo {\
483  template <>\
484  struct type_traits<Type> : type_traits_helper<\
485  Type, \
486  OZO__TYPE_NAME_TYPE(Name), \
487  null_oid_t, \
488  Size\
489  >{};\
490  }
491 
492 OZO_PG_DEFINE_TYPE(bool, "bool", BOOLOID, bytes<1>)
493 OZO_PG_DEFINE_TYPE(char, "char", CHAROID, bytes<1>)
494 OZO_PG_DEFINE_TYPE(std::vector<char>, "bytea", BYTEAOID, dynamic_size)
495 
496 OZO_PG_DEFINE_TYPE_AND_ARRAY(boost::uuids::uuid, "uuid", UUIDOID, 2951, bytes<16>)
497 
498 OZO_PG_DEFINE_TYPE_AND_ARRAY(int64_t, "int8", INT8OID, 1016, bytes<8>)
499 OZO_PG_DEFINE_TYPE_AND_ARRAY(int32_t, "int4", INT4OID, INT4ARRAYOID, bytes<4>)
500 OZO_PG_DEFINE_TYPE_AND_ARRAY(int16_t, "int2", INT2OID, INT2ARRAYOID, bytes<2>)
501 
502 OZO_PG_DEFINE_TYPE_AND_ARRAY(ozo::oid_t, "oid", OIDOID, OIDARRAYOID, bytes<4>)
503 
504 OZO_PG_DEFINE_TYPE_AND_ARRAY(double, "float8", FLOAT8OID, 1022, decltype(size_of(detail::to_integral(double()))))
505 OZO_PG_DEFINE_TYPE_AND_ARRAY(float, "float4", FLOAT4OID, FLOAT4ARRAYOID, decltype(size_of(detail::to_integral(float()))))
506 
507 OZO_PG_DEFINE_TYPE_AND_ARRAY(std::string, "text", TEXTOID, TEXTARRAYOID, dynamic_size)
508 
509 
510 namespace ozo {
511 
512 template <typename ImplT>
513 struct oid_map_t {
514  using impl_type = ImplT;
515 
516  impl_type impl;
517 };
518 
519 
520 template <typename T>
521 struct is_oid_map : std::false_type {};
522 
523 template <typename T>
524 struct is_oid_map<oid_map_t<T>> : std::true_type {};
525 
526 template <typename T>
527 constexpr auto OidMap = is_oid_map<std::decay_t<T>>::value;
528 
529 namespace detail {
530 
531 template <typename ... T>
532 constexpr decltype(auto) register_types() noexcept {
533  return hana::make_map(
534  hana::make_pair(hana::type_c<T>, null_oid()) ...
535  );
536 }
537 
538 } // namespace detail
539 
540 template <typename ... T>
541 constexpr decltype(auto) register_types() noexcept {
542  using impl_type = decltype(detail::register_types<T ...>());
543  return oid_map_t<impl_type> {detail::register_types<T ...>()};
544 }
545 
546 using empty_oid_map = std::decay_t<decltype(register_types<>())>;
547 
551 template <typename T, typename MapImplT>
552 inline void set_type_oid(oid_map_t<MapImplT>& map, oid_t oid) noexcept {
553  static_assert(!is_built_in<T>::value, "type must not be built-in");
554  map.impl[hana::type_c<T>] = oid;
555 }
556 
560 template <typename T, typename MapImplT>
561 inline auto type_oid(const oid_map_t<MapImplT>& map) noexcept
562  -> std::enable_if_t<!is_built_in<T>::value, oid_t> {
563  return map.impl[hana::type_c<T>];
564 }
565 
566 template <typename T, typename MapImplT>
567 constexpr auto type_oid(const oid_map_t<MapImplT>&) noexcept
568  -> std::enable_if_t<is_built_in<T>::value, oid_t> {
569  return typename type_traits<T>::oid();
570 }
571 
572 template <typename T, typename MapImplT>
573 inline auto type_oid(const oid_map_t<MapImplT>& map, const T&) noexcept{
574  return type_oid<std::decay_t<T>>(map);
575 }
576 
581 template <typename T, typename MapImplT>
582 inline bool accepts_oid(const oid_map_t<MapImplT>& map, oid_t oid) noexcept {
583  return type_oid<T>(map) == oid;
584 }
585 
586 template <typename T, typename MapImplT>
587 inline bool accepts_oid(const oid_map_t<MapImplT>& map, const T&, oid_t oid) noexcept {
588  return accepts_oid<std::decay_t<T>>(map, oid);
589 }
590 
591 template <typename MapImplT>
592 inline constexpr bool empty(const oid_map_t<MapImplT>& map) noexcept {
593  return hana::length(map.impl) == hana::size_c<0>;
594 }
595 
596 } // namespace ozo
Helper defines the way for the type traits definitions.Type is undefined then Name type is not define...
Definition: type_traits.h:350
-
Indicates if type is a composite.In general we suppose that composite is a type being adapted for int...
Definition: type_traits.h:289
-
std::integral_constant< bool, boost::fusion::traits::is_sequence< T >::value > is_fusion_adapted
Definition: type_traits.h:267
+
1 #pragma once
2 
3 #include <ozo/detail/pg_type.h>
4 #include <ozo/detail/float.h>
5 
6 #include <libpq-fe.h>
7 
8 #include <boost/hana/at_key.hpp>
9 #include <boost/hana/insert.hpp>
10 #include <boost/hana/string.hpp>
11 #include <boost/hana/map.hpp>
12 #include <boost/hana/pair.hpp>
13 #include <boost/hana/type.hpp>
14 #include <boost/uuid/uuid.hpp>
15 #include <boost/optional.hpp>
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/shared_ptr.hpp>
18 #include <boost/make_shared.hpp>
19 #include <boost/weak_ptr.hpp>
20 #include <boost/serialization/strong_typedef.hpp>
21 
22 // Fusion adaptors support
23 #include <boost/fusion/support/is_sequence.hpp>
24 #include <boost/fusion/include/is_sequence.hpp>
25 
26 #include <ozo/concept.h>
27 #include <ozo/optional.h>
28 #include <memory>
29 #include <string>
30 #include <list>
31 #include <vector>
32 #include <set>
33 #include <type_traits>
34 
40 namespace ozo {
41 
42 namespace hana = boost::hana;
43 using namespace hana::literals;
44 
45 namespace fusion = boost::fusion;
50 using oid_t = ::Oid;
51 
56 using null_oid_t = std::integral_constant<oid_t, 0>;
57 constexpr null_oid_t null_oid;
58 
59 template <typename T, typename Enable = void>
60 struct is_nullable : std::false_type {};
61 
65 template <typename T>
66 struct is_nullable<boost::optional<T>> : std::true_type {};
67 
68 #ifdef __OZO_STD_OPTIONAL
69 template <typename T>
70 struct is_nullable<__OZO_STD_OPTIONAL<T>> : std::true_type {};
71 #endif
72 
73 template <typename T>
74 struct is_nullable<boost::scoped_ptr<T>> : std::true_type {};
75 template <typename T, typename Deleter>
76 struct is_nullable<std::unique_ptr<T, Deleter>> : std::true_type {};
77 template <typename T>
78 struct is_nullable<boost::shared_ptr<T>> : std::true_type {};
79 template <typename T>
80 struct is_nullable<std::shared_ptr<T>> : std::true_type {};
81 template <typename T>
82 struct is_nullable<boost::weak_ptr<T>> : std::true_type {};
83 template <typename T>
84 struct is_nullable<std::weak_ptr<T>> : std::true_type {};
85 
116 template <typename T>
117 constexpr auto Nullable = is_nullable<std::decay_t<T>>::value;
118 
119 
120 #ifdef OZO_DOCUMENTATION
121 
130 template <typename T>
131 decltype(auto) unwrap_nullable(T&& value) noexcept;
132 #else
133 template <typename T>
134 inline decltype(auto) unwrap_nullable(T&& t, Require<Nullable<T>>* = 0) noexcept {
135  return *t;
136 }
137 
138 template <typename T>
139 inline decltype(auto) unwrap_nullable(T&& t, Require<!Nullable<T>>* = 0) noexcept {
140  return std::forward<T>(t);
141 }
142 #endif
143 template <typename T>
144 using unwrap_nullable_type = typename std::decay_t<decltype(unwrap_nullable(
145  std::declval<T>()))>;
146 
147 template <typename T>
148 inline auto is_null(const T& v) noexcept -> Require<Nullable<T>, bool> {
149  return !v;
150 }
151 
152 template <typename T>
153 inline auto is_null(const boost::weak_ptr<T>& v) noexcept {
154  return is_null(v.lock());
155 }
156 
157 template <typename T>
158 inline auto is_null(const std::weak_ptr<T>& v) noexcept {
159  return is_null(v.lock());
160 }
161 
162 #ifdef OZO_DOCUMENTATION
163 
173 template <typename T>
174 constexpr auto is_null(const T&) noexcept;
175 #endif
176 
177 template <typename T>
178 constexpr auto is_null(const T&) noexcept -> Require<!Nullable<T>, std::false_type> {
179  return {};
180 }
181 
182 template <typename T, typename = std::void_t<>>
183 struct allocate_nullable_impl {
184  static_assert(Emplaceable<T>, "default implementation uses emplace() method");
185  template <typename Alloc>
186  static void apply(T& out, const Alloc&) {
187  out.emplace();
188  }
189 };
190 
191 template <typename T>
192 struct allocate_nullable_impl<std::unique_ptr<T>> {
193  template <typename Alloc>
194  static void apply(std::unique_ptr<T>& out, const Alloc&) {
195  out = std::make_unique<T>();
196  }
197 };
198 
199 template <typename T>
200 struct allocate_nullable_impl<boost::scoped_ptr<T>> {
201  template <typename Alloc>
202  static void apply(boost::scoped_ptr<T>& out, const Alloc&) {
203  out.reset(new T{});
204  }
205 };
206 
207 template <typename T>
208 struct allocate_nullable_impl<boost::shared_ptr<T>> {
209  template <typename Alloc>
210  static void apply(boost::shared_ptr<T>& out, const Alloc& a) {
211  out = boost::allocate_shared<T, Alloc>(a);
212  }
213 };
214 
215 template <typename T>
216 struct allocate_nullable_impl<std::shared_ptr<T>> {
217  template <typename Alloc>
218  static void apply(std::shared_ptr<T>& out, const Alloc& a) {
219  out = std::allocate_shared<T, Alloc>(a);
220  }
221 };
222 
223 template <typename T, typename Alloc>
224 inline void allocate_nullable(T& out, const Alloc& a) {
225  static_assert(Nullable<T>, "T must be nullable");
226  allocate_nullable_impl<std::decay_t<T>>::apply(out, a);
227 }
228 
229 template <typename T, typename Alloc = std::allocator<char>>
230 inline void init_nullable(T& n, const Alloc& a = Alloc{}) {
231  static_assert(Nullable<T>, "T must be nullable");
232  if (is_null(n)) {
233  allocate_nullable(n, a);
234  }
235 }
236 
237 template <typename T>
238 inline void reset_nullable(T& n) {
239  static_assert(Nullable<T>, "T must be nullable");
240  n = T{};
241 }
242 
257 #ifdef OZO_DOCUMENTATION
258 template <typename T>
259 struct type_traits {
260  using name = ;
261  using oid = ;
262  using size = ;
263 };
264 #else
265 template <typename T>
266 struct type_traits;
267 #endif
268 
273 template <std::size_t n>
274 using bytes = std::integral_constant<std::size_t, n>;
275 using dynamic_size = void;
276 
277 template <typename T, typename Size>
278 struct type_size_match : std::integral_constant<bool, sizeof(T) == Size::value> {};
279 
280 template <typename T>
281 struct type_size_match<T, dynamic_size> : std::true_type {};
294 template <typename T, typename Name, typename Oid = null_oid_t, typename Size = dynamic_size>
296  using name = Name;
297  using oid = Oid;
298  using size = Size;
299  static_assert(type_size_match<T, size>::value,
300  "type size does not match to declared size");
301 };
302 
303 template <typename T>
304 struct type_traits : type_traits_helper<T, void> {};
305 
311 template <typename T>
312 struct is_built_in : std::bool_constant<
313  !std::is_same_v<typename type_traits<T>::oid, null_oid_t>> {};
314 
315 template <typename T>
316 using is_dynamic_size = std::is_same<typename type_traits<T>::size, dynamic_size>;
317 
322 template <typename T>
323 constexpr auto type_name() noexcept {
324  static_assert(!std::is_void<typename type_traits<T>::name>::value,
325  "no type_traits found for the type");
326  constexpr auto name = typename type_traits<T>::name{};
327  constexpr char const* retval = hana::to<char const*>(name);
328  return retval;
329 }
330 
331 template <typename T>
332 constexpr auto type_name(const T&) noexcept {return type_name<T>();}
333 
337 template <typename T>
338 constexpr auto size_of(T&&) noexcept -> typename std::enable_if<
339  !is_dynamic_size<std::decay_t<T>>::value,
340  typename type_traits<std::decay_t<T>>::size>::type {
341  return {};
342 }
343 
344 template <typename T>
345 constexpr auto size_of(const T& v) noexcept -> typename std::enable_if<
346  is_dynamic_size<std::decay_t<T>>::value,
347  decltype(std::size(std::declval<T>()))>::type {
348  return std::size(v) ? std::size(v) * size_of(*std::begin(v)) : 0;
349 }
350 
351 namespace pg {
352 
353 BOOST_STRONG_TYPEDEF(std::string, name)
354 
355 } // namespace pg
356 } // namespace ozo
357 
358 #define OZO__TYPE_NAME_TYPE(Name) decltype(Name##_s)
359 #define OZO__TYPE_ARRAY_NAME_TYPE(Name) decltype(Name##_s+"[]"_s)
360 
361 #define OZO_PG_DEFINE_TYPE(Type, Name, Oid, Size) \
362  namespace ozo {\
363  template <>\
364  struct type_traits<Type> : type_traits_helper<\
365  Type, \
366  OZO__TYPE_NAME_TYPE(Name), \
367  std::integral_constant<oid_t, Oid>, \
368  Size\
369  >{};\
370  }
371 
372 #define OZO_PG_DEFINE_TYPE_ARRAY(Type, Name, Oid) \
373  namespace ozo {\
374  template <>\
375  struct type_traits<std::vector<Type>> : type_traits_helper<\
376  std::vector<Type>, \
377  OZO__TYPE_ARRAY_NAME_TYPE(Name), \
378  std::integral_constant<oid_t, Oid>, \
379  dynamic_size\
380  >{};\
381  }
382 
383 #ifdef __OZO_STD_OPTIONAL
384 #define OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid) \
385  OZO_PG_DEFINE_TYPE_ARRAY(__OZO_STD_OPTIONAL<Type>, Name, Oid)
386 #else
387 #define OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid)
388 #endif
389 
390 #define OZO_PG_DEFINE_TYPE_ARRAY_NULLABLES(Type, Name, Oid) \
391  OZO_PG_DEFINE_TYPE_ARRAY(boost::optional<Type>, Name, Oid) \
392  OZO_PG_DEFINE_TYPE_ARRAY_OZO_OPTIONAL(Type, Name, Oid) \
393  OZO_PG_DEFINE_TYPE_ARRAY(boost::scoped_ptr<Type>, Name, Oid) \
394  OZO_PG_DEFINE_TYPE_ARRAY(std::unique_ptr<Type>, Name, Oid) \
395  OZO_PG_DEFINE_TYPE_ARRAY(boost::shared_ptr<Type>, Name, Oid) \
396  OZO_PG_DEFINE_TYPE_ARRAY(std::shared_ptr<Type>, Name, Oid)
397 
438 #ifdef OZO_DOCUMENTATION
439 #define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size)
440 #else
441 #define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size) \
442  OZO_PG_DEFINE_TYPE(Type, Name, Oid, Size) \
443  OZO_PG_DEFINE_TYPE_ARRAY(Type, Name, ArrayOid) \
444  OZO_PG_DEFINE_TYPE_ARRAY_NULLABLES(Type, Name, ArrayOid)
445 #endif
446 
447 
448 #define OZO_PG_DEFINE_CUSTOM_TYPE(Type, Name, Size) \
449  namespace ozo {\
450  template <>\
451  struct type_traits<Type> : type_traits_helper<\
452  Type, \
453  OZO__TYPE_NAME_TYPE(Name), \
454  null_oid_t, \
455  Size\
456  >{};\
457  }
458 
459 OZO_PG_DEFINE_TYPE(bool, "bool", BOOLOID, bytes<1>)
460 OZO_PG_DEFINE_TYPE(char, "char", CHAROID, bytes<1>)
461 OZO_PG_DEFINE_TYPE(std::vector<char>, "bytea", BYTEAOID, dynamic_size)
462 
463 OZO_PG_DEFINE_TYPE_AND_ARRAY(boost::uuids::uuid, "uuid", UUIDOID, 2951, bytes<16>)
464 
465 OZO_PG_DEFINE_TYPE_AND_ARRAY(int64_t, "int8", INT8OID, 1016, bytes<8>)
466 OZO_PG_DEFINE_TYPE_AND_ARRAY(int32_t, "int4", INT4OID, INT4ARRAYOID, bytes<4>)
467 OZO_PG_DEFINE_TYPE_AND_ARRAY(int16_t, "int2", INT2OID, INT2ARRAYOID, bytes<2>)
468 
469 OZO_PG_DEFINE_TYPE_AND_ARRAY(ozo::oid_t, "oid", OIDOID, OIDARRAYOID, bytes<4>)
470 
471 OZO_PG_DEFINE_TYPE_AND_ARRAY(double, "float8", FLOAT8OID, 1022, decltype(size_of(detail::to_integral(double()))))
472 OZO_PG_DEFINE_TYPE_AND_ARRAY(float, "float4", FLOAT4OID, FLOAT4ARRAYOID, decltype(size_of(detail::to_integral(float()))))
473 
474 OZO_PG_DEFINE_TYPE_AND_ARRAY(std::string, "text", TEXTOID, TEXTARRAYOID, dynamic_size)
475 
476 OZO_PG_DEFINE_TYPE_AND_ARRAY(ozo::pg::name, "name", NAMEOID, 1003, dynamic_size)
477 
478 namespace ozo {
479 
486 template <typename ImplT>
487 struct oid_map_t {
488  using impl_type = ImplT;
489 
490  impl_type impl;
491 };
492 
493 
494 template <typename T>
495 struct is_oid_map : std::false_type {};
496 
497 template <typename T>
498 struct is_oid_map<oid_map_t<T>> : std::true_type {};
499 
533 template <typename T>
534 constexpr auto OidMap = is_oid_map<std::decay_t<T>>::value;
535 
536 namespace detail {
537 
538 template <typename ... T>
539 constexpr decltype(auto) register_types() noexcept {
540  return hana::make_map(
541  hana::make_pair(hana::type_c<T>, null_oid()) ...
542  );
543 }
544 
545 } // namespace detail
546 
572 template <typename ... T>
573 constexpr decltype(auto) register_types() noexcept {
574  using impl_type = decltype(detail::register_types<T ...>());
576 }
577 
582 using empty_oid_map = std::decay_t<decltype(register_types<>())>;
583 
591 template <typename T, typename MapImplT>
592 inline void set_type_oid(oid_map_t<MapImplT>& map, oid_t oid) noexcept {
593  static_assert(!is_built_in<T>::value, "type must not be built-in");
594  map.impl[hana::type_c<T>] = oid;
595 }
596 
603 template <typename T, typename MapImplT>
604 inline auto type_oid(const oid_map_t<MapImplT>& map) noexcept
605  -> std::enable_if_t<!is_built_in<T>::value, oid_t> {
606  return map.impl[hana::type_c<T>];
607 }
608 
609 template <typename T, typename MapImplT>
610 constexpr auto type_oid(const oid_map_t<MapImplT>&) noexcept
611  -> std::enable_if_t<is_built_in<T>::value, oid_t> {
612  return typename type_traits<T>::oid();
613 }
614 
615 template <typename T, typename MapImplT>
616 inline auto type_oid(const oid_map_t<MapImplT>& map, const T&) noexcept{
617  return type_oid<std::decay_t<T>>(map);
618 }
619 
628 template <typename T, typename MapImplT>
629 inline bool accepts_oid(const oid_map_t<MapImplT>& map, oid_t oid) noexcept {
630  return type_oid<T>(map) == oid;
631 }
632 
641 template <typename T, typename MapImplT>
642 inline bool accepts_oid(const oid_map_t<MapImplT>& map, const T& , oid_t oid) noexcept {
643  return accepts_oid<std::decay_t<T>>(map, oid);
644 }
645 
657 template <typename MapImplT>
658 inline constexpr bool empty(const oid_map_t<MapImplT>& map) noexcept {
659  return hana::length(map.impl) == hana::size_c<0>;
660 }
661 
662 } // namespace ozo
Helper for the type traits definitions.
Definition: type_traits.h:295
Definition: error.h:357
-
std::integral_constant< bool, hana::Sequence< T >::value||hana::Struct< T >::value > is_hana_adapted
Definition: type_traits.h:276
-
std::integral_constant< oid_t, 0 > null_oid_t
Type for non initialized OID.
Definition: type_traits.h:54
+
std::integral_constant< oid_t, 0 > null_oid_t
Type for non initialized OID.
Definition: type_traits.h:56
Definition: native_conn_handle.h:5
decltype(auto) unwrap_nullable(T &&value) noexcept
Dereference Nullable argument or forward it.
Type Require
Concept requirement emulation.
Definition: concept.h:54
+
decltype(auto) constexpr register_types() noexcept
Provides OidMap implementation for user-defined types.
Definition: type_traits.h:573
-
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:393
-
typedef oid
std::integral_constant with Oid of the built-in type or null_oid_t for non built-in type ...
Definition: type_traits.h:315
-
#define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size)
Helper macro to define type mappingIn general type mapping is provided via ozo::type_traits specializ...
Definition: type_traits.h:472
-
constexpr auto Nullable
Indicates if type meets nullable requirements.
Definition: type_traits.h:115
-
std::integral_constant< std::size_t, n > bytes
Definition: type_traits.h:328
-
Type traits template forward declaration.Type traits contains information related to it&#39;s representat...
Definition: type_traits.h:313
-
void set_type_oid(oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:552
-
constexpr auto type_name() noexcept
Definition: type_traits.h:378
-
bool accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:582
-
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:48
+
constexpr auto size_of(T &&) noexcept -> typename std::enable_if< !is_dynamic_size< std::decay_t< T >>::value, typename type_traits< std::decay_t< T >>::size >::type
Definition: type_traits.h:338
+
constexpr bool empty(const oid_map_t< MapImplT > &map) noexcept
Definition: type_traits.h:658
+
typedef oid
std::integral_constant with Oid of the built-in type or null_oid_t for non built-in type ...
Definition: type_traits.h:261
+
#define OZO_PG_DEFINE_TYPE_AND_ARRAY(Type, Name, Oid, ArrayOid, Size)
Helper macro to define type mappingIn general type mapping is provided via ozo::type_traits specializ...
Definition: type_traits.h:439
+
constexpr auto Nullable
Indicates if type meets nullable requirements.
Definition: type_traits.h:117
+
std::integral_constant< std::size_t, n > bytes
Definition: type_traits.h:274
+
Type traits template forward declaration.Type traits contains information related to it&#39;s representat...
Definition: type_traits.h:259
+
void set_type_oid(oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:592
+
bool accepts_oid(const oid_map_t< MapImplT > &map, oid_t oid) noexcept
Definition: type_traits.h:629
+
auto type_oid(const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
Definition: type_traits.h:604
+
constexpr auto type_name() noexcept
Definition: type_traits.h:323
+
::Oid oid_t
PostgreSQL OID type - object identifier.
Definition: type_traits.h:50
Definition: asio.h:5
-
Definition: type_traits.h:245
-
Condition indicates if the specified type is built-in for PG.
Definition: type_traits.h:367
-
Definition: type_traits.h:256
-
auto type_oid(const oid_map_t< MapImplT > &map) noexcept -> std::enable_if_t<!is_built_in< T >::value, oid_t >
Definition: type_traits.h:561
+
constexpr auto OidMap
Map of C++ types to corresponding PostgreSQL types OIDs.
Definition: type_traits.h:534
+
Condition indicates if the specified type is built-in for PG.
Definition: type_traits.h:312
+
std::decay_t< decltype(register_types<>())> empty_oid_map
Type alias for empty OidMap.
Definition: type_traits.h:582
+
OidMap implementation type.This type implements OidMap concept based on boost::hana::map.
Definition: type_traits.h:487
diff --git a/docs/html/typed__buffer_8h_source.html b/docs/html/typed__buffer_8h_source.html index 5e08f3134..fef467cfd 100644 --- a/docs/html/typed__buffer_8h_source.html +++ b/docs/html/typed__buffer_8h_source.html @@ -101,7 +101,7 @@
typed_buffer.h
-
1 #pragma once
2 
3 #include <ozo/concept.h>
4 
5 namespace ozo {
6 namespace detail {
7 
8 template <typename T>
9 union typed_buffer {
10  constexpr static auto size = sizeof(T);
11  T typed;
12  char raw[size];
13 };
14 
15 template <typename T>
16 constexpr char* data(typed_buffer<T>& buf) { return buf.raw;}
17 
18 template <typename T>
19 constexpr const char* data(const typed_buffer<T>& buf) { return buf.raw;}
20 
21 template <typename T>
22 constexpr auto size(const typed_buffer<T>& buf) { return buf.size;}
23 } // namespace detail
24 
25 template <typename T>
26 struct is_raw_data_writable<detail::typed_buffer<T>> : std::true_type {};
27 
28 } // namespace ozo
29 
Definition: asio.h:5
+
1 #pragma once
2 
3 #include <ozo/concept.h>
4 
5 namespace ozo {
6 namespace detail {
7 
8 template <typename T>
9 union typed_buffer {
10  constexpr static auto size = sizeof(T);
11  T typed;
12  char raw[size];
13 };
14 
15 template <typename T>
16 constexpr char* data(typed_buffer<T>& buf) { return buf.raw;}
17 
18 template <typename T>
19 constexpr const char* data(const typed_buffer<T>& buf) { return buf.raw;}
20 
21 template <typename T>
22 constexpr auto size(const typed_buffer<T>& buf) { return buf.size;}
23 } // namespace detail
24 
25 } // namespace ozo
26 
Definition: asio.h:5
Name— type which can be converted into a string representation which contain the fully qualified type name in DB