PageRenderTime 38ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/pq/connection.h

http://github.com/mozy/mordor
C Header | 173 lines | 125 code | 30 blank | 18 comment | 0 complexity | b79c66da14f1263150fd97160ba47c26 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifndef __MORDOR_PQ_CONNECTION_H__
  2. #define __MORDOR_PQ_CONNECTION_H__
  3. // Copyright (c) 2010 Mozy, Inc.
  4. #include <boost/noncopyable.hpp>
  5. #include <boost/date_time/posix_time/posix_time_types.hpp>
  6. #include "exception.h"
  7. #include "preparedstatement.h"
  8. namespace Mordor {
  9. class Stream;
  10. namespace PQ {
  11. class Connection : boost::noncopyable
  12. {
  13. public:
  14. Connection(const std::string &conninfo, IOManager *ioManager = NULL,
  15. Scheduler *scheduler = NULL,
  16. bool connectImmediately = true);
  17. ConnStatusType status();
  18. void connect();
  19. /// @brief Resets the communication channel to the server.
  20. /// This function will close the connection to the server and attempt to
  21. /// reestablish a new connection to the same server, using all the same
  22. /// parameters previously used. This may be useful for error recovery if a
  23. /// working connection is lost.
  24. void reset();
  25. std::string escape(const std::string &string);
  26. std::string escapeBinary(const std::string &blob);
  27. /// @param name If non-empty, specifies to prepare this command on the
  28. /// server. Statements prepared on the server msut have unique names
  29. /// (per-connection)
  30. PreparedStatement prepare(const std::string &command,
  31. const std::string &name = std::string(), PreparedStatement::ResultFormat = PreparedStatement::BINARY);
  32. /// Create a PreparedStatement object representing a previously prepared
  33. /// statement on the server
  34. PreparedStatement find(const std::string &name);
  35. #define PQ_EXCEPTION_WRAPPER_EXECUTE(code) \
  36. try { \
  37. return code; \
  38. } catch (Mordor::PQ::Exception &) { \
  39. m_exceptioned = true; \
  40. throw; \
  41. }
  42. Result execute(const std::string &command)
  43. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute()); }
  44. template <class T1>
  45. Result execute(const std::string &command, const T1 &param1)
  46. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1)); }
  47. template <class T1, class T2>
  48. Result execute(const std::string &command, const T1 &param1, const T2 &param2)
  49. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2)); }
  50. template <class T1, class T2, class T3>
  51. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3)
  52. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3)); }
  53. template <class T1, class T2, class T3, class T4>
  54. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4)
  55. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4)); }
  56. template <class T1, class T2, class T3, class T4, class T5>
  57. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4, const T5 &param5)
  58. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4, param5)); }
  59. template <class T1, class T2, class T3, class T4, class T5, class T6>
  60. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4, const T5 &param5, const T6 &param6)
  61. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4, param5, param6)); }
  62. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
  63. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4, const T5 &param5, const T6 &param6, const T7 &param7)
  64. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4, param5, param6, param7)); }
  65. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
  66. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4, const T5 &param5, const T6 &param6, const T7 &param7, const T8 &param8)
  67. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4, param5, param6, param7, param8)); }
  68. template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
  69. Result execute(const std::string &command, const T1 &param1, const T2 &param2, const T3 &param3, const T4 &param4, const T5 &param5, const T6 &param6, const T7 &param7, const T8 &param8, const T9 &param9)
  70. { PQ_EXCEPTION_WRAPPER_EXECUTE(prepare(command).execute(param1, param2, param3, param4, param5, param6, param7, param8, param9)); }
  71. #undef PQ_EXCEPTION_WRAPPER_EXECUTE
  72. /// Bulk copy data to the server
  73. struct CopyParams
  74. {
  75. protected:
  76. CopyParams(const std::string &table, boost::shared_ptr<PGconn> conn,
  77. SchedulerType *scheduler);
  78. public:
  79. /// Execute
  80. virtual boost::shared_ptr<Stream> operator()() = 0;
  81. CopyParams &columns(const std::vector<std::string> &columns);
  82. CopyParams &binary();
  83. CopyParams &csv();
  84. CopyParams &delimiter(char delimiter);
  85. CopyParams &nullString(const std::string &nullString);
  86. CopyParams &header();
  87. CopyParams &quote(char quote);
  88. CopyParams &escape(char escape);
  89. CopyParams &notNullQuoteColumns(const std::vector<std::string> &columns);
  90. protected:
  91. boost::shared_ptr<Stream> execute(bool out);
  92. private:
  93. std::string m_table;
  94. SchedulerType *m_scheduler;
  95. boost::shared_ptr<PGconn> m_conn;
  96. std::vector<std::string> m_columns, m_notNullQuoteColumns;
  97. bool m_binary, m_csv, m_header;
  98. char m_delimiter, m_quote, m_escape;
  99. std::string m_nullString;
  100. };
  101. struct CopyInParams : public CopyParams
  102. {
  103. private:
  104. friend class Connection;
  105. CopyInParams(const std::string &table, boost::shared_ptr<PGconn> conn,
  106. SchedulerType *scheduler)
  107. : CopyParams(table, conn, scheduler)
  108. {}
  109. public:
  110. /// Execute
  111. boost::shared_ptr<Stream> operator()();
  112. };
  113. struct CopyOutParams : public CopyParams
  114. {
  115. private:
  116. friend class Connection;
  117. CopyOutParams(const std::string &table, boost::shared_ptr<PGconn> conn,
  118. SchedulerType *scheduler)
  119. : CopyParams(table, conn, scheduler)
  120. {}
  121. public:
  122. /// Execute
  123. boost::shared_ptr<Stream> operator()();
  124. };
  125. /// See http://www.postgresql.org/docs/current/static/sql-copy.html for the
  126. /// data format the server is expecting
  127. CopyInParams copyIn(const std::string &table);
  128. CopyOutParams copyOut(const std::string &table);
  129. const PGconn *conn() const { return m_conn.get(); }
  130. private:
  131. std::string m_conninfo;
  132. SchedulerType *m_scheduler;
  133. boost::shared_ptr<PGconn> m_conn;
  134. bool m_exceptioned;
  135. };
  136. // Internal functions
  137. #ifndef WIN32
  138. void flush(PGconn *conn, SchedulerType *scheduler);
  139. PGresult *nextResult(PGconn *conn, SchedulerType *scheduler);
  140. #endif
  141. std::string escape(PGconn *conn, const std::string &string);
  142. }}
  143. #endif