diff --git a/CHANGELOG b/CHANGELOG index d3b4adc7f..2c5e2f7e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,9 @@ For a complete change history, see the SVN log. Mapnik 0.6.2 Release -------------------- +- PostGIS: Add a 'persist_connection' option (default true), that when false will release + the idle psql connection after datasource goes out of scope (r1337) (#433,#434) + - Filters: Add support for '!=' as an alias to '<>' for not-equals filters (avoids <>) (r1326) (#427) - Gdal Plugin: Add support for Gdal overviews, enabling fast loading of > 1GB rasters (r1321) (#54) diff --git a/plugins/input/postgis/connection.hpp b/plugins/input/postgis/connection.hpp index b219f287e..5ec4bd247 100644 --- a/plugins/input/postgis/connection.hpp +++ b/plugins/input/postgis/connection.hpp @@ -40,9 +40,11 @@ class Connection private: PGconn *conn_; int cursorId; + bool closed_; public: Connection(std::string const& connection_str) - :cursorId(0) + :cursorId(0), + closed_(false) { conn_=PQconnectdb(connection_str.c_str()); if (PQstatus(conn_) != CONNECTION_OK) @@ -67,6 +69,7 @@ class Connection PQclear(result); return ok; } + boost::shared_ptr executeQuery(const std::string& sql,int type=0) const { PGresult *result=0; @@ -109,7 +112,14 @@ class Connection void close() { - PQfinish(conn_); + if (!closed_) + { + PQfinish(conn_); +#ifdef MAPNIK_DEBUG + std::clog << "PostGIS: datasource closed, also closing connection - " << conn_ << "\n"; +#endif + closed_ = true; + } } std::string new_cursor_name() @@ -121,10 +131,14 @@ class Connection ~Connection() { - PQfinish(conn_); + if (!closed_) + { + PQfinish(conn_); #ifdef MAPNIK_DEBUG - std::clog << "close connection " << conn_ << "\n"; -#endif + std::clog << "PostGIS: postgresql connection closed - " << conn_ << "\n"; +#endif + closed_ = true; + } } }; diff --git a/plugins/input/postgis/postgis.cpp b/plugins/input/postgis/postgis.cpp index fe53a472f..347136731 100644 --- a/plugins/input/postgis/postgis.cpp +++ b/plugins/input/postgis/postgis.cpp @@ -76,11 +76,23 @@ postgis_datasource::postgis_datasource(parameters const& params) params.get("dbname"), params.get("user"), params.get("password")), - bbox_token_("!bbox!") + bbox_token_("!bbox!"), + persist_connection_(*params_.get("persist_connection",true)) { - if (table_.empty()) throw mapnik::datasource_exception("missing parameter"); - + if (table_.empty()) throw mapnik::datasource_exception("PostGIS: missing
parameter"); + +#ifdef MAPNIK_DEBUG + if (persist_connection_) + { + clog << "PostGIS: persisting connection pool..." << endl; + } + else + { + clog << "PostGIS: not persisting connection..." << endl; + } +#endif + boost::optional initial_size = params_.get("inital_size",1); boost::optional max_size = params_.get("max_size",10); @@ -257,7 +269,7 @@ postgis_datasource::postgis_datasource(parameters const& params) case 25: // text desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String)); break; - default: // shouldn't get here + default: // shouldn not get here #ifdef MAPNIK_DEBUG clog << "unknown type_oid="< postgis_datasource::envelope() const return extent_; } -postgis_datasource::~postgis_datasource() {} +postgis_datasource::~postgis_datasource() +{ + if (!persist_connection_) + { + ConnectionManager *mgr=ConnectionManager::instance(); + shared_ptr > pool=mgr->getPool(creator_.id()); + if (pool) + { + shared_ptr conn = pool->borrowObject(); + if (conn) + { + conn->close(); + } + } + } +} diff --git a/plugins/input/postgis/postgis.hpp b/plugins/input/postgis/postgis.hpp index 79e68ab1b..d64d8f08a 100644 --- a/plugins/input/postgis/postgis.hpp +++ b/plugins/input/postgis/postgis.hpp @@ -70,6 +70,7 @@ class postgis_datasource : public datasource bool multiple_geometries_; static const std::string name_; const std::string bbox_token_; + bool persist_connection_; public: static std::string name(); int type() const;