📄 ogrsqlitedatasource.cpp
字号:
/****************************************************************************** * $Id: ogrsqlitedatasource.cpp,v 1.6 2004/10/30 05:13:10 fwarmerdam Exp $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRSQLiteDataSource class. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com> * * 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: ogrsqlitedatasource.cpp,v $ * Revision 1.6 2004/10/30 05:13:10 fwarmerdam * ensure we shut the database on exit! * * Revision 1.5 2004/07/13 15:11:19 warmerda * implemented SetFeature, transaction support * * Revision 1.4 2004/07/12 21:50:59 warmerda * fixed up SQL escaping * * Revision 1.3 2004/07/12 20:50:46 warmerda * table/database creation now implemented * * Revision 1.2 2004/07/11 19:23:51 warmerda * read implementation working well * * Revision 1.1 2004/07/09 06:25:04 warmerda * New */#include "ogr_sqlite.h"#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrsqlitedatasource.cpp,v 1.6 2004/10/30 05:13:10 fwarmerdam Exp $");/************************************************************************//* OGRSQLiteDataSource() *//************************************************************************/OGRSQLiteDataSource::OGRSQLiteDataSource(){ pszName = NULL; papoLayers = NULL; nLayers = 0; nSoftTransactionLevel = 0; nKnownSRID = 0; panSRID = NULL; papoSRS = NULL;}/************************************************************************//* ~OGRSQLiteDataSource() *//************************************************************************/OGRSQLiteDataSource::~OGRSQLiteDataSource(){ int i; CPLFree( pszName ); for( i = 0; i < nLayers; i++ ) delete papoLayers[i]; CPLFree( papoLayers ); for( i = 0; i < nKnownSRID; i++ ) { if( papoSRS[i] != NULL && papoSRS[i]->Dereference() == 0 ) delete papoSRS[i]; } CPLFree( panSRID ); CPLFree( papoSRS ); if( hDB != NULL ) sqlite3_close( hDB );}/************************************************************************//* Open() *//* *//* Note, the Open() will implicitly create the database if it *//* does not already exist. *//************************************************************************/int OGRSQLiteDataSource::Open( const char * pszNewName ){ CPLAssert( nLayers == 0 ); pszName = CPLStrdup( pszNewName );/* -------------------------------------------------------------------- *//* Try to open the sqlite database properly now. *//* -------------------------------------------------------------------- */ int rc; hDB = NULL; rc = sqlite3_open( pszNewName, &hDB ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_OpenFailed, "sqlite3_open(%s) failed: %d", pszNewName, sqlite3_errmsg( hDB ) ); return FALSE; }/* -------------------------------------------------------------------- *//* If we have a GEOMETRY_COLUMN tables, initialize on the basis *//* of that. *//* -------------------------------------------------------------------- */ char **papszResult; int nRowCount, iRow, nColCount; char *pszErrMsg;#ifdef notdef rc = sqlite3_get_table( hDB, "SELECT f_table_name, f_geometry_column, geometry_type" " FROM geometry_columns", &papszResult, &nRowCount, &nColCount, &pszErrMsg ); if( rc == SQLITE_OK ) { for( iRow = 0; iRow < nRowCount; iRow++ ) { char **papszRow = papszResult + iRow * 3 + 3; OpenTable( papszRow[0], papszRow[1] ); } sqlite3_free_table(papszResult); return TRUE; } else sqlite3_free( pszErrMsg );#endif/* -------------------------------------------------------------------- *//* Otherwise our final resort is to return all tables and views *//* as non-spatial tables. *//* -------------------------------------------------------------------- */ rc = sqlite3_get_table( hDB, "SELECT name FROM sqlite_master " "WHERE type IN ('table','view') " "UNION ALL " "SELECT name FROM sqlite_temp_master " "WHERE type IN ('table','view') " "ORDER BY 1", &papszResult, &nRowCount, &nColCount, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to fetch list of tables: %s", pszErrMsg ); sqlite3_free( pszErrMsg ); return FALSE; } for( iRow = 0; iRow < nRowCount; iRow++ ) { OpenTable( papszResult[iRow+1], NULL ); } sqlite3_free_table(papszResult); return TRUE;}/************************************************************************//* OpenTable() *//************************************************************************/int OGRSQLiteDataSource::OpenTable( const char *pszNewName, const char *pszGeomCol ){/* -------------------------------------------------------------------- *//* Create the layer object. *//* -------------------------------------------------------------------- */ OGRSQLiteTableLayer *poLayer; poLayer = new OGRSQLiteTableLayer( this ); if( poLayer->Initialize( pszNewName, pszGeomCol ) ) { delete poLayer; return FALSE; }/* -------------------------------------------------------------------- *//* Add layer to data source layer list. *//* -------------------------------------------------------------------- */ papoLayers = (OGRSQLiteLayer **) CPLRealloc( papoLayers, sizeof(OGRSQLiteLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return TRUE;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRSQLiteDataSource::TestCapability( const char * pszCap ){ if( EQUAL(pszCap,ODsCCreateLayer) ) return TRUE; else return FALSE;}/************************************************************************//* GetLayer() *//************************************************************************/OGRLayer *OGRSQLiteDataSource::GetLayer( int iLayer ){ if( iLayer < 0 || iLayer >= nLayers ) return NULL; else return papoLayers[iLayer];}/************************************************************************//* ExecuteSQL() *//************************************************************************/OGRLayer * OGRSQLiteDataSource::ExecuteSQL( const char *pszSQLCommand, OGRGeometry *poSpatialFilter, const char *pszDialect ){ if( pszDialect != NULL && EQUAL(pszDialect,"OGRSQL") ) return OGRDataSource::ExecuteSQL( pszSQLCommand, poSpatialFilter, pszDialect );/* -------------------------------------------------------------------- *//* Special case DELLAYER: command. *//* -------------------------------------------------------------------- */ if( EQUALN(pszSQLCommand,"DELLAYER:",9) ) { const char *pszLayerName = pszSQLCommand + 9; while( *pszLayerName == ' ' ) pszLayerName++; DeleteLayer( pszLayerName ); return NULL; }/* -------------------------------------------------------------------- *//* Prepare statement. *//* -------------------------------------------------------------------- */ int rc; sqlite3_stmt *hSQLStmt = NULL; rc = sqlite3_prepare( GetDB(), pszSQLCommand, strlen(pszSQLCommand), &hSQLStmt, NULL ); if( rc != SQLITE_OK ) { if( hSQLStmt != NULL ) sqlite3_finalize( hSQLStmt ); return NULL; }/* -------------------------------------------------------------------- *//* Do we get a resultset? *//* -------------------------------------------------------------------- */ rc = sqlite3_step( hSQLStmt ); if( rc != SQLITE_ROW ) { sqlite3_finalize( hSQLStmt ); return NULL; } /* -------------------------------------------------------------------- *//* Create layer. *//* -------------------------------------------------------------------- */ OGRSQLiteSelectLayer *poLayer = NULL; poLayer = new OGRSQLiteSelectLayer( this, hSQLStmt ); if( poSpatialFilter != NULL ) poLayer->SetSpatialFilter( poSpatialFilter ); return poLayer;}/************************************************************************//* ReleaseResultSet() *//************************************************************************/void OGRSQLiteDataSource::ReleaseResultSet( OGRLayer * poLayer ){ delete poLayer;}/************************************************************************//* CreateLayer() *//************************************************************************/OGRLayer *OGRSQLiteDataSource::CreateLayer( const char * pszLayerNameIn, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ){ char szCommand[1024]; char *pszLayerName; if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ) pszLayerName = LaunderName( pszLayerNameIn ); else pszLayerName = CPLStrdup( pszLayerNameIn );/* -------------------------------------------------------------------- *//* Do we already have this layer? If so, should we blow it *//* away? *//* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( pszLayerName ); } else { CPLError( CE_Failure, CPLE_AppDefined,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -