libpqxx 3.1.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-2009, 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 <map>
27 #include <memory>
28
29 #include "pqxx/except"
30 #include "pqxx/prepared_statement"
31 #include "pqxx/strconv"
32 #include "pqxx/util"
33
34
35 /* Use of the libpqxx library starts here.
36 *
37 * Everything that can be done with a database through libpqxx must go through
38 * a connection object derived from connection_base.
39 */
40
41 /* Methods tested in eg. self-test program test1 are marked with "//[t1]"
42 */
43
44 namespace pqxx
45 {
46 class result;
47 class transaction_base;
48 class notify_listener;
49 class connectionpolicy;
50
51 namespace internal
52 {
53 class reactivation_avoidance_exemption;
54 class sql_cursor;
55
56 class reactivation_avoidance_counter
57 {
58 public:
59 reactivation_avoidance_counter() : m_counter(0) {}
60
61 void add(int n) throw () { m_counter += n; }
62 void clear() throw () { m_counter = 0; }
63 int get() const throw () { return m_counter; }
64
65 private:
66 int m_counter;
67 };
68
69 }
70
76
77
82 struct PQXX_LIBEXPORT PQXX_NOVTABLE noticer :
83 PGSTD::unary_function<const char[], void>
84 {
85 noticer(){} // Silences bogus warning in some gcc versions
86 virtual ~noticer() throw () {}
87 virtual void operator()(const char Msg[]) throw () =0;
88 };
89
90
92 struct PQXX_LIBEXPORT nonnoticer : noticer
93 {
94 nonnoticer(){} // Silences bogus warning in some gcc versions
95 virtual void operator()(const char []) throw () {}
96 };
97
102
103
121 PGSTD::string PQXX_LIBEXPORT encrypt_password( //[t0]
122 const PGSTD::string &user,
123 const PGSTD::string &password);
124
125
126 namespace internal
127 {
128 namespace gate
129 {
130 class connection_dbtransaction;
131 class connection_largeobject;
132 class connection_notify_listener;
133 class connection_parameterized_invocation;
134 class connection_pipeline;
135 class connection_prepare_declaration;
136 class connection_prepare_invocation;
137 class connection_reactivation_avoidance_exemption;
138 class connection_sql_cursor;
139 class connection_transaction;
140 } // namespace pqxx::internal::gate
141 } // namespace pqxx::internal
142
143
145
178 class PQXX_LIBEXPORT connection_base
179 {
180 public:
182 void disconnect() throw (); //[t2]
183
185
189 bool is_open() const throw (); //[t1]
190
201
202
212 void activate(); //[t12]
213
215
223 void deactivate(); //[t12]
224
226
270 void inhibit_reactivation(bool inhibit) //[t86]
271 { m_inhibit_reactivation=inhibit; }
272
274
279 void simulate_failure(); //[t94]
281
291
293
305 PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
306 throw (); //[t14]
307 noticer *get_noticer() const throw () { return m_Noticer.get(); } //[t14]
308
310 void process_notice(const char[]) throw (); //[t14]
312 void process_notice(const PGSTD::string &) throw (); //[t14]
313
315
317 void trace(FILE *) throw (); //[t3]
318
327
328
331 const char *dbname(); //[t1]
332
334
337 const char *username(); //[t1]
338
340
343 const char *hostname(); //[t1]
344
346
349 const char *port(); //[t1]
350
352
361 int backendpid() const throw (); //[t1]
362
364
378 int sock() const throw (); //[t87]
379
390
392 enum capability
393 {
395 cap_prepared_statements,
396
398 cap_create_table_with_oids,
399
401 cap_nested_transactions,
402
404 cap_cursor_scroll,
406 cap_cursor_with_hold,
408 cap_cursor_update,
410 cap_cursor_fetch_0,
411
413 cap_table_column,
414
416 cap_read_only_transactions,
417
419 cap_statement_varargs,
420
422 cap_prepare_unnamed_statement,
423
425 cap_parameterized_statements,
426
428 cap_end
429 };
430
431
433
449 bool supports(capability c) const throw () { return m_caps.test(c); } //[t88]
450
452
464 int protocol_version() const throw (); //[t1]
465
467
479 int server_version() const throw (); //[t1]
481
483
489 void set_client_encoding(const PGSTD::string &Encoding) //[t7]
490 { set_variable("CLIENT_ENCODING", Encoding); }
491
493
509 void set_variable(const PGSTD::string &Var,
510 const PGSTD::string &Value); //[t60]
511
513
520 PGSTD::string get_variable(const PGSTD::string &); //[t60]
522
523
528
529
541 int get_notifs(); //[t4]
542
543
545
551 int await_notification(); //[t78]
552
554
560 int await_notification(long seconds, long microseconds); //[t79]
562
563
600
601
643 prepare::declaration prepare(const PGSTD::string &name,
644 const PGSTD::string &definition);
645
647
653 prepare::declaration prepare(const PGSTD::string &definition);
654
656 void unprepare(const PGSTD::string &name);
657
659
669 void prepare_now(const PGSTD::string &name);
670
700
701
709 template<typename TRANSACTOR>
710 void perform(const TRANSACTOR &T, int Attempts); //[t4]
711
713
716 template<typename TRANSACTOR>
717 void perform(const TRANSACTOR &T) { perform(T, 3); }
718
723
724
727 PGSTD::string adorn_name(const PGSTD::string &); //[90]
728
797
798 PGSTD::string esc(const char str[]);
799
801 PGSTD::string esc(const char str[], size_t maxlen);
802
804 PGSTD::string esc(const PGSTD::string &str);
805
807 PGSTD::string esc_raw(const unsigned char str[], size_t len);
808
810
811 template<typename T>
812 PGSTD::string quote(const T &t)
813 {
814 if (string_traits<T>::is_null(t)) return "NULL";
815 return "'" + this->esc(to_string(t)) + "'";
816 }
818
820 void cancel_query();
821
822 protected:
823 explicit connection_base(connectionpolicy &);
824 void init();
825
826 void close() throw ();
827 void wait_read() const;
828 void wait_read(long seconds, long microseconds) const;
829 void wait_write() const;
830
831 private:
832 result make_result(internal::pq::PGresult *rhs, const PGSTD::string &query);
833
834 void PQXX_PRIVATE clearcaps() throw ();
835 void PQXX_PRIVATE SetupState();
836 void PQXX_PRIVATE check_result(const result &);
837
838 void PQXX_PRIVATE InternalSetTrace() throw ();
839 int PQXX_PRIVATE Status() const throw ();
840 const char *ErrMsg() const throw ();
841 void PQXX_PRIVATE Reset();
842 void PQXX_PRIVATE RestoreVars();
843 PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
844 void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
845 void switchnoticer(const PGSTD::auto_ptr<noticer> &) throw ();
846
847 void read_capabilities() throw ();
848
849 prepare::internal::prepared_def &find_prepared(const PGSTD::string &);
850
851 friend class internal::gate::connection_prepare_declaration;
852 void prepare_param_declare(
853 const PGSTD::string &statement,
854 const PGSTD::string &sqltype,
855 prepare::param_treatment);
856 void prepare_param_declare_varargs(
857 const PGSTD::string &statement,
858 prepare::param_treatment);
859
860 prepare::internal::prepared_def &register_prepared(const PGSTD::string &);
861
862 friend class internal::gate::connection_prepare_invocation;
863 result prepared_exec(const PGSTD::string &,
864 const char *const[],
865 const int[],
866 int);
867 bool prepared_exists(const PGSTD::string &) const;
868
870 internal::pq::PGconn *m_Conn;
871
872 connectionpolicy &m_policy;
873
875 internal::unique<transaction_base> m_Trans;
876
878 PGSTD::auto_ptr<noticer> m_Noticer;
879
881
885 internal::pq::PQnoticeProcessor m_defaultNoticeProcessor;
886
888 FILE *m_Trace;
889
890 typedef PGSTD::multimap<PGSTD::string, pqxx::notify_listener *> listenerlist;
892 listenerlist m_listeners;
893
895 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
896
897 typedef PGSTD::map<PGSTD::string, prepare::internal::prepared_def> PSMap;
898
900 PSMap m_prepared;
901
903 int m_serverversion;
904
906 internal::reactivation_avoidance_counter m_reactivation_avoidance;
907
909 int m_unique_id;
910
912 bool m_Completed;
913
915 bool m_inhibit_reactivation;
916
918 PGSTD::bitset<cap_end> m_caps;
919
920 friend class internal::gate::connection_transaction;
921 result PQXX_PRIVATE Exec(const char[], int Retries);
922 void PQXX_PRIVATE RegisterTransaction(transaction_base *);
923 void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
924 bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
925 void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
926 void PQXX_PRIVATE EndCopyWrite();
927 void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
928 void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
929 PGSTD::string> &);
930
931 friend class internal::gate::connection_largeobject;
932 internal::pq::PGconn *RawConnection() const { return m_Conn; }
933
934 friend class internal::gate::connection_notify_listener;
935 void add_listener(notify_listener *);
936 void remove_listener(notify_listener *) throw ();
937
938 friend class internal::gate::connection_pipeline;
939 void PQXX_PRIVATE start_exec(const PGSTD::string &);
940 bool PQXX_PRIVATE consume_input() throw ();
941 bool PQXX_PRIVATE is_busy() const throw ();
942 int PQXX_PRIVATE encoding_code() throw ();
943 internal::pq::PGresult *get_result();
944
945 friend class internal::gate::connection_dbtransaction;
946
947 friend class internal::gate::connection_sql_cursor;
948 void add_reactivation_avoidance_count(int);
949
950 friend class internal::gate::connection_reactivation_avoidance_exemption;
951
952 friend class internal::gate::connection_parameterized_invocation;
953 result parameterized_exec(
954 const PGSTD::string &query,
955 const char *const params[],
956 const int paramlengths[],
957 int nparams);
958
959 // Not allowed:
960 connection_base(const connection_base &);
961 connection_base &operator=(const connection_base &);
962 };
963
964
965
967
973 class PQXX_LIBEXPORT scoped_noticer
974 {
975 public:
977
981 scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
982 m_c(c), m_org(c.set_noticer(t)) { }
983
984 ~scoped_noticer() { m_c.set_noticer(m_org); }
985
986 protected:
988
992 scoped_noticer(connection_base &c, noticer *t) throw () :
993 m_c(c),
994 m_org()
995 {
996 PGSTD::auto_ptr<noticer> x(t);
997 PGSTD::auto_ptr<noticer> y(c.set_noticer(x));
998 m_org = y;
999 }
1000
1001 private:
1002 connection_base &m_c;
1003 PGSTD::auto_ptr<noticer> m_org;
1004
1006 scoped_noticer();
1007 scoped_noticer(const scoped_noticer &);
1008 scoped_noticer operator=(const scoped_noticer &);
1009 };
1010
1011
1013 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
1014 {
1015 public:
1016 explicit disable_noticer(connection_base &c) :
1017 scoped_noticer(c, new nonnoticer) {}
1018 };
1019
1020
1021 namespace internal
1022 {
1023
1025 class PQXX_LIBEXPORT reactivation_avoidance_exemption
1026 {
1027 public:
1028 explicit reactivation_avoidance_exemption(connection_base &C);
1029 ~reactivation_avoidance_exemption();
1030
1031 void close_connection() throw () { m_open = false; }
1032
1033 private:
1034 connection_base &m_home;
1035 int m_count;
1036 bool m_open;
1037 };
1038
1039
1040 void wait_read(const internal::pq::PGconn *);
1041 void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
1042 void wait_write(const internal::pq::PGconn *);
1043 } // namespace pqxx::internal
1044
1045
1046 } // namespace pqxx
1047
1048 #include "pqxx/compiler-internal-post.hxx"
1049
1050 #endif
1051