00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pqxx/compiler-public.hxx"
00020 #include "pqxx/compiler-internal-pre.hxx"
00021
00022 #include <map>
00023 #include <memory>
00024
00025 #include "pqxx/except"
00026 #include "pqxx/prepared_statement"
00027 #include "pqxx/util"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 namespace pqxx
00040 {
00041 class result;
00042 class transaction_base;
00043 class trigger;
00044 class connectionpolicy;
00045
00046 namespace internal
00047 {
00048 class reactivation_avoidance_exemption;
00049
00050 class reactivation_avoidance_counter
00051 {
00052 public:
00053 reactivation_avoidance_counter() : m_counter(0) {}
00054
00055 void add(int n) throw () { m_counter += n; }
00056 void clear() throw () { m_counter = 0; }
00057 int get() const throw () { return m_counter; }
00058
00059 void give_to(reactivation_avoidance_counter &rhs) throw ()
00060 {
00061 rhs.add(m_counter);
00062 clear();
00063 }
00064
00065 private:
00066 int m_counter;
00067 };
00068
00069 }
00070
00076
00077
00082 struct PQXX_LIBEXPORT noticer : PGSTD::unary_function<const char[], void>
00083 {
00084 noticer(){}
00085 virtual ~noticer() throw () {}
00086 virtual void operator()(const char Msg[]) throw () =0;
00087 };
00088
00089
00091 struct PQXX_LIBEXPORT nonnoticer : noticer
00092 {
00093 nonnoticer(){}
00094 virtual void operator()(const char []) throw () {}
00095 };
00096
00101
00102
00120 PGSTD::string encrypt_password(const PGSTD::string &user,
00121 const PGSTD::string &password);
00122
00124
00149 class PQXX_LIBEXPORT connection_base
00150 {
00151 public:
00153 void disconnect() throw ();
00154
00156
00160 bool is_open() const throw ();
00161
00172
00173
00183 void activate();
00184
00186
00194 void deactivate();
00195
00197
00241 void inhibit_reactivation(bool inhibit)
00242 { m_inhibit_reactivation=inhibit; }
00243
00245
00250 void simulate_failure();
00252
00262
00264
00276 PGSTD::auto_ptr<noticer> set_noticer(PGSTD::auto_ptr<noticer> N)
00277 throw ();
00278 noticer *get_noticer() const throw () { return m_Noticer.get(); }
00279
00281 void process_notice(const char[]) throw ();
00283 void process_notice(const PGSTD::string &) throw ();
00284
00286
00288 void trace(FILE *) throw ();
00289
00298
00299 const char *dbname();
00300
00302 const char *username();
00303
00305 const char *hostname();
00306
00308 const char *port();
00309
00311
00320 int backendpid() const throw ();
00321
00323
00337 int sock() const throw ();
00338
00349
00351 enum capability
00352 {
00354 cap_prepared_statements,
00355
00357 cap_create_table_with_oids,
00358
00360 cap_nested_transactions,
00361
00363 cap_cursor_scroll,
00365 cap_cursor_with_hold,
00367 cap_cursor_update,
00368
00370 cap_table_column,
00371
00373 cap_end
00374 };
00375
00376
00378
00395 bool supports(capability c) const throw () { return m_caps[c]; }
00396
00398
00410 int protocol_version() const throw ();
00411
00413
00425 int server_version() const throw ();
00427
00429
00435 void set_client_encoding(const PGSTD::string &Encoding)
00436 { set_variable("CLIENT_ENCODING", Encoding); }
00437
00439
00455 void set_variable(const PGSTD::string &Var,
00456 const PGSTD::string &Value);
00457
00459
00466 PGSTD::string get_variable(const PGSTD::string &);
00468
00469
00474
00475
00486 int get_notifs();
00487
00488
00490
00496 int await_notification();
00497
00499
00505 int await_notification(long seconds, long microseconds);
00507
00508
00540
00541
00576 prepare::declaration prepare(const PGSTD::string &name,
00577 const PGSTD::string &definition);
00578
00580 void unprepare(const PGSTD::string &name);
00581
00583
00593 void prepare_now(const PGSTD::string &name);
00594
00624
00625
00633 template<typename TRANSACTOR>
00634 void perform(const TRANSACTOR &T, int Attempts);
00635
00637
00640 template<typename TRANSACTOR>
00641 void perform(const TRANSACTOR &T) { perform(T, 3); }
00642
00647
00648
00651 PGSTD::string adorn_name(const PGSTD::string &);
00652
00653
00654 protected:
00655 explicit connection_base(connectionpolicy &);
00656 void init();
00657
00658 void close() throw ();
00659 void wait_read() const;
00660 void wait_read(long seconds, long microseconds) const;
00661 void wait_write() const;
00662
00663 private:
00664 void PQXX_PRIVATE clearcaps() throw ();
00665 void PQXX_PRIVATE SetupState();
00666 void PQXX_PRIVATE check_result(const result &);
00667
00668 void PQXX_PRIVATE InternalSetTrace() throw ();
00669 int PQXX_PRIVATE Status() const throw ();
00670 const char *ErrMsg() const throw ();
00671 void PQXX_PRIVATE Reset();
00672 void PQXX_PRIVATE RestoreVars();
00673 PGSTD::string PQXX_PRIVATE RawGetVar(const PGSTD::string &);
00674 void PQXX_PRIVATE process_notice_raw(const char msg[]) throw ();
00675 void switchnoticer(const PGSTD::auto_ptr<noticer> &) throw ();
00676
00677 void read_capabilities() throw ();
00678
00679 friend class subtransaction;
00680 void set_capability(capability) throw ();
00681
00682 prepare::internal::prepared_def &find_prepared(const PGSTD::string &);
00683
00684 friend class prepare::declaration;
00685 void prepare_param_declare(const PGSTD::string &statement,
00686 const PGSTD::string &sqltype,
00687 prepare::param_treatment);
00688
00689 prepare::internal::prepared_def ®ister_prepared(const PGSTD::string &);
00690 result prepared_exec(const PGSTD::string &,
00691 const char *const[],
00692 const int[],
00693 int);
00694
00696 internal::pq::PGconn *m_Conn;
00697
00698 connectionpolicy &m_policy;
00699
00701 bool m_Completed;
00702
00704 internal::unique<transaction_base> m_Trans;
00705
00707 PGSTD::auto_ptr<noticer> m_Noticer;
00708
00710
00714 internal::pq::PQnoticeProcessor m_defaultNoticeProcessor;
00715
00717 FILE *m_Trace;
00718
00719 typedef PGSTD::multimap<PGSTD::string, pqxx::trigger *> TriggerList;
00721 TriggerList m_Triggers;
00722
00724 PGSTD::map<PGSTD::string, PGSTD::string> m_Vars;
00725
00726 typedef PGSTD::map<PGSTD::string, prepare::internal::prepared_def> PSMap;
00727
00729 PSMap m_prepared;
00730
00732 int m_serverversion;
00733
00735 bool m_caps[cap_end];
00736
00738 bool m_inhibit_reactivation;
00739
00741 internal::reactivation_avoidance_counter m_reactivation_avoidance;
00742
00744 int m_unique_id;
00745
00746 friend class transaction_base;
00747 result PQXX_PRIVATE Exec(const char[], int Retries);
00748 result pq_exec_prepared(const PGSTD::string &, int, const char *const *);
00749 void PQXX_PRIVATE RegisterTransaction(transaction_base *);
00750 void PQXX_PRIVATE UnregisterTransaction(transaction_base *) throw ();
00751 void PQXX_PRIVATE MakeEmpty(result &);
00752 bool PQXX_PRIVATE ReadCopyLine(PGSTD::string &);
00753 void PQXX_PRIVATE WriteCopyLine(const PGSTD::string &);
00754 void PQXX_PRIVATE EndCopyWrite();
00755 void PQXX_PRIVATE start_exec(const PGSTD::string &);
00756 internal::pq::PGresult *get_result();
00757 PGSTD::string esc(const char str[], size_t maxlen);
00758 PGSTD::string esc_raw(const unsigned char str[], size_t len);
00759
00760 void PQXX_PRIVATE RawSetVar(const PGSTD::string &, const PGSTD::string &);
00761 void PQXX_PRIVATE AddVariables(const PGSTD::map<PGSTD::string,
00762 PGSTD::string> &);
00763
00764 friend class largeobject;
00765 internal::pq::PGconn *RawConnection() const { return m_Conn; }
00766
00767 friend class trigger;
00768 void AddTrigger(trigger *);
00769 void RemoveTrigger(trigger *) throw ();
00770
00771 friend class pipeline;
00772 bool PQXX_PRIVATE consume_input() throw ();
00773 bool PQXX_PRIVATE is_busy() const throw ();
00774
00775 friend class cursor_base;
00776 friend class dbtransaction;
00777 friend class internal::reactivation_avoidance_exemption;
00778
00779
00780 connection_base(const connection_base &);
00781 connection_base &operator=(const connection_base &);
00782 };
00783
00784
00785
00787
00793 class PQXX_LIBEXPORT scoped_noticer
00794 {
00795 public:
00797
00801 scoped_noticer(connection_base &c, PGSTD::auto_ptr<noticer> t) throw () :
00802 m_c(c), m_org(c.set_noticer(t)) { }
00803
00804 ~scoped_noticer() { m_c.set_noticer(m_org); }
00805
00806 protected:
00808
00812 scoped_noticer(connection_base &c, noticer *t) throw () :
00813 m_c(c),
00814 m_org()
00815 {
00816 PGSTD::auto_ptr<noticer> x(t);
00817 PGSTD::auto_ptr<noticer> y(c.set_noticer(x));
00818 m_org = y;
00819 }
00820
00821 private:
00822 connection_base &m_c;
00823 PGSTD::auto_ptr<noticer> m_org;
00824
00826 scoped_noticer();
00827 scoped_noticer(const scoped_noticer &);
00828 scoped_noticer operator=(const scoped_noticer &);
00829 };
00830
00831
00833 class PQXX_LIBEXPORT disable_noticer : scoped_noticer
00834 {
00835 public:
00836 explicit disable_noticer(connection_base &c) :
00837 scoped_noticer(c, new nonnoticer) {}
00838 };
00839
00840
00841 namespace internal
00842 {
00843
00845 class PQXX_LIBEXPORT reactivation_avoidance_exemption
00846 {
00847 public:
00848 explicit reactivation_avoidance_exemption(connection_base &C) :
00849 m_home(C),
00850 m_count(C.m_reactivation_avoidance.get()),
00851 m_open(C.is_open())
00852 {
00853 C.m_reactivation_avoidance.clear();
00854 }
00855
00856 ~reactivation_avoidance_exemption()
00857 {
00858
00859
00860 if (m_count && !m_open) m_home.deactivate();
00861 m_home.m_reactivation_avoidance.add(m_count);
00862 }
00863
00864 void close_connection() throw () { m_open = false; }
00865
00866 private:
00867 connection_base &m_home;
00868 int m_count;
00869 bool m_open;
00870 };
00871
00872
00873 void wait_read(const internal::pq::PGconn *);
00874 void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
00875 void wait_write(const internal::pq::PGconn *);
00876 }
00877
00878
00879 }
00880
00881 #include "pqxx/compiler-internal-post.hxx"