libpqxx  7.1.2
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-2020, 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 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
18 
19 #include <functional>
20 #include <list>
21 #include <map>
22 #include <memory>
23 #include <string_view>
24 
25 #include "pqxx/errorhandler.hxx"
26 #include "pqxx/except.hxx"
27 #include "pqxx/prepared_statement.hxx"
28 #include "pqxx/strconv.hxx"
29 #include "pqxx/util.hxx"
30 #include "pqxx/zview.hxx"
31 
32 
60 namespace pqxx::internal
61 {
62 class sql_cursor;
63 } // namespace pqxx::internal
64 
65 
67 {
68 class connection_dbtransaction;
69 class connection_errorhandler;
70 class connection_largeobject;
71 class connection_notification_receiver;
72 class connection_pipeline;
73 class connection_sql_cursor;
74 class connection_stream_from;
75 class connection_stream_to;
76 class connection_transaction;
77 class const_connection_largeobject;
78 } // namespace pqxx::internal::gate
79 
80 
81 namespace pqxx
82 {
84 [[nodiscard]] std::string PQXX_LIBEXPORT
85 encrypt_password(char const user[], char const password[]);
86 
88 [[nodiscard]] inline std::string
89 encrypt_password(std::string const &user, std::string const &password)
90 {
91  return encrypt_password(user.c_str(), password.c_str());
92 }
93 
94 
96 enum class error_verbosity : int
97 {
98  // These values must match those in libpq's PGVerbosity enum.
99  terse = 0,
100  normal = 1,
101  verbose = 2
102 };
103 
104 
106 
136 class PQXX_LIBEXPORT connection
137 {
138 public:
140 
141  explicit connection(std::string const &options) : connection{options.c_str()}
142  {}
143 
144  explicit connection(char const options[])
145  {
146  check_version();
147  init(options);
148  }
149 
150  explicit connection(zview options) : connection{options.c_str()} {}
151 
153 
158  connection(connection &&rhs);
159 
161  {
162  try
163  {
164  close();
165  }
166  catch (std::exception const &)
167  {}
168  }
169 
171 
174  connection &operator=(connection &&rhs);
175 
176  connection(connection const &) = delete;
177  connection &operator=(connection const &) = delete;
178 
180 
184  [[nodiscard]] bool PQXX_PURE is_open() const noexcept;
185 
187  void process_notice(char const[]) noexcept;
189  void process_notice(std::string const &msg) noexcept
190  {
191  process_notice(zview{msg});
192  }
194 
197  void process_notice(zview) noexcept;
198 
200  void trace(std::FILE *) noexcept;
201 
212  [[nodiscard]] char const *dbname() const;
214 
216  [[nodiscard]] char const *username() const;
217 
219  [[nodiscard]] char const *hostname() const;
220 
222  [[nodiscard]] char const *port() const;
223 
225  [[nodiscard]] int PQXX_PURE backendpid() const noexcept;
226 
228 
243  [[nodiscard]] int PQXX_PURE sock() const noexcept;
244 
246 
249  [[nodiscard]] int PQXX_PURE protocol_version() const noexcept;
250 
252 
264  [[nodiscard]] int PQXX_PURE server_version() const noexcept;
266 
268 
288  [[nodiscard]] std::string get_client_encoding() const;
290 
292 
295  void set_client_encoding(std::string const &encoding)
296  {
297  set_client_encoding(encoding.c_str());
298  }
299 
301 
304  void set_client_encoding(char const encoding[]);
305 
307  [[nodiscard]] int PQXX_PRIVATE encoding_id() const;
308 
310 
312 
327  void set_variable(std::string_view var, std::string_view value);
328 
330 
333  std::string get_variable(std::string_view);
335 
336 
341 
354  int get_notifs();
355 
356 
358 
366  int await_notification();
367 
368  // TODO: Use time_t instead of long? See #339.
370 
378  int await_notification(long seconds, long microseconds);
380 
382 
408  [[nodiscard]] std::string encrypt_password(
409  char const user[], char const password[], char const *algorithm = nullptr);
410  [[nodiscard]] std::string
411  encrypt_password(zview user, zview password, zview algorithm)
412  {
413  return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
414  }
415 
444 
466  void prepare(char const name[], char const definition[]);
467 
468  void prepare(std::string const &name, std::string const &definition)
469  {
470  prepare(name.c_str(), definition.c_str());
471  }
472 
473  void prepare(zview name, zview definition)
474  {
475  prepare(name.c_str(), definition.c_str());
476  }
477 
479 
486  void prepare(char const definition[]);
487  void prepare(zview definition) { return prepare(definition.c_str()); }
488 
490  void unprepare(std::string_view name);
491 
496 
500  [[nodiscard]] std::string adorn_name(std::string_view);
501 
506 
508 
512  [[nodiscard]] std::string esc(char const text[], std::size_t maxlen) const
513  {
514  return esc(std::string_view(text, maxlen));
515  }
516 
518  [[nodiscard]] std::string esc(char const text[]) const
519  {
520  return esc(std::string_view(text));
521  }
522 
524 
527  [[nodiscard]] std::string esc(std::string_view text) const;
528 
530  [[nodiscard]] std::string
531  esc_raw(unsigned char const bin[], std::size_t len) const;
532 
534 
537  [[nodiscard]] std::string unesc_raw(std::string const &text) const
538  {
539  return unesc_raw(text.c_str());
540  }
541 
543 
546  [[nodiscard]] std::string unesc_raw(zview text) const
547  {
548  return unesc_raw(text.c_str());
549  }
550 
552 
555  [[nodiscard]] std::string unesc_raw(char const text[]) const;
556 
558  [[nodiscard]] std::string
559  quote_raw(unsigned char const bin[], std::size_t len) const;
560 
562  [[nodiscard]] std::string quote_name(std::string_view identifier) const;
563 
565 
568  template<typename T>[[nodiscard]] inline std::string quote(T const &t) const;
569 
570  [[nodiscard]] std::string quote(binarystring const &) const;
571 
573 
596  [[nodiscard]] std::string
597  esc_like(std::string_view text, char escape_char = '\\') const;
599 
601 
605  void cancel_query();
606 
608 
617  void set_verbosity(error_verbosity verbosity) noexcept;
618 
620 
632  [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
633 
635 
641  [[nodiscard]] std::string connection_string() const;
642 
644 
647  void close();
648 
649 private:
650  void init(char const options[]);
651 
652  void wait_read() const;
653  // TODO: Use time_t instead of long? See #339.
654  void wait_read(long seconds, long microseconds) const;
655 
656  result make_result(
657  internal::pq::PGresult *pgr, std::shared_ptr<std::string> const &query);
658 
659  void PQXX_PRIVATE set_up_state();
660 
661  int PQXX_PRIVATE PQXX_PURE status() const noexcept;
662 
664 
668  std::size_t esc_to_buf(std::string_view text, char *buf) const;
669 
670  friend class internal::gate::const_connection_largeobject;
671  char const *PQXX_PURE err_msg() const noexcept;
672 
673  void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept;
674 
675  result exec_prepared(std::string_view statement, internal::params const &);
676 
678  void check_movable() const;
680  void check_overwritable() const;
681 
682  friend class internal::gate::connection_errorhandler;
683  void PQXX_PRIVATE register_errorhandler(errorhandler *);
684  void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
685 
686  friend class internal::gate::connection_transaction;
687  result PQXX_PRIVATE exec(std::string_view);
688  result PQXX_PRIVATE exec(std::shared_ptr<std::string>);
689  void PQXX_PRIVATE register_transaction(transaction_base *);
690  void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
691 
692  friend class internal::gate::connection_stream_from;
693  std::pair<std::unique_ptr<char, std::function<void(char *)>>, std::size_t>
694  PQXX_PRIVATE read_copy_line();
695 
696  friend class internal::gate::connection_stream_to;
697  void PQXX_PRIVATE write_copy_line(std::string_view);
698  void PQXX_PRIVATE end_copy_write();
699 
700  friend class internal::gate::connection_largeobject;
701  internal::pq::PGconn *raw_connection() const { return m_conn; }
702 
703  friend class internal::gate::connection_notification_receiver;
704  void add_receiver(notification_receiver *);
705  void remove_receiver(notification_receiver *) noexcept;
706 
707  friend class internal::gate::connection_pipeline;
708  void PQXX_PRIVATE start_exec(char const query[]);
709  bool PQXX_PRIVATE consume_input() noexcept;
710  bool PQXX_PRIVATE is_busy() const noexcept;
711  internal::pq::PGresult *get_result();
712 
713  friend class internal::gate::connection_dbtransaction;
714  friend class internal::gate::connection_sql_cursor;
715 
716  result exec_params(std::string_view query, internal::params const &args);
717 
719  internal::pq::PGconn *m_conn = nullptr;
720 
722  internal::unique<transaction_base> m_trans;
723 
724  std::list<errorhandler *> m_errorhandlers;
725 
726  using receiver_list =
727  std::multimap<std::string, pqxx::notification_receiver *>;
729  receiver_list m_receivers;
730 
732  int m_unique_id = 0;
733 };
734 
735 
738 
739 
740 template<typename T> inline std::string connection::quote(T const &t) const
741 {
742  if (is_null(t))
743  return "NULL";
744  auto const text{to_string(t)};
745 
746  // Okay, there's an easy way to do this and there's a hard way. The easy
747  // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
748  // because it's going to save some string manipulation that will probably
749  // incur some unnecessary memory allocations and deallocations.
750  std::string buf{'\''};
751  buf.resize(2 + 2 * text.size() + 1);
752  auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
753  auto const closing_quote{1 + content_bytes};
754  buf[closing_quote] = '\'';
755  auto const end{closing_quote + 1};
756  buf.resize(end);
757  return buf;
758 }
759 } // namespace pqxx
760 
761 
762 namespace pqxx::internal
763 {
764 PQXX_LIBEXPORT void wait_read(internal::pq::PGconn const *);
765 PQXX_LIBEXPORT void
766 wait_read(internal::pq::PGconn const *, long seconds, long microseconds);
767 PQXX_LIBEXPORT void wait_write(internal::pq::PGconn const *);
768 } // namespace pqxx::internal
769 
770 #include "pqxx/internal/compiler-internal-post.hxx"
771 #endif
Private namespace for libpqxx&#39;s internal use; do not access.
Definition: connection.hxx:60
constexpr char const * c_str() const noexcept
Either a null pointer, or a zero-terminated text buffer.
Definition: zview.hxx:53
void prepare(std::string const &name, std::string const &definition)
Definition: connection.hxx:468
void wait_write(internal::pq::PGconn const *)
Definition: connection.cxx:931
connection(zview options)
Definition: connection.hxx:150
std::string encrypt_password(zview user, zview password, zview algorithm)
Definition: connection.hxx:411
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:498
void set_client_encoding(std::string const &encoding)
Set client-side character encoding, by name.
Definition: connection.hxx:295
std::string unesc_raw(zview text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:546
connection(char const options[])
Definition: connection.hxx:144
error_verbosity
Error verbosity levels.
Definition: connection.hxx:96
std::string esc(char const text[]) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:518
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
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:512
Connection to a database.
Definition: connection.hxx:136
void process_notice(std::string const &msg) noexcept
Invoke notice processor function. Newline at end is recommended.
Definition: connection.hxx:189
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:307
Binary data corresponding to PostgreSQL&#39;s "BYTEA" binary-string type.
Definition: binarystring.hxx:53
STL namespace.
~connection()
Definition: connection.hxx:160
void check_version()
Definition: util.hxx:143
connection(std::string const &options)
Definition: connection.hxx:141
Definition: connection.hxx:66
Result set containing data returned by a query or command.
Definition: result.hxx:70
void prepare(zview definition)
Definition: connection.hxx:487
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:32
Definition: notification.hxx:55
Base class for error-handler callbacks.
Definition: errorhandler.hxx:52
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:67
std::string encrypt_password(char const user[], char const password[])
Encrypt a password.
Definition: connection.cxx:93
void prepare(zview name, zview definition)
Definition: connection.hxx:473
void wait_read(internal::pq::PGconn const *)
Definition: connection.cxx:911
connection()
Definition: connection.hxx:139
std::string unesc_raw(std::string const &text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:537