1 // This may look like C code, but it's really -*- C++ -*- 2 /* 3 * Copyright (C) 2008 Emweb bv, Herent, Belgium. 4 * 5 * See the LICENSE file for terms of use. 6 * 7 * Contributed by: Hilary Cheng 8 */ 9 #ifndef WT_DBO_BACKEND_POSTGRES_H_ 10 #define WT_DBO_BACKEND_POSTGRES_H_ 11 12 #include <Wt/Dbo/SqlConnection.h> 13 #include <Wt/Dbo/SqlStatement.h> 14 #include <Wt/Dbo/backend/WDboPostgresDllDefs.h> 15 16 #include <chrono> 17 18 struct pg_conn; 19 typedef struct pg_conn PGconn; 20 21 namespace Wt { 22 namespace Dbo { 23 namespace backend { 24 25 /*! \class Postgres Wt/Dbo/backend/Postgres.h Wt/Dbo/backend/Postgres.h 26 * \brief A PostgreSQL connection 27 * 28 * This class provides the backend implementation for PostgreSQL databases. 29 * 30 * When applicable, exceptions from the backend will return the 31 * five-character SQLSTATE error codes, as in 32 * http://www.postgresql.org/docs/8.1/static/errcodes-appendix.html, in 33 * Exception::code(). 34 * 35 * \ingroup dbo 36 */ 37 class WTDBOPOSTGRES_API Postgres : public SqlConnection 38 { 39 public: 40 /*! \brief Creates new PostgreSQL backend connection. 41 * 42 * The connection is not yet open, and requires a connect() before it 43 * can be used. 44 */ 45 Postgres(); 46 47 /*! \brief Opens a new PostgreSQL backend connection. 48 * 49 * The \p db may be any of the values supported by PQconnectdb(). 50 */ 51 Postgres(const std::string& db); 52 53 /*! \brief Copies a PostgreSQL connection. 54 * 55 * This creates a new connection with the same settings as another 56 * connection. 57 * 58 * \sa clone() 59 */ 60 Postgres(const Postgres& other); 61 62 /*! \brief Destructor. 63 * 64 * Closes the connection. 65 */ 66 ~Postgres(); 67 68 virtual std::unique_ptr<SqlConnection> clone() const override; 69 70 /*! \brief Tries to connect. 71 * 72 * Throws an exception if there was a problem, otherwise true. 73 * An example connecion string could be: 74 * "host=127.0.0.1 user=test password=test port=5432 dbname=test" 75 */ 76 bool connect(const std::string& db); 77 78 /*! \brief Disconnects. 79 * 80 * This disconnects from the server. Any subsequent action on the connection 81 * will result in an automatic reconnect. 82 * 83 * \sa reconnect() 84 */ 85 void disconnect(); 86 87 /*! \brief Reconnect. 88 * 89 * This will try to reconnect a previously disconnected connection. If the connection 90 * is still open, it will first disconnect. 91 */ 92 bool reconnect(); 93 94 /*! \brief Returns the underlying connection. 95 */ connection()96 PGconn *connection() { return conn_; } 97 98 /*! \brief Sets a timeout. 99 * 100 * Sets a timeout for queries. When the query exceeds this timeout, the connection 101 * is closed using disconnect() and an exception is thrown. 102 * 103 * In practice, as a result, the connection (and statements) can still be used again 104 * when a successful reconnect() is performed. 105 * 106 * A value of 0 disables the timeout handling, allowing operations 107 * to take as much time is they require. 108 * 109 * The default value is 0. 110 */ 111 void setTimeout(std::chrono::microseconds timeout); 112 113 /*! \brief Returns the timeout. 114 * 115 * \sa setTimeout() 116 */ timeout()117 std::chrono::microseconds timeout() const { return timeout_; } 118 119 /*! \brief Sets the maximum lifetime for the underlying connection. 120 * 121 * The maximum lifetime is specified in seconds. If set to a value > 122 * 0, then the underlying connection object will be closed and 123 * reopened when the connection has been open longer than this 124 * lifetime. 125 * 126 * The default value is -1 (unlimited lifetime). 127 */ 128 void setMaximumLifetime(std::chrono::seconds seconds); 129 130 virtual void executeSql(const std::string &sql) override; 131 132 virtual void startTransaction() override; 133 virtual void commitTransaction() override; 134 virtual void rollbackTransaction() override; 135 136 virtual std::unique_ptr<SqlStatement> prepareStatement(const std::string& sql) override; 137 138 /** @name Methods that return dialect information 139 */ 140 //!@{ 141 virtual std::string autoincrementSql() const override; 142 virtual std::vector<std::string> 143 autoincrementCreateSequenceSql(const std::string &table, 144 const std::string &id) const override; 145 virtual std::vector<std::string> 146 autoincrementDropSequenceSql(const std::string &table, 147 const std::string &id) const override; 148 virtual std::string autoincrementType() const override; 149 virtual std::string autoincrementInsertSuffix(const std::string& id) const override; 150 virtual const char *dateTimeType(SqlDateTimeType type) const override; 151 virtual const char *blobType() const override; 152 virtual bool supportAlterTable() const override; 153 virtual bool supportDeferrableFKConstraint() const override; 154 virtual bool requireSubqueryAlias() const override; 155 //!@} 156 157 void checkConnection(std::chrono::seconds margin); 158 159 private: 160 std::string connInfo_; 161 PGconn *conn_; 162 std::chrono::microseconds timeout_; 163 std::chrono::seconds maximumLifetime_; 164 std::chrono::steady_clock::time_point connectTime_; 165 166 void exec(const std::string& sql, bool showQuery); 167 }; 168 169 } 170 } 171 } 172 173 #endif // WT_DBO_BACKEND_POSTGRES_H_ 174