121 строка
4.5 KiB
C++
121 строка
4.5 KiB
C++
/******************************************************************************
|
|
* 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<CPLString, PGconn *>::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<CPLString, PGconn *>::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;
|
|
}
|