connection_base.hxx
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef PQXX_H_CONNECTION_BASE
00020 #define PQXX_H_CONNECTION_BASE
00021
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024
00025 #include <bitset>
00026 #include <list>
00027 #include <map>
00028 #include <memory>
00029
00030 #include "pqxx/errorhandler"
00031 #include "pqxx/except"
00032 #include "pqxx/prepared_statement"
00033 #include "pqxx/strconv"
00034 #include "pqxx/util"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 namespace pqxx
00047 {
00048 class binarystring;
00049 class connectionpolicy;
00050 class notification_receiver;
00051 class result;
00052 class transaction_base;
00053
00054 namespace internal
00055 {
00056 class reactivation_avoidance_exemption;
00057 class sql_cursor;
00058
00059 class reactivation_avoidance_counter
00060 {
00061 public:
00062 reactivation_avoidance_counter() : m_counter(0) {}
00063
00064 void add(int n) PQXX_NOEXCEPT { m_counter += n; }
00065 void clear() PQXX_NOEXCEPT { m_counter = 0; }
00066 int get() const PQXX_NOEXCEPT { return m_counter; }
00067
00068 private:
00069 int m_counter;
00070 };
00071
00072 }
00073
00074
00076
00092 std::string PQXX_LIBEXPORT encrypt_password(
00093 const std::string &user,
00094 const std::string &password);
00095
00096
00097 namespace internal
00098 {
00099 namespace gate
00100 {
00101 class connection_dbtransaction;
00102 class connection_errorhandler;
00103 class connection_largeobject;
00104 class connection_notification_receiver;
00105 class connection_parameterized_invocation;
00106 class connection_pipeline;
00107 class connection_prepare_invocation;
00108 class connection_reactivation_avoidance_exemption;
00109 class connection_sql_cursor;
00110 class connection_transaction;
00111 }
00112 }
00113
00114
00116
00149 class PQXX_LIBEXPORT connection_base
00150 {
00151 public:
00153 void disconnect() PQXX_NOEXCEPT;
00154
00156
00160 bool PQXX_PURE is_open() const PQXX_NOEXCEPT;
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
00254 void process_notice(const char[]) PQXX_NOEXCEPT;
00256 void process_notice(const std::string &) PQXX_NOEXCEPT;
00257
00259 void trace(std::FILE *) PQXX_NOEXCEPT;
00260
00269
00270
00273 const char *dbname();
00274
00276
00279 const char *username();
00280
00282
00285 const char *hostname();
00286
00288
00291 const char *port();
00292
00294
00303 int PQXX_PURE backendpid() const PQXX_NOEXCEPT;
00304
00306
00320 int PQXX_PURE sock() const PQXX_NOEXCEPT;
00321
00330
00332 enum capability
00333 {
00337 cap_prepared_statements,
00341 cap_create_table_with_oids,
00345 cap_nested_transactions,
00349 cap_cursor_scroll,
00353 cap_cursor_with_hold,
00357 cap_cursor_update,
00361 cap_cursor_fetch_0,
00365 cap_table_column,
00369 cap_read_only_transactions,
00373 cap_statement_varargs,
00377 cap_prepare_unnamed_statement,
00381 cap_parameterized_statements,
00385 cap_notify_payload,
00386
00388 cap_end
00389 };
00390
00391
00393
00409 bool supports(capability c) const PQXX_NOEXCEPT
00410 { return m_caps.test(c); }
00411
00413
00421 int PQXX_PURE protocol_version() const PQXX_NOEXCEPT;
00422
00424
00436 int PQXX_PURE server_version() const PQXX_NOEXCEPT;
00438
00440
00446 void set_client_encoding(const std::string &Encoding)
00447 { set_variable("CLIENT_ENCODING", Encoding); }
00448
00450
00466 void set_variable(const std::string &Var,
00467 const std::string &Value);
00468
00470
00477 std::string get_variable(const std::string &);
00479
00480
00485
00486
00498 int get_notifs();
00499
00500
00502
00508 int await_notification();
00509
00511
00517 int await_notification(long seconds, long microseconds);
00519
00520
00557
00558
00591 void prepare(const std::string &name, const std::string &definition);
00592
00594
00600 void prepare(const std::string &definition);
00601
00603 void unprepare(const std::string &name);
00604
00606
00616 void prepare_now(const std::string &name);
00617
00647
00648
00656 template<typename TRANSACTOR>
00657 void perform(const TRANSACTOR &T, int Attempts);
00658
00660
00663 template<typename TRANSACTOR>
00664 void perform(const TRANSACTOR &T) { perform(T, 3); }
00665
00670
00671
00674 std::string adorn_name(const std::string &);
00675
00744
00745 std::string esc(const char str[]);
00746
00748 std::string esc(const char str[], size_t maxlen);
00749
00751 std::string esc(const std::string &str);
00752
00754 std::string esc_raw(const unsigned char str[], size_t len);
00755
00757
00760 std::string unesc_raw(const std::string &text)
00761 { return unesc_raw(text.c_str()); }
00762
00764
00767 std::string unesc_raw(const char *text);
00768
00770 std::string quote_raw(const unsigned char str[], size_t len);
00771
00773 std::string quote_name(const std::string &identifier);
00774
00776
00777 template<typename T>
00778 std::string quote(const T &t)
00779 {
00780 if (string_traits<T>::is_null(t)) return "NULL";
00781 return "'" + this->esc(to_string(t)) + "'";
00782 }
00783
00784 std::string quote(const binarystring &);
00786
00788 void cancel_query();
00789
00791 enum error_verbosity
00792 {
00793
00794 terse=0,
00795 normal=1,
00796 verbose=2
00797 };
00798
00800
00808 void set_verbosity(error_verbosity verbosity) PQXX_NOEXCEPT;
00810 error_verbosity get_verbosity() const PQXX_NOEXCEPT {return m_verbosity;}
00811
00813
00825 std::vector<errorhandler *> get_errorhandlers() const;
00826
00827 protected:
00828 explicit connection_base(connectionpolicy &);
00829 void init();
00830
00831 void close() PQXX_NOEXCEPT;
00832 void wait_read() const;
00833 void wait_read(long seconds, long microseconds) const;
00834 void wait_write() const;
00835
00836 private:
00837
00838 result make_result(internal::pq::PGresult *rhs, const std::string &query);
00839
00840 void PQXX_PRIVATE clearcaps() PQXX_NOEXCEPT;
00841 void PQXX_PRIVATE SetupState();
00842 void PQXX_PRIVATE check_result(const result &);
00843
00844 void PQXX_PRIVATE InternalSetTrace() PQXX_NOEXCEPT;
00845 int PQXX_PRIVATE PQXX_PURE Status() const PQXX_NOEXCEPT;
00846 const char * PQXX_PURE ErrMsg() const PQXX_NOEXCEPT;
00847 void PQXX_PRIVATE Reset();
00848 void PQXX_PRIVATE RestoreVars();
00849 std::string PQXX_PRIVATE RawGetVar(const std::string &);
00850 void PQXX_PRIVATE process_notice_raw(const char msg[]) PQXX_NOEXCEPT;
00851
00852 void read_capabilities();
00853
00854 prepare::internal::prepared_def &find_prepared(const std::string &);
00855
00856 prepare::internal::prepared_def ®ister_prepared(const std::string &);
00857
00858 friend class internal::gate::connection_prepare_invocation;
00859 result prepared_exec(const std::string &,
00860 const char *const[],
00861 const int[],
00862 const int[],
00863 int);
00864 bool prepared_exists(const std::string &) const;
00865
00867 internal::pq::PGconn *m_Conn;
00868
00869 connectionpolicy &m_policy;
00870
00872 internal::unique<transaction_base> m_Trans;
00873
00874 std::list<errorhandler *> m_errorhandlers;
00875
00877 std::FILE *m_Trace;
00878
00879 typedef std::multimap<std::string, pqxx::notification_receiver *>
00880 receiver_list;
00882 receiver_list m_receivers;
00883
00885 std::map<std::string, std::string> m_Vars;
00886
00887 typedef std::map<std::string, prepare::internal::prepared_def> PSMap;
00888
00890 PSMap m_prepared;
00891
00893 int m_serverversion;
00894
00896 internal::reactivation_avoidance_counter m_reactivation_avoidance;
00897
00899 int m_unique_id;
00900
00902 bool m_Completed;
00903
00905 bool m_inhibit_reactivation;
00906
00908 std::bitset<cap_end> m_caps;
00909
00911 error_verbosity m_verbosity;
00912
00913 friend class internal::gate::connection_errorhandler;
00914 void PQXX_PRIVATE register_errorhandler(errorhandler *);
00915 void PQXX_PRIVATE unregister_errorhandler(errorhandler *) PQXX_NOEXCEPT;
00916
00917 friend class internal::gate::connection_transaction;
00918 result PQXX_PRIVATE Exec(const char[], int Retries);
00919 void PQXX_PRIVATE RegisterTransaction(transaction_base *);
00920 void PQXX_PRIVATE UnregisterTransaction(transaction_base *) PQXX_NOEXCEPT;
00921 bool PQXX_PRIVATE ReadCopyLine(std::string &);
00922 void PQXX_PRIVATE WriteCopyLine(const std::string &);
00923 void PQXX_PRIVATE EndCopyWrite();
00924 void PQXX_PRIVATE RawSetVar(const std::string &, const std::string &);
00925 void PQXX_PRIVATE AddVariables(const std::map<std::string, std::string> &);
00926
00927 friend class internal::gate::connection_largeobject;
00928 internal::pq::PGconn *RawConnection() const { return m_Conn; }
00929
00930 friend class internal::gate::connection_notification_receiver;
00931 void add_receiver(notification_receiver *);
00932 void remove_receiver(notification_receiver *) PQXX_NOEXCEPT;
00933
00934 friend class internal::gate::connection_pipeline;
00935 void PQXX_PRIVATE start_exec(const std::string &);
00936 bool PQXX_PRIVATE consume_input() PQXX_NOEXCEPT;
00937 bool PQXX_PRIVATE is_busy() const PQXX_NOEXCEPT;
00938 int PQXX_PRIVATE encoding_code();
00939 internal::pq::PGresult *get_result();
00940
00941 friend class internal::gate::connection_dbtransaction;
00942
00943 friend class internal::gate::connection_sql_cursor;
00944 void add_reactivation_avoidance_count(int);
00945
00946 friend class internal::gate::connection_reactivation_avoidance_exemption;
00947
00948 friend class internal::gate::connection_parameterized_invocation;
00949 result parameterized_exec(
00950 const std::string &query,
00951 const char *const params[],
00952 const int paramlengths[],
00953 const int binaries[],
00954 int nparams);
00955
00956
00957 connection_base(const connection_base &) PQXX_DELETED_OP;
00958 connection_base &operator=(const connection_base &) PQXX_DELETED_OP;
00959 };
00960
00961
00962 namespace internal
00963 {
00964
00966 class PQXX_LIBEXPORT reactivation_avoidance_exemption
00967 {
00968 public:
00969 explicit reactivation_avoidance_exemption(connection_base &C);
00970 ~reactivation_avoidance_exemption();
00971
00972 void close_connection() PQXX_NOEXCEPT { m_open = false; }
00973
00974 private:
00975 connection_base &m_home;
00976 int m_count;
00977 bool m_open;
00978 };
00979
00980
00981 void wait_read(const internal::pq::PGconn *);
00982 void wait_read(const internal::pq::PGconn *, long seconds, long microseconds);
00983 void wait_write(const internal::pq::PGconn *);
00984 }
00985
00986
00987 }
00988
00989 #include "pqxx/compiler-internal-post.hxx"
00990
00991 #endif