diff --git a/plugins/input/pgraster/pgraster_datasource.cpp b/plugins/input/pgraster/pgraster_datasource.cpp index 10b126b78..c7ec2b1f2 100644 --- a/plugins/input/pgraster/pgraster_datasource.cpp +++ b/plugins/input/pgraster/pgraster_datasource.cpp @@ -78,12 +78,7 @@ pgraster_datasource::pgraster_datasource(parameters const& params) use_overviews_(*params.get("use_overviews", false)), clip_rasters_(*params.get("clip_rasters", false)), desc_(*params.get("type"), "utf-8"), - creator_(params.get("host"), - params.get("port"), - params.get("dbname"), - params.get("user"), - params.get("password"), - params.get("connect_timeout", "4")), + creator_(params), re_tokens_("!(@?\\w+)!"), // matches !mapnik_var! or !@user_var! pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), diff --git a/plugins/input/postgis/connection_manager.hpp b/plugins/input/postgis/connection_manager.hpp index 49dca17f5..e6415c90a 100644 --- a/plugins/input/postgis/connection_manager.hpp +++ b/plugins/input/postgis/connection_manager.hpp @@ -26,16 +26,15 @@ #include "connection.hpp" // mapnik +#include #include #include // boost -#include #include // stl #include -#include #include using mapnik::Pool; @@ -47,22 +46,19 @@ class ConnectionCreator { public: - ConnectionCreator(boost::optional const& host, - boost::optional const& port, - boost::optional const& dbname, - boost::optional const& user, - boost::optional const& pass, - boost::optional const& connect_timeout) - : host_(host), - port_(port), - dbname_(dbname), - user_(user), - pass_(pass), - connect_timeout_(connect_timeout) {} + ConnectionCreator(mapnik::parameters const& params) + : host_{params.get("host")}, + port_{params.get("port")}, + dbname_{params.get("dbname")}, + user_{params.get("user")}, + password_{params.get("password")}, + connect_timeout_{params.get("connect_timeout", "4")}, + application_name_{params.get("application_name")} + {} T* operator()() const { - return new T(connection_string_safe(),pass_); + return new T(connection_string_safe(), password_); } inline std::string id() const @@ -73,29 +69,52 @@ public: inline std::string connection_string() const { std::string connect_str = connection_string_safe(); - if (pass_ && !pass_->empty()) connect_str += " password=" + *pass_; + append_param(connect_str, "password=", password_); return connect_str; } inline std::string connection_string_safe() const { std::string connect_str; - if (host_ && !host_->empty()) connect_str += "host=" + *host_; - if (port_ && !port_->empty()) connect_str += " port=" + *port_; - if (dbname_ && !dbname_->empty()) connect_str += " dbname=" + *dbname_; - if (user_ && !user_->empty()) connect_str += " user=" + *user_; - if (connect_timeout_ && !connect_timeout_->empty()) - connect_str +=" connect_timeout=" + *connect_timeout_; + append_param(connect_str, "host=", host_); + append_param(connect_str, "port=", port_); + append_param(connect_str, "dbname=", dbname_); + append_param(connect_str, "user=", user_); + append_param(connect_str, "connect_timeout=", connect_timeout_); + if (!append_param(connect_str, "application_name=", application_name_)) + { + // only set fallback_application_name, so that application_name + // can still be overriden with PGAPPNAME environment variable + append_param(connect_str, "fallback_application_name=", "mapnik"); + } return connect_str; } private: + + static bool append_param(std::string & dest, char const* key, + std::string const& val) + { + if (val.empty()) return false; + if (!dest.empty()) dest += ' '; + dest += key; + dest += val; + return true; + } + + static bool append_param(std::string & dest, char const* key, + boost::optional const& opt) + { + return opt && append_param(dest, key, *opt); + } + boost::optional host_; boost::optional port_; boost::optional dbname_; boost::optional user_; - boost::optional pass_; + boost::optional password_; boost::optional connect_timeout_; + boost::optional application_name_; }; class ConnectionManager : public singleton diff --git a/plugins/input/postgis/postgis_datasource.cpp b/plugins/input/postgis/postgis_datasource.cpp index 6e556dadd..48301047b 100644 --- a/plugins/input/postgis/postgis_datasource.cpp +++ b/plugins/input/postgis/postgis_datasource.cpp @@ -71,12 +71,7 @@ postgis_datasource::postgis_datasource(parameters const& params) extent_initialized_(false), simplify_geometries_(false), desc_(postgis_datasource::name(), "utf-8"), - creator_(params.get("host"), - params.get("port"), - params.get("dbname"), - params.get("user"), - params.get("password"), - params.get("connect_timeout", "4")), + creator_(params), pool_max_size_(*params_.get("max_size", 10)), persist_connection_(*params.get("persist_connection", true)), extent_from_subquery_(*params.get("extent_from_subquery", false)), diff --git a/test/unit/datasource/postgis.cpp b/test/unit/datasource/postgis.cpp index 4487569a9..b66aa0d15 100644 --- a/test/unit/datasource/postgis.cpp +++ b/test/unit/datasource/postgis.cpp @@ -433,14 +433,16 @@ TEST_CASE("ConnectionCreator") { SECTION("ConnectionCreator::id() should not expose password") { - ConnectionCreator creator(boost::optional("host"), - boost::optional("12345"), - boost::optional("dbname"), - boost::optional("user"), - boost::optional("pass"), - boost::optional("111")); - - CHECK(creator.id() == "host=host port=12345 dbname=dbname user=user connect_timeout=111"); + mapnik::parameters params; + params["host"] = "H"; + params["port"] = "1234"; + params["dbname"] = "D"; + params["user"] = "U"; + params["password"] = "SECRET"; + params["connect_timeout"] = "5"; + params["application_name"] = "A"; + ConnectionCreator creator(params); + CHECK(creator.id() == "host=H port=1234 dbname=D user=U connect_timeout=5 application_name=A"); } } diff --git a/utils/pgsql2sqlite/main.cpp b/utils/pgsql2sqlite/main.cpp index 2d4fa4171..2fac6ed27 100644 --- a/utils/pgsql2sqlite/main.cpp +++ b/utils/pgsql2sqlite/main.cpp @@ -83,20 +83,15 @@ int main ( int argc, char** argv) return EXIT_FAILURE; } - boost::optional host; - boost::optional port ; - boost::optional dbname; - boost::optional user; - boost::optional password; - boost::optional connect_timeout("4"); + mapnik::parameters conn_params; + conn_params["application_name"] = "pgsql2sqlite"; + for (auto k : {"host", "port", "dbname", "user", "password"}) + { + if (!vm[k].empty()) + conn_params[k] = vm[k].as(); + } - if (vm.count("host")) host = vm["host"].as(); - if (vm.count("port")) port = vm["port"].as(); - if (vm.count("dbname")) dbname = vm["dbname"].as(); - if (vm.count("user")) user = vm["user"].as(); - if (vm.count("password")) password = vm["password"].as(); - - ConnectionCreator creator(host,port,dbname,user,password,connect_timeout); + ConnectionCreator creator(conn_params); try { std::shared_ptr conn(creator()); @@ -112,8 +107,8 @@ int main ( int argc, char** argv) catch (mapnik::datasource_exception & ex) { std::cerr << ex.what() << "\n"; + return EXIT_FAILURE; } - } catch(std::exception& e) { std::cerr << desc << "\n";