@@ -126,6 +126,20 @@ class pg_result_t
126126 std::unique_ptr<PGresult, pg_result_deleter_t > m_result;
127127};
128128
129+ /* *
130+ * Wrapper class for query parameters that should be sent to the database
131+ * as binary parameter.
132+ */
133+ class binary_param : public std ::string_view
134+ {
135+ public:
136+ using std::string_view::string_view;
137+
138+ binary_param (std::string const &str)
139+ : std::string_view(str.data(), str.size())
140+ {}
141+ };
142+
129143/* *
130144 * PostgreSQL connection.
131145 *
@@ -229,6 +243,8 @@ class pg_conn_t
229243 return 0 ;
230244 } else if constexpr (std::is_same_v<T, std::string>) {
231245 return 0 ;
246+ } else if constexpr (std::is_same_v<T, binary_param>) {
247+ return 0 ;
232248 }
233249 return 1 ;
234250 }
@@ -240,12 +256,18 @@ class pg_conn_t
240256 * strings.
241257 */
242258 template <typename T>
243- static char const *to_str (std::vector<std::string> *data, T const ¶m)
259+ static char const *to_str (std::vector<std::string> *data, int *length,
260+ int *bin, T const ¶m)
244261 {
245262 if constexpr (std::is_same_v<T, char const *>) {
246263 return param;
247264 } else if constexpr (std::is_same_v<T, std::string>) {
265+ *length = param.size ();
248266 return param.c_str ();
267+ } else if constexpr (std::is_same_v<T, binary_param>) {
268+ *length = param.size ();
269+ *bin = 1 ;
270+ return param.data ();
249271 }
250272 return data->emplace_back (fmt::to_string (param)).c_str ();
251273 }
@@ -275,16 +297,21 @@ class pg_conn_t
275297 std::vector<std::string> exec_params;
276298 exec_params.reserve (total_buffers_needed);
277299
300+ std::array<int , sizeof ...(params)> lengths = {0 };
301+ std::array<int , sizeof ...(params)> bins = {0 };
302+
278303 // This array holds the pointers to all parameter strings, either
279304 // to the original string parameters or to the recently converted
280305 // in the exec_params vector.
306+ std::size_t n = 0 ;
307+ std::size_t m = 0 ;
281308 std::array<char const *, sizeof ...(params)> param_ptrs = {
282- to_str<std::decay_t <TArgs>>(&exec_params,
309+ to_str<std::decay_t <TArgs>>(&exec_params, &lengths[n++], &bins[m++],
283310 std::forward<TArgs>(params))...};
284311
285312 return exec_prepared_internal (stmt, sizeof ...(params),
286- param_ptrs.data (), nullptr , nullptr ,
287- result_as_binary ? 1 : 0 );
313+ param_ptrs.data (), lengths. data () ,
314+ bins. data (), result_as_binary ? 1 : 0 );
288315 }
289316
290317 struct pg_conn_deleter_t
0 commit comments