/****************************************************************************** * File : PostGISRasterDriver.cpp * Project: PostGIS Raster driver * Purpose: Implements PostGIS Raster driver class methods * Author: Jorge Arevalo, jorge.arevalo@deimos-space.com * * Last changes: $Id$ * ****************************************************************************** * Copyright (c) 2010, Jorge Arevalo, jorge.arevalo@deimos-space.com * Copyright (c) 2013, Even Rouault * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ******************************************************************************/ #include "postgisraster.h" #include "cpl_multiproc.h" /************************ * \brief Constructor ************************/ PostGISRasterDriver::PostGISRasterDriver() : hMutex(nullptr) { } /************************ * \brief Destructor ************************/ PostGISRasterDriver::~PostGISRasterDriver() { if (hMutex != nullptr) CPLDestroyMutex(hMutex); std::map::iterator oIter = oMapConnection.begin(); for (; oIter != oMapConnection.end(); ++oIter) PQfinish(oIter->second); } /*************************************************************************** * \brief Create a PQconn object and store it in a list * * The PostGIS Raster driver keeps the connection with the PostgreSQL database * server for as long it leaves. Following PostGISRasterDataset instance * can re-use the existing connection as long it used the same database, * same host, port and user name. * * The PostGIS Raster driver will keep a list of all the successful * connections so, when connection is requested and it does not exist * on the list a new one will be instantiated, added to the list and * returned to the caller. * * All connection will be destroyed when the PostGISRasterDriver is destroyed. * ***************************************************************************/ PGconn *PostGISRasterDriver::GetConnection(const char *pszConnectionString, const char *pszServiceIn, const char *pszDbnameIn, const char *pszHostIn, const char *pszPortIn, const char *pszUserIn) { PGconn *poConn = nullptr; if (pszHostIn == nullptr) pszHostIn = "(null)"; if (pszPortIn == nullptr) pszPortIn = "(null)"; if (pszUserIn == nullptr) pszUserIn = "(null)"; CPLString osKey = (pszServiceIn == nullptr) ? pszDbnameIn : pszServiceIn; osKey += "-"; osKey += pszHostIn; osKey += "-"; osKey += pszPortIn; osKey += "-"; osKey += pszUserIn; osKey += "-"; osKey += CPLSPrintf(CPL_FRMT_GIB, CPLGetPID()); /** * Look for an existing connection in the map **/ CPLMutexHolderD(&hMutex); std::map::iterator oIter = oMapConnection.find(osKey); if (oIter != oMapConnection.end()) return oIter->second; /** * There's no existing connection. Create a new one. **/ poConn = PQconnectdb(pszConnectionString); if (poConn == nullptr || PQstatus(poConn) == CONNECTION_BAD) { CPLError(CE_Failure, CPLE_AppDefined, "PQconnectdb failed: %s\n", PQerrorMessage(poConn)); PQfinish(poConn); return nullptr; } /** * Save connection in the connection map. **/ oMapConnection[osKey] = poConn; return poConn; }