libpqxx  4.0.1
connection_base.hxx
1 /*-------------------------------------------------------------------------
2  *
3  * FILE
4  * pqxx/connection_base.hxx
5  *
6  * DESCRIPTION
7  * definition of the pqxx::connection_base abstract base class.
8  * pqxx::connection_base encapsulates a frontend to backend connection
9  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/connection_base instead.
10  *
11  * Copyright (c) 2001-2011, Jeroen T. Vermeulen <jtv@xs4all.nl>
12  *
13  * See COPYING for copyright license. If you did not receive a file called
14  * COPYING with this source code, please notify the distributor of this mistake,
15  * or contact the author.
16  *
17  *-------------------------------------------------------------------------
18  */
19 #ifndef PQXX_H_CONNECTION_BASE
20 #define PQXX_H_CONNECTION_BASE
21 
22 #include "pqxx/compiler-public.hxx"
23 #include "pqxx/compiler-internal-pre.hxx"
24 
25 #include <bitset>
26 #include <list>
27 #include <map>
28 #include <memory>
29 
30 #include "pqxx/errorhandler"
31 #include "pqxx/except"
32 #include "pqxx/prepared_statement"
33 #include "pqxx/strconv"
34 #include "pqxx/util"
35 
36 
37 /* Use of the libpqxx library starts here.
38  *
39  * Everything that can be done with a database through libpqxx must go through
40  * a connection object derived from connection_base.
41  */
42 
43 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
44  */
45 
46 namespace pqxx
47 {
48 class binarystring;
49 class connectionpolicy;
50 class notification_receiver;
51 class result;
52 class transaction_base;
53 
54 namespace internal
55 {
57 class sql_cursor;
58 
60 {
61 public:
62  reactivation_avoidance_counter() : m_counter(0) {}
63 
64  void add(int n) throw () { m_counter += n; }
65  void clear() throw () { m_counter = 0; }
66  int get() const throw () { return m_counter; }
67 
68 private:
69  int m_counter;
70 };
71 
72 }
73 
74 
76 
94 PGSTD::string PQXX_LIBEXPORT encrypt_password( //[t0]
95  const PGSTD::string &user,
96  const PGSTD::string &password);
97 
98 
99 namespace internal
100 {
101 namespace gate
102 {
103 class connection_dbtransaction;
104 class connection_errorhandler;
105 class connection_largeobject;
106 class connection_notification_receiver;
107 class connection_parameterized_invocation;
108 class connection_pipeline;
109 class connection_prepare_invocation;
110 class connection_reactivation_avoidance_exemption;
111 class connection_sql_cursor;
112 class connection_transaction;
113 } // namespace pqxx::internal::gate
114 } // namespace pqxx::internal
115 
116 
118 
151 class PQXX_LIBEXPORT connection_base
152 {
153 public:
155  void disconnect() throw (); //[t2]
156 
158 
162  bool PQXX_PURE is_open() const throw (); //[t1]
163 
174 
175 
185  void activate(); //[t12]
186 
188 
196  void deactivate(); //[t12]
197 
199 
243  void inhibit_reactivation(bool inhibit) //[t86]
244  { m_inhibit_reactivation=inhibit; }
245 
247 
252  void simulate_failure(); //[t94]
254 
256  void process_notice(const char[]) throw (); //[t14]
258  void process_notice(const PGSTD::string &) throw (); //[t14]
259 
261  void trace(PGSTD::FILE *) throw (); //[t3]
262 
271 
272 
275  const char *dbname(); //[t1]
276 
278 
281  const char *username(); //[t1]
282 
284 
287  const char *hostname(); //[t1]
288 
290 
293  const char *port(); //[t1]
294 
296 
305  int PQXX_PURE backendpid() const throw (); //[t1]
306 
308 
322  int PQXX_PURE sock() const throw (); //[t87]
323 
334 
337  {
340 
343 
346 
355 
358 
361 
364 
367 
370 
373 
375  cap_end
376  };
377 
378 
380 
396  bool supports(capability c) const throw () { return m_caps.test(c); } //[t88]
397 
399 
411  int PQXX_PURE protocol_version() const throw (); //[t1]
412 
414 
426  int PQXX_PURE server_version() const throw (); //[t1]
428 
430 
436  void set_client_encoding(const PGSTD::string &Encoding) //[t7]
437  { set_variable("CLIENT_ENCODING", Encoding); }
438 
440 
456  void set_variable(const PGSTD::string &Var,
457  const PGSTD::string &Value); //[t60]
458 
460 
467  PGSTD::string get_variable(const PGSTD::string &); //[t60]
469 
470 
475 
476 
488  int get_notifs(); //[t4]
489 
490 
492 
498  int await_notification(); //[t78]
499 
501 
507  int await_notification(long seconds, long microseconds); //[t79]
509 
510 
547 
548 
581  void prepare(const PGSTD::string &name, const PGSTD::string &definition);
582 
584 
590  void prepare(const PGSTD::string &definition);
591 
593  void unprepare(const PGSTD::string &name);
594 
596 
606  void prepare_now(const PGSTD::string &name);
607 
637 
638 
646  template<typename TRANSACTOR>
647  void perform(const TRANSACTOR &T, int Attempts); //[t4]
648 
650 
653  template<typename TRANSACTOR>
654  void perform(const TRANSACTOR &T) { perform(T, 3); }
655 
660 
661 
664  PGSTD::string adorn_name(const PGSTD::string &); //[90]
665 
734 
735  PGSTD::string esc(const char str[]);
736 
738  PGSTD::string esc(const char str[], size_t maxlen);
739 
741  PGSTD::string esc(const PGSTD::string &str);
742 
744  PGSTD::string esc_raw(const unsigned char str[], size_t len);
745 
747  PGSTD::string quote_raw(const unsigned char str[], size_t len);
748 
750  PGSTD::string quote_name(const PGSTD::string &identifier);
751 
753 
754  template<typename T>
755  PGSTD::string quote(const T &t)
756  {
757  if (string_traits<T>::is_null(t)) return "NULL";
758  return "'" + this->esc(to_string(t)) + "'";
759  }
760 
761  PGSTD::string quote(const binarystring &);
763 
765  void cancel_query();
766 
769  {
770  // These values must match those in libpq's PGVerbosity enum.
771  terse=0,
772  normal=1,
773  verbose=2
774  };
775 
777 
785  void set_verbosity(error_verbosity verbosity) throw();
787  error_verbosity get_verbosity() const throw() {return m_verbosity;}
788 
790 
802  PGSTD::vector<errorhandler *> get_errorhandlers() const;
803 
804 protected:
805  explicit connection_base(connectionpolicy &);
806  void init();
807 
808  void close() throw ();
809  void wait_read() const;
810  void wait_read(long seconds, long microseconds) const;
811  void wait_write() const;
812 
813 private:
814 
815  result make_result(internal::pq::PGresult *rhs, const PGSTD::string &query);
816 
817  void PQXX_PRIVATE clearcaps() throw ();
818  void PQXX_PRIVATE SetupState();
819  void PQXX_PRIVATE check_result(const result &);
820 
821  void PQXX_PRIVATE InternalSetTrace() throw ();
822  int PQXX_PRIVATE PQXX_PURE Status() const throw ();
823  const char * PQXX_PURE ErrMsg() const throw ();
824  void PQXX_PRIVATE Reset();
825  void PQXX_PRIVATE RestoreVars();
826  PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
827  void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
828 
829  void read_capabilities() throw ();
830 
831  prepare::internal::prepared_def &find_prepared(const PGSTD::string &);
832 
833  prepare::internal::prepared_def &register_prepared(const PGSTD::string &);
834 
835  friend class internal::gate::connection_prepare_invocation;
836  result prepared_exec(const PGSTD::string &,
837  const char *const[],
838  const int[],
839  const int[],
840  int);
841  bool prepared_exists(const PGSTD::string &) const;
842 
844  internal::pq::PGconn *m_Conn;
845 
846  connectionpolicy &m_policy;
847 
849  internal::unique<transaction_base> m_Trans;
850 
851  PGSTD::list<errorhandler *> m_errorhandlers;
852 
854  PGSTD::FILE *m_Trace;
855 
856  typedef PGSTD::multimap<PGSTD::string, pqxx::notification_receiver *>
857  receiver_list;
859  receiver_list m_receivers;
860 
862  PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
863 
864  typedef PGSTD::map<PGSTD::string, prepare::internal::prepared_def> PSMap;
865 
867  PSMap m_prepared;
868 
870  int m_serverversion;
871 
873  internal::reactivation_avoidance_counter m_reactivation_avoidance;
874 
876  int m_unique_id;
877 
879  bool m_Completed;
880 
882  bool m_inhibit_reactivation;
883 
885  PGSTD::bitset<cap_end> m_caps;
886 
888  error_verbosity m_verbosity;
889 
890  friend class internal::gate::connection_errorhandler;
891  void PQXX_PRIVATE register_errorhandler(errorhandler *);
892  void PQXX_PRIVATE unregister_errorhandler(errorhandler *) throw ();
893 
894  friend class internal::gate::connection_transaction;
895  result PQXX_PRIVATE Exec(const char[], int Retries);
896  void PQXX_PRIVATE RegisterTransaction(transaction_base *);
897  void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
898  bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
899  void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
900  void PQXX_PRIVATE EndCopyWrite();
901  void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
902  void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
903  PGSTD::string> &);
904 
905  friend class internal::gate::connection_largeobject;
906  internal::pq::PGconn *RawConnection() const { return m_Conn; }
907 
908  friend class internal::gate::connection_notification_receiver;
909  void add_receiver(notification_receiver *);
910  void remove_receiver(notification_receiver *) throw ();
911 
912  friend class internal::gate::connection_pipeline;
913  void PQXX_PRIVATE start_exec(const PGSTD::string &);
914  bool PQXX_PRIVATE consume_input() throw ();
915  bool PQXX_PRIVATE is_busy() const throw ();
916  int PQXX_PRIVATE encoding_code();
917  internal::pq::PGresult *get_result();
918 
919  friend class internal::gate::connection_dbtransaction;
920 
921  friend class internal::gate::connection_sql_cursor;
922  void add_reactivation_avoidance_count(int);
923 
924  friend class internal::gate::connection_reactivation_avoidance_exemption;
925 
926  friend class internal::gate::connection_parameterized_invocation;
927  result parameterized_exec(
928  const PGSTD::string &query,
929  const char *const params[],
930  const int paramlengths[],
931  const int binaries[],
932  int nparams);
933 
934  // Not allowed:
936  connection_base &operator=(const connection_base &);
937 };
938 
939 
940 
941 #ifdef PQXX_HAVE_AUTO_PTR
942 
943 struct PQXX_LIBEXPORT PQXX_NOVTABLE noticer :
944  PGSTD::unary_function<const char[], void>
945 {
946  virtual ~noticer() throw () {}
947  virtual void operator()(const char[]) throw () =0;
948 };
950 struct PQXX_LIBEXPORT nonnoticer : noticer
951 {
952  virtual void operator()(const char[]) throw () {}
953 };
955 class PQXX_LIBEXPORT scoped_noticer : errorhandler
956 {
957 public:
958  scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
959  errorhandler(c), m_noticer(t.release()) {}
960 protected:
961  scoped_noticer(connection_base &c, noticer *t) throw () :
962  errorhandler(c), m_noticer(t) {}
963  virtual bool operator()(const char msg[]) throw ()
964  {
965  (*m_noticer)(msg);
966  return false;
967  }
968 private:
969  PGSTD::auto_ptr<noticer> m_noticer;
970 };
972 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
973 {
974 public:
975  explicit disable_noticer(connection_base &c) :
976  scoped_noticer(c, new nonnoticer) {}
977 };
978 #endif
979 
980 
981 namespace internal
982 {
983 
986 {
987 public:
988  explicit reactivation_avoidance_exemption(connection_base &C);
990 
991  void close_connection() throw () { m_open = false; }
992 
993 private:
994  connection_base &m_home;
995  int m_count;
996  bool m_open;
997 };
998 
999 
1000 void wait_read(const internal::pq::PGconn *);
1001 void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
1002 void wait_write(const internal::pq::PGconn *);
1003 } // namespace pqxx::internal
1004 
1005 
1006 } // namespace pqxx
1007 
1008 #include "pqxx/compiler-internal-post.hxx"
1009 
1010 #endif