Line data Source code
1 : /****************************************************************************** 2 : * File : PostGISRasterDriver.cpp 3 : * Project: PostGIS Raster driver 4 : * Purpose: Implements PostGIS Raster driver class methods 5 : * Author: Jorge Arevalo, jorge.arevalo@deimos-space.com 6 : * 7 : * Last changes: $Id$ 8 : * 9 : ****************************************************************************** 10 : * Copyright (c) 2010, Jorge Arevalo, jorge.arevalo@deimos-space.com 11 : * Copyright (c) 2013, Even Rouault 12 : * 13 : * SPDX-License-Identifier: MIT 14 : ******************************************************************************/ 15 : #include "postgisraster.h" 16 : #include "cpl_multiproc.h" 17 : 18 : PostGISRasterDriver *PostGISRasterDriver::gpoPostGISRasterDriver = nullptr; 19 : 20 : /************************ 21 : * \brief Constructor 22 : ************************/ 23 9 : PostGISRasterDriver::PostGISRasterDriver() 24 : { 25 9 : gpoPostGISRasterDriver = this; 26 9 : } 27 : 28 : /************************ 29 : * \brief Destructor 30 : ************************/ 31 10 : PostGISRasterDriver::~PostGISRasterDriver() 32 : { 33 5 : gpoPostGISRasterDriver = nullptr; 34 5 : if (hMutex != nullptr) 35 0 : CPLDestroyMutex(hMutex); 36 5 : std::map<CPLString, PGconn *>::iterator oIter = oMapConnection.begin(); 37 5 : for (; oIter != oMapConnection.end(); ++oIter) 38 0 : PQfinish(oIter->second); 39 10 : } 40 : 41 : /*************************************************************************** 42 : * \brief Create a PQconn object and store it in a list 43 : * 44 : * The PostGIS Raster driver keeps the connection with the PostgreSQL database 45 : * server for as long it leaves. Following PostGISRasterDataset instance 46 : * can re-use the existing connection as long it used the same database, 47 : * same host, port and user name. 48 : * 49 : * The PostGIS Raster driver will keep a list of all the successful 50 : * connections so, when connection is requested and it does not exist 51 : * on the list a new one will be instantiated, added to the list and 52 : * returned to the caller. 53 : * 54 : * All connection will be destroyed when the PostGISRasterDriver is destroyed. 55 : * 56 : ***************************************************************************/ 57 2 : PGconn *PostGISRasterDriver::GetConnection(const char *pszConnectionString, 58 : const char *pszServiceIn, 59 : const char *pszDbnameIn, 60 : const char *pszHostIn, 61 : const char *pszPortIn, 62 : const char *pszUserIn) 63 : { 64 2 : PGconn *poConn = nullptr; 65 : 66 2 : if (pszHostIn == nullptr) 67 0 : pszHostIn = "(null)"; 68 2 : if (pszPortIn == nullptr) 69 0 : pszPortIn = "(null)"; 70 2 : if (pszUserIn == nullptr) 71 0 : pszUserIn = "(null)"; 72 4 : CPLString osKey = (pszServiceIn == nullptr) ? pszDbnameIn : pszServiceIn; 73 2 : osKey += "-"; 74 2 : osKey += pszHostIn; 75 2 : osKey += "-"; 76 2 : osKey += pszPortIn; 77 2 : osKey += "-"; 78 2 : osKey += pszUserIn; 79 2 : osKey += "-"; 80 2 : osKey += CPLSPrintf(CPL_FRMT_GIB, CPLGetPID()); 81 : 82 : /** 83 : * Look for an existing connection in the map 84 : **/ 85 4 : CPLMutexHolderD(&hMutex); 86 2 : std::map<CPLString, PGconn *>::iterator oIter = oMapConnection.find(osKey); 87 2 : if (oIter != oMapConnection.end()) 88 1 : return oIter->second; 89 : 90 : /** 91 : * There's no existing connection. Create a new one. 92 : **/ 93 1 : poConn = PQconnectdb(pszConnectionString); 94 1 : if (poConn == nullptr || PQstatus(poConn) == CONNECTION_BAD) 95 : { 96 0 : CPLError(CE_Failure, CPLE_AppDefined, "PQconnectdb failed: %s\n", 97 : PQerrorMessage(poConn)); 98 0 : PQfinish(poConn); 99 0 : return nullptr; 100 : } 101 : 102 : /** 103 : * Save connection in the connection map. 104 : **/ 105 1 : oMapConnection[osKey] = poConn; 106 1 : return poConn; 107 : }