libpqxx: connection_base.hxx Source File

libpqxx 4.0.1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes

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 {
56 class reactivation_avoidance_exemption;
57 class sql_cursor;
58
59 class reactivation_avoidance_counter
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
336 enum capability
337 {
339 cap_prepared_statements,
340
342 cap_create_table_with_oids,
343
345 cap_nested_transactions,
346
348 cap_cursor_scroll,
350 cap_cursor_with_hold,
352 cap_cursor_update,
354 cap_cursor_fetch_0,
355
357 cap_table_column,
358
360 cap_read_only_transactions,
361
363 cap_statement_varargs,
364
366 cap_prepare_unnamed_statement,
367
369 cap_parameterized_statements,
370
372 cap_notify_payload,
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
768 enum error_verbosity
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:
935 connection_base(const connection_base &);
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
985 class PQXX_LIBEXPORT reactivation_avoidance_exemption
986 {
987 public:
988 explicit reactivation_avoidance_exemption(connection_base &C);
989 ~reactivation_avoidance_exemption();
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