8 #ifndef LIB_PG_ASYNC_INCLUDE_TIP_DB_PG_QUERY_INL_
9 #define LIB_PG_ASYNC_INCLUDE_TIP_DB_PG_QUERY_INL_
12 #include <tip/util/meta_helpers.hpp>
21 template <
size_t Index,
typename T >
27 typedef io::traits::best_formatter<type> best_formatter;
32 write_format( std::vector<byte>& buffer )
34 return io::protocol_write< BINARY_DATA_FORMAT >(buffer, (
smallint)data_format);
38 write_value (std::vector<byte>& buffer, type
const& value)
41 size_t buffer_pos = buffer.size();
43 buffer.resize(buffer.size() +
sizeof(
integer));
44 size_t prev_size = buffer.size();
45 io::protocol_write< data_format >(buffer, value);
46 integer len = buffer.size() - prev_size;
48 std::vector<byte>::iterator sz_iter = buffer.begin() +
50 io::protocol_write< BINARY_DATA_FORMAT >( sz_iter, len );
52 io::protocol_read< BINARY_DATA_FORMAT > (sz_iter, sz_iter +
sizeof(
integer), written);
53 assert(written == len &&
"Length is written ok");
58 size(type
const& value)
60 return io::protocol_writer< data_format >(value).size() +
sizeof(
integer);
64 template <
size_t Index,
typename T >
65 struct nth_param < Index, boost::optional< T > > {
70 typedef io::traits::best_formatter<type> best_formatter;
75 write_format( std::vector<byte>& buffer )
77 return io::protocol_write< BINARY_DATA_FORMAT >(buffer, (
smallint)data_format);
81 write_value (std::vector<byte>& buffer, boost::optional<type>
const& value)
84 return nth_param< Index, T >::write_value( buffer, *value );
87 return io::protocol_write< BINARY_DATA_FORMAT >( buffer, (
integer)-1 );
92 template <
size_t Index,
typename ... T >
93 struct format_selector;
95 template <
typename T >
96 struct format_selector< 0, T > {
101 typedef io::traits::best_formatter<type> best_formatter;
102 typedef typename best_formatter::type formatter_type;
104 typedef io::traits::cpppg_data_mapping< T > data_mapping;
107 static constexpr
bool single_format =
true;
109 type_oid = data_mapping::type_oid
116 "Parameter type doesn't have a PostgreSQL typeoid mapping" );
120 write_format( std::vector<byte>& buffer )
122 io::protocol_write< BINARY_DATA_FORMAT >(buffer, (
smallint)data_format);
126 write_param_value( std::vector<byte>& buffer, type
const& value)
128 nth_param<index, T>::write_value(buffer, value);
132 size( type
const& value )
134 return nth_param< index, T >::size(value);
138 template <
size_t N,
typename T,
typename ... Y >
139 struct format_selector< N, T, Y ... > {
144 typedef io::traits::best_formatter<type> best_formatter;
145 typedef typename best_formatter::type formatter_type;
147 typedef format_selector< N - 1, Y ...> next_param_type;
149 typedef io::traits::cpppg_data_mapping< T > data_mapping;
152 static constexpr
bool single_format =
153 next_param_type::single_format &&
154 next_param_type::data_format == data_format;
156 type_oid = data_mapping::type_oid
163 "Parameter type doesn't have a PostgreSQL typeoid mapping" );
165 next_param_type::write_type(param_types);
168 write_format( std::vector<byte>& buffer )
170 io::protocol_write< BINARY_DATA_FORMAT >(buffer, (
smallint)data_format);
171 next_param_type::write_format(buffer);
175 write_param_value( std::vector<byte>& buffer, type
const& value,
178 nth_param<index, T>::write_value(buffer, value);
179 next_param_type::write_param_value(buffer, next ...);
182 size( type
const& value, Y
const& ... next )
184 return nth_param< index, T >::size(value) + next_param_type::size(next ...);
191 template <
typename ... T >
192 struct is_text_format {
194 size =
sizeof ... (T),
195 last_index = size - 1
197 typedef format_selector< last_index, T... > last_selector;
198 static constexpr
bool value = last_selector::single_format &&
204 template < bool,
typename IndexTuple,
typename ... T >
205 struct param_format_builder;
210 template <
size_t ... Indexes,
typename ... T >
211 struct param_format_builder< true, util::indexes_tuple< Indexes ... >, T ... > {
213 size =
sizeof ... (T),
214 last_index = size - 1
217 typedef format_selector< last_index, T... > first_selector;
225 param_types.reserve(size);
226 first_selector::write_type(param_types);
229 + first_selector::size(args ...);
232 io::protocol_write<BINARY_DATA_FORMAT>(buffer, (
smallint)data_format);
233 io::protocol_write<BINARY_DATA_FORMAT>(buffer, (
smallint)size);
234 first_selector::write_param_value(buffer, args ...);
243 template <
size_t ... Indexes,
typename ... T >
244 struct param_format_builder< false, util::indexes_tuple< Indexes ... >, T ... > {
246 size =
sizeof ... (T),
247 last_index = size - 1
250 typedef format_selector< last_index, T... > first_selector;
258 param_types.reserve(size);
259 first_selector::write_type(param_types);
263 + first_selector::size(args ...);
266 io::protocol_write<BINARY_DATA_FORMAT>(buffer, (
smallint)size);
267 first_selector::write_format(buffer);
268 io::protocol_write<BINARY_DATA_FORMAT>(buffer, (
smallint)size);
269 first_selector::write_param_value(buffer, args ...);
276 template <
typename ... T >
277 struct param_formatter : param_format_builder <
278 is_text_format< T ... >::value,
279 typename util::index_builder< sizeof ... (T) >::type,
284 struct ___no_binary_format {};
285 static_assert( !is_text_format< smallint, integer, bigint, ___no_binary_format >::value,
288 static_assert( !is_text_format< smallint, integer, bigint >::value,
289 "Single format for integral types" );
290 static_assert( param_formatter< smallint, integer, bigint >::data_format
292 "Binary format for integral types");
294 template <
typename ... T >
297 std::vector<byte>& buffer, T
const& ... params)
304 template <
typename ... T >
307 : pimpl_(create_impl(alias, expression, params ...))
311 template <
typename ... T >
314 : pimpl_(create_impl(t, expression, params ... ))
318 template <
typename ... T >
326 return create_impl(alias, expression, std::move(ptypes), std::move(buf));
329 template <
typename ... T >
337 return create_impl(tran, expression, std::move(ptypes), std::move(buf));
341 template <
typename ... T >
355 params_buffer& buf = buffer();
query & bind()
Mark the query as prepared statement.
Short unique string to refer a database. Signature structure, to pass instead of connection string...
std::shared_ptr< transaction > transaction_ptr
query(dbalias const &alias, std::string const &expression)
Construct a query.
boost::int_t< 32 >::exact integer
4-byte integer, to match PostgreSQL integer and serial types
boost::int_t< 16 >::exact smallint
2-byte integer, to match PostgreSQL smallint and smallserial types
void write_params(std::vector< oids::type::oid_type > ¶m_types, std::vector< byte > &buffer, T const &...params)
std::vector< oids::type::oid_type > type_oid_sequence