connection_base.hxx
#ifndef PQXX_H_CONNECTION_BASE
#define PQXX_H_CONNECTION_BASE
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include <bitset>
#include <list>
#include <map>
#include <memory>
#include "pqxx/errorhandler.hxx"
#include "pqxx/except.hxx"
#include "pqxx/prepared_statement.hxx"
#include "pqxx/strconv.hxx"
#include "pqxx/util.hxx"
#include "pqxx/version.hxx"
/* Use of the libpqxx library starts here.
*
* Everything that can be done with a database through libpqxx must go through
* a connection object derived from connection_base.
*/
/* Methods tested in eg. self-test program test1 are marked with "//[t01]"
*/
namespace pqxx
{
namespace internal
{
class reactivation_avoidance_exemption;
class sql_cursor;
class reactivation_avoidance_counter
{
public:
reactivation_avoidance_counter() =default;
void add(int n) noexcept { m_counter += n; }
void clear() noexcept { m_counter = 0; }
int get() const noexcept { return m_counter; }
private:
int m_counter = 0;
};
}
std::string PQXX_LIBEXPORT encrypt_password( //[t00]
const std::string &user,
const std::string &password);
namespace internal
{
namespace gate
{
class connection_dbtransaction;
class connection_errorhandler;
class connection_largeobject;
class connection_notification_receiver;
class connection_parameterized_invocation;
class connection_pipeline;
class connection_prepare_invocation;
class connection_reactivation_avoidance_exemption;
class connection_sql_cursor;
class connection_transaction;
class const_connection_largeobject;
} // namespace pqxx::internal::gate
} // namespace pqxx::internal
class PQXX_LIBEXPORT connection_base
{
public:
void disconnect() noexcept; //[t02]
bool PQXX_PURE is_open() const noexcept; //[t01]
PQXX_DEPRECATED void activate(); //[t12]
PQXX_DEPRECATED void deactivate(); //[t12]
PQXX_DEPRECATED void inhibit_reactivation(bool inhibit) //[t86]
{ m_inhibit_reactivation=inhibit; }
void simulate_failure(); //[t94]
void process_notice(const char[]) noexcept; //[t14]
void process_notice(const std::string &) noexcept; //[t14]
void trace(std::FILE *) noexcept; //[t03]
const char *dbname(); //[t01]
const char *username(); //[t01]
const char *hostname(); //[t01]
const char *port(); //[t01]
int PQXX_PURE backendpid() const noexcept; //[t01]
int PQXX_PURE sock() const noexcept; //[t87]
enum capability
{
cap_end,
};
bool supports(capability c) const noexcept //[t88]
{ return m_caps.test(c); }
int PQXX_PURE protocol_version() const noexcept; //[t01]
int PQXX_PURE server_version() const noexcept; //[t01]
std::string get_client_encoding() const;
void set_client_encoding(const std::string &encoding); //[t07]
void set_client_encoding(const char encoding[]); //[t07]
int PQXX_PRIVATE encoding_id() const;
void set_variable( //[t60]
const std::string &Var,
const std::string &Value);
std::string get_variable(const std::string &); //[t60]
int get_notifs(); //[t04]
int await_notification(); //[t78]
int await_notification(long seconds, long microseconds); //[t79]
void prepare(const std::string &name, const std::string &definition);
void prepare(const std::string &definition);
void unprepare(const std::string &name);
void prepare_now(const std::string &name);
template<typename TRANSACTOR>
PQXX_DEPRECATED void perform(const TRANSACTOR &T, int Attempts); //[t04]
template<typename TRANSACTOR>
PQXX_DEPRECATED void perform(const TRANSACTOR &T)
{
#include "pqxx/internal/ignore-deprecated-pre.hxx"
perform(T, 3);
#include "pqxx/internal/ignore-deprecated-post.hxx"
}
std::string adorn_name(const std::string &); //[90]
std::string esc(const char str[]);
std::string esc(const char str[], size_t maxlen);
std::string esc(const std::string &str);
std::string esc_raw(const unsigned char str[], size_t len);
std::string unesc_raw(const std::string &text)
{ return unesc_raw(text.c_str()); }
std::string unesc_raw(const char *text);
std::string quote_raw(const unsigned char str[], size_t len);
std::string quote_name(const std::string &identifier);
template<typename T>
std::string quote(const T &t)
{
if (string_traits<T>::is_null(t)) return "NULL";
return "'" + this->esc(to_string(t)) + "'";
}
std::string quote(const binarystring &);
std::string esc_like(const std::string &str, char escape_char='\\') const;
void cancel_query();
enum error_verbosity
{
// These values must match those in libpq's PGVerbosity enum.
terse=0,
normal=1,
verbose=2
};
void set_verbosity(error_verbosity verbosity) noexcept;
error_verbosity get_verbosity() const noexcept {return m_verbosity;}
std::vector<errorhandler *> get_errorhandlers() const;
protected:
explicit connection_base(connectionpolicy &pol) :
m_policy{pol}
{
// Check library version. The check_library_version template is declared
// for any library version, but only actually defined for the version of
// the libpqxx binary against which the code is linked.
//
// If the library binary is a different version than the one declared in
// these headers, then this call will fail to link: there will be no
// definition for the function with these exact template parameter values.
// There will be a definition, but the version in the parameter values will
// be different.
//
// There is no particular reason to do this here in this constructor, except
// to ensure that every meaningful libpqxx client will execute it. The call
// must be in the execution path somewhere or the compiler won't try to link
// it. We can't use it to initialise a global or class-static variable,
// because a smart compiler might resolve it at compile time.
//
// On the other hand, we don't want to make a useless function call too
// often for performance reasons. A local static variable is initialised
// only on the definition's first execution. Compilers will be well
// optimised for this behaviour, so there's a minimal one-time cost.
static const auto version_ok =
internal::check_library_version<PQXX_VERSION_MAJOR, PQXX_VERSION_MINOR>();
ignore_unused(version_ok);
clearcaps();
}
void init();
void close() noexcept;
void wait_read() const;
void wait_read(long seconds, long microseconds) const;
void wait_write() const;
private:
result make_result(internal::pq::PGresult *rhs, const std::string &query);
void clearcaps() noexcept;
void PQXX_PRIVATE set_up_state();
void PQXX_PRIVATE check_result(const result &);
void PQXX_PRIVATE internal_set_trace() noexcept;
int PQXX_PRIVATE PQXX_PURE status() const noexcept;
friend class internal::gate::const_connection_largeobject;
const char * PQXX_PURE err_msg() const noexcept;
void PQXX_PRIVATE reset();
std::string PQXX_PRIVATE raw_get_var(const std::string &);
void PQXX_PRIVATE process_notice_raw(const char msg[]) noexcept;
void read_capabilities();
prepare::internal::prepared_def &find_prepared(const std::string &);
prepare::internal::prepared_def &register_prepared(const std::string &);
friend class internal::gate::connection_prepare_invocation;
PQXX_DEPRECATED result prepared_exec(
const std::string &,
const char *const[],
const int[],
const int[],
int);
result exec_prepared(const std::string &statement, const internal::params &);
bool prepared_exists(const std::string &) const;
internal::pq::PGconn *m_conn = nullptr;
connectionpolicy &m_policy;
internal::unique<transaction_base> m_trans;
void set_notice_processor();
void clear_notice_processor();
std::list<errorhandler *> m_errorhandlers;
std::FILE *m_trace = nullptr;
using receiver_list =
std::multimap<std::string, pqxx::notification_receiver *>;
receiver_list m_receivers;
std::map<std::string, std::string> m_vars;
using PSMap = std::map<std::string, prepare::internal::prepared_def>;
PSMap m_prepared;
int m_serverversion = 0;
internal::reactivation_avoidance_counter m_reactivation_avoidance;
int m_unique_id = 0;
bool m_completed = false;
bool m_inhibit_reactivation = false;
std::bitset<cap_end> m_caps;
error_verbosity m_verbosity = normal;
friend class internal::gate::connection_errorhandler;
void PQXX_PRIVATE register_errorhandler(errorhandler *);
void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
friend class internal::gate::connection_transaction;
result PQXX_PRIVATE exec(const char[], int Retries);
void PQXX_PRIVATE register_transaction(transaction_base *);
void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
bool PQXX_PRIVATE read_copy_line(std::string &);
void PQXX_PRIVATE write_copy_line(const std::string &);
void PQXX_PRIVATE end_copy_write();
void PQXX_PRIVATE raw_set_var(const std::string &, const std::string &);
void PQXX_PRIVATE add_variables(const std::map<std::string, std::string> &);
friend class internal::gate::connection_largeobject;
internal::pq::PGconn *raw_connection() const { return m_conn; }
friend class internal::gate::connection_notification_receiver;
void add_receiver(notification_receiver *);
void remove_receiver(notification_receiver *) noexcept;
friend class internal::gate::connection_pipeline;
void PQXX_PRIVATE start_exec(const std::string &);
bool PQXX_PRIVATE consume_input() noexcept;
bool PQXX_PRIVATE is_busy() const noexcept;
internal::pq::PGresult *get_result();
friend class internal::gate::connection_dbtransaction;
friend class internal::gate::connection_sql_cursor;
void add_reactivation_avoidance_count(int);
friend class internal::gate::connection_reactivation_avoidance_exemption;
friend class internal::gate::connection_parameterized_invocation;
PQXX_DEPRECATED result parameterized_exec(
const std::string &query,
const char *const params[],
const int paramlengths[],
const int binaries[],
int nparams);
result exec_params(
const std::string &query,
const internal::params &args);
connection_base(const connection_base &) =delete;
connection_base &operator=(const connection_base &) =delete;
};
namespace internal
{
class PQXX_LIBEXPORT reactivation_avoidance_exemption
{
public:
explicit reactivation_avoidance_exemption(connection_base &C);
~reactivation_avoidance_exemption();
void close_connection() noexcept { m_open = false; }
private:
connection_base &m_home;
int m_count;
bool m_open;
};
void wait_read(const internal::pq::PGconn *);
void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
void wait_write(const internal::pq::PGconn *);
} // namespace pqxx::internal
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::connection_base::encoding_id
int encoding_id() const
Get the connection's encoding, as a PostgreSQL-defined code.
Definition: connection_base.cxx:1417
pqxx::connection_base::supports
bool supports(capability c) const noexcept
Does this connection seem to support the given capability?
Definition: connection_base.hxx:355
pqxx::connection_base::server_version
int PQXX_PURE server_version() const noexcept
What version of the PostgreSQL server are we connected to?
Definition: connection_base.cxx:218
pqxx::connection_base::capability
capability
Session capabilities.
Definition: connection_base.hxx:331
pqxx::connection_base::inhibit_reactivation
void inhibit_reactivation(bool inhibit)
Definition: connection_base.hxx:236
pqxx::connection_base::prepare_now
void prepare_now(const std::string &name)
Request that prepared statement be registered with the server.
Definition: connection_base.cxx:810
pqxx::connection_base::adorn_name
std::string adorn_name(const std::string &)
Suffix unique number to name to make it unique within session context.
Definition: connection_base.cxx:1380
pqxx::internal
Private namespace for libpqxx's internal use; do not access.
Definition: connection_base.hxx:43
pqxx::connection_base::backendpid
int PQXX_PURE backendpid() const noexcept
Process ID for backend process.
Definition: connection_base.cxx:119
pqxx::connection_base::disconnect
void disconnect() noexcept
Explicitly close connection.
Definition: connection_base.cxx:344
pqxx::internal::reactivation_avoidance_exemption::close_connection
void close_connection() noexcept
Definition: connection_base.hxx:921
pqxx::connection_base::set_variable
void set_variable(const std::string &Var, const std::string &Value)
Set session variable.
Definition: connection_base.cxx:224
pqxx::connection_base::username
const char * username()
Database user ID we're connected under, if any.
Definition: connection_base.cxx:631
pqxx::connection_base::process_notice
void process_notice(const char[]) noexcept
Invoke notice processor function. The message should end in newline.
Definition: connection_base.cxx:369
pqxx::connection_base::unprepare
void unprepare(const std::string &name)
Drop prepared statement.
Definition: connection_base.cxx:763
pqxx::connection_base::port
const char * port()
Server port number we're connected to.
Definition: connection_base.cxx:649
pqxx::connection_base::connection_base
connection_base(connectionpolicy &pol)
Definition: connection_base.hxx:738
pqxx::internal::reactivation_avoidance_counter::add
void add(int n) noexcept
Definition: connection_base.hxx:53
pqxx::connection_base::get_errorhandlers
std::vector< errorhandler * > get_errorhandlers() const
Return pointers to the active errorhandlers.
Definition: connection_base.cxx:702
pqxx::connection_base::activate
void activate()
Definition: connection_base.cxx:140
pqxx::connection_base::deactivate
void deactivate()
Definition: connection_base.cxx:178
pqxx::failure
Run-time failure encountered by libpqxx, similar to std::runtime_error.
Definition: except.hxx:89
pqxx::connection_base::close
void close() noexcept
Definition: connection_base.cxx:902
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:69
pqxx::encrypt_password
std::string encrypt_password(const std::string &user, const std::string &password)
Encrypt password for given user.
Definition: connection_base.cxx:89
pqxx::connection_base::get_verbosity
error_verbosity get_verbosity() const noexcept
Retrieve current error verbosity.
Definition: connection_base.hxx:720
pqxx::connection_base::esc_like
std::string esc_like(const std::string &str, char escape_char='\\') const
Escape string for literal LIKE match.
Definition: connection_base.cxx:1186
pqxx::connection_base::quote_name
std::string quote_name(const std::string &identifier)
Escape and quote an SQL identifier for use in a query.
Definition: connection_base.cxx:1171
pqxx::notification_receiver::channel
const std::string & channel() const
The channel that this receiver listens on.
Definition: notification.hxx:69
pqxx::connection_base::get_notifs
int get_notifs()
Check for pending notifications and take appropriate action.
Definition: connection_base.cxx:570
pqxx::ignore_unused
void ignore_unused(T)
Suppress compiler warning about an unused item.
Definition: util.hxx:38
pqxx::connection_base::prepare
void prepare(const std::string &name, const std::string &definition)
Define a prepared statement.
Definition: connection_base.cxx:731
pqxx::internal::name_encoding
const char * name_encoding(int encoding_id)
Definition: encodings.cxx:631
pqxx::connection_base::cap_end
@ cap_end
Not a capability value; end-of-enumeration marker.
Definition: connection_base.hxx:334
pqxx::sql_error
Exception class for failed queries.
Definition: except.hxx:130
pqxx::notification_receiver
Definition: notification.hxx:55
pqxx::internal::reactivation_avoidance_counter
Definition: connection_base.hxx:48
pqxx::connection_base::wait_write
void wait_write() const
Definition: connection_base.cxx:1322
pqxx::internal::enc_group
encoding_group enc_group(int libpq_enc_id)
Definition: encodings.cxx:637
pqxx::connection_base::esc
std::string esc(const char str[])
Escape string for use as SQL string literal on this connection.
Definition: connection_base.cxx:1114
pqxx::connection_base::dbname
const char * dbname()
Name of database we're connected to, if any.
Definition: connection_base.cxx:622
pqxx::connection_base::trace
void trace(std::FILE *) noexcept
Enable tracing to a given output stream, or nullptr to disable.
Definition: connection_base.cxx:430
pqxx::internal::wait_write
void wait_write(const internal::pq::PGconn *)
Definition: connection_base.cxx:1304
pqxx::internal::reactivation_avoidance_counter::reactivation_avoidance_counter
reactivation_avoidance_counter()=default
pqxx::errorhandler
Base class for error-handler callbacks.
Definition: errorhandler.hxx:54
pqxx::binarystring::size
size_type size() const noexcept
Size of converted string in bytes.
Definition: binarystring.hxx:80
pqxx::connection_base::get_client_encoding
std::string get_client_encoding() const
Get client-side character encoding, by name.
Definition: connection_base.cxx:1387
pqxx::connection_base::init
void init()
Definition: connection_base.cxx:99
pqxx::internal_error
Internal error in libpqxx library.
Definition: except.hxx:207
pqxx::binarystring
Binary data corresponding to PostgreSQL's "BYTEA" binary-string type.
Definition: binarystring.hxx:53
pqxx::broken_connection
Exception class for lost or failed backend connection.
Definition: except.hxx:118
pqxx::connection_base::error_verbosity
error_verbosity
Error verbosity levels.
Definition: connection_base.hxx:701
pqxx::connection_base::unesc_raw
std::string unesc_raw(const std::string &text)
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection_base.hxx:644
pqxx::prepare
Dedicated namespace for helper types related to prepared statements.
Definition: prepared_statement.hxx:25
pqxx::connection_base::cancel_query
void cancel_query()
Attempt to cancel the ongoing query, if any.
Definition: connection_base.cxx:542
pqxx::connection_base::await_notification
int await_notification()
Wait for a notification to come in.
Definition: connection_base.cxx:1328
pqxx::connection_base::esc_raw
std::string esc_raw(const unsigned char str[], size_t len)
Escape binary string for use as SQL string literal on this connection.
Definition: connection_base.cxx:1126
pqxx::internal::reactivation_avoidance_exemption::~reactivation_avoidance_exemption
~reactivation_avoidance_exemption()
Definition: connection_base.cxx:1220
pqxx::connection_base::simulate_failure
void simulate_failure()
Make the connection fail.
Definition: connection_base.cxx:200
pqxx::internal::reactivation_avoidance_counter::get
int get() const noexcept
Definition: connection_base.hxx:55
pqxx::internal::reactivation_avoidance_exemption
Scoped exemption to reactivation avoidance.
Definition: connection_base.hxx:915
pqxx::connection_base::quote
std::string quote(const T &t)
Represent object as SQL string, including quoting & escaping.
Definition: connection_base.hxx:662
pqxx::internal::wait_read
void wait_read(const internal::pq::PGconn *)
Definition: connection_base.cxx:1284
pqxx::connection_base::protocol_version
int PQXX_PURE protocol_version() const noexcept
What version of the PostgreSQL protocol is this connection using?
Definition: connection_base.cxx:212
pqxx::internal::freepqmem
void freepqmem(const void *) noexcept
Definition: util.cxx:106
pqxx::connection_base::hostname
const char * hostname()
Address of server, or nullptr if none specified (i.e. default or local)
Definition: connection_base.cxx:640
pqxx::perform
auto perform(const TRANSACTION_CALLBACK &callback, int attempts=3) -> decltype(callback())
Simple way to execute a transaction with automatic retry.
Definition: transactor.hxx:99
pqxx::connection_base::is_open
bool PQXX_PURE is_open() const noexcept
Is this connection open at the moment?
Definition: connection_base.cxx:353
pqxx::argument_error
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition: except.hxx:229
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
pqxx::connection_base::set_verbosity
void set_verbosity(error_verbosity verbosity) noexcept
Set session verbosity.
Definition: connection_base.cxx:549
pqxx::feature_not_supported
Database feature not supported in current setup.
Definition: except.hxx:272
pqxx::connection_base
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:139
pqxx::connection_base::sock
int PQXX_PURE sock() const noexcept
Socket currently used for connection, or -1 for none. Use with care!
Definition: connection_base.cxx:134
pqxx::connection_base::quote_raw
std::string quote_raw(const unsigned char str[], size_t len)
Escape and quote a string of binary data.
Definition: connection_base.cxx:1157
pqxx::connection_base::set_client_encoding
void set_client_encoding(const std::string &encoding)
Set client-side character encoding, by name.
Definition: connection_base.cxx:1411
pqxx::prepare::internal::prepared_def
Internal representation of a prepared statement definition.
Definition: prepared_statement.hxx:156
pqxx::string_traits
Traits class for use in string conversions.
Definition: strconv.hxx:51
pqxx::connection_base::get_variable
std::string get_variable(const std::string &)
Read session variable.
Definition: connection_base.cxx:241
pqxx::internal::reactivation_avoidance_exemption::reactivation_avoidance_exemption
reactivation_avoidance_exemption(connection_base &C)
Definition: connection_base.cxx:1208
pqxx::transaction_base
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:136
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::usage_error
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:218
pqxx::binarystring::data
const value_type * data() const noexcept
Unescaped field contents.
Definition: binarystring.hxx:102
pqxx::connectionpolicy
Definition: connectionpolicy.hxx:31
pqxx::connection_base::wait_read
void wait_read() const
Definition: connection_base.cxx:1310
pqxx::internal::check_library_version< PQXX_VERSION_MAJOR, PQXX_VERSION_MINOR >
int check_library_version< PQXX_VERSION_MAJOR, PQXX_VERSION_MINOR >() noexcept
Definition: version.cxx:13
pqxx::internal::reactivation_avoidance_counter::clear
void clear() noexcept
Definition: connection_base.hxx:54