13#ifndef PQXX_H_CONNECTION
14#define PQXX_H_CONNECTION
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
23#include <initializer_list>
33#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
84#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
87concept ZKey_ZValues = std::ranges::input_range<T> and
requires(T t) {
89 { std::get<0>(*std::cbegin(t)) } -> ZString;
90 { std::get<1>(*std::cbegin(t)) } -> ZString;
91} and std::tuple_size_v<typename std::ranges::iterator_t<T>::value_type> == 2;
109class connection_dbtransaction;
112class connection_notification_receiver;
113class connection_pipeline;
115struct connection_stream_from;
116class connection_stream_to;
220 pqxx::internal::skip_init_ssl(((1 << SKIP) | ...));
282 connection() : connection{
""} {}
285 explicit connection(
char const options[])
292 explicit connection(zview options) : connection{options.c_str()}
303 connection(connection &&rhs);
305#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
322 template<
internal::ZKey_ZValues MAPPING>
323 inline connection(MAPPING
const ¶ms);
332 catch (std::exception
const &)
341 connection &operator=(connection &&rhs);
343 connection(connection
const &) =
delete;
344 connection &operator=(connection
const &) =
delete;
352 [[nodiscard]]
bool PQXX_PURE is_open() const noexcept;
355 void process_notice(
char const[]) noexcept;
360 void process_notice(zview) noexcept;
363 void trace(std::FILE *) noexcept;
377 [[nodiscard]]
char const *dbname() const;
381 [[nodiscard]]
char const *username() const;
387 [[nodiscard]]
char const *hostname() const;
390 [[nodiscard]]
char const *port() const;
393 [[nodiscard]]
int PQXX_PURE backendpid() const & noexcept;
406 [[nodiscard]]
int PQXX_PURE sock() const & noexcept;
412 [[nodiscard]]
int PQXX_PURE protocol_version() const noexcept;
427 [[nodiscard]]
int PQXX_PURE server_version() const noexcept;
452 [[nodiscard]] std::
string get_client_encoding() const;
458 void set_client_encoding(zview encoding) &
460 set_client_encoding(encoding.c_str());
467 void set_client_encoding(
char const encoding[]) &;
470 [[nodiscard]]
int encoding_id()
const;
496 template<
typename TYPE>
497 void set_session_var(std::string_view var, TYPE
const &value) &
499 if constexpr (nullness<TYPE>::has_null)
501 if (nullness<TYPE>::is_null(value))
502 throw variable_set_to_null{
503 internal::concat(
"Attempted to set variable ", var,
" to null.")};
505 exec(internal::concat(
"SET ", quote_name(var),
"=", quote(value)));
515 std::string get_var(std::string_view var);
524 template<
typename TYPE> TYPE get_var_as(std::string_view var)
526 return from_string<TYPE>(get_var(var));
654 int await_notification();
673 int await_notification(std::time_t seconds,
long microseconds = 0);
683 using notification_handler = std::function<void(notification)>;
713 void listen(std::string_view channel, notification_handler handler = {});
748 [[nodiscard]] std::string
755 char const user[],
char const password[],
char const *algorithm =
nullptr);
806 void prepare(zview name, zview definition) &
808 prepare(name.c_str(), definition.c_str());
815 void prepare(
char const name[],
char const definition[]) &;
818 [[deprecated(
"Either name your statement, or just parameterise it.")]]
void
819 prepare(
char const definition[]) &;
820 [[deprecated(
"Either name your statement, or just parameterise it.")]]
void
821 prepare(zview definition) &
824 prepare(definition.c_str());
829 void unprepare(std::string_view name);
838 [[nodiscard]] std::string adorn_name(std::string_view);
846 [[nodiscard]] std::string esc(
char const text[])
const
848 return esc(std::string_view{
text});
851#if defined(PQXX_HAVE_SPAN)
864 [[nodiscard]] std::string_view
865 esc(std::string_view text, std::span<char> buffer)
867 auto const size{std::size(text)}, space{std::size(buffer)};
868 auto const needed{2 * size + 1};
870 throw range_error{internal::concat(
871 "Not enough room to escape string of ", size,
" byte(s): need ",
872 needed,
" bytes of buffer space, but buffer size is ", space,
".")};
873 auto const data{buffer.data()};
874 return {data, esc_to_buf(text, data)};
882 [[nodiscard]] std::string esc(std::string_view text)
const;
884#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
887 template<binary DATA> [[nodiscard]] std::string esc(DATA
const &data)
const
889 return esc_raw(data);
893#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
906 template<binary DATA>
907 [[nodiscard]] zview esc(DATA
const &data, std::span<char> buffer)
const
909 auto const size{std::size(data)}, space{std::size(buffer)};
910 auto const needed{internal::size_esc_bin(std::size(data))};
912 throw range_error{internal::concat(
913 "Not enough room to escape binary string of ", size,
" byte(s): need ",
914 needed,
" bytes of buffer space, but buffer size is ", space,
".")};
916 bytes_view view{std::data(data), std::size(data)};
917 auto const out{std::data(buffer)};
920 internal::esc_bin(view, out);
921 return zview{out, needed - 1};
926 [[deprecated(
"Use std::byte for binary data.")]] std::string
927 esc_raw(
unsigned char const bin[], std::size_t len)
const;
931 [[nodiscard]] std::string esc_raw(bytes_view)
const;
933#if defined(PQXX_HAVE_SPAN)
936 [[nodiscard]] std::string esc_raw(bytes_view, std::span<char> buffer)
const;
939#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
942 template<binary DATA>
943 [[nodiscard]] std::string esc_raw(DATA
const &data)
const
945 return esc_raw(bytes_view{std::data(data), std::size(data)});
949#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_SPAN)
951 template<binary DATA>
952 [[nodiscard]] zview esc_raw(DATA
const &data, std::span<char> buffer)
const
976 std::string quote_raw(bytes_view)
const;
978#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
981 template<binary DATA>
982 [[nodiscard]] std::string quote_raw(DATA
const &data)
const
984 return quote_raw(bytes_view{std::data(data), std::size(data)});
990 [[nodiscard]] std::string quote_name(std::string_view identifier)
const;
997 [[nodiscard]] std::string quote_table(std::string_view name)
const;
1009 [[nodiscard]] std::string quote_table(table_path)
const;
1020 template<PQXX_CHAR_STRINGS_ARG STRINGS>
1021 inline std::string quote_columns(STRINGS
const &columns)
const;
1028 template<
typename T>
1029 [[nodiscard]]
inline std::string quote(T
const &t)
const;
1031 [[deprecated(
"Use std::byte for binary data.")]] std::string
1032 quote(binarystring
const &)
const;
1036 [[nodiscard]] std::string quote(bytes_view bytes)
const;
1065 [[nodiscard]] std::string
1066 esc_like(std::string_view text,
char escape_char =
'\\')
const;
1073 [[deprecated(
"Use std::string_view or pqxx:zview.")]] std::string
1074 esc(
char const text[], std::size_t maxlen)
const
1076 return esc(std::string_view{
text, maxlen});
1083 [[nodiscard, deprecated(
"Use unesc_bin() instead.")]] std::string
1084 unesc_raw(zview text)
const
1087 return unesc_raw(
text.c_str());
1095 [[nodiscard, deprecated(
"Use unesc_bin() instead.")]] std::string
1096 unesc_raw(
char const text[])
const;
1099 [[deprecated(
"Use quote(bytes_view).")]] std::string
1100 quote_raw(
unsigned char const bin[], std::size_t len)
const;
1108 void cancel_query();
1110#if defined(_WIN32) || __has_include(<fcntl.h>)
1116 void set_blocking(
bool block) &;
1132 void set_verbosity(error_verbosity verbosity) &
noexcept;
1149 void set_notice_handler(std::function<
void(zview)> handler)
1151 m_notice_waiters->notice_handler = std::move(handler);
1160 [[nodiscard, deprecated(
"Use a notice handler instead.")]]
1161 std::vector<errorhandler *> get_errorhandlers()
const;
1170 [[nodiscard]] std::string connection_string()
const;
1190 static connection seize_raw_connection(internal::pq::PGconn *raw_conn)
1192 return connection{raw_conn};
1201 internal::pq::PGconn *release_raw_connection() &&
1203 return std::exchange(m_conn,
nullptr);
1220 [[deprecated(
"To set session variables, use set_session_var.")]]
void
1221 set_variable(std::string_view var, std::string_view value) &;
1227 [[deprecated(
"Use get_var instead.")]] std::string
1228 get_variable(std::string_view);
1231 friend class connecting;
1236 connection(connect_mode, zview connection_string);
1239 explicit connection(internal::pq::PGconn *raw_conn);
1247 std::pair<bool, bool> poll_connect();
1250 void init(
char const options[]);
1252 void init(
char const *params[],
char const *values[]);
1253 void set_up_notice_handlers();
1254 void complete_init();
1257 internal::pq::PGresult *pgr, std::shared_ptr<std::string>
const &query,
1258 std::string_view desc =
""sv);
1269 std::
size_t esc_to_buf(std::string_view text,
char *buf) const;
1271 friend class internal::gate::const_connection_largeobject;
1272 char const *
PQXX_PURE err_msg() const noexcept;
1274 result exec_prepared(std::string_view statement, internal::c_params const &);
1277 void check_movable() const;
1279 void check_overwritable() const;
1281 friend class internal::gate::connection_errorhandler;
1282 void PQXX_PRIVATE register_errorhandler(errorhandler *);
1283 void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
1285 friend class internal::gate::connection_transaction;
1286 result exec(std::string_view, std::string_view =
""sv);
1288 exec(std::shared_ptr<std::
string> const &, std::string_view =
""sv);
1289 void PQXX_PRIVATE register_transaction(transaction_base *);
1290 void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
1292 friend struct internal::gate::connection_stream_from;
1299 std::pair<std::unique_ptr<
char,
void (*)(
void const *)>, std::
size_t>
1302 friend class internal::gate::connection_stream_to;
1306 friend class internal::gate::connection_largeobject;
1307 internal::pq::PGconn *raw_connection()
const {
return m_conn; }
1309 friend class internal::gate::connection_notification_receiver;
1310 void add_receiver(notification_receiver *);
1311 void remove_receiver(notification_receiver *)
noexcept;
1313 friend class internal::gate::connection_pipeline;
1317 internal::pq::PGresult *get_result();
1319 friend class internal::gate::connection_dbtransaction;
1320 friend class internal::gate::connection_sql_cursor;
1322 result exec_params(std::string_view query, internal::c_params const &args);
1325 internal::pq::PGconn *m_conn =
nullptr;
1335 transaction_base const *m_trans =
nullptr;
1338 std::shared_ptr<pqxx::internal::notice_waiters> m_notice_waiters;
1342 using receiver_list =
1343 std::multimap<std::
string, pqxx::notification_receiver *>;
1345 receiver_list m_receivers;
1355 std::map<std::
string, notification_handler> m_notification_handlers;
1358 int m_unique_id = 0;
1414 connecting(
zview connection_string =
""_zv);
1416 connecting(connecting
const &) =
delete;
1417 connecting(connecting &&) =
default;
1418 connecting &operator=(connecting
const &) =
delete;
1419 connecting &operator=(connecting &&) =
default;
1422 [[nodiscard]]
int sock()
const &
noexcept {
return m_conn.sock(); }
1425 [[nodiscard]]
constexpr bool wait_to_read()
const &
noexcept
1431 [[nodiscard]]
constexpr bool wait_to_write()
const &
noexcept
1440 [[nodiscard]]
constexpr bool done()
const &
noexcept
1442 return not m_reading and not m_writing;
1454 [[nodiscard]] connection produce() &&;
1458 bool m_reading{
false};
1459 bool m_writing{
true};
1463template<
typename T>
inline std::string connection::quote(T
const &t)
const
1465 if constexpr (nullness<T>::always_null)
1479 std::string buf{
'\''};
1480 buf.resize(2 + 2 * std::size(text) + 1);
1481 auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
1482 auto const closing_quote{1 + content_bytes};
1483 buf[closing_quote] =
'\'';
1484 auto const end{closing_quote + 1};
1491template<PQXX_CHAR_STRINGS_ARG STRINGS>
1492inline std::string connection::quote_columns(STRINGS
const &columns)
const
1495 ","sv, std::cbegin(columns), std::cend(columns),
1496 [
this](
auto col) {
return this->quote_name(*col); });
1500#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
1501template<
internal::ZKey_ZValues MAPPING>
1502inline connection::connection(MAPPING
const ¶ms)
1506 std::vector<char const *> keys, values;
1507 if constexpr (std::ranges::sized_range<MAPPING>)
1509 auto const size{std::ranges::size(params) + 1};
1511 values.reserve(size);
1513 for (
auto const &[key, value] : params)
1515 keys.push_back(internal::as_c_string(key));
1516 values.push_back(internal::as_c_string(value));
1518 keys.push_back(
nullptr);
1519 values.push_back(
nullptr);
1520 init(std::data(keys), std::data(values));
1527 deprecated(
"Use connection::encrypt_password instead.")]] std::string
1533 deprecated(
"Use connection::encrypt_password instead.")]]
inline std::string
Definition connection-errorhandler.hxx:12
Definition connection-largeobject.hxx:16
Definition connection-sql_cursor.hxx:12
Definition connection-transaction.hxx:11
Definition connection-largeobject.hxx:27
Cursor with SQL positioning semantics.
Definition sql_cursor.hxx:32
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
Definition connection.hxx:108
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
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 encrypt_password(zview user, zview password)
Encrypt password.
Definition connection.hxx:1534
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
std::string char const password[]
Definition connection.hxx:1529
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
std::string to_string(T const &value)
Definition conversions.hxx:1249
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
void skip_init_ssl() noexcept
Control initialisation of OpenSSL and libcrypto libraries.
Definition connection.hxx:217
bytes_view binary_cast(TYPE const &data)
End a code block started by "ignore-deprecated-pre.hxx".
Definition util.hxx:409
std::initializer_list< std::string_view > table_path
Representation of a PostgreSQL table path.
Definition connection.hxx:232
connection & conn
The connection which received the notification.
Definition connection.hxx:144
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:516
int backend_pid
Process ID of the backend that sent the notification.
Definition connection.hxx:168
skip_init
Flags for skipping initialisation of SSL-related libraries.
Definition connection.hxx:181
@ crypto
Skip initialisation of libcrypto.
Definition connection.hxx:189
@ openssl
Skip initialisation of OpenSSL library.
Definition connection.hxx:186
@ nothing
A do-nothing flag that does not affect anything.
Definition connection.hxx:183
zview channel
Channel name.
Definition connection.hxx:150
connection connection_base
Definition connection.hxx:1363
zview payload
Optional payload text.
Definition connection.hxx:155
error_verbosity
Error verbosity levels.
Definition connection.hxx:237
@ terse
Definition connection.hxx:239
@ verbose
Definition connection.hxx:241
@ normal
Definition connection.hxx:240
@ text
Definition types.hxx:71
An incoming notification.
Definition connection.hxx:137