libpqxx  7.1.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-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 
369 
377  int await_notification(long seconds, long microseconds);
379 
381 
407  [[nodiscard]] std::string encrypt_password(
408  char const user[], char const password[], char const *algorithm = nullptr);
409  [[nodiscard]] std::string
410  encrypt_password(zview user, zview password, zview algorithm)
411  {
412  return encrypt_password(user.c_str(), password.c_str(), algorithm.c_str());
413  }
414 
443 
465  void prepare(char const name[], char const definition[]);
466 
467  void prepare(std::string const &name, std::string const &definition)
468  {
469  prepare(name.c_str(), definition.c_str());
470  }
471 
472  void prepare(zview name, zview definition)
473  {
474  prepare(name.c_str(), definition.c_str());
475  }
476 
478 
485  void prepare(char const definition[]);
486  void prepare(zview definition) { return prepare(definition.c_str()); }
487 
489  void unprepare(std::string_view name);
490 
495 
499  [[nodiscard]] std::string adorn_name(std::string_view);
500 
505 
507 
511  [[nodiscard]] std::string esc(char const text[], std::size_t maxlen) const
512  {
513  return esc(std::string_view(text, maxlen));
514  }
515 
517  [[nodiscard]] std::string esc(char const text[]) const
518  {
519  return esc(std::string_view(text));
520  }
521 
523 
526  [[nodiscard]] std::string esc(std::string_view text) const;
527 
529  [[nodiscard]] std::string
530  esc_raw(unsigned char const bin[], std::size_t len) const;
531 
533 
536  [[nodiscard]] std::string unesc_raw(std::string const &text) const
537  {
538  return unesc_raw(text.c_str());
539  }
540 
542 
545  [[nodiscard]] std::string unesc_raw(zview text) const
546  {
547  return unesc_raw(text.c_str());
548  }
549 
551 
554  [[nodiscard]] std::string unesc_raw(char const text[]) const;
555 
557  [[nodiscard]] std::string
558  quote_raw(unsigned char const bin[], std::size_t len) const;
559 
561  [[nodiscard]] std::string quote_name(std::string_view identifier) const;
562 
564 
567  template<typename T>[[nodiscard]] inline std::string quote(T const &t) const;
568 
569  [[nodiscard]] std::string quote(binarystring const &) const;
570 
572 
595  [[nodiscard]] std::string
596  esc_like(std::string_view text, char escape_char = '\\') const;
598 
600 
604  void cancel_query();
605 
607 
616  void set_verbosity(error_verbosity verbosity) noexcept;
617 
619 
631  [[nodiscard]] std::vector<errorhandler *> get_errorhandlers() const;
632 
634 
640  [[nodiscard]] std::string connection_string() const;
641 
643 
646  void close();
647 
648 private:
649  void init(char const options[]);
650 
651  void wait_read() const;
652  void wait_read(long seconds, long microseconds) const;
653 
654  result make_result(
655  internal::pq::PGresult *pgr, std::shared_ptr<std::string> const &query);
656 
657  void PQXX_PRIVATE set_up_state();
658 
659  int PQXX_PRIVATE PQXX_PURE status() const noexcept;
660 
662 
666  std::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  std::pair<std::unique_ptr<char, std::function<void(char *)>>, std::size_t>
692  PQXX_PRIVATE read_copy_line();
693 
694  friend class internal::gate::connection_stream_to;
695  void PQXX_PRIVATE write_copy_line(std::string_view);
696  void PQXX_PRIVATE end_copy_write();
697 
698  friend class internal::gate::connection_largeobject;
699  internal::pq::PGconn *raw_connection() const { return m_conn; }
700 
701  friend class internal::gate::connection_notification_receiver;
702  void add_receiver(notification_receiver *);
703  void remove_receiver(notification_receiver *) noexcept;
704 
705  friend class internal::gate::connection_pipeline;
706  void PQXX_PRIVATE start_exec(char const query[]);
707  bool PQXX_PRIVATE consume_input() noexcept;
708  bool PQXX_PRIVATE is_busy() const noexcept;
709  internal::pq::PGresult *get_result();
710 
711  friend class internal::gate::connection_dbtransaction;
712  friend class internal::gate::connection_sql_cursor;
713 
714  result exec_params(std::string_view query, internal::params const &args);
715 
717  internal::pq::PGconn *m_conn = nullptr;
718 
720  internal::unique<transaction_base> m_trans;
721 
722  std::list<errorhandler *> m_errorhandlers;
723 
724  using receiver_list =
725  std::multimap<std::string, pqxx::notification_receiver *>;
727  receiver_list m_receivers;
728 
730  int m_unique_id = 0;
731 };
732 
733 
736 
737 
738 template<typename T> inline std::string connection::quote(T const &t) const
739 {
740  if (is_null(t))
741  return "NULL";
742  auto const text{to_string(t)};
743 
744  // Okay, there's an easy way to do this and there's a hard way. The easy
745  // way was "quote, esc(to_string(t)), quote". I'm going with the hard way
746  // because it's going to save some string manipulation that will probably
747  // incur some unnecessary memory allocations and deallocations.
748  std::string buf{'\''};
749  buf.resize(2 + 2 * text.size() + 1);
750  auto const content_bytes{esc_to_buf(text, buf.data() + 1)};
751  auto const closing_quote{1 + content_bytes};
752  buf[closing_quote] = '\'';
753  auto const end{closing_quote + 1};
754  buf.resize(end);
755  return buf;
756 }
757 } // namespace pqxx
758 
759 
760 namespace pqxx::internal
761 {
762 PQXX_LIBEXPORT void wait_read(internal::pq::PGconn const *);
763 PQXX_LIBEXPORT void
764 wait_read(internal::pq::PGconn const *, long seconds, long microseconds);
765 PQXX_LIBEXPORT void wait_write(internal::pq::PGconn const *);
766 } // namespace pqxx::internal
767 
768 #include "pqxx/internal/compiler-internal-post.hxx"
769 #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:467
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:410
std::string to_string(field const &value)
Convert a field to a string.
Definition: result.cxx:477
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:545
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:517
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:511
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:141
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:486
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:472
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:536