libpqxx 7.8.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-2023, 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
75namespace pqxx::internal
76{
77class sql_cursor;
78
79#if defined(PQXX_HAVE_CONCEPTS)
81template<typename T>
82concept ZKey_ZValues = std::ranges::input_range<T> and requires(T t)
83{
84 {std::cbegin(t)};
85 {
86 std::get<0>(*std::cbegin(t))
87 } -> ZString;
88 {
89 std::get<1>(*std::cbegin(t))
90 } -> ZString;
91} and std::tuple_size_v<typename std::ranges::iterator_t<T>::value_type>
92== 2;
93#endif // PQXX_HAVE_CONCEPTS
94
95
97
104void PQXX_COLD PQXX_LIBEXPORT skip_init_ssl(int flags) noexcept;
105} // namespace pqxx::internal
106
107
109{
110class connection_dbtransaction;
111class connection_errorhandler;
112class connection_largeobject;
113class connection_notification_receiver;
114class connection_pipeline;
115class connection_sql_cursor;
116struct connection_stream_from;
117class connection_stream_to;
118class connection_transaction;
119class const_connection_largeobject;
120} // namespace pqxx::internal::gate
121
122
123namespace pqxx
124{
126
133enum skip_init : int
134{
137
140
143};
144
145
147
170template<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
185using table_path = std::initializer_list<std::string_view>;
186
187
189[[nodiscard,
190 deprecated("Use connection::encrypt_password instead.")]] std::string
191 PQXX_LIBEXPORT
192 encrypt_password(char const user[], char const password[]);
193
195[[nodiscard,
196 deprecated("Use connection::encrypt_password instead.")]] inline std::string
198{
199#include "pqxx/internal/ignore-deprecated-pre.hxx"
200 return encrypt_password(user.c_str(), password.c_str());
201#include "pqxx/internal/ignore-deprecated-post.hxx"
202}
203
204
206enum class error_verbosity : int
207{
208 // These values must match those in libpq's PGVerbosity enum.
209 terse = 0,
210 normal = 1,
211 verbose = 2
212};
213
214
216
249class PQXX_LIBEXPORT connection
250{
251public:
253
255 explicit connection(char const options[])
256 {
258 init(options);
259 }
260
262 explicit connection(zview options) : connection{options.c_str()}
263 {
264 // (Delegates to other constructor which calls check_version for us.)
265 }
266
268
273 connection(connection &&rhs);
274
275#if defined(PQXX_HAVE_CONCEPTS)
277
292 template<internal::ZKey_ZValues MAPPING>
293 inline connection(MAPPING const &params);
294#endif // PQXX_HAVE_CONCEPTS
295
297 {
298 try
299 {
300 close();
301 }
302 catch (std::exception const &)
303 {}
304 }
305
307
310 connection &operator=(connection &&rhs);
311
312 connection(connection const &) = delete;
313 connection &operator=(connection const &) = delete;
314
316
321 [[nodiscard]] bool PQXX_PURE is_open() const noexcept;
322
324 void process_notice(char const[]) noexcept;
326
329 void process_notice(zview) noexcept;
330
332 void trace(std::FILE *) noexcept;
333
345
346 [[nodiscard]] char const *dbname() const;
347
349
350 [[nodiscard]] char const *username() const;
351
353
356 [[nodiscard]] char const *hostname() const;
357
359 [[nodiscard]] char const *port() const;
360
362 [[nodiscard]] int PQXX_PURE backendpid() const &noexcept;
363
365
375 [[nodiscard]] int PQXX_PURE sock() const &noexcept;
376
378
381 [[nodiscard]] int PQXX_PURE protocol_version() const noexcept;
382
384
396 [[nodiscard]] int PQXX_PURE server_version() const noexcept;
398
400
421 [[nodiscard]] std::string get_client_encoding() const;
422
424
427 void set_client_encoding(zview encoding) &
428 {
429 set_client_encoding(encoding.c_str());
430 }
431
433
436 void set_client_encoding(char const encoding[]) &;
437
439 [[nodiscard]] int encoding_id() const;
440
442
444
457 [[deprecated("To set session variables, use set_session_var.")]] void
458 set_variable(std::string_view var, std::string_view value) &;
459
461
482 template<typename TYPE>
483 void set_session_var(std::string_view var, TYPE const &value) &
484 {
485 if constexpr (nullness<TYPE>::has_null)
486 {
487 if (nullness<TYPE>::is_null(value))
489 internal::concat("Attempted to set variable ", var, " to null.")};
490 }
491 exec(internal::concat("SET ", quote_name(var), "=", quote(value)));
492 }
493
495
498 [[deprecated("Use get_var instead.")]] std::string
499 get_variable(std::string_view);
500
502
508 std::string get_var(std::string_view var);
509
511
517 template<typename TYPE> TYPE get_var_as(std::string_view var)
518 {
519 return from_string<TYPE>(get_var(var));
520 }
521
527
544 int get_notifs();
545
547
559 int await_notification();
560
562
574 int await_notification(std::time_t seconds, long microseconds);
576
608 [[nodiscard]] std::string
609 encrypt_password(zview user, zview password, zview algorithm)
610 {
611 return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
612 }
614 [[nodiscard]] std::string encrypt_password(
615 char const user[], char const password[], char const *algorithm = nullptr);
617
660
662
666 void prepare(zview name, zview definition) &
667 {
668 prepare(name.c_str(), definition.c_str());
669 }
670
675 void prepare(char const name[], char const definition[]) &;
676
678
685 void prepare(char const definition[]) &;
686 void prepare(zview definition) &
687 {
688 return prepare(definition.c_str());
689 }
690
692 void unprepare(std::string_view name);
693
695
696 // C++20: constexpr. Breaks ABI.
698
701 [[nodiscard]] std::string adorn_name(std::string_view);
702
707
709
713 [[deprecated("Use std::string_view or pqxx:zview.")]] std::string
714 esc(char const text[], std::size_t maxlen) const
715 {
716 return esc(std::string_view{text, maxlen});
717 }
718
720 [[nodiscard]] std::string esc(char const text[]) const
721 {
722 return esc(std::string_view{text});
723 }
724
725#if defined(PQXX_HAVE_SPAN)
727
738 [[nodiscard]] std::string_view
739 esc(std::string_view text, std::span<char> buffer)
740 {
741 auto const size{std::size(text)}, space{std::size(buffer)};
742 auto const needed{2 * size + 1};
743 if (space < needed)
744 throw range_error{internal::concat(
745 "Not enough room to escape string of ", size, " byte(s): need ",
746 needed, " bytes of buffer space, but buffer size is ", space, ".")};
747 auto const data{buffer.data()};
748 return {data, esc_to_buf(text, data)};
749 }
750#endif
751
753
756 [[nodiscard]] std::string esc(std::string_view text) const;
757
758#if defined(PQXX_HAVE_CONCEPTS)
760
761 template<binary DATA> [[nodiscard]] std::string esc(DATA const &data) const
762 {
763 return esc_raw(data);
764 }
765#endif
766
767#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
769
780 template<binary DATA>
781 [[nodiscard]] zview esc(DATA const &data, std::span<char> buffer) const
782 {
783 auto const size{std::size(data)}, space{std::size(buffer)};
784 auto const needed{internal::size_esc_bin(std::size(data))};
785 if (space < needed)
786 throw range_error{internal::concat(
787 "Not enough room to escape binary string of ", size, " byte(s): need ",
788 needed, " bytes of buffer space, but buffer size is ", space, ".")};
789
790 std::basic_string_view<std::byte> view{std::data(data), std::size(data)};
791 auto const out{std::data(buffer)};
792 // Actually, in the modern format, we know beforehand exactly how many
793 // bytes we're going to fill. Just leave out the trailing zero.
794 internal::esc_bin(view, out);
795 return zview{out, needed - 1};
796 }
797#endif
798
800 [[deprecated("Use std::byte for binary data.")]] std::string
801 esc_raw(unsigned char const bin[], std::size_t len) const;
802
804
805 [[nodiscard]] std::string esc_raw(std::basic_string_view<std::byte>) const;
806
807#if defined(PQXX_HAVE_SPAN)
809
810 [[nodiscard]] std::string
811 esc_raw(std::basic_string_view<std::byte>, std::span<char> buffer) const;
812#endif
813
814#if defined(PQXX_HAVE_CONCEPTS)
816
817 template<binary DATA>
818 [[nodiscard]] std::string esc_raw(DATA const &data) const
819 {
820 return esc_raw(
821 std::basic_string_view<std::byte>{std::data(data), std::size(data)});
822 }
823#endif
824
825#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
827 template<binary DATA>
828 [[nodiscard]] zview esc_raw(DATA const &data, std::span<char> buffer) const
829 {
830 return this->esc(binary_cast(data), buffer);
831 }
832#endif
833
835
838 [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
839 unesc_raw(zview text) const
840 {
841#include "pqxx/internal/ignore-deprecated-pre.hxx"
842 return unesc_raw(text.c_str());
843#include "pqxx/internal/ignore-deprecated-post.hxx"
844 }
845
847
850 [[nodiscard, deprecated("Use unesc_bin() instead.")]] std::string
851 unesc_raw(char const text[]) const;
852
853 // TODO: Make "into buffer" variant to eliminate a string allocation.
855
862 [[nodiscard]] std::basic_string<std::byte>
863 unesc_bin(std::string_view text) const
864 {
865 std::basic_string<std::byte> buf;
866 buf.resize(pqxx::internal::size_unesc_bin(std::size(text)));
867 pqxx::internal::unesc_bin(text, buf.data());
868 return buf;
869 }
870
872 [[deprecated("Use quote(std::basic_string_view<std::byte>).")]] std::string
873 quote_raw(unsigned char const bin[], std::size_t len) const;
874
876 std::string quote_raw(std::basic_string_view<std::byte>) const;
877
878#if defined(PQXX_HAVE_CONCEPTS)
880
881 template<binary DATA>
882 [[nodiscard]] std::string quote_raw(DATA const &data) const
883 {
884 return quote_raw(
885 std::basic_string_view<std::byte>{std::data(data), std::size(data)});
886 }
887#endif
888
889 // TODO: Make "into buffer" variant to eliminate a string allocation.
891 [[nodiscard]] std::string quote_name(std::string_view identifier) const;
892
893 // TODO: Make "into buffer" variant to eliminate a string allocation.
895
898 [[nodiscard]] std::string quote_table(std::string_view name) const;
899
900 // TODO: Make "into buffer" variant to eliminate a string allocation.
902
910 [[nodiscard]] std::string quote_table(table_path) const;
911
912 // TODO: Make "into buffer" variant to eliminate a string allocation.
914
921 template<PQXX_CHAR_STRINGS_ARG STRINGS>
922 inline std::string quote_columns(STRINGS const &columns) const;
923
924 // TODO: Make "into buffer" variant to eliminate a string allocation.
926
929 template<typename T>
930 [[nodiscard]] inline std::string quote(T const &t) const;
931
932 [[deprecated("Use std::byte for binary data.")]] std::string
933 quote(binarystring const &) const;
934
935 // TODO: Make "into buffer" variant to eliminate a string allocation.
937 [[nodiscard]] std::string
938 quote(std::basic_string_view<std::byte> bytes) const;
939
940 // TODO: Make "into buffer" variant to eliminate a string allocation.
942
967 [[nodiscard]] std::string
968 esc_like(std::string_view text, char escape_char = '\\') const;
970
972
976 void cancel_query();
977
978#if defined(_WIN32) || __has_include(<fcntl.h>)
980
984 void set_blocking(bool block) &;
985#endif // defined(_WIN32) || __has_include(<fcntl.h>)
986
988
997 void set_verbosity(error_verbosity verbosity) &noexcept;
998
1000
1012 [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
1013
1015
1021 [[nodiscard]] std::string connection_string() const;
1022
1024
1032 void close();
1033
1035
1041 static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
1042 {
1043 return connection{raw_conn};
1044 }
1045
1047
1052 internal::pq::PGconn *release_raw_connection() &&
1053 {
1054 return std::exchange(m_conn, nullptr);
1055 }
1056
1057private:
1058 friend class connecting;
1059 enum connect_mode
1060 {
1061 connect_nonblocking
1062 };
1063 connection(connect_mode, zview connection_string);
1064
1066 explicit connection(internal::pq::PGconn *raw_conn) : m_conn{raw_conn} {}
1067
1069
1074 std::pair<bool, bool> poll_connect();
1075
1076 // Initialise based on connection string.
1077 void init(char const options[]);
1078 // Initialise based on parameter names and values.
1079 void init(char const *params[], char const *values[]);
1080 void complete_init();
1081
1082 result make_result(
1083 internal::pq::PGresult *pgr, std::shared_ptr<std::string> const &query,
1084 std::string_view desc = ""sv);
1085
1086 void PQXX_PRIVATE set_up_state();
1087
1088 int PQXX_PRIVATE PQXX_PURE status() const noexcept;
1089
1091
1095 std::size_t esc_to_buf(std::string_view text, char *buf) const;
1096
1097 friend class internal::gate::const_connection_largeobject;
1098 char const *PQXX_PURE err_msg() const noexcept;
1099
1100 void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept;
1101
1102 result exec_prepared(std::string_view statement, internal::c_params const &);
1103
1105 void check_movable() const;
1107 void check_overwritable() const;
1108
1109 friend class internal::gate::connection_errorhandler;
1110 void PQXX_PRIVATE register_errorhandler(errorhandler *);
1111 void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
1112
1113 friend class internal::gate::connection_transaction;
1114 result exec(std::string_view, std::string_view = ""sv);
1115 result
1116 PQXX_PRIVATE exec(std::shared_ptr<std::string>, std::string_view = ""sv);
1117 void PQXX_PRIVATE register_transaction(transaction_base *);
1118 void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
1119
1120 friend struct internal::gate::connection_stream_from;
1121 std::pair<std::unique_ptr<char, void(*)(void const *)>, std::size_t>
1122 read_copy_line();
1123
1124 friend class internal::gate::connection_stream_to;
1125 void PQXX_PRIVATE write_copy_line(std::string_view);
1126 void PQXX_PRIVATE end_copy_write();
1127
1128 friend class internal::gate::connection_largeobject;
1129 internal::pq::PGconn *raw_connection() const
1130 {
1131 return m_conn;
1132 }
1133
1134 friend class internal::gate::connection_notification_receiver;
1135 void add_receiver(notification_receiver *);
1136 void remove_receiver(notification_receiver *) noexcept;
1137
1138 friend class internal::gate::connection_pipeline;
1139 void PQXX_PRIVATE start_exec(char const query[]);
1140 bool PQXX_PRIVATE consume_input() noexcept;
1141 bool PQXX_PRIVATE is_busy() const noexcept;
1142 internal::pq::PGresult *get_result();
1143
1144 friend class internal::gate::connection_dbtransaction;
1145 friend class internal::gate::connection_sql_cursor;
1146
1147 result exec_params(std::string_view query, internal::c_params const &args);
1148
1150 internal::pq::PGconn *m_conn = nullptr;
1151
1153
1160 transaction_base const *m_trans = nullptr;
1161
1162 std::list<errorhandler *> m_errorhandlers;
1163
1164 using receiver_list =
1165 std::multimap<std::string, pqxx::notification_receiver *>;
1167 receiver_list m_receivers;
1168
1170 int m_unique_id = 0;
1171};
1172
1173
1176
1177
1179
1222class PQXX_LIBEXPORT connecting
1223{
1224public:
1226 connecting(zview connection_string = ""_zv);
1227
1228 connecting(connecting const &) = delete;
1229 connecting(connecting &&) = default;
1230 connecting &operator=(connecting const &) = delete;
1232
1234 [[nodiscard]] int sock() const &noexcept { return m_conn.sock(); }
1235
1237 [[nodiscard]] constexpr bool wait_to_read() const &noexcept
1238 {
1239 return m_reading;
1240 }
1241
1243 [[nodiscard]] constexpr bool wait_to_write() const &noexcept
1244 {
1245 return m_writing;
1246 }
1247
1249 void process() &;
1250
1252 [[nodiscard]] constexpr bool done() const &noexcept
1253 {
1254 return not m_reading and not m_writing;
1255 }
1256
1258
1266 [[nodiscard]] connection produce() &&;
1267
1268private:
1269 connection m_conn;
1270 bool m_reading{false};
1271 bool m_writing{true};
1272};
1273
1274
1275template<typename T> inline std::string connection::quote(T const &t) const
1276{
1277 if constexpr (nullness<T>::always_null)
1278 {
1279 return "NULL";
1280 }
1281 else
1282 {
1283 if (is_null(t))
1284 return "NULL";
1285 auto const text{to_string(t)};
1286
1287 // Okay, there's an easy way to do this and there's a hard way. The easy
1288 // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
1289 // because it's going to save some string manipulation that will probably
1290 // incur some unnecessary memory allocations and deallocations.
1291 std::string buf{'\''};
1292 buf.resize(2 + 2 * std::size(text) + 1);
1293 auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
1294 auto const closing_quote{1 + content_bytes};
1295 buf[closing_quote] = '\'';
1296 auto const end{closing_quote + 1};
1297 buf.resize(end);
1298 return buf;
1299 }
1300}
1301
1302
1303template<PQXX_CHAR_STRINGS_ARG STRINGS>
1304inline std::string connection::quote_columns(STRINGS const &columns) const
1305{
1306 return separated_list(
1307 ","sv, std::cbegin(columns), std::cend(columns),
1308 [this](auto col) { return this->quote_name(*col); });
1309}
1310
1311
1312#if defined(PQXX_HAVE_CONCEPTS)
1313template<internal::ZKey_ZValues MAPPING>
1314inline connection::connection(MAPPING const &params)
1315{
1316 check_version();
1317
1318 std::vector<char const *> keys, values;
1319 if constexpr (std::ranges::sized_range<MAPPING>)
1320 {
1321 auto const size{std::ranges::size(params) + 1};
1322 keys.reserve(size);
1323 values.reserve(size);
1324 }
1325 for (auto const &[key, value] : params)
1326 {
1327 keys.push_back(internal::as_c_string(key));
1328 values.push_back(internal::as_c_string(value));
1329 }
1330 keys.push_back(nullptr);
1331 values.push_back(nullptr);
1332 init(std::data(keys), std::data(values));
1333}
1334#endif // PQXX_HAVE_CONCEPTS
1335} // namespace pqxx
1336#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:96
std::basic_string_view< std::byte > binary_cast(TYPE const &data)
Cast binary data to a type that libpqxx will recognise as binary.
Definition util.hxx:303
void skip_init_ssl() noexcept
Control initialisation of OpenSSL and libcrypto libraries.
Definition connection.hxx:170
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:508
std::string to_string(field const &value)
Convert a field to a string.
Definition result.cxx:548
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
error_verbosity
Error verbosity levels.
Definition connection.hxx:207
Internal items for libpqxx' own use. Do not use these yourself.
Definition composite.hxx:84
void PQXX_COLD skip_init_ssl(int flags) noexcept
Control OpenSSL/crypto library initialisation.
Definition connection.cxx:84
void unesc_bin(std::string_view escaped_data, std::byte buffer[])
Reconstitute binary data from its escaped version.
Definition util.cxx:158
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:420
Definition connection.hxx:109
Connection to a database.
Definition connection.hxx:250
std::string encrypt_password(zview user, zview password, zview algorithm)
Encrypt a password for a given user.
Definition connection.hxx:609
void prepare(zview definition) &
Definition connection.hxx:686
connection(char const options[])
Connect to a database, using options string.
Definition connection.hxx:255
connection & operator=(connection const &)=delete
TYPE get_var_as(std::string_view var)
Read currently applicable value of a variable.
Definition connection.hxx:517
connection()
Definition connection.hxx:252
~connection()
Definition connection.hxx:296
connection(zview options)
Connect to a database, using options string.
Definition connection.hxx:262
internal::pq::PGconn * release_raw_connection() &&
Release the raw connection without closing it.
Definition connection.hxx:1052
static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
Seize control of a raw libpq connection.
Definition connection.hxx:1041
std::basic_string< std::byte > unesc_bin(std::string_view text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition connection.hxx:863
std::string esc(char const text[]) const
Escape string for use as SQL string literal on this connection.
Definition connection.hxx:720
std::string unesc_raw(zview text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition connection.hxx:839
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:714
void prepare(zview name, zview definition) &
Define a prepared statement.
Definition connection.hxx:666
void set_session_var(std::string_view var, TYPE const &value) &
Set one of the session variables to a new value.
Definition connection.hxx:483
connection(connection const &)=delete
An ongoing, non-blocking stepping stone to a connection.
Definition connection.hxx:1223
connecting(connecting &&)=default
int sock() const &noexcept
Get the socket. The socket may change during the connection process.
Definition connection.hxx:1234
constexpr bool done() const &noexcept
Is our connection finished?
Definition connection.hxx:1252
connecting & operator=(connecting const &)=delete
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:1243
void process() &
Progress towards completion (but don't block).
connecting & operator=(connecting &&)=default
constexpr bool wait_to_read() const &noexcept
Should we currently wait to be able to read from the socket?
Definition connection.hxx:1237
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:113
Definition notification.hxx:57
Build a parameter list for a parameterised or prepared statement.
Definition params.hxx:220
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:93
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