📄 ogrpgdatasource.cpp
字号:
/****************************************************************************** * $Id: ogrpgdatasource.cpp,v 1.30 2005/03/04 21:04:06 fwarmerdam Exp $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRPGDataSource class. * Author: Frank Warmerdam, warmerda@home.com * ****************************************************************************** * Copyright (c) 2000, Frank Warmerdam * * 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. ****************************************************************************** * * $Log: ogrpgdatasource.cpp,v $ * Revision 1.30 2005/03/04 21:04:06 fwarmerdam * Added setting of dimension based on geometry type, or DIM override. * * Revision 1.29 2004/07/10 04:45:52 warmerda * more rigerous soft transaction handling * * Revision 1.28 2004/07/09 07:05:37 warmerda * Added OGRSQL dialect support. * * Revision 1.27 2004/04/30 18:30:05 warmerda * Fixed pszLayerName typo. * * Revision 1.26 2004/04/30 17:52:42 warmerda * added layer name laundering * * Revision 1.25 2004/04/30 15:17:38 warmerda * Added DELLAYER:layername ExecuteSQL() pseudo-directive. * Clean stale entries in geometry_columns table when creating a layer. * * Revision 1.24 2004/04/30 00:45:45 warmerda * default to launder being on * * Revision 1.23 2004/04/28 12:45:46 warmerda * Fixed screwup in table selection query. * * Revision 1.22 2004/04/23 15:10:10 warmerda * Added support for enumerating views. * * Revision 1.21 2004/04/02 17:44:55 warmerda * SELECT in caps for readability * * Revision 1.20 2004/01/19 18:48:11 warmerda * added commit after DROP TABLE and before dropping sequence * * Revision 1.19 2003/09/11 20:03:03 warmerda * initialize poSRS ariable in FetchSRS * * Revision 1.18 2003/05/21 03:59:42 warmerda * expand tabs * * Revision 1.17 2002/12/12 14:28:35 warmerda * fixed bug in DeleteLayer * * Revision 1.16 2002/10/20 03:45:27 warmerda * added debug on table create command * * Revision 1.15 2002/10/09 18:30:10 warmerda * substantial upgrade to type handling, and preservations of width/precision * * Revision 1.14 2002/10/04 14:03:09 warmerda * added column name laundering support * * Revision 1.13 2002/05/09 16:48:08 warmerda * upgrade to quote table and field names * * Revision 1.12 2002/05/09 16:03:19 warmerda * major upgrade to support SRS better and add ExecuteSQL * * Revision 1.11 2002/03/01 20:42:00 warmerda * fixed parsing of connect string, see bug 107 * * Revision 1.10 2002/01/13 21:48:32 warmerda * fixed addgeometrycolumn call to include pszDBname * * Revision 1.9 2002/01/13 16:23:16 warmerda * capture dbname= parameter for use in AddGeometryColumn() call * * Revision 1.8 2001/11/15 21:19:58 warmerda * added soft transaction semantics * * Revision 1.7 2001/09/28 04:03:52 warmerda * partially upraded to PostGIS 0.6 * * Revision 1.6 2001/07/18 04:55:16 warmerda * added CPL_CSVID * * Revision 1.5 2001/06/26 20:59:13 warmerda * implement efficient spatial and attribute query support * * Revision 1.4 2001/06/20 16:10:24 warmerda * fixed PostGIS autodetect * * Revision 1.3 2001/06/19 22:29:12 warmerda * upgraded to include PostGIS support * * Revision 1.2 2000/11/23 06:03:35 warmerda * added Oid support * * Revision 1.1 2000/10/17 17:46:51 warmerda * New * */#include "ogr_pg.h"#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrpgdatasource.cpp,v 1.30 2005/03/04 21:04:06 fwarmerdam Exp $");static void OGRPGNoticeProcessor( void *arg, const char * pszMessage );/************************************************************************//* OGRPGDataSource() *//************************************************************************/OGRPGDataSource::OGRPGDataSource(){ pszName = NULL; pszDBName = NULL; papoLayers = NULL; nLayers = 0; hPGConn = NULL; bHavePostGIS = FALSE; nSoftTransactionLevel = 0; nKnownSRID = 0; panSRID = NULL; papoSRS = NULL;}/************************************************************************//* ~OGRPGDataSource() *//************************************************************************/OGRPGDataSource::~OGRPGDataSource(){ int i; FlushSoftTransaction(); CPLFree( pszName ); CPLFree( pszDBName ); for( i = 0; i < nLayers; i++ ) delete papoLayers[i]; CPLFree( papoLayers ); if( hPGConn != NULL ) PQfinish( hPGConn ); for( i = 0; i < nKnownSRID; i++ ) { if( papoSRS[i] != NULL && papoSRS[i]->Dereference() == 0 ) delete papoSRS[i]; } CPLFree( panSRID ); CPLFree( papoSRS );}/************************************************************************//* Open() *//************************************************************************/int OGRPGDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen ){ CPLAssert( nLayers == 0 );/* -------------------------------------------------------------------- *//* Verify postgresql prefix. *//* -------------------------------------------------------------------- */ if( !EQUALN(pszNewName,"PG:",3) ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_AppDefined, "%s does not conform to PostgreSQL naming convention," " PG:*\n" ); return FALSE; } /* -------------------------------------------------------------------- *//* Try to establish connection. *//* -------------------------------------------------------------------- */ hPGConn = PQconnectdb( pszNewName + 3 ); if( hPGConn == NULL || PQstatus(hPGConn) == CONNECTION_BAD ) { CPLError( CE_Failure, CPLE_AppDefined, "PGconnectcb failed.\n%s", PQerrorMessage(hPGConn) ); PQfinish(hPGConn); hPGConn = NULL; return FALSE; } pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate;/* -------------------------------------------------------------------- *//* Install a notice processor. *//* -------------------------------------------------------------------- */ PQsetNoticeProcessor( hPGConn, OGRPGNoticeProcessor, this );/* -------------------------------------------------------------------- *//* Try to establish the database name from the connection *//* string passed. *//* -------------------------------------------------------------------- */ if( strstr(pszNewName, "dbname=") != NULL ) { int i; pszDBName = CPLStrdup( strstr(pszNewName, "dbname=") + 7 ); for( i = 0; pszDBName[i] != '\0'; i++ ) { if( pszDBName[i] == ' ' ) { pszDBName[i] = '\0'; break; } } } else if( getenv( "USER" ) != NULL ) pszDBName = CPLStrdup( getenv("USER") ); else pszDBName = CPLStrdup( "unknown_dbname" ); CPLDebug( "OGR_PG", "DBName=\"%s\"", pszDBName );/* -------------------------------------------------------------------- *//* Test to see if this database instance has support for the *//* PostGIS Geometry type. If so, disable sequential scanning *//* so we will get the value of the gist indexes. *//* -------------------------------------------------------------------- */ PGresult *hResult; hResult = PQexec(hPGConn, "BEGIN"); if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); hResult = PQexec(hPGConn, "SELECT oid FROM pg_type WHERE typname = 'geometry'" ); } if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK && PQntuples(hResult) > 0 ) { bHavePostGIS = TRUE; nGeometryOID = atoi(PQgetvalue(hResult,0,0)); } else nGeometryOID = (Oid) 0; if( hResult ) PQclear( hResult ); hResult = PQexec(hPGConn, "SET ENABLE_SEQSCAN = OFF"); PQclear( hResult ); hResult = PQexec(hPGConn, "COMMIT"); PQclear( hResult );/* -------------------------------------------------------------------- *//* Get a list of available tables. *//* -------------------------------------------------------------------- */ hResult = PQexec(hPGConn, "BEGIN"); if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); hResult = PQexec(hPGConn, "DECLARE mycursor CURSOR for " "SELECT relname FROM pg_class " "WHERE (relkind in ('r','v') AND relname !~ '^pg')" ); } if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); hResult = PQexec(hPGConn, "FETCH ALL in mycursor" ); } if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) ); return FALSE; }/* -------------------------------------------------------------------- *//* Parse the returned table list *//* -------------------------------------------------------------------- */ char **papszTableNames=NULL; int iRecord; for( iRecord = 0; iRecord < PQntuples(hResult); iRecord++ ) { const char *pszTable = PQgetvalue(hResult, iRecord, 0); if( EQUAL(pszTable,"spatial_ref_sys") || EQUAL(pszTable,"geometry_columns") ) continue; papszTableNames = CSLAddString(papszTableNames, PQgetvalue(hResult, iRecord, 0)); }/* -------------------------------------------------------------------- *//* Cleanup *//* -------------------------------------------------------------------- */ PQclear( hResult ); hResult = PQexec(hPGConn, "CLOSE mycursor"); PQclear( hResult ); hResult = PQexec(hPGConn, "COMMIT"); PQclear( hResult );/* -------------------------------------------------------------------- *//* Get the schema of the available tables. *//* -------------------------------------------------------------------- */ for( iRecord = 0; papszTableNames != NULL && papszTableNames[iRecord] != NULL; iRecord++ ) { OpenTable( papszTableNames[iRecord], bUpdate, FALSE ); } CSLDestroy( papszTableNames ); return nLayers > 0 || bUpdate;}/************************************************************************//* OpenTable() *//************************************************************************/int OGRPGDataSource::OpenTable( const char *pszNewName, int bUpdate, int bTestOpen ){/* -------------------------------------------------------------------- *//* Create the layer object. *//* -------------------------------------------------------------------- */ OGRPGLayer *poLayer; poLayer = new OGRPGTableLayer( this, pszNewName, bUpdate );/* -------------------------------------------------------------------- *//* Add layer to data source layer list. *//* -------------------------------------------------------------------- */ papoLayers = (OGRPGLayer **) CPLRealloc( papoLayers, sizeof(OGRPGLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE;}/************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -