libpqxx
The C++ client library for PostgreSQL
connection.hxx
1 /* Definition of the connection class.
2  *
3  * pqxx::connection encapsulates a connection to a database.
4  *
5  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection instead.
6  *
7  * Copyright (c) 2000-2024, Jeroen T. Vermeulen.
8  *
9  * See COPYING for copyright license. If you did not receive a file called
10  * COPYING with this source code, please notify the distributor of this
11  * mistake, or contact the author.
12  */
13 #ifndef PQXX_H_CONNECTION
14 #define PQXX_H_CONNECTION
15 
16 #if !defined(PQXX_HEADER_PRE)
17 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18 #endif
19 
20 #include <cstddef>
21 #include <ctime>
22 #include <initializer_list>
23 #include <list>
24 #include <map>
25 #include <memory>
26 #include <string_view>
27 #include <tuple>
28 
29 // Double-check in order to suppress an overzealous Visual C++ warning (#418).
30 #if defined(PQXX_HAVE_CONCEPTS) && __has_include(<ranges>)
31 # include <ranges>
32 #endif
33 
34 #include "pqxx/errorhandler.hxx"
35 #include "pqxx/except.hxx"
36 #include "pqxx/internal/concat.hxx"
37 #include "pqxx/params.hxx"
38 #include "pqxx/separated_list.hxx"
39 #include "pqxx/strconv.hxx"
40 #include "pqxx/types.hxx"
41 #include "pqxx/util.hxx"
42 #include "pqxx/zview.hxx"
43 
44 
78 namespace pqxx::internal
79 {
80 class sql_cursor;
81 
82 #if defined(PQXX_HAVE_CONCEPTS)
84 template<typename T>
85 concept ZKey_ZValues = std::ranges::input_range<T> and requires(T t) {
86  { std::cbegin(t) };
87  { std::get<0>(*std::cbegin(t)) } -> ZString;
88  { std::get<1>(*std::cbegin(t)) } -> ZString;
89 } and std::tuple_size_v<typename std::ranges::iterator_t<T>::value_type> == 2;
90 #endif // PQXX_HAVE_CONCEPTS
91 
92 
94 
101 void PQXX_COLD PQXX_LIBEXPORT skip_init_ssl(int skips) noexcept;
102 } // namespace pqxx::internal
103 
104 
105 namespace pqxx::internal::gate
106 {
107 class connection_dbtransaction;
108 class connection_errorhandler;
109 class connection_largeobject;
110 class connection_notification_receiver;
111 class connection_pipeline;
112 class connection_sql_cursor;
113 struct connection_stream_from;
114 class connection_stream_to;
115 class connection_transaction;
116 class const_connection_largeobject;
117 } // namespace pqxx::internal::gate
118 
119 
120 namespace pqxx
121 {
123 
130 enum skip_init : int
131 {
134 
137 
140 };
141 
142 
144 
167 template<skip_init... SKIP> inline void skip_init_ssl() noexcept
168 {
169  // (Normalise skip flags to one per.)
170  pqxx::internal::skip_init_ssl(((1 << SKIP) | ...));
171 }
172 
173 
175 
182 using table_path = std::initializer_list<std::string_view>;
183 
184 
186 enum class error_verbosity : int
187 {
188  // These values must match those in libpq's PGVerbosity enum.
189  terse = 0,
190  normal = 1,
191  verbose = 2
192 };
193 
194 
196 
229 class PQXX_LIBEXPORT connection
230 {
231 public:
232  connection() : connection{""} {}
233 
235  explicit connection(char const options[])
236  {
237  check_version();
238  init(options);
239  }
240 
242  explicit connection(zview options) : connection{options.c_str()}
243  {
244  // (Delegates to other constructor which calls check_version for us.)
245  }
246 
248 
253  connection(connection &&rhs);
254 
255 #if defined(PQXX_HAVE_CONCEPTS)
257 
272  template<internal::ZKey_ZValues MAPPING>
273  inline connection(MAPPING const &params);
274 #endif // PQXX_HAVE_CONCEPTS
275 
276  ~connection()
277  {
278  try
279  {
280  close();
281  }
282  catch (std::exception const &)
283  {}
284  }
285 
287 
290  connection &operator=(connection &&rhs);
291 
292  connection(connection const &) = delete;
293  connection &operator=(connection const &) = delete;
294 
296 
301  [[nodiscard]] bool PQXX_PURE is_open() const noexcept;
302 
304  void process_notice(char const[]) noexcept;
306 
309  void process_notice(zview) noexcept;
310 
312  void trace(std::FILE *) noexcept;
313 
325 
326  [[nodiscard]] char const *dbname() const;
327 
329 
330  [[nodiscard]] char const *username() const;
331 
333 
336  [[nodiscard]] char const *hostname() const;
337 
339  [[nodiscard]] char const *port() const;
340 
342  [[nodiscard]] int PQXX_PURE backendpid() const & noexcept;
343 
345 
355  [[nodiscard]] int PQXX_PURE sock() const & noexcept;
356 
358 
361  [[nodiscard]] int PQXX_PURE protocol_version() const noexcept;
362 
364 
376  [[nodiscard]] int PQXX_PURE server_version() const noexcept;
378 
380 
401  [[nodiscard]] std::string get_client_encoding() const;
402 
404 
407  void set_client_encoding(zview encoding) &
408  {
409  set_client_encoding(encoding.c_str());
410  }
411 
413 
416  void set_client_encoding(char const encoding[]) &;
417 
419  [[nodiscard]] int encoding_id() const;
420 
422 
424 
445  template<typename TYPE>
446  void set_session_var(std::string_view var, TYPE const &value) &
447  {
448  if constexpr (nullness<TYPE>::has_null)
449  {
450  if (nullness<TYPE>::is_null(value))
451  throw variable_set_to_null{
452  internal::concat("Attempted to set variable ", var, " to null.")};
453  }
454  exec(internal::concat("SET ", quote_name(var), "=", quote(value)));
455  }
456 
458 
464  std::string get_var(std::string_view var);
465 
467 
473  template<typename TYPE> TYPE get_var_as(std::string_view var)
474  {
475  return from_string<TYPE>(get_var(var));
476  }
477 
483 
500  int get_notifs();
501 
503 
515  int await_notification();
516 
518 
530  int await_notification(std::time_t seconds, long microseconds);
532 
564  [[nodiscard]] std::string
565  encrypt_password(zview user, zview password, zview algorithm)
566  {
567  return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
568  }
570  [[nodiscard]] std::string encrypt_password(
571  char const user[], char const password[], char const *algorithm = nullptr);
573 
616 
618 
622  void prepare(zview name, zview definition) &
623  {
624  prepare(name.c_str(), definition.c_str());
625  }
626 
631  void prepare(char const name[], char const definition[]) &;
632 
634 
641  void prepare(char const definition[]) &;
642  void prepare(zview definition) & { return prepare(definition.c_str()); }
643 
645  void unprepare(std::string_view name);
646 
648 
649  // C++20: constexpr. Breaks ABI.
651 
654  [[nodiscard]] std::string adorn_name(std::string_view);
655 
660 
662  [[nodiscard]] std::string esc(char const text[]) const
663  {
664  return esc(std::string_view{text});
665  }
666 
667 #if defined(PQXX_HAVE_SPAN)
669 
680  [[nodiscard]] std::string_view
681  esc(std::string_view text, std::span<char> buffer)
682  {
683  auto const size{std::size(text)}, space{std::size(buffer)};
684  auto const needed{2 * size + 1};
685  if (space < needed)
686  throw range_error{internal::concat(
687  "Not enough room to escape string of ", size, " byte(s): need ",
688  needed, " bytes of buffer space, but buffer size is ", space, ".")};
689  auto const data{buffer.data()};
690  return {data, esc_to_buf(text, data)};
691  }
692 #endif
693 
695 
698  [[nodiscard]] std::string esc(std::string_view text) const;
699 
700 #if defined(PQXX_HAVE_CONCEPTS)
702 
703  template<binary DATA> [[nodiscard]] std::string esc(DATA const &data) const
704  {
705  return esc_raw(data);
706  }
707 #endif
708 
709 #if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
711 
722  template<binary DATA>
723  [[nodiscard]] zview esc(DATA const &data, std::span<char> buffer) const
724  {
725  auto const size{std::size(data)}, space{std::size(buffer)};
726  auto const needed{internal::size_esc_bin(std::size(data))};
727  if (space < needed)
728  throw range_error{internal::concat(
729  "Not enough room to escape binary string of ", size, " byte(s): need ",
730  needed, " bytes of buffer space, but buffer size is ", space, ".")};
731 
732  bytes_view view{std::data(data), std::size(data)};
733  auto const out{std::data(buffer)};
734  // Actually, in the modern format, we know beforehand exactly how many
735  // bytes we're going to fill. Just leave out the trailing zero.
736  internal::esc_bin(view, out);
737  return zview{out, needed - 1};
738  }
739 #endif
740 
742  [[deprecated("Use std::byte for binary data.")]] std::string
743  esc_raw(unsigned char const bin[], std::size_t len) const;
744 
746 
747  [[nodiscard]] std::string esc_raw(bytes_view) const;
748 
749 #if defined(PQXX_HAVE_SPAN)
751 
752  [[nodiscard]] std::string esc_raw(bytes_view, std::span<char> buffer) const;
753 #endif
754 
755 #if defined(PQXX_HAVE_CONCEPTS)
757 
758  template<binary DATA>
759  [[nodiscard]] std::string esc_raw(DATA const &data) const
760  {
761  return esc_raw(bytes_view{std::data(data), std::size(data)});
762  }
763 #endif
764 
765 #if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
767  template<binary DATA>
768  [[nodiscard]] zview esc_raw(DATA const &data, std::span<char> buffer) const
769  {
770  return this->esc(binary_cast(data), buffer);
771  }
772 #endif
773 
774  // TODO: Make "into buffer" variant to eliminate a string allocation.
776 
783  [[nodiscard]] bytes unesc_bin(std::string_view text) const
784  {
785  bytes buf;
786  buf.resize(pqxx::internal::size_unesc_bin(std::size(text)));
787  pqxx::internal::unesc_bin(text, buf.data());
788  return buf;
789  }
790 
792  std::string quote_raw(bytes_view) const;
793 
794 #if defined(PQXX_HAVE_CONCEPTS)
796 
797  template<binary DATA>
798  [[nodiscard]] std::string quote_raw(DATA const &data) const
799  {
800  return quote_raw(bytes_view{std::data(data), std::size(data)});
801  }
802 #endif
803 
804  // TODO: Make "into buffer" variant to eliminate a string allocation.
806  [[nodiscard]] std::string quote_name(std::string_view identifier) const;
807 
808  // TODO: Make "into buffer" variant to eliminate a string allocation.
810 
813  [[nodiscard]] std::string quote_table(std::string_view name) const;
814 
815  // TODO: Make "into buffer" variant to eliminate a string allocation.
817 
825  [[nodiscard]] std::string quote_table(table_path) const;
826 
827  // TODO: Make "into buffer" variant to eliminate a string allocation.
829 
836  template<PQXX_CHAR_STRINGS_ARG STRINGS>
837  inline std::string quote_columns(STRINGS const &columns) const;
838 
839  // TODO: Make "into buffer" variant to eliminate a string allocation.
841 
844  template<typename T>
845  [[nodiscard]] inline std::string quote(T const &t) const;
846 
847  [[deprecated("Use std::byte for binary data.")]] std::string
848  quote(binarystring const &) const;
849 
850  // TODO: Make "into buffer" variant to eliminate a string allocation.
852  [[nodiscard]] std::string quote(bytes_view bytes) const;
853 
854  // TODO: Make "into buffer" variant to eliminate a string allocation.
856 
881  [[nodiscard]] std::string
882  esc_like(std::string_view text, char escape_char = '\\') const;
883 
885 
889  [[deprecated("Use std::string_view or pqxx:zview.")]] std::string
890  esc(char const text[], std::size_t maxlen) const
891  {
892  return esc(std::string_view{text, maxlen});
893  }
894 
896 
899  [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
900  unesc_raw(zview text) const
901  {
902 #include "pqxx/internal/ignore-deprecated-pre.hxx"
903  return unesc_raw(text.c_str());
904 #include "pqxx/internal/ignore-deprecated-post.hxx"
905  }
906 
908 
911  [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
912  unesc_raw(char const text[]) const;
913 
915  [[deprecated("Use quote(bytes_view).")]] std::string
916  quote_raw(unsigned char const bin[], std::size_t len) const;
918 
920 
924  void cancel_query();
925 
926 #if defined(_WIN32) || __has_include(<fcntl.h>)
928 
932  void set_blocking(bool block) &;
933 #endif // defined(_WIN32) || __has_include(<fcntl.h>)
934 
936 
945  void set_verbosity(error_verbosity verbosity) & noexcept;
946 
948 
960  [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
961 
963 
969  [[nodiscard]] std::string connection_string() const;
970 
972 
980  void close();
981 
983 
989  static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
990  {
991  return connection{raw_conn};
992  }
993 
995 
1000  internal::pq::PGconn *release_raw_connection() &&
1001  {
1002  return std::exchange(m_conn, nullptr);
1003  }
1004 
1006 
1019  [[deprecated("To set session variables, use set_session_var.")]] void
1020  set_variable(std::string_view var, std::string_view value) &;
1021 
1023 
1026  [[deprecated("Use get_var instead.")]] std::string
1027  get_variable(std::string_view);
1028 
1029 private:
1030  friend class connecting;
1031  enum connect_mode
1032  {
1033  connect_nonblocking
1034  };
1035  connection(connect_mode, zview connection_string);
1036 
1038  explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {}
1039 
1041 
1046  std::pair<bool, bool> poll_connect();
1047 
1048  // Initialise based on connection string.
1049  void init(char const options[]);
1050  // Initialise based on parameter names and values.
1051  void init(char const *params[], char const *values[]);
1052  void complete_init();
1053 
1054  result make_result(
1055  internal::pq::PGresult *pgr, std::shared_ptr<std::string> const &query,
1056  std::string_view desc = ""sv);
1057 
1058  void PQXX_PRIVATE set_up_state();
1059 
1060  int PQXX_PRIVATE PQXX_PURE status() const noexcept;
1061 
1063 
1067  std::size_t esc_to_buf(std::string_view text, char *buf) const;
1068 
1069  friend class internal::gate::const_connection_largeobject;
1070  char const *PQXX_PURE err_msg() const noexcept;
1071 
1072  void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept;
1073 
1074  result exec_prepared(std::string_view statement, internal::c_params const &);
1075 
1077  void check_movable() const;
1079  void check_overwritable() const;
1080 
1081  friend class internal::gate::connection_errorhandler;
1082  void PQXX_PRIVATE register_errorhandler(errorhandler *);
1083  void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
1084 
1085  friend class internal::gate::connection_transaction;
1086  result exec(std::string_view, std::string_view = ""sv);
1087  result PQXX_PRIVATE
1088  exec(std::shared_ptr<std::string> const &, std::string_view = ""sv);
1089  void PQXX_PRIVATE register_transaction(transaction_base *);
1090  void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
1091 
1092  friend struct internal::gate::connection_stream_from;
1094 
1099  std::pair<std::unique_ptr<char, void (*)(void const *)>, std::size_t>
1100  read_copy_line();
1101 
1102  friend class internal::gate::connection_stream_to;
1103  void PQXX_PRIVATE write_copy_line(std::string_view);
1104  void PQXX_PRIVATE end_copy_write();
1105 
1106  friend class internal::gate::connection_largeobject;
1107  internal::pq::PGconn *raw_connection() const { return m_conn; }
1108 
1109  friend class internal::gate::connection_notification_receiver;
1110  void add_receiver(notification_receiver *);
1111  void remove_receiver(notification_receiver *) noexcept;
1112 
1113  friend class internal::gate::connection_pipeline;
1114  void PQXX_PRIVATE start_exec(char const query[]);
1115  bool PQXX_PRIVATE consume_input() noexcept;
1116  bool PQXX_PRIVATE is_busy() const noexcept;
1117  internal::pq::PGresult *get_result();
1118 
1119  friend class internal::gate::connection_dbtransaction;
1120  friend class internal::gate::connection_sql_cursor;
1121 
1122  result exec_params(std::string_view query, internal::c_params const &args);
1123 
1125  internal::pq::PGconn *m_conn = nullptr;
1126 
1128 
1135  transaction_base const *m_trans = nullptr;
1136 
1137  std::list<errorhandler *> m_errorhandlers;
1138 
1139  using receiver_list =
1140  std::multimap<std::string, pqxx::notification_receiver *>;
1142  receiver_list m_receivers;
1143 
1145  int m_unique_id = 0;
1146 };
1147 
1148 
1151 
1152 
1154 
1197 class PQXX_LIBEXPORT connecting
1198 {
1199 public:
1201  connecting(zview connection_string = ""_zv);
1202 
1203  connecting(connecting const &) = delete;
1204  connecting(connecting &&) = default;
1205  connecting &operator=(connecting const &) = delete;
1206  connecting &operator=(connecting &&) = default;
1207 
1209  [[nodiscard]] int sock() const & noexcept { return m_conn.sock(); }
1210 
1212  [[nodiscard]] constexpr bool wait_to_read() const & noexcept
1213  {
1214  return m_reading;
1215  }
1216 
1218  [[nodiscard]] constexpr bool wait_to_write() const & noexcept
1219  {
1220  return m_writing;
1221  }
1222 
1224  void process() &;
1225 
1227  [[nodiscard]] constexpr bool done() const & noexcept
1228  {
1229  return not m_reading and not m_writing;
1230  }
1231 
1233 
1241  [[nodiscard]] connection produce() &&;
1242 
1243 private:
1244  connection m_conn;
1245  bool m_reading{false};
1246  bool m_writing{true};
1247 };
1248 
1249 
1250 template<typename T> inline std::string connection::quote(T const &t) const
1251 {
1252  if constexpr (nullness<T>::always_null)
1253  {
1254  return "NULL";
1255  }
1256  else
1257  {
1258  if (is_null(t))
1259  return "NULL";
1260  auto const text{to_string(t)};
1261 
1262  // Okay, there's an easy way to do this and there's a hard way. The easy
1263  // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
1264  // because it's going to save some string manipulation that will probably
1265  // incur some unnecessary memory allocations and deallocations.
1266  std::string buf{'\''};
1267  buf.resize(2 + 2 * std::size(text) + 1);
1268  auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
1269  auto const closing_quote{1 + content_bytes};
1270  buf[closing_quote] = '\'';
1271  auto const end{closing_quote + 1};
1272  buf.resize(end);
1273  return buf;
1274  }
1275 }
1276 
1277 
1278 template<PQXX_CHAR_STRINGS_ARG STRINGS>
1279 inline std::string connection::quote_columns(STRINGS const &columns) const
1280 {
1281  return separated_list(
1282  ","sv, std::cbegin(columns), std::cend(columns),
1283  [this](auto col) { return this->quote_name(*col); });
1284 }
1285 
1286 
1287 #if defined(PQXX_HAVE_CONCEPTS)
1288 template<internal::ZKey_ZValues MAPPING>
1289 inline connection::connection(MAPPING const &params)
1290 {
1291  check_version();
1292 
1293  std::vector<char const *> keys, values;
1294  if constexpr (std::ranges::sized_range<MAPPING>)
1295  {
1296  auto const size{std::ranges::size(params) + 1};
1297  keys.reserve(size);
1298  values.reserve(size);
1299  }
1300  for (auto const &[key, value] : params)
1301  {
1302  keys.push_back(internal::as_c_string(key));
1303  values.push_back(internal::as_c_string(value));
1304  }
1305  keys.push_back(nullptr);
1306  values.push_back(nullptr);
1307  init(std::data(keys), std::data(values));
1308 }
1309 #endif // PQXX_HAVE_CONCEPTS
1310 
1311 
1313 [[nodiscard,
1314  deprecated("Use connection::encrypt_password instead.")]] std::string
1315  PQXX_LIBEXPORT
1316  encrypt_password(char const user[], char const password[]);
1317 
1319 [[nodiscard,
1320  deprecated("Use connection::encrypt_password instead.")]] inline std::string
1322 {
1323 #include "pqxx/internal/ignore-deprecated-pre.hxx"
1324  return encrypt_password(user.c_str(), password.c_str());
1325 #include "pqxx/internal/ignore-deprecated-post.hxx"
1326 }
1327 } // namespace pqxx
1328 #endif
An ongoing, non-blocking stepping stone to a connection.
Definition: connection.hxx:1198
int sock() const &noexcept
Get the socket. The socket may change during the connection process.
Definition: connection.hxx:1209
constexpr bool done() const &noexcept
Is our connection finished?
Definition: connection.hxx:1227
constexpr bool wait_to_write() const &noexcept
Should we currently wait to be able to write to the socket?
Definition: connection.hxx:1218
void process() &
Progress towards completion (but don't block).
constexpr bool wait_to_read() const &noexcept
Should we currently wait to be able to read from the socket?
Definition: connection.hxx:1212
connecting(zview connection_string=""_zv)
Start connecting.
connection produce() &&
Produce the completed connection object.
Connection to a database.
Definition: connection.hxx:230
std::string encrypt_password(zview user, zview password, zview algorithm)
Encrypt a password for a given user.
Definition: connection.hxx:565
connection(char const options[])
Connect to a database, using options string.
Definition: connection.hxx:235
TYPE get_var_as(std::string_view var)
Read currently applicable value of a variable.
Definition: connection.hxx:473
internal::pq::PGconn * release_raw_connection() &&
Release the raw connection without closing it.
Definition: connection.hxx:1000
bytes unesc_bin(std::string_view text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:783
std::string quote_columns(STRINGS const &columns) const
Quote and comma-separate a series of column names.
Definition: connection.hxx:1279
connection(zview options)
Connect to a database, using options string.
Definition: connection.hxx:242
static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
Seize control of a raw libpq connection.
Definition: connection.hxx:989
std::string esc(char const text[]) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:662
std::string unesc_raw(zview text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:900
std::string esc(char const text[], std::size_t maxlen) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:890
void prepare(zview name, zview definition) &
Define a prepared statement.
Definition: connection.hxx:622
void set_session_var(std::string_view var, TYPE const &value) &
Set one of the session variables to a new value.
Definition: connection.hxx:446
std::string quote(T const &t) const
Represent object as SQL string, including quoting & escaping.
Definition: connection.hxx:1250
Build a parameter list for a parameterised or prepared statement.
Definition: params.hxx:46
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:38
constexpr char const * c_str() const &noexcept
Either a null pointer, or a zero-terminated text buffer.
Definition: zview.hxx:96
The caller attempted to set a variable to null, which is not allowed.
Definition: except.hxx:116
Internal items for libpqxx' own use. Do not use these yourself.
Definition: encodings.cxx:33
void PQXX_LIBEXPORT unesc_bin(std::string_view escaped_data, std::byte buffer[])
Reconstitute binary data from its escaped version.
Definition: util.cxx:165
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition: concat.hxx:31
constexpr std::size_t size_esc_bin(std::size_t binary_bytes) noexcept
Compute buffer size needed to escape binary data for use as a BYTEA.
Definition: util.hxx:516
void PQXX_COLD PQXX_LIBEXPORT skip_init_ssl(int skips) noexcept
Control OpenSSL/crypto library initialisation.
constexpr char const * as_c_string(char const str[]) noexcept
Get a raw C string pointer.
Definition: zview.hxx:145
void PQXX_LIBEXPORT esc_bin(bytes_view binary_data, char buffer[]) noexcept
Hex-escape binary data into a buffer.
Definition: util.cxx:133
constexpr std::size_t size_unesc_bin(std::size_t escaped_bytes) noexcept
Compute binary size from the size of its escaped version.
Definition: util.hxx:525
The home of all libpqxx classes, functions, templates, etc.
Definition: array.cxx:27
std::string separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access)
Represent sequence of values as a string, joined by a given separator.
Definition: separated_list.hxx:46
PQXX_PRIVATE void check_version() noexcept
Definition: util.hxx:236
void skip_init_ssl() noexcept
Control initialisation of OpenSSL and libcrypto libraries.
Definition: connection.hxx:167
bytes_view binary_cast(TYPE const &data)
Cast binary data to a type that libpqxx will recognise as binary.
Definition: util.hxx:409
std::initializer_list< std::string_view > table_path
Representation of a PostgreSQL table path.
Definition: connection.hxx:182
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:514
std::string PQXX_LIBEXPORT encrypt_password(char const user[], char const password[])
Encrypt a password.
std::conditional< has_generic_bytes_char_traits, std::basic_string< std::byte >, std::basic_string< std::byte, byte_char_traits > >::type bytes
Type alias for a container containing bytes.
Definition: util.hxx:375
PQXX_LIBEXPORT std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:566
skip_init
Flags for skipping initialisation of SSL-related libraries.
Definition: connection.hxx:131
@ crypto
Skip initialisation of libcrypto.
Definition: connection.hxx:139
@ openssl
Skip initialisation of OpenSSL library.
Definition: connection.hxx:136
@ nothing
A do-nothing flag that does not affect anything.
Definition: connection.hxx:133
std::conditional< has_generic_bytes_char_traits, std::basic_string_view< std::byte >, std::basic_string_view< std::byte, byte_char_traits > >::type bytes_view
Type alias for a view of bytes.
Definition: util.hxx:385
error_verbosity
Error verbosity levels.
Definition: connection.hxx:187
Traits describing a type's "null value," if any.
Definition: strconv.hxx:91