libpqxx  7.9.0
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 
75 namespace pqxx::internal
76 {
77 class sql_cursor;
78 
79 #if defined(PQXX_HAVE_CONCEPTS)
81 template<typename T>
82 concept ZKey_ZValues = std::ranges::input_range<T> and requires(T t) {
83  {
84  std::cbegin(t)
85  };
86  {
87  std::get<0>(*std::cbegin(t))
88  } -> ZString;
89  {
90  std::get<1>(*std::cbegin(t))
91  } -> ZString;
92 } and std::tuple_size_v<typename std::ranges::iterator_t<T>::value_type> == 2;
93 #endif // PQXX_HAVE_CONCEPTS
94 
95 
97 
104 void PQXX_COLD PQXX_LIBEXPORT skip_init_ssl(int skips) noexcept;
105 } // namespace pqxx::internal
106 
107 
109 {
110 class connection_dbtransaction;
111 class connection_errorhandler;
112 class connection_largeobject;
113 class connection_notification_receiver;
114 class connection_pipeline;
115 class connection_sql_cursor;
116 struct connection_stream_from;
117 class connection_stream_to;
118 class connection_transaction;
119 class const_connection_largeobject;
120 } // namespace pqxx::internal::gate
121 
122 
123 namespace pqxx
124 {
126 
133 enum skip_init : int
134 {
137 
140 
143 };
144 
145 
147 
170 template<skip_init... SKIP> inline void skip_init_ssl() noexcept
171 {
172  // (Normalise skip flags to one per.)
173  pqxx::internal::skip_init_ssl(((1 << SKIP) | ...));
174 }
175 
176 
178 
185 using table_path = std::initializer_list<std::string_view>;
186 
187 
189 enum class error_verbosity : int
190 {
191  // These values must match those in libpq's PGVerbosity enum.
192  terse = 0,
193  normal = 1,
194  verbose = 2
195 };
196 
197 
199 
232 class PQXX_LIBEXPORT connection
233 {
234 public:
236 
238  explicit connection(char const options[])
239  {
240  check_version();
241  init(options);
242  }
243 
245  explicit connection(zview options) : connection{options.c_str()}
246  {
247  // (Delegates to other constructor which calls check_version for us.)
248  }
249 
251 
256  connection(connection &&rhs);
257 
258 #if defined(PQXX_HAVE_CONCEPTS)
260 
275  template<internal::ZKey_ZValues MAPPING>
276  inline connection(MAPPING const &params);
277 #endif // PQXX_HAVE_CONCEPTS
278 
280  {
281  try
282  {
283  close();
284  }
285  catch (std::exception const &)
286  {}
287  }
288 
290 
293  connection &operator=(connection &&rhs);
294 
295  connection(connection const &) = delete;
296  connection &operator=(connection const &) = delete;
297 
299 
304  [[nodiscard]] bool PQXX_PURE is_open() const noexcept;
305 
307  void process_notice(char const[]) noexcept;
309 
312  void process_notice(zview) noexcept;
313 
315  void trace(std::FILE *) noexcept;
316 
328 
329  [[nodiscard]] char const *dbname() const;
330 
332 
333  [[nodiscard]] char const *username() const;
334 
336 
339  [[nodiscard]] char const *hostname() const;
340 
342  [[nodiscard]] char const *port() const;
343 
345  [[nodiscard]] int PQXX_PURE backendpid() const & noexcept;
346 
348 
358  [[nodiscard]] int PQXX_PURE sock() const & noexcept;
359 
361 
364  [[nodiscard]] int PQXX_PURE protocol_version() const noexcept;
365 
367 
379  [[nodiscard]] int PQXX_PURE server_version() const noexcept;
381 
383 
404  [[nodiscard]] std::string get_client_encoding() const;
405 
407 
410  void set_client_encoding(zview encoding) &
411  {
412  set_client_encoding(encoding.c_str());
413  }
414 
416 
419  void set_client_encoding(char const encoding[]) &;
420 
422  [[nodiscard]] int encoding_id() const;
423 
425 
427 
448  template<typename TYPE>
449  void set_session_var(std::string_view var, TYPE const &value) &
450  {
451  if constexpr (nullness<TYPE>::has_null)
452  {
453  if (nullness<TYPE>::is_null(value))
454  throw variable_set_to_null{
455  internal::concat("Attempted to set variable ", var, " to null.")};
456  }
457  exec(internal::concat("SET ", quote_name(var), "=", quote(value)));
458  }
459 
461 
467  std::string get_var(std::string_view var);
468 
470 
476  template<typename TYPE> TYPE get_var_as(std::string_view var)
477  {
478  return from_string<TYPE>(get_var(var));
479  }
480 
486 
503  int get_notifs();
504 
506 
518  int await_notification();
519 
521 
533  int await_notification(std::time_t seconds, long microseconds);
535 
567  [[nodiscard]] std::string
568  encrypt_password(zview user, zview password, zview algorithm)
569  {
570  return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
571  }
573  [[nodiscard]] std::string encrypt_password(
574  char const user[], char const password[], char const *algorithm = nullptr);
576 
619 
621 
625  void prepare(zview name, zview definition) &
626  {
627  prepare(name.c_str(), definition.c_str());
628  }
629 
634  void prepare(char const name[], char const definition[]) &;
635 
637 
644  void prepare(char const definition[]) &;
645  void prepare(zview definition) & { return prepare(definition.c_str()); }
646 
648  void unprepare(std::string_view name);
649 
651 
652  // C++20: constexpr. Breaks ABI.
654 
657  [[nodiscard]] std::string adorn_name(std::string_view);
658 
663 
665  [[nodiscard]] std::string esc(char const text[]) const
666  {
667  return esc(std::string_view{text});
668  }
669 
670 #if defined(PQXX_HAVE_SPAN)
672 
683  [[nodiscard]] std::string_view
684  esc(std::string_view text, std::span<char> buffer)
685  {
686  auto const size{std::size(text)}, space{std::size(buffer)};
687  auto const needed{2 * size + 1};
688  if (space < needed)
689  throw range_error{internal::concat(
690  "Not enough room to escape string of ", size, " byte(s): need ",
691  needed, " bytes of buffer space, but buffer size is ", space, ".")};
692  auto const data{buffer.data()};
693  return {data, esc_to_buf(text, data)};
694  }
695 #endif
696 
698 
701  [[nodiscard]] std::string esc(std::string_view text) const;
702 
703 #if defined(PQXX_HAVE_CONCEPTS)
705 
706  template<binary DATA> [[nodiscard]] std::string esc(DATA const &data) const
707  {
708  return esc_raw(data);
709  }
710 #endif
711 
712 #if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
714 
725  template<binary DATA>
726  [[nodiscard]] zview esc(DATA const &data, std::span<char> buffer) const
727  {
728  auto const size{std::size(data)}, space{std::size(buffer)};
729  auto const needed{internal::size_esc_bin(std::size(data))};
730  if (space < needed)
731  throw range_error{internal::concat(
732  "Not enough room to escape binary string of ", size, " byte(s): need ",
733  needed, " bytes of buffer space, but buffer size is ", space, ".")};
734 
735  bytes_view view{std::data(data), std::size(data)};
736  auto const out{std::data(buffer)};
737  // Actually, in the modern format, we know beforehand exactly how many
738  // bytes we're going to fill. Just leave out the trailing zero.
739  internal::esc_bin(view, out);
740  return zview{out, needed - 1};
741  }
742 #endif
743 
745  [[deprecated("Use std::byte for binary data.")]] std::string
746  esc_raw(unsigned char const bin[], std::size_t len) const;
747 
749 
750  [[nodiscard]] std::string esc_raw(bytes_view) const;
751 
752 #if defined(PQXX_HAVE_SPAN)
754 
755  [[nodiscard]] std::string esc_raw(bytes_view, std::span<char> buffer) const;
756 #endif
757 
758 #if defined(PQXX_HAVE_CONCEPTS)
760 
761  template<binary DATA>
762  [[nodiscard]] std::string esc_raw(DATA const &data) const
763  {
764  return esc_raw(bytes_view{std::data(data), std::size(data)});
765  }
766 #endif
767 
768 #if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
770  template<binary DATA>
771  [[nodiscard]] zview esc_raw(DATA const &data, std::span<char> buffer) const
772  {
773  return this->esc(binary_cast(data), buffer);
774  }
775 #endif
776 
777  // TODO: Make "into buffer" variant to eliminate a string allocation.
779 
786  [[nodiscard]] bytes unesc_bin(std::string_view text) const
787  {
788  bytes buf;
789  buf.resize(pqxx::internal::size_unesc_bin(std::size(text)));
790  pqxx::internal::unesc_bin(text, buf.data());
791  return buf;
792  }
793 
795  std::string quote_raw(bytes_view) const;
796 
797 #if defined(PQXX_HAVE_CONCEPTS)
799 
800  template<binary DATA>
801  [[nodiscard]] std::string quote_raw(DATA const &data) const
802  {
803  return quote_raw(bytes_view{std::data(data), std::size(data)});
804  }
805 #endif
806 
807  // TODO: Make "into buffer" variant to eliminate a string allocation.
809  [[nodiscard]] std::string quote_name(std::string_view identifier) const;
810 
811  // TODO: Make "into buffer" variant to eliminate a string allocation.
813 
816  [[nodiscard]] std::string quote_table(std::string_view name) const;
817 
818  // TODO: Make "into buffer" variant to eliminate a string allocation.
820 
828  [[nodiscard]] std::string quote_table(table_path) const;
829 
830  // TODO: Make "into buffer" variant to eliminate a string allocation.
832 
839  template<PQXX_CHAR_STRINGS_ARG STRINGS>
840  inline std::string quote_columns(STRINGS const &columns) const;
841 
842  // TODO: Make "into buffer" variant to eliminate a string allocation.
844 
847  template<typename T>
848  [[nodiscard]] inline std::string quote(T const &t) const;
849 
850  [[deprecated("Use std::byte for binary data.")]] std::string
851  quote(binarystring const &) const;
852 
853  // TODO: Make "into buffer" variant to eliminate a string allocation.
855  [[nodiscard]] std::string quote(bytes_view bytes) const;
856 
857  // TODO: Make "into buffer" variant to eliminate a string allocation.
859 
884  [[nodiscard]] std::string
885  esc_like(std::string_view text, char escape_char = '\\') const;
886 
888 
892  [[deprecated("Use std::string_view or pqxx:zview.")]] std::string
893  esc(char const text[], std::size_t maxlen) const
894  {
895  return esc(std::string_view{text, maxlen});
896  }
897 
899 
902  [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
903  unesc_raw(zview text) const
904  {
905 #include "pqxx/internal/ignore-deprecated-pre.hxx"
906  return unesc_raw(text.c_str());
907 #include "pqxx/internal/ignore-deprecated-post.hxx"
908  }
909 
911 
914  [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
915  unesc_raw(char const text[]) const;
916 
918  [[deprecated("Use quote(bytes_view).")]] std::string
919  quote_raw(unsigned char const bin[], std::size_t len) const;
921 
923 
927  void cancel_query();
928 
929 #if defined(_WIN32) || __has_include(<fcntl.h>)
931 
935  void set_blocking(bool block) &;
936 #endif // defined(_WIN32) || __has_include(<fcntl.h>)
937 
939 
948  void set_verbosity(error_verbosity verbosity) & noexcept;
949 
951 
963  [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
964 
966 
972  [[nodiscard]] std::string connection_string() const;
973 
975 
983  void close();
984 
986 
992  static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
993  {
994  return connection{raw_conn};
995  }
996 
998 
1003  internal::pq::PGconn *release_raw_connection() &&
1004  {
1005  return std::exchange(m_conn, nullptr);
1006  }
1007 
1009 
1022  [[deprecated("To set session variables, use set_session_var.")]] void
1023  set_variable(std::string_view var, std::string_view value) &;
1024 
1026 
1029  [[deprecated("Use get_var instead.")]] std::string
1030  get_variable(std::string_view);
1031 
1032 private:
1033  friend class connecting;
1034  enum connect_mode
1035  {
1036  connect_nonblocking
1037  };
1038  connection(connect_mode, zview connection_string);
1039 
1041  explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {}
1042 
1044 
1049  std::pair<bool, bool> poll_connect();
1050 
1051  // Initialise based on connection string.
1052  void init(char const options[]);
1053  // Initialise based on parameter names and values.
1054  void init(char const *params[], char const *values[]);
1055  void complete_init();
1056 
1057  result make_result(
1058  internal::pq::PGresult *pgr, std::shared_ptr<std::string> const &query,
1059  std::string_view desc = ""sv);
1060 
1061  void PQXX_PRIVATE set_up_state();
1062 
1063  int PQXX_PRIVATE PQXX_PURE status() const noexcept;
1064 
1066 
1070  std::size_t esc_to_buf(std::string_view text, char *buf) const;
1071 
1072  friend class internal::gate::const_connection_largeobject;
1073  char const *PQXX_PURE err_msg() const noexcept;
1074 
1075  void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept;
1076 
1077  result exec_prepared(std::string_view statement, internal::c_params const &);
1078 
1080  void check_movable() const;
1082  void check_overwritable() const;
1083 
1084  friend class internal::gate::connection_errorhandler;
1085  void PQXX_PRIVATE register_errorhandler(errorhandler *);
1086  void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
1087 
1088  friend class internal::gate::connection_transaction;
1089  result exec(std::string_view, std::string_view = ""sv);
1090  result PQXX_PRIVATE
1091  exec(std::shared_ptr<std::string> const &, std::string_view = ""sv);
1092  void PQXX_PRIVATE register_transaction(transaction_base *);
1093  void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
1094 
1095  friend struct internal::gate::connection_stream_from;
1097 
1102  std::pair<std::unique_ptr<char, void (*)(void const *)>, std::size_t>
1103  read_copy_line();
1104 
1105  friend class internal::gate::connection_stream_to;
1106  void PQXX_PRIVATE write_copy_line(std::string_view);
1107  void PQXX_PRIVATE end_copy_write();
1108 
1109  friend class internal::gate::connection_largeobject;
1110  internal::pq::PGconn *raw_connection() const { return m_conn; }
1111 
1112  friend class internal::gate::connection_notification_receiver;
1113  void add_receiver(notification_receiver *);
1114  void remove_receiver(notification_receiver *) noexcept;
1115 
1116  friend class internal::gate::connection_pipeline;
1117  void PQXX_PRIVATE start_exec(char const query[]);
1118  bool PQXX_PRIVATE consume_input() noexcept;
1119  bool PQXX_PRIVATE is_busy() const noexcept;
1120  internal::pq::PGresult *get_result();
1121 
1122  friend class internal::gate::connection_dbtransaction;
1123  friend class internal::gate::connection_sql_cursor;
1124 
1125  result exec_params(std::string_view query, internal::c_params const &args);
1126 
1128  internal::pq::PGconn *m_conn = nullptr;
1129 
1131 
1138  transaction_base const *m_trans = nullptr;
1139 
1140  std::list<errorhandler *> m_errorhandlers;
1141 
1142  using receiver_list =
1143  std::multimap<std::string, pqxx::notification_receiver *>;
1145  receiver_list m_receivers;
1146 
1148  int m_unique_id = 0;
1149 };
1150 
1151 
1154 
1155 
1157 
1200 class PQXX_LIBEXPORT connecting
1201 {
1202 public:
1204  connecting(zview connection_string = ""_zv);
1205 
1206  connecting(connecting const &) = delete;
1207  connecting(connecting &&) = default;
1208  connecting &operator=(connecting const &) = delete;
1210 
1212  [[nodiscard]] int sock() const & noexcept { return m_conn.sock(); }
1213 
1215  [[nodiscard]] constexpr bool wait_to_read() const & noexcept
1216  {
1217  return m_reading;
1218  }
1219 
1221  [[nodiscard]] constexpr bool wait_to_write() const & noexcept
1222  {
1223  return m_writing;
1224  }
1225 
1227  void process() &;
1228 
1230  [[nodiscard]] constexpr bool done() const & noexcept
1231  {
1232  return not m_reading and not m_writing;
1233  }
1234 
1236 
1244  [[nodiscard]] connection produce() &&;
1245 
1246 private:
1247  connection m_conn;
1248  bool m_reading{false};
1249  bool m_writing{true};
1250 };
1251 
1252 
1253 template<typename T> inline std::string connection::quote(T const &t) const
1254 {
1255  if constexpr (nullness<T>::always_null)
1256  {
1257  return "NULL";
1258  }
1259  else
1260  {
1261  if (is_null(t))
1262  return "NULL";
1263  auto const text{to_string(t)};
1264 
1265  // Okay, there's an easy way to do this and there's a hard way. The easy
1266  // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
1267  // because it's going to save some string manipulation that will probably
1268  // incur some unnecessary memory allocations and deallocations.
1269  std::string buf{'\''};
1270  buf.resize(2 + 2 * std::size(text) + 1);
1271  auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
1272  auto const closing_quote{1 + content_bytes};
1273  buf[closing_quote] = '\'';
1274  auto const end{closing_quote + 1};
1275  buf.resize(end);
1276  return buf;
1277  }
1278 }
1279 
1280 
1281 template<PQXX_CHAR_STRINGS_ARG STRINGS>
1282 inline std::string connection::quote_columns(STRINGS const &columns) const
1283 {
1284  return separated_list(
1285  ","sv, std::cbegin(columns), std::cend(columns),
1286  [this](auto col) { return this->quote_name(*col); });
1287 }
1288 
1289 
1290 #if defined(PQXX_HAVE_CONCEPTS)
1291 template<internal::ZKey_ZValues MAPPING>
1292 inline connection::connection(MAPPING const &params)
1293 {
1294  check_version();
1295 
1296  std::vector<char const *> keys, values;
1297  if constexpr (std::ranges::sized_range<MAPPING>)
1298  {
1299  auto const size{std::ranges::size(params) + 1};
1300  keys.reserve(size);
1301  values.reserve(size);
1302  }
1303  for (auto const &[key, value] : params)
1304  {
1305  keys.push_back(internal::as_c_string(key));
1306  values.push_back(internal::as_c_string(value));
1307  }
1308  keys.push_back(nullptr);
1309  values.push_back(nullptr);
1310  init(std::data(keys), std::data(values));
1311 }
1312 #endif // PQXX_HAVE_CONCEPTS
1313 
1314 
1316 [[nodiscard,
1317  deprecated("Use connection::encrypt_password instead.")]] std::string
1318  PQXX_LIBEXPORT
1319  encrypt_password(char const user[], char const password[]);
1320 
1322 [[nodiscard,
1323  deprecated("Use connection::encrypt_password instead.")]] inline std::string
1325 {
1326 #include "pqxx/internal/ignore-deprecated-pre.hxx"
1327  return encrypt_password(user.c_str(), password.c_str());
1328 #include "pqxx/internal/ignore-deprecated-post.hxx"
1329 }
1330 } // namespace pqxx
1331 #endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:33
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:44
std::string encrypt_password(char const user[], char const password[])
Encrypt a password.
Definition: connection.cxx:94
void skip_init_ssl() noexcept
Control initialisation of OpenSSL and libcrypto libraries.
Definition: connection.hxx:170
bytes_view binary_cast(TYPE const &data)
Cast binary data to a type that libpqxx will recognise as binary.
Definition: util.hxx:407
std::initializer_list< std::string_view > table_path
Representation of a PostgreSQL table path.
Definition: connection.hxx:185
void check_version() noexcept
Definition: util.hxx:234
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:513
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:373
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:134
@ crypto
Skip initialisation of libcrypto.
Definition: connection.hxx:142
@ openssl
Skip initialisation of OpenSSL library.
Definition: connection.hxx:139
@ nothing
A do-nothing flag that does not affect anything.
Definition: connection.hxx:136
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:383
error_verbosity
Error verbosity levels.
Definition: connection.hxx:190
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:84
void unesc_bin(std::string_view escaped_data, std::byte buffer[])
Reconstitute binary data from its escaped version.
Definition: util.cxx:165
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:514
void PQXX_COLD skip_init_ssl(int skips) noexcept
Control OpenSSL/crypto library initialisation.
Definition: connection.cxx:83
constexpr char const * as_c_string(char const str[]) noexcept
Get a raw C string pointer.
Definition: zview.hxx:145
void 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:523
Definition: connection.hxx:109
Connection to a database.
Definition: connection.hxx:233
std::string encrypt_password(zview user, zview password, zview algorithm)
Encrypt a password for a given user.
Definition: connection.hxx:568
void prepare(zview definition) &
Definition: connection.hxx:645
connection(char const options[])
Connect to a database, using options string.
Definition: connection.hxx:238
TYPE get_var_as(std::string_view var)
Read currently applicable value of a variable.
Definition: connection.hxx:476
internal::pq::PGconn * release_raw_connection() &&
Release the raw connection without closing it.
Definition: connection.hxx:1003
connection()
Definition: connection.hxx:235
~connection()
Definition: connection.hxx:279
bytes unesc_bin(std::string_view text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:786
std::string quote_columns(STRINGS const &columns) const
Quote and comma-separate a series of column names.
Definition: connection.hxx:1282
connection(zview options)
Connect to a database, using options string.
Definition: connection.hxx:245
static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
Seize control of a raw libpq connection.
Definition: connection.hxx:992
std::string esc(char const text[]) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:665
std::string unesc_raw(zview text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:903
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:893
connection & operator=(connection const &)=delete
void prepare(zview name, zview definition) &
Define a prepared statement.
Definition: connection.hxx:625
void set_session_var(std::string_view var, TYPE const &value) &
Set one of the session variables to a new value.
Definition: connection.hxx:449
std::string quote(T const &t) const
Represent object as SQL string, including quoting & escaping.
Definition: connection.hxx:1253
connection(connection const &)=delete
An ongoing, non-blocking stepping stone to a connection.
Definition: connection.hxx:1201
connecting(connecting &&)=default
int sock() const &noexcept
Get the socket. The socket may change during the connection process.
Definition: connection.hxx:1212
constexpr bool done() const &noexcept
Is our connection finished?
Definition: connection.hxx:1230
connecting(connecting const &)=delete
constexpr bool wait_to_write() const &noexcept
Should we currently wait to be able to write to the socket?
Definition: connection.hxx:1221
void process() &
Progress towards completion (but don't block).
connecting & operator=(connecting &&)=default
connecting & operator=(connecting const &)=delete
constexpr bool wait_to_read() const &noexcept
Should we currently wait to be able to read from the socket?
Definition: connection.hxx:1215
connecting(zview connection_string=""_zv)
Start connecting.
connection produce() &&
Produce the completed connection object.
Base class for error-handler callbacks.
Definition: errorhandler.hxx:54
The caller attempted to set a variable to null, which is not allowed.
Definition: except.hxx:116
Definition: notification.hxx:57
Build a parameter list for a parameterised or prepared statement.
Definition: params.hxx:46
Result set containing data returned by a query or command.
Definition: result.hxx:73
Traits describing a type's "null value," if any.
Definition: strconv.hxx:91
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:88
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