libpqxx  7.0.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 <list>
20 #include <map>
21 #include <memory>
22 #include <string_view>
23 
24 #include "pqxx/errorhandler.hxx"
25 #include "pqxx/except.hxx"
26 #include "pqxx/prepared_statement.hxx"
27 #include "pqxx/strconv.hxx"
28 #include "pqxx/util.hxx"
29 #include "pqxx/zview.hxx"
30 
31 
59 namespace pqxx::internal
60 {
61 class sql_cursor;
62 } // namespace pqxx::internal
63 
64 
66 {
67 class connection_dbtransaction;
68 class connection_errorhandler;
69 class connection_largeobject;
70 class connection_notification_receiver;
71 class connection_pipeline;
72 class connection_sql_cursor;
73 class connection_stream_from;
74 class connection_stream_to;
75 class connection_transaction;
76 class const_connection_largeobject;
77 } // namespace pqxx::internal::gate
78 
79 
80 namespace pqxx
81 {
83 [[nodiscard]] std::string PQXX_LIBEXPORT
84 encrypt_password(char const user[], char const password[]);
85 
87 [[nodiscard]] inline std::string
88 encrypt_password(std::string const &user, std::string const &password)
89 {
90  return encrypt_password(user.c_str(), password.c_str());
91 }
92 
93 
95 enum class error_verbosity : int
96 {
97  // These values must match those in libpq's PGVerbosity enum.
98  terse = 0,
99  normal = 1,
100  verbose = 2
101 };
102 
103 
105 
135 class PQXX_LIBEXPORT connection
136 {
137 public:
139 
140  explicit connection(std::string const &options) : connection{options.c_str()}
141  {}
142 
143  explicit connection(char const options[])
144  {
145  check_version();
146  init(options);
147  }
148 
149  explicit connection(zview options) : connection{options.c_str()} {}
150 
152 
157  connection(connection &&rhs);
158 
160  {
161  try
162  {
163  close();
164  }
165  catch (std::exception const &)
166  {}
167  }
168 
170 
173  connection &operator=(connection &&rhs);
174 
175  connection(connection const &) = delete;
176  connection &operator=(connection const &) = delete;
177 
179 
183  [[nodiscard]] bool PQXX_PURE is_open() const noexcept;
184 
186  void process_notice(char const[]) noexcept;
188  void process_notice(std::string const &msg) noexcept
189  {
190  process_notice(zview{msg});
191  }
193 
196  void process_notice(zview) noexcept;
197 
199  void trace(std::FILE *) noexcept;
200 
211  [[nodiscard]] char const *dbname() const;
213 
215  [[nodiscard]] char const *username() const;
216 
218  [[nodiscard]] char const *hostname() const;
219 
221  [[nodiscard]] char const *port() const;
222 
224  [[nodiscard]] int PQXX_PURE backendpid() const noexcept;
225 
227 
242  [[nodiscard]] int PQXX_PURE sock() const noexcept;
243 
245 
248  [[nodiscard]] int PQXX_PURE protocol_version() const noexcept;
249 
251 
263  [[nodiscard]] int PQXX_PURE server_version() const noexcept;
265 
267 
287  [[nodiscard]] std::string get_client_encoding() const;
289 
291 
294  void set_client_encoding(std::string const &encoding)
295  {
296  set_client_encoding(encoding.c_str());
297  }
298 
300 
303  void set_client_encoding(char const encoding[]);
304 
306  [[nodiscard]] int PQXX_PRIVATE encoding_id() const;
307 
309 
311 
326  void set_variable(std::string_view var, std::string_view value);
327 
329 
332  std::string get_variable(std::string_view);
334 
335 
340 
353  int get_notifs();
354 
355 
357 
365  int await_notification();
366 
368 
376  int await_notification(long seconds, long microseconds);
378 
380 
406  [[nodiscard]] std::string encrypt_password(
407  char const user[], char const password[], char const *algorithm = nullptr);
408  [[nodiscard]] std::string
409  encrypt_password(zview user, zview password, zview algorithm)
410  {
411  return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
412  }
413 
442 
464  void prepare(char const name[], char const definition[]);
465 
466  void prepare(std::string const &name, std::string const &definition)
467  {
468  prepare(name.c_str(), definition.c_str());
469  }
470 
471  void prepare(zview name, zview definition)
472  {
473  prepare(name.c_str(), definition.c_str());
474  }
475 
477 
484  void prepare(char const definition[]);
485  void prepare(zview definition) { return prepare(definition.c_str()); }
486 
488  void unprepare(std::string_view name);
489 
494 
498  [[nodiscard]] std::string adorn_name(std::string_view);
499 
504 
506 
510  [[nodiscard]] std::string esc(char const text[], size_t maxlen) const
511  {
512  return esc(std::string_view(text, maxlen));
513  }
514 
516  [[nodiscard]] std::string esc(char const text[]) const
517  {
518  return esc(std::string_view(text));
519  }
520 
522 
525  [[nodiscard]] std::string esc(std::string_view text) const;
526 
528  [[nodiscard]] std::string
529  esc_raw(unsigned char const bin[], size_t len) const;
530 
532 
535  [[nodiscard]] std::string unesc_raw(std::string const &text) const
536  {
537  return unesc_raw(text.c_str());
538  }
539 
541 
544  [[nodiscard]] std::string unesc_raw(zview text) const
545  {
546  return unesc_raw(text.c_str());
547  }
548 
550 
553  [[nodiscard]] std::string unesc_raw(char const text[]) const;
554 
556  [[nodiscard]] std::string
557  quote_raw(unsigned char const bin[], size_t len) const;
558 
560  [[nodiscard]] std::string quote_name(std::string_view identifier) const;
561 
563 
566  template<typename T>[[nodiscard]] inline std::string quote(T const &t) const;
567 
568  [[nodiscard]] std::string quote(binarystring const &) const;
569 
571 
594  [[nodiscard]] std::string
595  esc_like(std::string_view text, char escape_char = '\\') const;
597 
599 
603  void cancel_query();
604 
606 
615  void set_verbosity(error_verbosity verbosity) noexcept;
616 
618 
630  [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
631 
633 
639  [[nodiscard]] std::string connection_string() const;
640 
642 
645  void close();
646 
647 private:
648  void init(char const options[]);
649 
650  void wait_read() const;
651  void wait_read(long seconds, long microseconds) const;
652 
653  result make_result(
654  internal::pq::PGresult *rhs, std::shared_ptr<std::string> const &query);
655 
656  void PQXX_PRIVATE set_up_state();
657  void PQXX_PRIVATE check_result(result const &);
658 
659  int PQXX_PRIVATE PQXX_PURE status() const noexcept;
660 
662 
666  size_t esc_to_buf(std::string_view text, char *buf) const;
667 
668  friend class internal::gate::const_connection_largeobject;
669  char const *PQXX_PURE err_msg() const noexcept;
670 
671  void PQXX_PRIVATE process_notice_raw(char const msg[]) noexcept;
672 
673  result exec_prepared(std::string_view statement, internal::params const &);
674 
676  void check_movable() const;
678  void check_overwritable() const;
679 
680  friend class internal::gate::connection_errorhandler;
681  void PQXX_PRIVATE register_errorhandler(errorhandler *);
682  void PQXX_PRIVATE unregister_errorhandler(errorhandler *) noexcept;
683 
684  friend class internal::gate::connection_transaction;
685  result PQXX_PRIVATE exec(std::string_view);
686  result PQXX_PRIVATE exec(std::shared_ptr<std::string>);
687  void PQXX_PRIVATE register_transaction(transaction_base *);
688  void PQXX_PRIVATE unregister_transaction(transaction_base *) noexcept;
689 
690  friend class internal::gate::connection_stream_from;
691  bool PQXX_PRIVATE read_copy_line(std::string &);
692 
693  friend class internal::gate::connection_stream_to;
694  void PQXX_PRIVATE write_copy_line(std::string_view);
695  void PQXX_PRIVATE end_copy_write();
696 
697  friend class internal::gate::connection_largeobject;
698  internal::pq::PGconn *raw_connection() const { return m_conn; }
699 
700  friend class internal::gate::connection_notification_receiver;
701  void add_receiver(notification_receiver *);
702  void remove_receiver(notification_receiver *) noexcept;
703 
704  friend class internal::gate::connection_pipeline;
705  void PQXX_PRIVATE start_exec(char const query[]);
706  bool PQXX_PRIVATE consume_input() noexcept;
707  bool PQXX_PRIVATE is_busy() const noexcept;
708  internal::pq::PGresult *get_result();
709 
710  friend class internal::gate::connection_dbtransaction;
711  friend class internal::gate::connection_sql_cursor;
712 
713  result exec_params(std::string_view query, internal::params const &args);
714 
716  internal::pq::PGconn *m_conn = nullptr;
717 
719  internal::unique<transaction_base> m_trans;
720 
721  std::list<errorhandler *> m_errorhandlers;
722 
723  using receiver_list =
724  std::multimap<std::string, pqxx::notification_receiver *>;
726  receiver_list m_receivers;
727 
729  int m_unique_id = 0;
730 };
731 
732 
735 
736 
737 template<typename T> inline std::string connection::quote(T const &t) const
738 {
739  if (is_null(t))
740  return "NULL";
741  auto const text{to_string(t)};
742 
743  // Okay, there's an easy way to do this and there's a hard way. The easy
744  // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
745  // because it's going to save some string manipulation that will probably
746  // incur some unnecessary memory allocations and deallocations.
747  std::string buf{'\''};
748  buf.resize(2 + 2 * text.size() + 1);
749  auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
750  auto const closing_quote{1 + content_bytes};
751  buf[closing_quote] = '\'';
752  auto const end{closing_quote + 1};
753  buf.resize(end);
754  return buf;
755 }
756 } // namespace pqxx
757 
758 
759 namespace pqxx::internal
760 {
761 PQXX_LIBEXPORT void wait_read(internal::pq::PGconn const *);
762 PQXX_LIBEXPORT void
763 wait_read(internal::pq::PGconn const *, long seconds, long microseconds);
764 PQXX_LIBEXPORT void wait_write(internal::pq::PGconn const *);
765 } // namespace pqxx::internal
766 
767 #include "pqxx/internal/compiler-internal-post.hxx"
768 #endif
Private namespace for libpqxx&#39;s internal use; do not access.
Definition: connection.hxx:59
bool is_null(TYPE const &value)
Is value null?
Definition: strconv.hxx:286
void prepare(std::string const &name, std::string const &definition)
Definition: connection.hxx:466
void wait_write(internal::pq::PGconn const *)
Definition: connection.cxx:934
connection(zview options)
Definition: connection.hxx:149
std::string encrypt_password(zview user, zview password, zview algorithm)
Definition: connection.hxx:409
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:478
void set_client_encoding(std::string const &encoding)
Set client-side character encoding, by name.
Definition: connection.hxx:294
std::string unesc_raw(zview text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:544
connection(char const options[])
Definition: connection.hxx:143
error_verbosity
Error verbosity levels.
Definition: connection.hxx:95
std::string esc(char const text[]) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:516
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
Connection to a database.
Definition: connection.hxx:135
constexpr char const * c_str() const noexcept
Either a null pointer, or a zero-terminated text buffer.
Definition: zview.hxx:41
std::string esc(char const text[], size_t maxlen) const
Escape string for use as SQL string literal on this connection.
Definition: connection.hxx:510
void process_notice(std::string const &msg) noexcept
Invoke notice processor function. Newline at end is recommended.
Definition: connection.hxx:188
Binary data corresponding to PostgreSQL&#39;s "BYTEA" binary-string type.
Definition: binarystring.hxx:53
STL namespace.
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:97
~connection()
Definition: connection.hxx:159
void check_version()
Definition: util.hxx:135
connection(std::string const &options)
Definition: connection.hxx:140
Definition: connection.hxx:65
Result set containing data returned by a query or command.
Definition: result.hxx:70
void prepare(zview definition)
Definition: connection.hxx:485
Definition: notification.hxx:55
Base class for error-handler callbacks.
Definition: errorhandler.hxx:52
std::string encrypt_password(char const user[], char const password[])
Encrypt a password.
Definition: connection.cxx:93
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:32
void prepare(zview name, zview definition)
Definition: connection.hxx:471
void wait_read(internal::pq::PGconn const *)
Definition: connection.cxx:914
connection()
Definition: connection.hxx:138
std::string unesc_raw(std::string const &text) const
Unescape binary data, e.g. from a table field or notification payload.
Definition: connection.hxx:535