LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitedatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1088 810 74.4 %
Date: 2012-12-26 Functions: 42 38 90.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitedatasource.cpp 25186 2012-10-29 18:31:29Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRSQLiteDataSource class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  *
      10                 :  * Contributor: Alessandro Furieri, a.furieri@lqt.it
      11                 :  * Portions of this module properly supporting SpatiaLite Table/Geom creation
      12                 :  * Developed for Faunalia ( http://www.faunalia.it) with funding from 
      13                 :  * Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED AMBIENTALE
      14                 :  *
      15                 :  ******************************************************************************
      16                 :  * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
      17                 :  *
      18                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      19                 :  * copy of this software and associated documentation files (the "Software"),
      20                 :  * to deal in the Software without restriction, including without limitation
      21                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      22                 :  * and/or sell copies of the Software, and to permit persons to whom the
      23                 :  * Software is furnished to do so, subject to the following conditions:
      24                 :  *
      25                 :  * The above copyright notice and this permission notice shall be included
      26                 :  * in all copies or substantial portions of the Software.
      27                 :  *
      28                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      29                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      30                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      31                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      32                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      33                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      34                 :  * DEALINGS IN THE SOFTWARE.
      35                 :  ****************************************************************************/
      36                 : 
      37                 : #include "ogr_sqlite.h"
      38                 : #include "cpl_conv.h"
      39                 : #include "cpl_string.h"
      40                 : #include "cpl_hash_set.h"
      41                 : #include "cpl_csv.h"
      42                 : #include "ogrsqliteregexp.h"
      43                 : 
      44                 : #ifdef HAVE_SPATIALITE
      45                 : #include "spatialite.h"
      46                 : #endif
      47                 : 
      48                 : static int bSpatialiteLoaded = FALSE;
      49                 : 
      50                 : CPL_CVSID("$Id: ogrsqlitedatasource.cpp 25186 2012-10-29 18:31:29Z rouault $");
      51                 : 
      52                 : /************************************************************************/
      53                 : /*                      OGRSQLiteInitSpatialite()                       */
      54                 : /************************************************************************/
      55                 : 
      56             499 : static int OGRSQLiteInitSpatialite()
      57                 : {
      58                 : /* -------------------------------------------------------------------- */
      59                 : /*      Try loading SpatiaLite.                                         */
      60                 : /* -------------------------------------------------------------------- */
      61                 : #ifdef HAVE_SPATIALITE
      62             499 :     if (!bSpatialiteLoaded && CSLTestBoolean(CPLGetConfigOption("SPATIALITE_LOAD", "TRUE")))
      63                 :     {
      64              13 :         bSpatialiteLoaded = TRUE;
      65              13 :         spatialite_init(CSLTestBoolean(CPLGetConfigOption("SPATIALITE_INIT_VERBOSE", "FALSE")));
      66                 :     }
      67                 : #endif
      68             499 :     return bSpatialiteLoaded;
      69                 : }
      70                 : 
      71                 : /************************************************************************/
      72                 : /*                     OGRSQLiteIsSpatialiteLoaded()                    */
      73                 : /************************************************************************/
      74                 : 
      75            3154 : int OGRSQLiteIsSpatialiteLoaded()
      76                 : {
      77            3154 :     return bSpatialiteLoaded;
      78                 : }
      79                 : 
      80                 : /************************************************************************/
      81                 : /*               OGRSQLiteGetSpatialiteVersionNumber()                  */
      82                 : /************************************************************************/
      83                 : 
      84            2153 : int OGRSQLiteGetSpatialiteVersionNumber()
      85                 : {
      86            2153 :     int v = 0;
      87                 : #ifdef HAVE_SPATIALITE
      88            2153 :     if( bSpatialiteLoaded )
      89                 :     {
      90            2076 :         v = (int)(( atof( spatialite_version() ) + 0.001 )  * 10.0);
      91                 :     }
      92                 : #endif
      93            2153 :     return v;
      94                 : }
      95                 : 
      96                 : /************************************************************************/
      97                 : /*                        OGRSQLiteDataSource()                         */
      98                 : /************************************************************************/
      99                 : 
     100             637 : OGRSQLiteDataSource::OGRSQLiteDataSource()
     101                 : 
     102                 : {
     103             637 :     pszName = NULL;
     104             637 :     papoLayers = NULL;
     105             637 :     nLayers = 0;
     106                 : 
     107             637 :     nSoftTransactionLevel = 0;
     108                 : 
     109             637 :     nKnownSRID = 0;
     110             637 :     panSRID = NULL;
     111             637 :     papoSRS = NULL;
     112                 : 
     113             637 :     bHaveGeometryColumns = FALSE;
     114             637 :     bIsSpatiaLiteDB = FALSE;
     115             637 :     bSpatialite4Layout = FALSE;
     116             637 :     bUpdate = FALSE;
     117                 : 
     118             637 :     nUndefinedSRID = -1; /* will be changed to 0 if Spatialite >= 4.0 detected */
     119                 : 
     120             637 :     hDB = NULL;
     121                 : 
     122                 : #ifdef HAVE_SQLITE_VFS
     123             637 :     pMyVFS = NULL;
     124                 : #endif
     125                 : 
     126             637 :     fpMainFile = NULL; /* Do not close ! The VFS layer will do it for us */
     127             637 :     nFileTimestamp = 0;
     128             637 :     bLastSQLCommandIsUpdateLayerStatistics = FALSE;
     129                 : 
     130             637 :     hRegExpCache = NULL;
     131             637 : }
     132                 : 
     133                 : /************************************************************************/
     134                 : /*                        ~OGRSQLiteDataSource()                        */
     135                 : /************************************************************************/
     136                 : 
     137             637 : OGRSQLiteDataSource::~OGRSQLiteDataSource()
     138                 : 
     139                 : {
     140                 :     int         i;
     141                 : 
     142            2016 :     for( i = 0; i < nLayers; i++ )
     143                 :     {
     144            1379 :         if( papoLayers[i]->IsTableLayer() )
     145                 :         {
     146            1374 :             OGRSQLiteTableLayer* poLayer = (OGRSQLiteTableLayer*) papoLayers[i];
     147            1374 :             poLayer->CreateSpatialIndexIfNecessary();
     148                 :         }
     149                 :     }
     150                 : 
     151             637 :     SaveStatistics();
     152                 : 
     153             637 :     CPLFree( pszName );
     154                 : 
     155            2016 :     for( i = 0; i < nLayers; i++ )
     156            1379 :         delete papoLayers[i];
     157                 :     
     158             637 :     CPLFree( papoLayers );
     159                 : 
     160             791 :     for( i = 0; i < nKnownSRID; i++ )
     161                 :     {
     162             154 :         if( papoSRS[i] != NULL )
     163             154 :             papoSRS[i]->Release();
     164                 :     }
     165             637 :     CPLFree( panSRID );
     166             637 :     CPLFree( papoSRS );
     167                 : 
     168             637 :     OGRSQLiteFreeRegExpCache(hRegExpCache);
     169                 : 
     170             637 :     if( hDB != NULL )
     171             636 :         sqlite3_close( hDB );
     172                 : 
     173                 : #ifdef HAVE_SQLITE_VFS
     174             637 :     if (pMyVFS)
     175                 :     {
     176             456 :         sqlite3_vfs_unregister(pMyVFS);
     177             456 :         CPLFree(pMyVFS->pAppData);
     178             456 :         CPLFree(pMyVFS);
     179                 :     }
     180                 : #endif
     181             637 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                              SaveStatistics()                        */
     185                 : /************************************************************************/
     186                 : 
     187             637 : void OGRSQLiteDataSource::SaveStatistics()
     188                 : {
     189                 :     int i;
     190             637 :     int nSavedAllLayersCacheData = -1;
     191                 : 
     192             637 :     if( !bIsSpatiaLiteDB || !OGRSQLiteIsSpatialiteLoaded() || bLastSQLCommandIsUpdateLayerStatistics )
     193             295 :         return;
     194                 : 
     195            1341 :     for( i = 0; i < nLayers; i++ )
     196                 :     {
     197             999 :         if( papoLayers[i]->IsTableLayer() )
     198                 :         {
     199             994 :             OGRSQLiteTableLayer* poLayer = (OGRSQLiteTableLayer*) papoLayers[i];
     200             994 :             int nSaveRet = poLayer->SaveStatistics();
     201             994 :             if( nSaveRet >= 0)
     202                 :             {
     203             144 :                 if( nSavedAllLayersCacheData < 0 )
     204              44 :                     nSavedAllLayersCacheData = nSaveRet;
     205                 :                 else
     206             100 :                     nSavedAllLayersCacheData &= nSaveRet;
     207                 :             }
     208                 :         }
     209                 :     }
     210                 : 
     211             342 :     if( hDB && nSavedAllLayersCacheData == TRUE )
     212                 :     {
     213              32 :         char* pszErrMsg = NULL;
     214                 : 
     215              32 :         int nRowCount = 0, nColCount = 0;
     216              32 :         char **papszResult = NULL;
     217              32 :         int nReplaceEventId = -1;
     218                 : 
     219                 :         sqlite3_get_table( hDB,
     220                 :                            "SELECT event_id, table_name, geometry_column, event "
     221                 :                            "FROM spatialite_history ORDER BY event_id DESC LIMIT 1",
     222                 :                            &papszResult,
     223              32 :                            &nRowCount, &nColCount, &pszErrMsg );
     224                 : 
     225              32 :         if( nRowCount == 1 )
     226                 :         {
     227              32 :             char **papszRow = papszResult + 4;
     228              32 :             const char* pszEventId = papszRow[0];
     229              32 :             const char* pszTableName = papszRow[1];
     230              32 :             const char* pszGeomCol = papszRow[2];
     231              32 :             const char* pszEvent = papszRow[3];
     232                 : 
     233              32 :             if( pszEventId != NULL && pszTableName != NULL &&
     234                 :                 pszGeomCol != NULL && pszEvent != NULL &&
     235                 :                 strcmp(pszTableName, "ALL-TABLES") == 0 &&
     236                 :                 strcmp(pszGeomCol, "ALL-GEOMETRY-COLUMNS") == 0 &&
     237                 :                 strcmp(pszEvent, "UpdateLayerStatistics") == 0 )
     238                 :             {
     239              23 :                 nReplaceEventId = atoi(pszEventId);
     240                 :             }
     241                 :         }
     242              32 :         if( pszErrMsg )
     243               0 :             sqlite3_free( pszErrMsg );
     244              32 :         pszErrMsg = NULL;
     245                 : 
     246              32 :         sqlite3_free_table( papszResult );
     247                 : 
     248                 :         int rc;
     249                 : 
     250              32 :         if( nReplaceEventId >= 0 )
     251                 :         {
     252                 :             rc = sqlite3_exec( hDB,
     253                 :                                CPLSPrintf("UPDATE spatialite_history SET "
     254                 :                                           "timestamp = DateTime('now') "
     255                 :                                           "WHERE event_id = %d", nReplaceEventId),
     256              23 :                                NULL, NULL, &pszErrMsg );
     257                 :         }
     258                 :         else
     259                 :         {
     260                 :             rc = sqlite3_exec( hDB,
     261                 :                 "INSERT INTO spatialite_history (table_name, geometry_column, "
     262                 :                 "event, timestamp, ver_sqlite, ver_splite) VALUES ("
     263                 :                 "'ALL-TABLES', 'ALL-GEOMETRY-COLUMNS', 'UpdateLayerStatistics', "
     264                 :                 "DateTime('now'), sqlite_version(), spatialite_version())",
     265               9 :                 NULL, NULL, &pszErrMsg );
     266                 :         }
     267                 : 
     268              32 :         if( rc != SQLITE_OK )
     269                 :         {
     270               0 :             CPLDebug("SQLITE", "Error %s", pszErrMsg ? pszErrMsg : "unknown");
     271               0 :             sqlite3_free( pszErrMsg );
     272                 :         }
     273                 :     }
     274                 : }
     275                 : 
     276                 : /************************************************************************/
     277                 : /*                              SetSynchronous()                        */
     278                 : /************************************************************************/
     279                 : 
     280             619 : int OGRSQLiteDataSource::SetSynchronous()
     281                 : {
     282                 :     int rc;
     283             619 :     const char* pszSqliteSync = CPLGetConfigOption("OGR_SQLITE_SYNCHRONOUS", NULL);
     284             619 :     if (pszSqliteSync != NULL)
     285                 :     {
     286             607 :         char* pszErrMsg = NULL;
     287            1214 :         if (EQUAL(pszSqliteSync, "OFF") || EQUAL(pszSqliteSync, "0") ||
     288                 :             EQUAL(pszSqliteSync, "FALSE"))
     289             607 :             rc = sqlite3_exec( hDB, "PRAGMA synchronous = OFF", NULL, NULL, &pszErrMsg );
     290               0 :         else if (EQUAL(pszSqliteSync, "NORMAL") || EQUAL(pszSqliteSync, "1"))
     291               0 :             rc = sqlite3_exec( hDB, "PRAGMA synchronous = NORMAL", NULL, NULL, &pszErrMsg );
     292               0 :         else if (EQUAL(pszSqliteSync, "ON") || EQUAL(pszSqliteSync, "FULL") ||
     293                 :             EQUAL(pszSqliteSync, "2") || EQUAL(pszSqliteSync, "TRUE"))
     294               0 :             rc = sqlite3_exec( hDB, "PRAGMA synchronous = FULL", NULL, NULL, &pszErrMsg );
     295                 :         else
     296                 :         {
     297                 :             CPLError( CE_Warning, CPLE_AppDefined, "Unrecognized value for OGR_SQLITE_SYNCHRONOUS : %s",
     298               0 :                       pszSqliteSync);
     299               0 :             rc = SQLITE_OK;
     300                 :         }
     301                 : 
     302             607 :         if( rc != SQLITE_OK )
     303                 :         {
     304                 :             CPLError( CE_Failure, CPLE_AppDefined,
     305                 :                       "Unable to run PRAGMA synchronous : %s",
     306               0 :                       pszErrMsg );
     307               0 :             sqlite3_free( pszErrMsg );
     308               0 :             return FALSE;
     309                 :         }
     310                 :     }
     311             619 :     return TRUE;
     312                 : }
     313                 : 
     314                 : /************************************************************************/
     315                 : /*                              SetCacheSize()                          */
     316                 : /************************************************************************/
     317                 : 
     318             619 : int OGRSQLiteDataSource::SetCacheSize()
     319                 : {
     320                 :     int rc;
     321             619 :     const char* pszSqliteCacheMB = CPLGetConfigOption("OGR_SQLITE_CACHE", NULL);
     322             619 :     if (pszSqliteCacheMB != NULL)
     323                 :     {
     324               0 :         char* pszErrMsg = NULL;
     325                 :         char **papszResult;
     326                 :         int nRowCount, nColCount;
     327                 :         int iSqliteCachePages;
     328               0 :         int iSqlitePageSize = -1;
     329               0 :         int iSqliteCacheBytes = atoi( pszSqliteCacheMB ) * 1024 * 1024;
     330                 : 
     331                 :         /* querying the current PageSize */
     332                 :         rc = sqlite3_get_table( hDB, "PRAGMA page_size",
     333                 :                                 &papszResult, &nRowCount, &nColCount,
     334               0 :                                 &pszErrMsg );
     335               0 :         if( rc == SQLITE_OK )
     336                 :         {
     337                 :             int iRow;
     338               0 :             for (iRow = 1; iRow <= nRowCount; iRow++)
     339                 :             {
     340               0 :                 iSqlitePageSize = atoi( papszResult[(iRow * nColCount) + 0] );
     341                 :             }
     342               0 :             sqlite3_free_table(papszResult);
     343                 :         }
     344               0 :         if( iSqlitePageSize < 0 )
     345                 :         {
     346                 :             CPLError( CE_Failure, CPLE_AppDefined,
     347                 :                       "Unable to run PRAGMA page_size : %s",
     348               0 :                       pszErrMsg );
     349               0 :             sqlite3_free( pszErrMsg );
     350               0 :             return TRUE;
     351                 :         }
     352                 :     
     353                 :         /* computing the CacheSize as #Pages */
     354               0 :         iSqliteCachePages = iSqliteCacheBytes / iSqlitePageSize;
     355               0 :         if( iSqliteCachePages <= 0)
     356               0 :             return TRUE;
     357                 : 
     358                 :         rc = sqlite3_exec( hDB, CPLSPrintf( "PRAGMA cache_size = %d",
     359                 :                                             iSqliteCachePages ),
     360               0 :                            NULL, NULL, &pszErrMsg );
     361               0 :         if( rc != SQLITE_OK )
     362                 :         {
     363                 :             CPLError( CE_Warning, CPLE_AppDefined,
     364                 :                       "Unrecognized value for PRAGMA cache_size : %s",
     365               0 :                       pszErrMsg );
     366               0 :             sqlite3_free( pszErrMsg );
     367               0 :             rc = SQLITE_OK;
     368                 :         }
     369                 :     }
     370             619 :     return TRUE;
     371                 : }
     372                 : 
     373                 : /************************************************************************/
     374                 : /*                 OGRSQLiteDataSourceNotifyFileOpened()                */
     375                 : /************************************************************************/
     376                 : 
     377                 : static
     378            1147 : void OGRSQLiteDataSourceNotifyFileOpened (void* pfnUserData,
     379                 :                                               const char* pszFilename,
     380                 :                                               VSILFILE* fp)
     381                 : {
     382            1147 :     ((OGRSQLiteDataSource*)pfnUserData)->NotifyFileOpened(pszFilename, fp);
     383            1147 : }
     384                 : 
     385                 : 
     386                 : /************************************************************************/
     387                 : /*                          NotifyFileOpened()                          */
     388                 : /************************************************************************/
     389                 : 
     390            1147 : void OGRSQLiteDataSource::NotifyFileOpened(const char* pszFilename,
     391                 :                                            VSILFILE* fp)
     392                 : {
     393            1147 :     if (strcmp(pszFilename, pszName) == 0)
     394                 :     {
     395             456 :         fpMainFile = fp;
     396                 :     }
     397            1147 : }
     398                 : 
     399                 : /************************************************************************/
     400                 : /*                            OpenOrCreateDB()                          */
     401                 : /************************************************************************/
     402                 : 
     403             636 : int OGRSQLiteDataSource::OpenOrCreateDB(int flags)
     404                 : {
     405                 :     int rc;
     406                 : 
     407                 : #ifdef HAVE_SQLITE_VFS
     408             636 :     int bUseOGRVFS = CSLTestBoolean(CPLGetConfigOption("SQLITE_USE_OGR_VFS", "NO"));
     409            1092 :     if (bUseOGRVFS || strncmp(pszName, "/vsi", 4) == 0)
     410                 :     {
     411             456 :         pMyVFS = OGRSQLiteCreateVFS(OGRSQLiteDataSourceNotifyFileOpened, this);
     412             456 :         sqlite3_vfs_register(pMyVFS, 0);
     413             456 :         rc = sqlite3_open_v2( pszName, &hDB, flags, pMyVFS->zName );
     414                 :     }
     415                 :     else
     416             180 :         rc = sqlite3_open_v2( pszName, &hDB, flags, NULL );
     417                 : #else
     418                 :     rc = sqlite3_open( pszName, &hDB );
     419                 : #endif
     420             636 :     if( rc != SQLITE_OK )
     421                 :     {
     422                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     423                 :                   "sqlite3_open(%s) failed: %s",
     424              17 :                   pszName, sqlite3_errmsg( hDB ) );
     425              17 :         return FALSE;
     426                 :     }
     427                 : 
     428             619 :     const char* pszSqliteJournal = CPLGetConfigOption("OGR_SQLITE_JOURNAL", NULL);
     429             619 :     if (pszSqliteJournal != NULL)
     430                 :     {
     431               0 :         char* pszErrMsg = NULL;
     432                 :         char **papszResult;
     433                 :         int nRowCount, nColCount;
     434                 : 
     435                 :         const char* pszSQL = CPLSPrintf("PRAGMA journal_mode = %s",
     436               0 :                                         pszSqliteJournal);
     437                 : 
     438                 :         rc = sqlite3_get_table( hDB, pszSQL,
     439                 :                                 &papszResult, &nRowCount, &nColCount,
     440               0 :                                 &pszErrMsg );
     441               0 :         if( rc == SQLITE_OK )
     442                 :         {
     443               0 :             sqlite3_free_table(papszResult);
     444                 :         }
     445                 :         else
     446                 :         {
     447               0 :             sqlite3_free( pszErrMsg );
     448                 :         }
     449                 :     }
     450                 : 
     451             619 :     if (!SetCacheSize())
     452               0 :         return FALSE;
     453                 : 
     454             619 :     if (!SetSynchronous())
     455               0 :         return FALSE;
     456                 : 
     457             619 :     hRegExpCache = OGRSQLiteRegisterRegExpFunction(hDB);
     458                 : 
     459             619 :     return TRUE;
     460                 : }
     461                 : 
     462                 : /************************************************************************/
     463                 : /*                               Create()                               */
     464                 : /************************************************************************/
     465                 : 
     466             184 : int OGRSQLiteDataSource::Create( const char * pszNameIn, char **papszOptions )
     467                 : {
     468                 :     int rc;
     469             184 :     CPLString osCommand;
     470             184 :     char *pszErrMsg = NULL;
     471                 : 
     472             184 :     pszName = CPLStrdup( pszNameIn );
     473                 : 
     474                 : /* -------------------------------------------------------------------- */
     475                 : /*      Check that spatialite extensions are loaded if required to      */
     476                 : /*      create a spatialite database                                    */
     477                 : /* -------------------------------------------------------------------- */
     478             184 :     int bSpatialite = CSLFetchBoolean( papszOptions, "SPATIALITE", FALSE );
     479             184 :     int bMetadata = CSLFetchBoolean( papszOptions, "METADATA", TRUE );
     480                 : 
     481             184 :     if (bSpatialite == TRUE)
     482                 :     {
     483                 : #ifdef HAVE_SPATIALITE
     484              46 :         OGRSQLiteInitSpatialite();
     485              46 :         if (!OGRSQLiteIsSpatialiteLoaded())
     486                 :         {
     487                 :             CPLError( CE_Failure, CPLE_NotSupported,
     488               1 :                     "Creating a Spatialite database, but Spatialite extensions are not loaded." );
     489               1 :             return FALSE;
     490                 :         }
     491                 : #else
     492                 :         CPLError( CE_Failure, CPLE_NotSupported,
     493                 :             "OGR was built without libspatialite support\n"
     494                 :             "... sorry, creating/writing any SpatiaLite DB is unsupported\n" );
     495                 : 
     496                 :         return FALSE;
     497                 : #endif
     498                 :     }
     499                 : 
     500             183 :     bIsSpatiaLiteDB = bSpatialite;
     501                 : 
     502                 : /* -------------------------------------------------------------------- */
     503                 : /*      Create the database file.                                       */
     504                 : /* -------------------------------------------------------------------- */
     505                 : #ifdef HAVE_SQLITE_VFS
     506             183 :     if (!OpenOrCreateDB(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE))
     507                 : #else
     508                 :     if (!OpenOrCreateDB(0))
     509                 : #endif
     510              17 :         return FALSE;
     511                 : 
     512                 : /* -------------------------------------------------------------------- */
     513                 : /*      Create the SpatiaLite metadata tables.                          */
     514                 : /* -------------------------------------------------------------------- */
     515             166 :     if ( bSpatialite )
     516                 :     {
     517                 :         /*
     518                 :         / SpatiaLite full support: calling InitSpatialMetadata()
     519                 :         /
     520                 :         / IMPORTANT NOTICE: on SpatiaLite any attempt aimed
     521                 :         / to directly CREATE "geometry_columns" and "spatial_ref_sys"
     522                 :         / [by-passing InitSpatialMetadata() as absolutely required]
     523                 :         / will severely [and irremediably] corrupt the DB !!!
     524                 :         */
     525                 :         
     526              28 :         const char* pszVal = CSLFetchNameValue( papszOptions, "INIT_WITH_EPSG" );
     527              28 :         if( pszVal != NULL && !CSLTestBoolean(pszVal) &&
     528                 :             OGRSQLiteGetSpatialiteVersionNumber() >= 40 )
     529               0 :             osCommand =  "SELECT InitSpatialMetadata('NONE')";
     530                 :         else
     531              28 :             osCommand =  "SELECT InitSpatialMetadata()";
     532              28 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     533              28 :         if( rc != SQLITE_OK )
     534                 :         {
     535                 :             CPLError( CE_Failure, CPLE_AppDefined,
     536                 :                 "Unable to Initialize SpatiaLite Metadata: %s",
     537               0 :                     pszErrMsg );
     538               0 :             sqlite3_free( pszErrMsg );
     539               0 :             return FALSE;
     540                 :         }
     541                 :     }
     542                 : 
     543                 : /* -------------------------------------------------------------------- */
     544                 : /*  Create the geometry_columns and spatial_ref_sys metadata tables.    */
     545                 : /* -------------------------------------------------------------------- */
     546             138 :     else if( bMetadata )
     547                 :     {
     548                 :         osCommand =
     549                 :             "CREATE TABLE geometry_columns ("
     550                 :             "     f_table_name VARCHAR, "
     551                 :             "     f_geometry_column VARCHAR, "
     552                 :             "     geometry_type INTEGER, "
     553                 :             "     coord_dimension INTEGER, "
     554                 :             "     srid INTEGER,"
     555             138 :             "     geometry_format VARCHAR )";
     556             138 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     557             138 :         if( rc != SQLITE_OK )
     558                 :         {
     559                 :             CPLError( CE_Failure, CPLE_AppDefined,
     560                 :                       "Unable to create table geometry_columns: %s",
     561               0 :                       pszErrMsg );
     562               0 :             sqlite3_free( pszErrMsg );
     563               0 :             return FALSE;
     564                 :         }
     565                 : 
     566                 :         osCommand =
     567                 :             "CREATE TABLE spatial_ref_sys        ("
     568                 :             "     srid INTEGER UNIQUE,"
     569                 :             "     auth_name TEXT,"
     570                 :             "     auth_srid TEXT,"
     571             138 :             "     srtext TEXT)";
     572             138 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     573             138 :         if( rc != SQLITE_OK )
     574                 :         {
     575                 :             CPLError( CE_Failure, CPLE_AppDefined,
     576                 :                       "Unable to create table spatial_ref_sys: %s",
     577               0 :                       pszErrMsg );
     578               0 :             sqlite3_free( pszErrMsg );
     579               0 :             return FALSE;
     580                 :         }
     581                 :     }
     582                 : 
     583                 : /* -------------------------------------------------------------------- */
     584                 : /*      Optionnaly initialize the content of the spatial_ref_sys table  */
     585                 : /*      with the EPSG database                                          */
     586                 : /* -------------------------------------------------------------------- */
     587             166 :     if ( (bSpatialite || bMetadata) &&
     588                 :          CSLFetchBoolean( papszOptions, "INIT_WITH_EPSG", FALSE ) )
     589                 :     {
     590               2 :         if (!InitWithEPSG())
     591               0 :             return FALSE;
     592                 :     }
     593                 : 
     594             166 :     return Open(pszName, TRUE);
     595                 : }
     596                 : 
     597                 : /************************************************************************/
     598                 : /*                           InitWithEPSG()                             */
     599                 : /************************************************************************/
     600                 : 
     601               2 : int OGRSQLiteDataSource::InitWithEPSG()
     602                 : {
     603               2 :     CPLString osCommand;
     604               2 :     char* pszErrMsg = NULL;
     605                 : 
     606               2 :     if ( bIsSpatiaLiteDB )
     607                 :     {
     608                 :         /*
     609                 :         / if v.2.4.0 (or any subsequent) InitWithEPSG make no sense at all
     610                 :         / because the EPSG dataset is already self-initialized at DB creation
     611                 :         */
     612               0 :         int iSpatialiteVersion = OGRSQLiteGetSpatialiteVersionNumber();
     613               0 :         if ( iSpatialiteVersion >= 24 )
     614               0 :             return TRUE;
     615                 :     }
     616                 : 
     617               2 :     int rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, &pszErrMsg );
     618               2 :     if( rc != SQLITE_OK )
     619                 :     {
     620                 :         CPLError( CE_Failure, CPLE_AppDefined,
     621                 :                 "Unable to insert into spatial_ref_sys: %s",
     622               0 :                 pszErrMsg );
     623               0 :         sqlite3_free( pszErrMsg );
     624               0 :         return FALSE;
     625                 :     }
     626                 : 
     627                 :     FILE* fp;
     628                 :     int i;
     629               6 :     for(i=0;i<2 && rc == SQLITE_OK;i++)
     630                 :     {
     631               4 :         const char* pszFilename = (i == 0) ? "gcs.csv" : "pcs.csv";
     632               4 :         fp = VSIFOpen(CSVFilename(pszFilename), "rt");
     633               4 :         if (fp == NULL)
     634                 :         {
     635                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     636                 :                 "Unable to open EPSG support file %s.\n"
     637                 :                 "Try setting the GDAL_DATA environment variable to point to the\n"
     638                 :                 "directory containing EPSG csv files.",
     639               0 :                 pszFilename );
     640                 : 
     641               0 :             continue;
     642                 :         }
     643                 : 
     644               4 :         OGRSpatialReference oSRS;
     645                 :         char** papszTokens;
     646               4 :         CSLDestroy(CSVReadParseLine( fp ));
     647            8598 :         while ( (papszTokens = CSVReadParseLine( fp )) != NULL && rc == SQLITE_OK)
     648                 :         {
     649            8590 :             int nSRSId = atoi(papszTokens[0]);
     650            8590 :             CSLDestroy(papszTokens);
     651                 : 
     652            8590 :             CPLPushErrorHandler(CPLQuietErrorHandler);
     653            8590 :             oSRS.importFromEPSG(nSRSId);
     654            8590 :             CPLPopErrorHandler();
     655                 : 
     656            8590 :             if (bIsSpatiaLiteDB)
     657                 :             {
     658               0 :                 char    *pszProj4 = NULL;
     659                 : 
     660               0 :                 CPLPushErrorHandler(CPLQuietErrorHandler);
     661               0 :                 OGRErr eErr = oSRS.exportToProj4( &pszProj4 );
     662               0 :                 CPLPopErrorHandler();
     663                 : 
     664               0 :                 char    *pszWKT = NULL;
     665               0 :                 if( oSRS.exportToWkt( &pszWKT ) != OGRERR_NONE )
     666                 :                 {
     667               0 :                     CPLFree(pszWKT);
     668               0 :                     pszWKT = NULL;
     669                 :                 }
     670                 : 
     671               0 :                 if( eErr == OGRERR_NONE )
     672                 :                 {
     673               0 :                     const char  *pszProjCS = oSRS.GetAttrValue("PROJCS");
     674               0 :                     if (pszProjCS == NULL)
     675               0 :                         pszProjCS = oSRS.GetAttrValue("GEOGCS");
     676                 : 
     677               0 :                     const char* pszSRTEXTColName = GetSRTEXTColName();
     678               0 :                     if (pszSRTEXTColName != NULL)
     679                 :                     {
     680                 :                     /* the SPATIAL_REF_SYS table supports a SRS_WKT column */
     681               0 :                         if ( pszProjCS )
     682                 :                             osCommand.Printf(
     683                 :                                 "INSERT INTO spatial_ref_sys "
     684                 :                                 "(srid, auth_name, auth_srid, ref_sys_name, proj4text, %s) "
     685                 :                                 "VALUES (%d, 'EPSG', '%d', ?, ?, ?)",
     686               0 :                                 pszSRTEXTColName, nSRSId, nSRSId);
     687                 :                         else
     688                 :                             osCommand.Printf(
     689                 :                                 "INSERT INTO spatial_ref_sys "
     690                 :                                 "(srid, auth_name, auth_srid, proj4text, %s) "
     691                 :                                 "VALUES (%d, 'EPSG', '%d', ?, ?)",
     692               0 :                                 pszSRTEXTColName, nSRSId, nSRSId);
     693                 :                     }
     694                 :                     else
     695                 :                     {
     696                 :                     /* the SPATIAL_REF_SYS table does not support a SRS_WKT column */
     697               0 :                         if ( pszProjCS )
     698                 :                             osCommand.Printf(
     699                 :                                 "INSERT INTO spatial_ref_sys "
     700                 :                                 "(srid, auth_name, auth_srid, ref_sys_name, proj4text) "
     701                 :                                 "VALUES (%d, 'EPSG', '%d', ?, ?)",
     702               0 :                                 nSRSId, nSRSId);
     703                 :                         else
     704                 :                             osCommand.Printf(
     705                 :                                 "INSERT INTO spatial_ref_sys "
     706                 :                                 "(srid, auth_name, auth_srid, proj4text) "
     707                 :                                 "VALUES (%d, 'EPSG', '%d', ?)",
     708               0 :                                 nSRSId, nSRSId);
     709                 :                     }
     710                 : 
     711               0 :                     sqlite3_stmt *hInsertStmt = NULL;
     712               0 :                     rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
     713                 : 
     714               0 :                     if ( pszProjCS )
     715                 :                     {
     716               0 :                         if( rc == SQLITE_OK)
     717               0 :                             rc = sqlite3_bind_text( hInsertStmt, 1, pszProjCS, -1, SQLITE_STATIC );
     718               0 :                         if( rc == SQLITE_OK)
     719               0 :                             rc = sqlite3_bind_text( hInsertStmt, 2, pszProj4, -1, SQLITE_STATIC );
     720               0 :                         if (pszSRTEXTColName != NULL)
     721                 :                         {
     722                 :                         /* the SPATIAL_REF_SYS table supports a SRS_WKT column */
     723               0 :                             if( rc == SQLITE_OK && pszWKT != NULL)
     724               0 :                                 rc = sqlite3_bind_text( hInsertStmt, 3, pszWKT, -1, SQLITE_STATIC );
     725                 :                         }
     726                 :                     }
     727                 :                     else
     728                 :                     {
     729               0 :                         if( rc == SQLITE_OK)
     730               0 :                             rc = sqlite3_bind_text( hInsertStmt, 1, pszProj4, -1, SQLITE_STATIC );
     731               0 :                         if (pszSRTEXTColName != NULL)
     732                 :                         {
     733                 :                         /* the SPATIAL_REF_SYS table supports a SRS_WKT column */
     734               0 :                             if( rc == SQLITE_OK && pszWKT != NULL)
     735               0 :                                 rc = sqlite3_bind_text( hInsertStmt, 2, pszWKT, -1, SQLITE_STATIC );
     736                 :                         }
     737                 :                     }
     738                 : 
     739               0 :                     if( rc == SQLITE_OK)
     740               0 :                         rc = sqlite3_step( hInsertStmt );
     741                 : 
     742               0 :                     if( rc != SQLITE_OK && rc != SQLITE_DONE )
     743                 :                     {
     744                 :                         CPLError( CE_Failure, CPLE_AppDefined,
     745                 :                                     "Cannot insert %s into spatial_ref_sys : %s",
     746                 :                                     pszProj4,
     747               0 :                                     sqlite3_errmsg(hDB) );
     748                 : 
     749               0 :                         sqlite3_finalize( hInsertStmt );
     750               0 :                         CPLFree(pszProj4);
     751               0 :                         CPLFree(pszWKT);
     752               0 :                         break;
     753                 :                     }
     754               0 :                     rc = SQLITE_OK;
     755                 : 
     756               0 :                     sqlite3_finalize( hInsertStmt );
     757                 :                 }
     758                 : 
     759               0 :                 CPLFree(pszProj4);
     760               0 :                 CPLFree(pszWKT);
     761                 :             }
     762                 :             else
     763                 :             {
     764            8590 :                 char    *pszWKT = NULL;
     765            8590 :                 if( oSRS.exportToWkt( &pszWKT ) == OGRERR_NONE )
     766                 :                 {
     767                 :                     osCommand.Printf(
     768                 :                         "INSERT INTO spatial_ref_sys "
     769                 :                         "(srid, auth_name, auth_srid, srtext) "
     770                 :                         "VALUES (%d, 'EPSG', '%d', ?)",
     771            8590 :                         nSRSId, nSRSId );
     772                 : 
     773            8590 :                     sqlite3_stmt *hInsertStmt = NULL;
     774            8590 :                     rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
     775                 : 
     776            8590 :                     if( rc == SQLITE_OK)
     777            8590 :                         rc = sqlite3_bind_text( hInsertStmt, 1, pszWKT, -1, SQLITE_STATIC );
     778                 : 
     779            8590 :                     if( rc == SQLITE_OK)
     780            8590 :                         rc = sqlite3_step( hInsertStmt );
     781                 : 
     782            8590 :                     if( rc != SQLITE_OK && rc != SQLITE_DONE )
     783                 :                     {
     784                 :                         CPLError( CE_Failure, CPLE_AppDefined,
     785                 :                                     "Cannot insert %s into spatial_ref_sys : %s",
     786                 :                                     pszWKT,
     787               0 :                                     sqlite3_errmsg(hDB) );
     788                 : 
     789               0 :                         sqlite3_finalize( hInsertStmt );
     790               0 :                         CPLFree(pszWKT);
     791               0 :                         break;
     792                 :                     }
     793            8590 :                     rc = SQLITE_OK;
     794                 : 
     795            8590 :                     sqlite3_finalize( hInsertStmt );
     796                 :                 }
     797                 : 
     798            8590 :                 CPLFree(pszWKT);
     799                 :             }
     800                 :         }
     801               4 :         VSIFClose(fp);
     802                 :     }
     803                 : 
     804               2 :     if (rc == SQLITE_OK)
     805               2 :         rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, &pszErrMsg );
     806                 :     else
     807               0 :         rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, &pszErrMsg );
     808                 : 
     809               2 :     if( rc != SQLITE_OK )
     810                 :     {
     811                 :         CPLError( CE_Failure, CPLE_AppDefined,
     812                 :                 "Unable to insert into spatial_ref_sys: %s",
     813               0 :                 pszErrMsg );
     814               0 :         sqlite3_free( pszErrMsg );
     815                 :     }
     816                 : 
     817               2 :     return (rc == SQLITE_OK);
     818                 : }
     819                 : 
     820                 : /************************************************************************/
     821                 : /*                                Open()                                */
     822                 : /************************************************************************/
     823                 : 
     824             619 : int OGRSQLiteDataSource::Open( const char * pszNewName, int bUpdateIn )
     825                 : 
     826                 : {
     827             619 :     CPLAssert( nLayers == 0 );
     828                 : 
     829             619 :     if (pszName == NULL)
     830             453 :         pszName = CPLStrdup( pszNewName );
     831             619 :     bUpdate = bUpdateIn;
     832                 : 
     833                 :     VSIStatBufL sStat;
     834             619 :     if( VSIStatL( pszName, &sStat ) == 0 )
     835                 :     {
     836             603 :         nFileTimestamp = sStat.st_mtime;
     837                 :     }
     838                 : 
     839             619 :     int bListAllTables = CSLTestBoolean(CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "NO"));
     840                 : 
     841                 : /* -------------------------------------------------------------------- */
     842                 : /*      Try to open the sqlite database properly now.                   */
     843                 : /* -------------------------------------------------------------------- */
     844             619 :     if (hDB == NULL)
     845                 :     {
     846             453 :         OGRSQLiteInitSpatialite();
     847                 : 
     848                 : #ifdef HAVE_SQLITE_VFS
     849             453 :         if (!OpenOrCreateDB((bUpdateIn) ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY) )
     850                 : #else
     851                 :         if (!OpenOrCreateDB(0))
     852                 : #endif
     853               0 :             return FALSE;
     854                 :     }
     855                 : 
     856                 :     int rc;
     857             619 :     char *pszErrMsg = NULL;
     858                 : 
     859             619 :     CPLHashSet* hSet = CPLHashSetNew(CPLHashSetHashStr, CPLHashSetEqualStr, CPLFree);
     860                 : 
     861                 : /* -------------------------------------------------------------------- */
     862                 : /*      If we have a GEOMETRY_COLUMNS tables, initialize on the basis   */
     863                 : /*      of that.                                                        */
     864                 : /* -------------------------------------------------------------------- */
     865                 :     char **papszResult;
     866                 :     int nRowCount, iRow, nColCount;
     867                 : 
     868                 :     rc = sqlite3_get_table( 
     869                 :         hDB,
     870                 :         "SELECT f_table_name, f_geometry_column, geometry_type, coord_dimension, geometry_format, srid"
     871                 :         " FROM geometry_columns",
     872             619 :         &papszResult, &nRowCount, &nColCount, &pszErrMsg );
     873                 : 
     874             619 :     if( rc == SQLITE_OK )
     875                 :     {
     876             273 :         CPLDebug("SQLITE", "OGR style SQLite DB found !");
     877                 :     
     878             273 :         bHaveGeometryColumns = TRUE;
     879                 : 
     880             443 :         for ( iRow = 0; iRow < nRowCount; iRow++ )
     881                 :         {
     882             170 :             char **papszRow = papszResult + iRow * 6 + 6;
     883             170 :             const char* pszTableName = papszRow[0];
     884             170 :             const char* pszGeomCol = papszRow[1];
     885                 : 
     886             170 :             if( pszTableName == NULL || pszGeomCol == NULL )
     887               0 :                 continue;
     888                 : 
     889             170 :             aoMapTableToSetOfGeomCols[pszTableName].insert(pszGeomCol);
     890                 :         }
     891                 : 
     892             443 :         for( iRow = 0; iRow < nRowCount; iRow++ )
     893                 :         {
     894             170 :             char **papszRow = papszResult + iRow * 6 + 6;
     895             170 :             OGRwkbGeometryType eGeomType = wkbUnknown;
     896             170 :             int nSRID = 0;
     897             170 :             const char* pszTableName = papszRow[0];
     898             170 :             const char* pszGeomCol = papszRow[1];
     899                 : 
     900             510 :             if (pszTableName == NULL ||
     901                 :                 pszGeomCol == NULL ||
     902             170 :                 papszRow[2] == NULL ||
     903             170 :                 papszRow[3] == NULL)
     904               0 :                 continue;
     905                 : 
     906             170 :             eGeomType = (OGRwkbGeometryType) atoi(papszRow[2]);
     907                 : 
     908             170 :             if( atoi(papszRow[3]) > 2 )
     909               0 :                 eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit);
     910                 : 
     911             170 :             if( papszRow[5] != NULL )
     912              89 :                 nSRID = atoi(papszRow[5]);
     913                 : 
     914             170 :             int nOccurences = (int)aoMapTableToSetOfGeomCols[pszTableName].size();
     915                 : 
     916             170 :             OpenTable( pszTableName, pszGeomCol, nOccurences > 1, eGeomType, papszRow[4],
     917             340 :                        FetchSRS( nSRID ) );
     918                 :                        
     919             170 :             if (bListAllTables)
     920               0 :                 CPLHashSetInsert(hSet, CPLStrdup(papszRow[0]));
     921                 :         }
     922                 : 
     923             273 :         sqlite3_free_table(papszResult);
     924                 : 
     925             273 :         if (bListAllTables)
     926               0 :             goto all_tables;
     927                 :             
     928             273 :         CPLHashSetDestroy(hSet);
     929                 :         
     930             273 :         return TRUE;
     931                 :     }
     932                 : 
     933                 : /* -------------------------------------------------------------------- */
     934                 : /*      Otherwise we can deal with SpatiaLite database.                 */
     935                 : /* -------------------------------------------------------------------- */
     936             346 :     sqlite3_free( pszErrMsg );
     937                 :     rc = sqlite3_get_table( hDB,
     938                 :                             "SELECT f_table_name, f_geometry_column, "
     939                 :                             "type, coord_dimension, srid, "
     940                 :                             "spatial_index_enabled FROM geometry_columns",
     941                 :                             &papszResult, &nRowCount, 
     942             346 :                             &nColCount, &pszErrMsg );
     943             346 :     if (rc != SQLITE_OK )
     944                 :     {
     945                 :         /* Test with SpatiaLite 4.0 schema */
     946               5 :         sqlite3_free( pszErrMsg );
     947                 :         rc = sqlite3_get_table( hDB,
     948                 :                                 "SELECT f_table_name, f_geometry_column, "
     949                 :                                 "geometry_type, coord_dimension, srid, "
     950                 :                                 "spatial_index_enabled FROM geometry_columns",
     951                 :                                 &papszResult, &nRowCount,
     952               5 :                                 &nColCount, &pszErrMsg );
     953               5 :         if ( rc == SQLITE_OK )
     954                 :         {
     955               2 :             bSpatialite4Layout = TRUE;
     956               2 :             nUndefinedSRID = 0;
     957                 :         }
     958                 :     }
     959                 : 
     960             346 :     if ( rc == SQLITE_OK )
     961                 :     {
     962             343 :         bIsSpatiaLiteDB = TRUE;
     963             343 :         bHaveGeometryColumns = TRUE;
     964                 : 
     965             343 :         int iSpatialiteVersion = -1;
     966                 : 
     967                 :         /* Only enables write-mode if linked against SpatiaLite */
     968             343 :         if( OGRSQLiteIsSpatialiteLoaded() )
     969                 :         {
     970             343 :             iSpatialiteVersion = OGRSQLiteGetSpatialiteVersionNumber();
     971                 :         }
     972               0 :         else if( bUpdate )
     973                 :         {
     974                 :             CPLDebug("SQLITE", "SpatiaLite%s DB found, "
     975                 :                      "but updating tables disabled because no linking against spatialite library !",
     976               0 :                      (bSpatialite4Layout) ? " v4" : "");
     977               0 :             bUpdate = FALSE;
     978                 :         }
     979                 : 
     980             345 :         if (bSpatialite4Layout && bUpdate && iSpatialiteVersion > 0 && iSpatialiteVersion < 40)
     981                 :         {
     982                 :             CPLDebug("SQLITE", "SpatiaLite v4 DB found, "
     983                 :                      "but updating tables disabled because runtime spatialite library is v%.1f !",
     984               2 :                      iSpatialiteVersion / 10.0);
     985               2 :             bUpdate = FALSE;
     986                 :         }
     987                 :         else
     988                 :         {
     989                 :             CPLDebug("SQLITE", "SpatiaLite%s DB found !",
     990             341 :                      (bSpatialite4Layout) ? " v4" : "");
     991                 :         }
     992                 : 
     993             561 :         for ( iRow = 0; iRow < nRowCount; iRow++ )
     994                 :         {
     995             218 :             char **papszRow = papszResult + iRow * 6 + 6;
     996             218 :             const char* pszTableName = papszRow[0];
     997             218 :             const char* pszGeomCol = papszRow[1];
     998                 : 
     999             218 :             if( pszTableName == NULL || pszGeomCol == NULL )
    1000               0 :                 continue;
    1001                 : 
    1002             218 :             aoMapTableToSetOfGeomCols[pszTableName].insert(pszGeomCol);
    1003                 :         }
    1004                 : 
    1005             561 :         for ( iRow = 0; iRow < nRowCount; iRow++ )
    1006                 :         {
    1007             218 :             char **papszRow = papszResult + iRow * 6 + 6;
    1008             218 :             OGRwkbGeometryType eGeomType = wkbUnknown;
    1009             218 :             int nSRID = 0;
    1010             218 :             int bHasM = FALSE;
    1011             218 :             int bHasSpatialIndex = FALSE;
    1012             218 :             const char* pszTableName = papszRow[0];
    1013             218 :             const char* pszGeomCol = papszRow[1];
    1014                 : 
    1015             654 :             if (pszTableName == NULL ||
    1016                 :                 pszGeomCol == NULL ||
    1017             218 :                 papszRow[2] == NULL ||
    1018             218 :                 papszRow[3] == NULL)
    1019               0 :                 continue;
    1020                 : 
    1021             218 :             if( bSpatialite4Layout )
    1022                 :             {
    1023               2 :                 int nGeomType = atoi(papszRow[2]);
    1024                 : 
    1025               4 :                 if( nGeomType >= 0 && nGeomType <= 7 ) /* XY */
    1026               2 :                     eGeomType = (OGRwkbGeometryType) nGeomType;
    1027               0 :                 else if( nGeomType >= 1000 && nGeomType <= 1007 ) /* XYZ */
    1028               0 :                     eGeomType = (OGRwkbGeometryType) ((nGeomType - 1000) | wkb25DBit);
    1029               0 :                 else if( nGeomType >= 2000 && nGeomType <= 2007 ) /* XYM */
    1030                 :                 {
    1031               0 :                     eGeomType = (OGRwkbGeometryType) (nGeomType - 2000);
    1032               0 :                     bHasM = TRUE;
    1033                 :                 }
    1034               0 :                 else if( nGeomType >= 3000 && nGeomType <= 3007 ) /* XYZM */
    1035                 :                 {
    1036               0 :                     eGeomType = (OGRwkbGeometryType) ((nGeomType - 3000) | wkb25DBit);
    1037               0 :                     bHasM = TRUE;
    1038                 :                 }
    1039                 :             }
    1040                 :             else
    1041                 :             {
    1042             216 :                 eGeomType = OGRFromOGCGeomType(papszRow[2]);
    1043                 : 
    1044             600 :                 if( strcmp ( papszRow[3], "XYZ" ) == 0 ||
    1045             192 :                     strcmp ( papszRow[3], "XYZM" ) == 0 ||
    1046             192 :                     strcmp ( papszRow[3], "3" ) == 0) // SpatiaLite's own 3D geometries
    1047              24 :                     eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit);
    1048                 : 
    1049             432 :                 if( strcmp ( papszRow[3], "XYM" ) == 0 ||
    1050             216 :                     strcmp ( papszRow[3], "XYZM" ) == 0 ) // M coordinate declared
    1051               0 :                     bHasM = TRUE;
    1052                 :             }
    1053                 : 
    1054                 : 
    1055             218 :             if( papszRow[4] != NULL )
    1056             218 :                 nSRID = atoi(papszRow[4]);
    1057                 : 
    1058             218 :             if( papszRow[5] != NULL )
    1059             218 :                 bHasSpatialIndex = atoi(papszRow[5]);
    1060                 : 
    1061             218 :             int nOccurences = (int)aoMapTableToSetOfGeomCols[pszTableName].size();
    1062                 : 
    1063                 :             OpenTable( pszTableName, pszGeomCol, nOccurences > 1, eGeomType, "SpatiaLite",
    1064             218 :                        FetchSRS( nSRID ), nSRID, bHasSpatialIndex, bHasM );
    1065                 :                        
    1066             218 :             if (bListAllTables)
    1067              48 :                 CPLHashSetInsert(hSet, CPLStrdup(papszRow[0]));
    1068                 :         }
    1069                 : 
    1070             343 :         sqlite3_free_table(papszResult);
    1071                 : 
    1072                 : /* -------------------------------------------------------------------- */
    1073                 : /*      Detect VirtualShape layers                                      */
    1074                 : /* -------------------------------------------------------------------- */
    1075                 : #ifdef HAVE_SPATIALITE
    1076             343 :         if (OGRSQLiteIsSpatialiteLoaded())
    1077                 :         {
    1078                 :             rc = sqlite3_get_table( hDB,
    1079                 :                                 "SELECT name, sql FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE %'",
    1080                 :                                 &papszResult, &nRowCount, 
    1081             343 :                                 &nColCount, &pszErrMsg );
    1082                 : 
    1083             343 :             if ( rc == SQLITE_OK )
    1084                 :             {
    1085             955 :                 for( iRow = 0; iRow < nRowCount; iRow++ )
    1086                 :                 {
    1087             612 :                     char **papszRow = papszResult + iRow * 2 + 2;
    1088             612 :                     const char *pszName = papszRow[0];
    1089             612 :                     const char *pszSQL = papszRow[1];
    1090             612 :                     if( pszName == NULL || pszSQL == NULL )
    1091               0 :                         continue;
    1092                 : 
    1093             612 :                     if( strstr(pszSQL, "VirtualShape") || strstr(pszSQL, "VirtualXL") )
    1094                 :                     {
    1095               2 :                         OpenVirtualTable(pszName, pszSQL);
    1096                 : 
    1097               2 :                         if (bListAllTables)
    1098               0 :                             CPLHashSetInsert(hSet, CPLStrdup(pszName));
    1099                 :                     }
    1100                 :                 }
    1101                 :             }
    1102                 :             else
    1103                 :             {
    1104                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    1105                 :                         "Unable to fetch list of tables: %s", 
    1106               0 :                         pszErrMsg );
    1107               0 :                 sqlite3_free( pszErrMsg );
    1108                 :             }
    1109                 : 
    1110             343 :             sqlite3_free_table(papszResult);
    1111                 :         }
    1112                 : #endif
    1113                 : 
    1114                 : /* -------------------------------------------------------------------- */
    1115                 : /*      Detect spatial views                                            */
    1116                 : /* -------------------------------------------------------------------- */
    1117                 :         rc = sqlite3_get_table( hDB,
    1118                 :                                 "SELECT view_name, view_geometry, view_rowid, f_table_name, f_geometry_column FROM views_geometry_columns",
    1119                 :                                 &papszResult, &nRowCount,
    1120             343 :                                 &nColCount, &pszErrMsg );
    1121             343 :         if ( rc == SQLITE_OK )
    1122                 :         {
    1123             344 :             for( iRow = 0; iRow < nRowCount; iRow++ )
    1124                 :             {
    1125               5 :                 char **papszRow = papszResult + iRow * 5 + 5;
    1126               5 :                 const char* pszViewName = papszRow[0];
    1127               5 :                 const char* pszViewGeometry = papszRow[1];
    1128               5 :                 const char* pszViewRowid = papszRow[2];
    1129               5 :                 const char* pszTableName = papszRow[3];
    1130               5 :                 const char* pszGeometryColumn = papszRow[4];
    1131                 : 
    1132               5 :                 if (pszViewName == NULL ||
    1133                 :                     pszViewGeometry == NULL ||
    1134                 :                     pszViewRowid == NULL ||
    1135                 :                     pszTableName == NULL ||
    1136                 :                     pszGeometryColumn == NULL)
    1137               0 :                     continue;
    1138                 : 
    1139                 :                 OpenView( pszViewName, pszViewGeometry, pszViewRowid,
    1140               5 :                           pszTableName, pszGeometryColumn );
    1141                 : 
    1142               5 :                 if (bListAllTables)
    1143               0 :                     CPLHashSetInsert(hSet, CPLStrdup(pszViewName));
    1144                 :             }
    1145             339 :             sqlite3_free_table(papszResult);
    1146                 :         }
    1147                 : 
    1148                 : 
    1149             343 :         if (bListAllTables)
    1150              66 :             goto all_tables;
    1151                 : 
    1152             277 :         CPLHashSetDestroy(hSet);
    1153                 :         
    1154             277 :         return TRUE;
    1155                 :     }
    1156                 : 
    1157                 : /* -------------------------------------------------------------------- */
    1158                 : /*      Otherwise our final resort is to return all tables and views    */
    1159                 : /*      as non-spatial tables.                                          */
    1160                 : /* -------------------------------------------------------------------- */
    1161               3 :     sqlite3_free( pszErrMsg );
    1162                 :     
    1163                 : all_tables:
    1164                 :     rc = sqlite3_get_table( hDB,
    1165                 :                             "SELECT name FROM sqlite_master "
    1166                 :                             "WHERE type IN ('table','view') "
    1167                 :                             "UNION ALL "
    1168                 :                             "SELECT name FROM sqlite_temp_master "
    1169                 :                             "WHERE type IN ('table','view') "
    1170                 :                             "ORDER BY 1",
    1171                 :                             &papszResult, &nRowCount, 
    1172              69 :                             &nColCount, &pszErrMsg );
    1173                 : 
    1174              69 :     if( rc != SQLITE_OK )
    1175                 :     {
    1176                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1177                 :                   "Unable to fetch list of tables: %s", 
    1178               0 :                   pszErrMsg );
    1179               0 :         sqlite3_free( pszErrMsg );
    1180               0 :         CPLHashSetDestroy(hSet);
    1181               0 :         return FALSE;
    1182                 :     }
    1183                 :     
    1184            1001 :     for( iRow = 0; iRow < nRowCount; iRow++ )
    1185                 :     {
    1186             932 :         if (CPLHashSetLookup(hSet, papszResult[iRow+1]) == NULL)
    1187             884 :             OpenTable( papszResult[iRow+1] );
    1188                 :     }
    1189                 :     
    1190              69 :     sqlite3_free_table(papszResult);
    1191              69 :     CPLHashSetDestroy(hSet);
    1192                 : 
    1193              69 :     return TRUE;
    1194                 : }
    1195                 : 
    1196                 : /************************************************************************/
    1197                 : /*                          OpenVirtualTable()                          */
    1198                 : /************************************************************************/
    1199                 : 
    1200              12 : int OGRSQLiteDataSource::OpenVirtualTable(const char* pszName, const char* pszSQL)
    1201                 : {
    1202              12 :     int nSRID = nUndefinedSRID;
    1203              12 :     const char* pszVirtualShape = strstr(pszSQL, "VirtualShape");
    1204              12 :     if (pszVirtualShape != NULL)
    1205                 :     {
    1206               4 :         const char* pszParenthesis = strchr(pszVirtualShape, '(');
    1207               4 :         if (pszParenthesis)
    1208                 :         {
    1209                 :             /* CREATE VIRTUAL TABLE table_name VirtualShape(shapename, codepage, srid) */
    1210                 :             /* Extract 3rd parameter */
    1211               4 :             char** papszTokens = CSLTokenizeString2( pszParenthesis + 1, ",", CSLT_HONOURSTRINGS );
    1212               4 :             if (CSLCount(papszTokens) == 3)
    1213                 :             {
    1214               4 :                 nSRID = atoi(papszTokens[2]);
    1215                 :             }
    1216               4 :             CSLDestroy(papszTokens);
    1217                 :         }
    1218                 :     }
    1219                 : 
    1220              12 :     if (OpenTable(pszName, NULL, FALSE, wkbUnknown, NULL,
    1221                 :                  (nSRID > 0) ? FetchSRS( nSRID ) : NULL, nSRID,
    1222                 :                   FALSE, FALSE,
    1223                 :                   pszVirtualShape != NULL))
    1224                 :     {
    1225              12 :         OGRSQLiteLayer* poLayer = papoLayers[nLayers-1];
    1226              12 :         OGRFeature* poFeature = poLayer->GetNextFeature();
    1227              12 :         if (poFeature)
    1228                 :         {
    1229              11 :             OGRGeometry* poGeom = poFeature->GetGeometryRef();
    1230              11 :             if (poGeom)
    1231              11 :                 poLayer->GetLayerDefn()->SetGeomType(poGeom->getGeometryType());
    1232              11 :             delete poFeature;
    1233                 :         }
    1234              12 :         poLayer->ResetReading();
    1235              12 :         return TRUE;
    1236                 :     }
    1237               0 :     return FALSE;
    1238                 : }
    1239                 : 
    1240                 : /************************************************************************/
    1241                 : /*                             OpenTable()                              */
    1242                 : /************************************************************************/
    1243                 : 
    1244            1284 : int OGRSQLiteDataSource::OpenTable( const char *pszTableName,
    1245                 :                                     const char *pszGeomCol,
    1246                 :                                     int bMustIncludeGeomColName,
    1247                 :                                     OGRwkbGeometryType eGeomType,
    1248                 :                                     const char *pszGeomFormat,
    1249                 :                                     OGRSpatialReference *poSRS, int nSRID,
    1250                 :                                     int bHasSpatialIndex, int bHasM, 
    1251                 :                                     int bIsVirtualShapeIn )
    1252                 : 
    1253                 : {
    1254                 : /* -------------------------------------------------------------------- */
    1255                 : /*      Create the layer object.                                        */
    1256                 : /* -------------------------------------------------------------------- */
    1257                 :     OGRSQLiteTableLayer  *poLayer;
    1258                 : 
    1259            1284 :     poLayer = new OGRSQLiteTableLayer( this );
    1260                 : 
    1261            1284 :     if( poLayer->Initialize( pszTableName, pszGeomCol, bMustIncludeGeomColName,
    1262                 :                              eGeomType, pszGeomFormat,
    1263                 :                              poSRS, nSRID, bHasSpatialIndex, 
    1264                 :                              bHasM,
    1265                 :                              bIsVirtualShapeIn) != CE_None )
    1266                 :     {
    1267               0 :         delete poLayer;
    1268               0 :         return FALSE;
    1269                 :     }
    1270                 : 
    1271                 : /* -------------------------------------------------------------------- */
    1272                 : /*      Add layer to data source layer list.                            */
    1273                 : /* -------------------------------------------------------------------- */
    1274                 :     papoLayers = (OGRSQLiteLayer **)
    1275            1284 :         CPLRealloc( papoLayers,  sizeof(OGRSQLiteLayer *) * (nLayers+1) );
    1276            1284 :     papoLayers[nLayers++] = poLayer;
    1277                 :     
    1278            1284 :     return TRUE;
    1279                 : }
    1280                 : 
    1281                 : /************************************************************************/
    1282                 : /*                             OpenView()                               */
    1283                 : /************************************************************************/
    1284                 : 
    1285               5 : int OGRSQLiteDataSource::OpenView( const char *pszViewName,
    1286                 :                                    const char *pszViewGeometry,
    1287                 :                                    const char *pszViewRowid,
    1288                 :                                    const char *pszTableName,
    1289                 :                                    const char *pszGeometryColumn)
    1290                 : 
    1291                 : {
    1292                 : /* -------------------------------------------------------------------- */
    1293                 : /*      Create the layer object.                                        */
    1294                 : /* -------------------------------------------------------------------- */
    1295                 :     OGRSQLiteViewLayer  *poLayer;
    1296                 : 
    1297               5 :     poLayer = new OGRSQLiteViewLayer( this );
    1298                 : 
    1299               5 :     if( poLayer->Initialize( pszViewName, pszViewGeometry,
    1300                 :                              pszViewRowid, pszTableName, pszGeometryColumn ) != CE_None )
    1301                 :     {
    1302               0 :         delete poLayer;
    1303               0 :         return FALSE;
    1304                 :     }
    1305                 : 
    1306                 : /* -------------------------------------------------------------------- */
    1307                 : /*      Add layer to data source layer list.                            */
    1308                 : /* -------------------------------------------------------------------- */
    1309                 :     papoLayers = (OGRSQLiteLayer **)
    1310               5 :         CPLRealloc( papoLayers,  sizeof(OGRSQLiteLayer *) * (nLayers+1) );
    1311               5 :     papoLayers[nLayers++] = poLayer;
    1312                 : 
    1313               5 :     return TRUE;
    1314                 : }
    1315                 : 
    1316                 : /************************************************************************/
    1317                 : /*                           TestCapability()                           */
    1318                 : /************************************************************************/
    1319                 : 
    1320              18 : int OGRSQLiteDataSource::TestCapability( const char * pszCap )
    1321                 : 
    1322                 : {
    1323              18 :     if( EQUAL(pszCap,ODsCCreateLayer) )
    1324               8 :         return bUpdate;
    1325              10 :     else if( EQUAL(pszCap,ODsCDeleteLayer) )
    1326               0 :         return bUpdate;
    1327                 :     else
    1328              10 :         return FALSE;
    1329                 : }
    1330                 : 
    1331                 : /************************************************************************/
    1332                 : /*                              GetLayer()                              */
    1333                 : /************************************************************************/
    1334                 : 
    1335            2389 : OGRLayer *OGRSQLiteDataSource::GetLayer( int iLayer )
    1336                 : 
    1337                 : {
    1338            2389 :     if( iLayer < 0 || iLayer >= nLayers )
    1339              20 :         return NULL;
    1340                 :     else
    1341            2369 :         return papoLayers[iLayer];
    1342                 : }
    1343                 : 
    1344                 : /************************************************************************/
    1345                 : /*                             ExecuteSQL()                             */
    1346                 : /************************************************************************/
    1347                 : 
    1348                 : static const char* apszSpatialiteFuncs[] =
    1349                 : {
    1350                 :     "InitSpatialMetaData",
    1351                 :     "AddGeometryColumn",
    1352                 :     "RecoverGeometryColumn",
    1353                 :     "DiscardGeometryColumn",
    1354                 :     "CreateSpatialIndex",
    1355                 :     "CreateMbrCache",
    1356                 :     "DisableSpatialIndex",
    1357                 :     "UpdateLayerStatistics"
    1358                 : };
    1359                 : 
    1360             608 : OGRLayer * OGRSQLiteDataSource::ExecuteSQL( const char *pszSQLCommand,
    1361                 :                                           OGRGeometry *poSpatialFilter,
    1362                 :                                           const char *pszDialect )
    1363                 : 
    1364                 : {
    1365             608 :     if( pszDialect != NULL && EQUAL(pszDialect,"OGRSQL") )
    1366                 :         return OGRDataSource::ExecuteSQL( pszSQLCommand, 
    1367                 :                                           poSpatialFilter, 
    1368               4 :                                           pszDialect );
    1369                 : 
    1370                 : /* -------------------------------------------------------------------- */
    1371                 : /*      Special case DELLAYER: command.                                 */
    1372                 : /* -------------------------------------------------------------------- */
    1373             604 :     if( EQUALN(pszSQLCommand,"DELLAYER:",9) )
    1374                 :     {
    1375              22 :         const char *pszLayerName = pszSQLCommand + 9;
    1376                 : 
    1377              44 :         while( *pszLayerName == ' ' )
    1378               0 :             pszLayerName++;
    1379                 : 
    1380              22 :         DeleteLayer( pszLayerName );
    1381              22 :         return NULL;
    1382                 :     }
    1383                 : 
    1384                 : /* -------------------------------------------------------------------- */
    1385                 : /*      Special case GetVSILFILE() command (used by GDAL MBTiles driver)*/
    1386                 : /* -------------------------------------------------------------------- */
    1387             582 :     if (strcmp(pszSQLCommand, "GetVSILFILE()") == 0)
    1388                 :     {
    1389               1 :         if (fpMainFile == NULL)
    1390               0 :             return NULL;
    1391                 : 
    1392                 :         char szVal[64];
    1393               1 :         int nRet = CPLPrintPointer( szVal, fpMainFile, sizeof(szVal)-1 );
    1394               1 :         szVal[nRet] = '\0';
    1395               1 :         return new OGRSQLiteSingleFeatureLayer( "VSILFILE", szVal );
    1396                 :     }
    1397                 : 
    1398                 : /* -------------------------------------------------------------------- */
    1399                 : /*      In case, this is not a SELECT, invalidate cached feature        */
    1400                 : /*      count and extent to be on the safe side.                        */
    1401                 : /* -------------------------------------------------------------------- */
    1402             581 :     if( EQUAL(pszSQLCommand, "VACUUM") )
    1403                 :     {
    1404               1 :         int bNeedRefresh = -1;
    1405                 :         int i;
    1406               4 :         for( i = 0; i < nLayers; i++ )
    1407                 :         {
    1408               3 :             if( papoLayers[i]->IsTableLayer() )
    1409                 :             {
    1410               3 :                 OGRSQLiteTableLayer* poLayer = (OGRSQLiteTableLayer*) papoLayers[i];
    1411               3 :                 if ( !(poLayer->AreStatisticsValid()) ||
    1412                 :                      poLayer->DoStatisticsNeedToBeFlushed())
    1413                 :                 {
    1414               0 :                     bNeedRefresh = FALSE;
    1415               0 :                     break;
    1416                 :                 }
    1417               3 :                 else if( bNeedRefresh < 0 )
    1418               1 :                     bNeedRefresh = TRUE;
    1419                 :             }
    1420                 :         }
    1421               1 :         if( bNeedRefresh == TRUE )
    1422                 :         {
    1423               4 :             for( i = 0; i < nLayers; i++ )
    1424                 :             {
    1425               3 :                 if( papoLayers[i]->IsTableLayer() )
    1426                 :                 {
    1427               3 :                     OGRSQLiteTableLayer* poLayer = (OGRSQLiteTableLayer*) papoLayers[i];
    1428               3 :                     poLayer->ForceStatisticsToBeFlushed();
    1429                 :                 }
    1430                 :             }
    1431                 :         }
    1432                 :     }
    1433             580 :     else if( !EQUALN(pszSQLCommand,"SELECT ",7) && !EQUAL(pszSQLCommand, "BEGIN")
    1434                 :         && !EQUAL(pszSQLCommand, "COMMIT")
    1435                 :         && !EQUALN(pszSQLCommand, "CREATE TABLE ", strlen("CREATE TABLE ")) )
    1436                 :     {
    1437             401 :         for(int i = 0; i < nLayers; i++)
    1438             326 :             papoLayers[i]->InvalidateCachedFeatureCountAndExtent();
    1439                 :     }
    1440                 : 
    1441                 :     bLastSQLCommandIsUpdateLayerStatistics =
    1442             581 :         EQUAL(pszSQLCommand, "SELECT UpdateLayerStatistics()");
    1443                 : 
    1444                 : /* -------------------------------------------------------------------- */
    1445                 : /*      Prepare statement.                                              */
    1446                 : /* -------------------------------------------------------------------- */
    1447                 :     int rc;
    1448             581 :     sqlite3_stmt *hSQLStmt = NULL;
    1449                 : 
    1450             581 :     CPLString osSQLCommand = pszSQLCommand;
    1451                 : 
    1452                 :     /* This will speed-up layer creation */
    1453                 :     /* ORDER BY are costly to evaluate and are not necessary to establish */
    1454                 :     /* the layer definition. */
    1455             581 :     int bUseStatementForGetNextFeature = TRUE;
    1456             581 :     int bEmptyLayer = FALSE;
    1457                 : 
    1458             581 :     if( osSQLCommand.ifind("SELECT ") == 0 &&
    1459                 :         osSQLCommand.ifind(" UNION ") == std::string::npos &&
    1460                 :         osSQLCommand.ifind(" INTERSECT ") == std::string::npos &&
    1461                 :         osSQLCommand.ifind(" EXCEPT ") == std::string::npos )
    1462                 :     {
    1463             411 :         size_t nOrderByPos = osSQLCommand.ifind(" ORDER BY ");
    1464             411 :         if( nOrderByPos != std::string::npos )
    1465                 :         {
    1466              37 :             osSQLCommand.resize(nOrderByPos);
    1467              37 :             bUseStatementForGetNextFeature = FALSE;
    1468                 :         }
    1469                 :     }
    1470                 : 
    1471                 :     rc = sqlite3_prepare( GetDB(), osSQLCommand.c_str(), osSQLCommand.size(),
    1472             581 :                           &hSQLStmt, NULL );
    1473                 : 
    1474             581 :     if( rc != SQLITE_OK )
    1475                 :     {
    1476                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1477                 :                 "In ExecuteSQL(): sqlite3_prepare(%s):\n  %s", 
    1478              14 :                 pszSQLCommand, sqlite3_errmsg(GetDB()) );
    1479                 : 
    1480              14 :         if( hSQLStmt != NULL )
    1481                 :         {
    1482               0 :             sqlite3_finalize( hSQLStmt );
    1483                 :         }
    1484                 : 
    1485              14 :         return NULL;
    1486                 :     }
    1487                 : 
    1488                 : /* -------------------------------------------------------------------- */
    1489                 : /*      Do we get a resultset?                                          */
    1490                 : /* -------------------------------------------------------------------- */
    1491             567 :     rc = sqlite3_step( hSQLStmt );
    1492             567 :     if( rc != SQLITE_ROW )
    1493                 :     {
    1494             206 :         if ( rc != SQLITE_DONE )
    1495                 :         {
    1496                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1497                 :                   "In ExecuteSQL(): sqlite3_step(%s):\n  %s", 
    1498              12 :                   pszSQLCommand, sqlite3_errmsg(GetDB()) );
    1499                 : 
    1500              12 :             sqlite3_finalize( hSQLStmt );
    1501              12 :             return NULL;
    1502                 :         }
    1503                 : 
    1504             194 :         if( EQUALN(pszSQLCommand, "CREATE ", 7) )
    1505                 :         {
    1506              58 :             char **papszTokens = CSLTokenizeString( pszSQLCommand );
    1507             126 :             if ( CSLCount(papszTokens) >= 4 &&
    1508              58 :                  EQUAL(papszTokens[1], "VIRTUAL") &&
    1509              10 :                  EQUAL(papszTokens[2], "TABLE") )
    1510                 :             {
    1511              10 :                 OpenVirtualTable(papszTokens[3], pszSQLCommand);
    1512                 :             }
    1513              58 :             CSLDestroy(papszTokens);
    1514                 : 
    1515              58 :             sqlite3_finalize( hSQLStmt );
    1516              58 :             return NULL;
    1517                 :         }
    1518                 : 
    1519             136 :         if( !EQUALN(pszSQLCommand, "SELECT ", 7) )
    1520                 :         {
    1521              92 :             sqlite3_finalize( hSQLStmt );
    1522              92 :             return NULL;
    1523                 :         }
    1524                 : 
    1525              44 :         bUseStatementForGetNextFeature = FALSE;
    1526              44 :         bEmptyLayer = TRUE;
    1527                 :     }
    1528                 :     
    1529                 : /* -------------------------------------------------------------------- */
    1530                 : /*      Special case for some spatialite functions which must be run    */
    1531                 : /*      only once                                                       */
    1532                 : /* -------------------------------------------------------------------- */
    1533             405 :     if( EQUALN(pszSQLCommand,"SELECT ",7) &&
    1534                 :         bIsSpatiaLiteDB && OGRSQLiteIsSpatialiteLoaded() )
    1535                 :     {
    1536                 :         unsigned int i;
    1537            1972 :         for(i=0;i<sizeof(apszSpatialiteFuncs)/
    1538                 :                   sizeof(apszSpatialiteFuncs[0]);i++)
    1539                 :         {
    1540            1786 :             if( EQUALN(apszSpatialiteFuncs[i], pszSQLCommand + 7,
    1541                 :                        strlen(apszSpatialiteFuncs[i])) )
    1542                 :             {
    1543              60 :                 if (sqlite3_column_count( hSQLStmt ) == 1 &&
    1544                 :                     sqlite3_column_type( hSQLStmt, 0 ) == SQLITE_INTEGER )
    1545                 :                 {
    1546              60 :                     int ret = sqlite3_column_int( hSQLStmt, 0 );
    1547                 : 
    1548              60 :                     sqlite3_finalize( hSQLStmt );
    1549                 : 
    1550                 :                     return new OGRSQLiteSingleFeatureLayer
    1551              60 :                                         ( apszSpatialiteFuncs[i], ret );
    1552                 :                 }
    1553                 :             }
    1554                 :         }
    1555                 :     }
    1556                 : 
    1557                 : /* -------------------------------------------------------------------- */
    1558                 : /*      Create layer.                                                   */
    1559                 : /* -------------------------------------------------------------------- */
    1560             345 :     OGRSQLiteSelectLayer *poLayer = NULL;
    1561                 :         
    1562             345 :     CPLString osSQL = pszSQLCommand;
    1563                 :     poLayer = new OGRSQLiteSelectLayer( this, osSQL, hSQLStmt,
    1564             345 :                                         bUseStatementForGetNextFeature, bEmptyLayer );
    1565                 : 
    1566             345 :     if( poSpatialFilter != NULL )
    1567               0 :         poLayer->SetSpatialFilter( poSpatialFilter );
    1568                 :     
    1569             345 :     return poLayer;
    1570                 : }
    1571                 : 
    1572                 : /************************************************************************/
    1573                 : /*                          ReleaseResultSet()                          */
    1574                 : /************************************************************************/
    1575                 : 
    1576             424 : void OGRSQLiteDataSource::ReleaseResultSet( OGRLayer * poLayer )
    1577                 : 
    1578                 : {
    1579             424 :     delete poLayer;
    1580             424 : }
    1581                 : 
    1582                 : /************************************************************************/
    1583                 : /*                            CreateLayer()                             */
    1584                 : /************************************************************************/
    1585                 : 
    1586                 : OGRLayer *
    1587             119 : OGRSQLiteDataSource::CreateLayer( const char * pszLayerNameIn,
    1588                 :                                   OGRSpatialReference *poSRS,
    1589                 :                                   OGRwkbGeometryType eType,
    1590                 :                                   char ** papszOptions )
    1591                 : 
    1592                 : {
    1593                 :     char                *pszLayerName;
    1594                 :     const char          *pszGeomFormat;
    1595             119 :     int                  bImmediateSpatialIndexCreation = FALSE;
    1596             119 :     int                  bDeferedSpatialIndexCreation = FALSE;
    1597                 : 
    1598                 : /* -------------------------------------------------------------------- */
    1599                 : /*      Verify we are in update mode.                                   */
    1600                 : /* -------------------------------------------------------------------- */
    1601             119 :     if( !bUpdate )
    1602                 :     {
    1603                 :         CPLError( CE_Failure, CPLE_NoWriteAccess,
    1604                 :                   "Data source %s opened read-only.\n"
    1605                 :                   "New layer %s cannot be created.\n",
    1606               2 :                   pszName, pszLayerNameIn );
    1607                 : 
    1608               2 :         return NULL;
    1609                 :     }
    1610                 : 
    1611             117 :     if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) )
    1612             116 :         pszLayerName = LaunderName( pszLayerNameIn );
    1613                 :     else
    1614               1 :         pszLayerName = CPLStrdup( pszLayerNameIn );
    1615                 : 
    1616             117 :     CPLString osEscapedLayerName = OGRSQLiteEscape(pszLayerName);
    1617             117 :     const char* pszEscapedLayerName = osEscapedLayerName.c_str();
    1618                 :     
    1619             117 :     pszGeomFormat = CSLFetchNameValue( papszOptions, "FORMAT" );
    1620             117 :     if( pszGeomFormat == NULL )
    1621                 :     {
    1622             108 :         if ( !bIsSpatiaLiteDB )
    1623              38 :             pszGeomFormat = "WKB";
    1624                 :         else
    1625              70 :             pszGeomFormat = "SpatiaLite";
    1626                 :     }
    1627                 : 
    1628             117 :     if( !EQUAL(pszGeomFormat,"WKT") 
    1629                 :         && !EQUAL(pszGeomFormat,"WKB")
    1630                 :         && !EQUAL(pszGeomFormat, "SpatiaLite") )
    1631                 :     {
    1632                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1633                 :                   "FORMAT=%s not recognised or supported.", 
    1634               2 :                   pszGeomFormat );
    1635               2 :         CPLFree( pszLayerName );
    1636               2 :         return NULL;
    1637                 :     }
    1638                 : 
    1639             115 :     if (bIsSpatiaLiteDB && !EQUAL(pszGeomFormat, "SpatiaLite") )
    1640                 :     {
    1641                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1642                 :                   "FORMAT=%s not supported on a SpatiaLite enabled database.",
    1643               1 :                   pszGeomFormat );
    1644               1 :         CPLFree( pszLayerName );
    1645               1 :         return NULL;
    1646                 :     }
    1647                 : 
    1648                 :     /* Shouldn't happen since a spatialite DB should be opened in read-only mode */
    1649                 :     /* if libspatialite isn't loaded */
    1650             114 :     if (bIsSpatiaLiteDB && !OGRSQLiteIsSpatialiteLoaded())
    1651                 :     {
    1652                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1653                 :                   "Creating layers on a SpatiaLite enabled database, "
    1654               0 :                   "without Spatialite extensions loaded, is not supported." );
    1655               0 :         CPLFree( pszLayerName );
    1656               0 :         return NULL;
    1657                 :     }
    1658                 : 
    1659                 : /* -------------------------------------------------------------------- */
    1660                 : /*      Do we already have this layer?  If so, should we blow it        */
    1661                 : /*      away?                                                           */
    1662                 : /* -------------------------------------------------------------------- */
    1663                 :     int iLayer;
    1664                 : 
    1665            1213 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
    1666                 :     {
    1667            1101 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) )
    1668                 :         {
    1669               4 :             if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL
    1670                 :                 && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") )
    1671                 :             {
    1672               2 :                 DeleteLayer( pszLayerName );
    1673                 :             }
    1674                 :             else
    1675                 :             {
    1676                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    1677                 :                           "Layer %s already exists, CreateLayer failed.\n"
    1678                 :                           "Use the layer creation option OVERWRITE=YES to "
    1679                 :                           "replace it.",
    1680               2 :                           pszLayerName );
    1681               2 :                 CPLFree( pszLayerName );
    1682               2 :                 return NULL;
    1683                 :             }
    1684                 :         }
    1685                 :     }
    1686                 : 
    1687                 : /* -------------------------------------------------------------------- */
    1688                 : /*      Try to get the SRS Id of this spatial reference system,         */
    1689                 : /*      adding to the srs table if needed.                              */
    1690                 : /* -------------------------------------------------------------------- */
    1691             112 :     int nSRSId = nUndefinedSRID;
    1692             112 :     const char* pszSRID = CSLFetchNameValue(papszOptions, "SRID");
    1693                 : 
    1694             112 :     if( pszSRID != NULL )
    1695                 :     {
    1696               6 :         nSRSId = atoi(pszSRID);
    1697               6 :         if( nSRSId > 0 )
    1698                 :         {
    1699               6 :             OGRSpatialReference* poSRSFetched = FetchSRS( nSRSId );
    1700               6 :             if( poSRSFetched == NULL )
    1701                 :             {
    1702                 :                 CPLError(CE_Warning, CPLE_AppDefined,
    1703                 :                          "SRID %d will be used, but no matching SRS is defined in spatial_ref_sys",
    1704               3 :                          nSRSId);
    1705                 :             }
    1706                 :         }
    1707                 :     }
    1708             106 :     else if( poSRS != NULL )
    1709              80 :         nSRSId = FetchSRSId( poSRS );
    1710                 : 
    1711                 : /* -------------------------------------------------------------------- */
    1712                 : /*      Create a basic table with the FID.  Also include the            */
    1713                 : /*      geometry if this is not a PostGIS enabled table.                */
    1714                 : /* -------------------------------------------------------------------- */
    1715                 :     int rc;
    1716                 :     char *pszErrMsg;
    1717             112 :     const char *pszGeomCol = NULL;
    1718             112 :     CPLString osCommand;
    1719                 : 
    1720             112 :     if( eType == wkbNone )
    1721                 :         osCommand.Printf( 
    1722                 :             "CREATE TABLE '%s' ( OGC_FID INTEGER PRIMARY KEY )", 
    1723               0 :             pszEscapedLayerName );
    1724                 :     else
    1725                 :     {
    1726             112 :         if( EQUAL(pszGeomFormat,"WKT") )
    1727                 :         {
    1728               2 :             pszGeomCol = "WKT_GEOMETRY";
    1729                 :             osCommand.Printf(
    1730                 :                 "CREATE TABLE '%s' ( "
    1731                 :                 "  OGC_FID INTEGER PRIMARY KEY,"
    1732                 :                 "  '%s' VARCHAR )", 
    1733                 :                 pszEscapedLayerName,
    1734               2 :                 OGRSQLiteEscape(pszGeomCol).c_str() );
    1735                 :         }
    1736                 :         else
    1737                 :         {
    1738             110 :             pszGeomCol = "GEOMETRY";
    1739                 : 
    1740                 :             /* Only if was created as a SpatiaLite DB */
    1741             110 :             if ( bIsSpatiaLiteDB )
    1742                 :             {
    1743                 :                 /* 
    1744                 :                 / SpatiaLite full support: we must create the 
    1745                 :                 / Geometry in a second time using AddGeometryColumn()
    1746                 :                 /
    1747                 :                 / IMPORTANT NOTICE: on SpatiaLite any attempt aimed
    1748                 :                 / to directly creating some Geometry column 
    1749                 :                 / [by-passing AddGeometryColumn() as absolutely required]
    1750                 :                 / will severely [and irremediably] corrupt the DB !!!
    1751                 :                 */
    1752                 :                 osCommand.Printf( "CREATE TABLE '%s' ( "
    1753                 :                                   "  OGC_FID INTEGER PRIMARY KEY)",
    1754              70 :                                   pszEscapedLayerName);
    1755                 :             }
    1756                 :             else
    1757                 :             {
    1758                 :                 osCommand.Printf( "CREATE TABLE '%s' ( "
    1759                 :                                   "  OGC_FID INTEGER PRIMARY KEY,"
    1760                 :                                   "  '%s' BLOB )", 
    1761                 :                                   pszEscapedLayerName,
    1762              40 :                                   OGRSQLiteEscape(pszGeomCol).c_str() );
    1763                 :             }
    1764                 :         }
    1765                 :     }
    1766                 : 
    1767                 : #ifdef DEBUG
    1768             112 :     CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
    1769                 : #endif
    1770                 : 
    1771             112 :     rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
    1772             112 :     if( rc != SQLITE_OK )
    1773                 :     {
    1774                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1775                 :                   "Unable to create table %s: %s",
    1776               0 :                   pszLayerName, pszErrMsg );
    1777               0 :         sqlite3_free( pszErrMsg );
    1778               0 :         return FALSE;
    1779                 :     }
    1780                 : 
    1781                 : /* -------------------------------------------------------------------- */
    1782                 : /*      Eventually we should be adding this table to a table of         */
    1783                 : /*      "geometric layers", capturing the WKT projection, and           */
    1784                 : /*      perhaps some other housekeeping.                                */
    1785                 : /* -------------------------------------------------------------------- */
    1786             112 :     if( bHaveGeometryColumns && eType != wkbNone )
    1787                 :     {
    1788                 :         int nCoordDim;
    1789                 : 
    1790                 :         /* Sometimes there is an old cruft entry in the geometry_columns
    1791                 :          * table if things were not properly cleaned up before.  We make
    1792                 :          * an effort to clean out such cruft.
    1793                 :          */
    1794                 :         osCommand.Printf(
    1795                 :             "DELETE FROM geometry_columns WHERE f_table_name = '%s'", 
    1796             112 :             pszEscapedLayerName );
    1797                 :                  
    1798                 : #ifdef DEBUG
    1799             112 :         CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
    1800                 : #endif
    1801                 : 
    1802             112 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
    1803             112 :         if( rc != SQLITE_OK )
    1804                 :         {
    1805               0 :             sqlite3_free( pszErrMsg );
    1806               0 :             return FALSE;
    1807                 :         }
    1808                 :         
    1809             112 :         if( eType == wkbFlatten(eType) )
    1810              88 :             nCoordDim = 2;
    1811                 :         else
    1812              24 :             nCoordDim = 3;
    1813                 :         
    1814             112 :         if ( bIsSpatiaLiteDB )
    1815                 :         {
    1816                 :             /*
    1817                 :             / SpatiaLite full support: calling AddGeometryColumn()
    1818                 :             /
    1819                 :             / IMPORTANT NOTICE: on SpatiaLite any attempt aimed
    1820                 :             / to directly INSERT a row into GEOMETRY_COLUMNS
    1821                 :             / [by-passing AddGeometryColumn() as absolutely required]
    1822                 :             / will severely [and irremediably] corrupt the DB !!!
    1823                 :             */
    1824              70 :             const char *pszType = OGRToOGCGeomType(eType);
    1825              70 :             if (pszType[0] == '\0')
    1826               0 :                 pszType = "GEOMETRY";
    1827                 : 
    1828                 :             /*
    1829                 :             / SpatiaLite v.2.4.0 (or any subsequent) is required
    1830                 :             / to support 2.5D: if an obsolete version of the library
    1831                 :             / is found we'll unconditionally activate 2D casting mode
    1832                 :             */
    1833              70 :             int iSpatialiteVersion = OGRSQLiteGetSpatialiteVersionNumber();
    1834              70 :             if ( iSpatialiteVersion < 24 && nCoordDim == 3 )
    1835                 :             {
    1836               0 :                 CPLDebug("SQLITE", "Spatialite < 2.4.0 --> 2.5D geometry not supported. Casting to 2D");
    1837               0 :                 nCoordDim = 2;
    1838                 :             }
    1839                 : 
    1840                 :             osCommand.Printf( "SELECT AddGeometryColumn("
    1841                 :                               "'%s', '%s', %d, '%s', %d)",
    1842                 :                               pszEscapedLayerName,
    1843                 :                               OGRSQLiteEscape(pszGeomCol).c_str(), nSRSId,
    1844              70 :                               pszType, nCoordDim );
    1845                 :         }
    1846                 :         else
    1847                 :         {
    1848              42 :             if( nSRSId > 0 )
    1849                 :             {
    1850                 :                 osCommand.Printf(
    1851                 :                     "INSERT INTO geometry_columns "
    1852                 :                     "(f_table_name, f_geometry_column, geometry_format, "
    1853                 :                     "geometry_type, coord_dimension, srid) VALUES "
    1854                 :                     "('%s','%s','%s', %d, %d, %d)", 
    1855                 :                     pszEscapedLayerName,
    1856                 :                     OGRSQLiteEscape(pszGeomCol).c_str(), pszGeomFormat,
    1857              16 :                     (int) wkbFlatten(eType), nCoordDim, nSRSId );
    1858                 :             }
    1859                 :             else
    1860                 :             {
    1861                 :                 osCommand.Printf(
    1862                 :                     "INSERT INTO geometry_columns "
    1863                 :                     "(f_table_name, f_geometry_column, geometry_format, "
    1864                 :                     "geometry_type, coord_dimension) VALUES "
    1865                 :                     "('%s','%s','%s', %d, %d)",
    1866                 :                     pszEscapedLayerName,
    1867                 :                     OGRSQLiteEscape(pszGeomCol).c_str(), pszGeomFormat,
    1868              26 :                     (int) wkbFlatten(eType), nCoordDim );
    1869                 :             }
    1870                 :         }
    1871                 : 
    1872                 : #ifdef DEBUG
    1873             112 :         CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
    1874                 : #endif
    1875                 : 
    1876             112 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
    1877             112 :         if( rc != SQLITE_OK )
    1878                 :         {
    1879                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1880                 :                       "Unable to add %s table to geometry_columns:\n%s",
    1881               0 :                       pszLayerName, pszErrMsg );
    1882               0 :             sqlite3_free( pszErrMsg );
    1883               0 :             return FALSE;
    1884                 :         }
    1885                 : 
    1886                 : /* -------------------------------------------------------------------- */
    1887                 : /*      Create the spatial index.                                       */
    1888                 : /*                                                                      */
    1889                 : /*      We're doing this before we add geometry and record to the table */
    1890                 : /*      so this may not be exactly the best way to do it.               */
    1891                 : /* -------------------------------------------------------------------- */
    1892                 : 
    1893             112 :         const char* pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" );
    1894             112 :         if ( pszSI != NULL && CSLTestBoolean(pszSI) &&
    1895                 :              (bIsSpatiaLiteDB || EQUAL(pszGeomFormat, "SpatiaLite")) && !OGRSQLiteIsSpatialiteLoaded() )
    1896                 :         {
    1897                 :             CPLError( CE_Warning, CPLE_OpenFailed,
    1898               0 :                     "Cannot create a spatial index when Spatialite extensions are not loaded." );
    1899                 :         }
    1900                 : 
    1901                 : #ifdef HAVE_SPATIALITE
    1902                 :         /* Only if linked against SpatiaLite and the datasource was created as a SpatiaLite DB */
    1903             112 :         if ( bIsSpatiaLiteDB && OGRSQLiteIsSpatialiteLoaded() )
    1904                 : #else
    1905                 :         if ( 0 )
    1906                 : #endif
    1907                 :         {
    1908              70 :             if( pszSI != NULL && EQUAL(pszSI, "IMMEDIATE") )
    1909                 :             {
    1910               0 :                 bImmediateSpatialIndexCreation = TRUE;
    1911                 :             }
    1912              70 :             else if( pszSI == NULL || CSLTestBoolean(pszSI) )
    1913                 :             {
    1914              70 :                 bDeferedSpatialIndexCreation = TRUE;
    1915                 :             }
    1916                 :         }
    1917                 :     }
    1918                 : 
    1919                 : /* -------------------------------------------------------------------- */
    1920                 : /*      Create the layer object.                                        */
    1921                 : /* -------------------------------------------------------------------- */
    1922                 :     OGRSQLiteTableLayer     *poLayer;
    1923                 : 
    1924             112 :     poLayer = new OGRSQLiteTableLayer( this );
    1925                 : 
    1926             224 :     if ( poLayer->Initialize( pszLayerName, pszGeomCol, FALSE, eType, pszGeomFormat,
    1927                 :                               FetchSRS(nSRSId), nSRSId, FALSE, FALSE,
    1928                 :                               FALSE ) != CE_None )
    1929                 :     {
    1930               0 :         delete poLayer;
    1931               0 :         CPLFree( pszLayerName );
    1932               0 :         return NULL;
    1933                 :     }
    1934                 : 
    1935             112 :     poLayer->InitFeatureCount();
    1936             112 :     poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) );
    1937             112 :     if ( CSLFetchBoolean(papszOptions,"COMPRESS_GEOM",FALSE) )
    1938              32 :         poLayer->SetUseCompressGeom( TRUE );
    1939             112 :     if( bImmediateSpatialIndexCreation )
    1940               0 :         poLayer->CreateSpatialIndex();
    1941             112 :     else if( bDeferedSpatialIndexCreation )
    1942              70 :         poLayer->SetDeferedSpatialIndexCreation( TRUE );
    1943                 : 
    1944                 : 
    1945             112 :     if( bIsSpatiaLiteDB && nLayers == 0)
    1946                 :     {
    1947                 :         /* To create the layer_statistics and spatialite_history tables */
    1948               5 :         sqlite3_exec( hDB, "SELECT UpdateLayerStatistics()", NULL, NULL, NULL );
    1949                 :     }
    1950                 : 
    1951                 : /* -------------------------------------------------------------------- */
    1952                 : /*      Add layer to data source layer list.                            */
    1953                 : /* -------------------------------------------------------------------- */
    1954                 :     papoLayers = (OGRSQLiteLayer **)
    1955             112 :         CPLRealloc( papoLayers,  sizeof(OGRSQLiteLayer *) * (nLayers+1) );
    1956                 :     
    1957             112 :     papoLayers[nLayers++] = poLayer;
    1958                 : 
    1959             112 :     CPLFree( pszLayerName );
    1960                 : 
    1961             112 :     return poLayer;
    1962                 : }
    1963                 : 
    1964                 : /************************************************************************/
    1965                 : /*                            LaunderName()                             */
    1966                 : /************************************************************************/
    1967                 : 
    1968             181 : char *OGRSQLiteDataSource::LaunderName( const char *pszSrcName )
    1969                 : 
    1970                 : {
    1971             181 :     char    *pszSafeName = CPLStrdup( pszSrcName );
    1972                 :     int     i;
    1973                 : 
    1974            1330 :     for( i = 0; pszSafeName[i] != '\0'; i++ )
    1975                 :     {
    1976            1149 :         pszSafeName[i] = (char) tolower( pszSafeName[i] );
    1977            1149 :         if( pszSafeName[i] == '\'' || pszSafeName[i] == '-' || pszSafeName[i] == '#' )
    1978               0 :             pszSafeName[i] = '_';
    1979                 :     }
    1980                 : 
    1981             181 :     return pszSafeName;
    1982                 : }
    1983                 : 
    1984                 : /************************************************************************/
    1985                 : /*                       OGRSQLiteParamsUnquote()                       */
    1986                 : /************************************************************************/
    1987                 : 
    1988           10866 : CPLString OGRSQLiteParamsUnquote(const char* pszVal)
    1989                 : {
    1990           10866 :     char chQuoteChar = pszVal[0];
    1991           10866 :     if( chQuoteChar != '\'' && chQuoteChar != '"' )
    1992           10324 :         return pszVal;
    1993                 :     
    1994             542 :     CPLString osRet;
    1995             542 :     pszVal ++;
    1996            4880 :     while( *pszVal != '\0' )
    1997                 :     {
    1998            4338 :         if( *pszVal == chQuoteChar )
    1999                 :         {
    2000             548 :             if( pszVal[1] == chQuoteChar )
    2001               6 :                 pszVal ++;
    2002                 :             else
    2003             542 :                 break;
    2004                 :         }
    2005            3796 :         osRet += *pszVal;
    2006            3796 :         pszVal ++;
    2007                 :     }
    2008             542 :     return osRet;
    2009                 : }
    2010                 : 
    2011                 : /************************************************************************/
    2012                 : /*                          OGRSQLiteEscape()                           */
    2013                 : /************************************************************************/
    2014                 : 
    2015            4593 : CPLString OGRSQLiteEscape( const char *pszLiteral )
    2016                 : {
    2017            4593 :     CPLString osVal;
    2018           38471 :     for( int i = 0; pszLiteral[i] != '\0'; i++ )
    2019                 :     {
    2020           33878 :         if ( pszLiteral[i] == '\'' )
    2021              12 :             osVal += '\'';
    2022           33878 :         osVal += pszLiteral[i];
    2023                 :     }
    2024               0 :     return osVal;
    2025                 : }
    2026                 : 
    2027                 : /************************************************************************/
    2028                 : /*                        OGRSQLiteEscapeName()                         */
    2029                 : /************************************************************************/
    2030                 : 
    2031            6434 : CPLString OGRSQLiteEscapeName(const char* pszName)
    2032                 : {
    2033            6434 :     CPLString osRet;
    2034           69087 :     while( *pszName != '\0' )
    2035                 :     {
    2036           56219 :         if( *pszName == '"' )
    2037               8 :             osRet += "\"\"";
    2038                 :         else
    2039           56211 :             osRet += *pszName;
    2040           56219 :         pszName ++;
    2041                 :     }
    2042               0 :     return osRet;
    2043                 : }
    2044                 : 
    2045                 : /************************************************************************/
    2046                 : /*                            DeleteLayer()                             */
    2047                 : /************************************************************************/
    2048                 : 
    2049              24 : void OGRSQLiteDataSource::DeleteLayer( const char *pszLayerName )
    2050                 : 
    2051                 : {
    2052                 :     int iLayer;
    2053                 : 
    2054                 : /* -------------------------------------------------------------------- */
    2055                 : /*      Verify we are in update mode.                                   */
    2056                 : /* -------------------------------------------------------------------- */
    2057              24 :     if( !bUpdate )
    2058                 :     {
    2059                 :         CPLError( CE_Failure, CPLE_NoWriteAccess,
    2060                 :                   "Data source %s opened read-only.\n"
    2061                 :                   "Layer %s cannot be deleted.\n",
    2062               0 :                   pszName, pszLayerName );
    2063                 : 
    2064               0 :         return;
    2065                 :     }
    2066                 : 
    2067                 : /* -------------------------------------------------------------------- */
    2068                 : /*      Try to find layer.                                              */
    2069                 : /* -------------------------------------------------------------------- */
    2070              78 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
    2071                 :     {
    2072              76 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) )
    2073              22 :             break;
    2074                 :     }
    2075                 : 
    2076              24 :     if( iLayer == nLayers )
    2077                 :     {
    2078                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2079                 :                   "Attempt to delete layer '%s', but this layer is not known to OGR.", 
    2080               2 :                   pszLayerName );
    2081               2 :         return;
    2082                 :     }
    2083                 : 
    2084              22 :     DeleteLayer(iLayer);
    2085                 : }
    2086                 : 
    2087                 : /************************************************************************/
    2088                 : /*                            DeleteLayer()                             */
    2089                 : /************************************************************************/
    2090                 : 
    2091              22 : OGRErr OGRSQLiteDataSource::DeleteLayer(int iLayer)
    2092                 : {
    2093              22 :     if( iLayer < 0 || iLayer >= nLayers )
    2094                 :     {
    2095                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2096                 :                   "Layer %d not in legal range of 0 to %d.",
    2097               0 :                   iLayer, nLayers-1 );
    2098               0 :         return OGRERR_FAILURE;
    2099                 :     }
    2100                 : 
    2101              22 :     CPLString osLayerName = GetLayer(iLayer)->GetName();
    2102              22 :     CPLString osGeometryColumn = GetLayer(iLayer)->GetGeometryColumn();
    2103                 : 
    2104                 : /* -------------------------------------------------------------------- */
    2105                 : /*      Blow away our OGR structures related to the layer.  This is     */
    2106                 : /*      pretty dangerous if anything has a reference to this layer!     */
    2107                 : /* -------------------------------------------------------------------- */
    2108              22 :     CPLDebug( "OGR_SQLITE", "DeleteLayer(%s)", osLayerName.c_str() );
    2109                 : 
    2110              22 :     delete papoLayers[iLayer];
    2111                 :     memmove( papoLayers + iLayer, papoLayers + iLayer + 1, 
    2112              22 :              sizeof(void *) * (nLayers - iLayer - 1) );
    2113              22 :     nLayers--;
    2114                 : 
    2115                 : /* -------------------------------------------------------------------- */
    2116                 : /*      Remove from the database.                                       */
    2117                 : /* -------------------------------------------------------------------- */
    2118                 :     int rc;
    2119                 :     char *pszErrMsg;
    2120                 : 
    2121              22 :     CPLString osEscapedLayerName = OGRSQLiteEscape(osLayerName);
    2122              22 :     const char* pszEscapedLayerName = osEscapedLayerName.c_str();
    2123              22 :     const char* pszGeometryColumn = osGeometryColumn.size() ? osGeometryColumn.c_str() : NULL;
    2124                 : 
    2125                 :     rc = sqlite3_exec( hDB, CPLSPrintf( "DROP TABLE '%s'", pszEscapedLayerName ),
    2126              22 :                        NULL, NULL, &pszErrMsg );
    2127              22 :     if( rc != SQLITE_OK )
    2128                 :     {
    2129                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2130                 :                   "Unable to drop table %s: %s",
    2131               0 :                   osLayerName.c_str(), pszErrMsg );
    2132               0 :         sqlite3_free( pszErrMsg );
    2133               0 :         return OGRERR_FAILURE;
    2134                 :     }
    2135                 : 
    2136                 : /* -------------------------------------------------------------------- */
    2137                 : /*      Drop from geometry_columns table.                               */
    2138                 : /* -------------------------------------------------------------------- */
    2139              22 :     if( bHaveGeometryColumns )
    2140                 :     {
    2141              22 :         CPLString osCommand;
    2142                 : 
    2143                 :         osCommand.Printf( 
    2144                 :             "DELETE FROM geometry_columns WHERE f_table_name = '%s'",
    2145              22 :             pszEscapedLayerName );
    2146                 :         
    2147              22 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
    2148              22 :         if( rc != SQLITE_OK )
    2149                 :         {
    2150                 :             CPLError( CE_Warning, CPLE_AppDefined,
    2151                 :                       "Removal from geometry_columns failed.\n%s: %s", 
    2152               0 :                       osCommand.c_str(), pszErrMsg );
    2153               0 :             sqlite3_free( pszErrMsg );
    2154               0 :             return OGRERR_FAILURE;
    2155                 :         }
    2156                 : 
    2157                 : /* -------------------------------------------------------------------- */
    2158                 : /*      Drop spatialite spatial index tables                            */
    2159                 : /* -------------------------------------------------------------------- */
    2160              22 :         if( bIsSpatiaLiteDB && pszGeometryColumn )
    2161                 :         {
    2162                 :             osCommand.Printf( "DROP TABLE 'idx_%s_%s'", pszEscapedLayerName,
    2163               0 :                               OGRSQLiteEscape(pszGeometryColumn).c_str());
    2164               0 :             rc = sqlite3_exec( hDB, osCommand, NULL, NULL, NULL );
    2165                 : 
    2166                 :             osCommand.Printf( "DROP TABLE 'idx_%s_%s_node'", pszEscapedLayerName,
    2167               0 :                               OGRSQLiteEscape(pszGeometryColumn).c_str());
    2168               0 :             rc = sqlite3_exec( hDB, osCommand, NULL, NULL, NULL );
    2169                 : 
    2170                 :             osCommand.Printf( "DROP TABLE 'idx_%s_%s_parent'", pszEscapedLayerName,
    2171               0 :                               OGRSQLiteEscape(pszGeometryColumn).c_str());
    2172               0 :             rc = sqlite3_exec( hDB, osCommand, NULL, NULL, NULL );
    2173                 : 
    2174                 :             osCommand.Printf( "DROP TABLE 'idx_%s_%s_rowid'", pszEscapedLayerName,
    2175               0 :                               OGRSQLiteEscape(pszGeometryColumn).c_str());
    2176               0 :             rc = sqlite3_exec( hDB, osCommand, NULL, NULL, NULL );
    2177               0 :         }
    2178                 :     }
    2179              22 :     return OGRERR_NONE;
    2180                 : }
    2181                 : 
    2182                 : /************************************************************************/
    2183                 : /*                        SoftStartTransaction()                        */
    2184                 : /*                                                                      */
    2185                 : /*      Create a transaction scope.  If we already have a               */
    2186                 : /*      transaction active this isn't a real transaction, but just      */
    2187                 : /*      an increment to the scope count.                                */
    2188                 : /************************************************************************/
    2189                 : 
    2190              58 : OGRErr OGRSQLiteDataSource::SoftStartTransaction()
    2191                 : 
    2192                 : {
    2193              58 :     nSoftTransactionLevel++;
    2194                 : 
    2195              58 :     if( nSoftTransactionLevel == 1 )
    2196                 :     {
    2197                 :         int rc;
    2198                 :         char *pszErrMsg;
    2199                 :         
    2200                 : #ifdef DEBUG
    2201              58 :         CPLDebug( "OGR_SQLITE", "BEGIN Transaction" );
    2202                 : #endif
    2203                 : 
    2204              58 :         rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, &pszErrMsg );
    2205              58 :         if( rc != SQLITE_OK )
    2206                 :         {
    2207               0 :             nSoftTransactionLevel--;
    2208                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    2209                 :                       "BEGIN transaction failed: %s",
    2210               0 :                       pszErrMsg );
    2211               0 :             sqlite3_free( pszErrMsg );
    2212               0 :             return OGRERR_FAILURE;
    2213                 :         }
    2214                 :     }
    2215                 : 
    2216              58 :     return OGRERR_NONE;
    2217                 : }
    2218                 : 
    2219                 : /************************************************************************/
    2220                 : /*                             SoftCommit()                             */
    2221                 : /*                                                                      */
    2222                 : /*      Commit the current transaction if we are at the outer           */
    2223                 : /*      scope.                                                          */
    2224                 : /************************************************************************/
    2225                 : 
    2226              47 : OGRErr OGRSQLiteDataSource::SoftCommit()
    2227                 : 
    2228                 : {
    2229              47 :     if( nSoftTransactionLevel <= 0 )
    2230                 :     {
    2231               0 :         CPLDebug( "OGR_SQLITE", "SoftCommit() with no transaction active." );
    2232               0 :         return OGRERR_FAILURE;
    2233                 :     }
    2234                 : 
    2235              47 :     nSoftTransactionLevel--;
    2236                 : 
    2237              47 :     if( nSoftTransactionLevel == 0 )
    2238                 :     {
    2239                 :         int rc;
    2240                 :         char *pszErrMsg;
    2241                 :         
    2242                 : #ifdef DEBUG
    2243              47 :         CPLDebug( "OGR_SQLITE", "COMMIT Transaction" );
    2244                 : #endif
    2245                 : 
    2246              47 :         rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, &pszErrMsg );
    2247              47 :         if( rc != SQLITE_OK )
    2248                 :         {
    2249                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    2250                 :                       "COMMIT transaction failed: %s",
    2251               0 :                       pszErrMsg );
    2252               0 :             sqlite3_free( pszErrMsg );
    2253               0 :             return OGRERR_FAILURE;
    2254                 :         }
    2255                 :     }
    2256                 : 
    2257              47 :     return OGRERR_NONE;
    2258                 : }
    2259                 : 
    2260                 : /************************************************************************/
    2261                 : /*                            SoftRollback()                            */
    2262                 : /*                                                                      */
    2263                 : /*      Force a rollback of the current transaction if there is one,    */
    2264                 : /*      even if we are nested several levels deep.                      */
    2265                 : /************************************************************************/
    2266                 : 
    2267              11 : OGRErr OGRSQLiteDataSource::SoftRollback()
    2268                 : 
    2269                 : {
    2270              11 :     if( nSoftTransactionLevel <= 0 )
    2271                 :     {
    2272               0 :         CPLDebug( "OGR_SQLITE", "SoftRollback() with no transaction active." );
    2273               0 :         return OGRERR_FAILURE;
    2274                 :     }
    2275                 : 
    2276              11 :     nSoftTransactionLevel = 0;
    2277                 : 
    2278                 :     int rc;
    2279                 :     char *pszErrMsg;
    2280                 :     
    2281                 : #ifdef DEBUG
    2282              11 :     CPLDebug( "OGR_SQLITE", "ROLLBACK Transaction" );
    2283                 : #endif
    2284                 : 
    2285              11 :     rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, &pszErrMsg );
    2286              11 :     if( rc != SQLITE_OK )
    2287                 :     {
    2288                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2289                 :                   "ROLLBACK transaction failed: %s",
    2290               0 :                   pszErrMsg );
    2291               0 :         sqlite3_free( pszErrMsg );
    2292               0 :         return OGRERR_FAILURE;
    2293                 :     }
    2294                 : 
    2295              24 :     for(int i = 0; i < nLayers; i++)
    2296              13 :         papoLayers[i]->InvalidateCachedFeatureCountAndExtent();
    2297                 : 
    2298              11 :     return OGRERR_NONE;
    2299                 : }
    2300                 : 
    2301                 : /************************************************************************/
    2302                 : /*                        FlushSoftTransaction()                        */
    2303                 : /*                                                                      */
    2304                 : /*      Force the unwinding of any active transaction, and it's         */
    2305                 : /*      commit.                                                         */
    2306                 : /************************************************************************/
    2307                 : 
    2308               0 : OGRErr OGRSQLiteDataSource::FlushSoftTransaction()
    2309                 : 
    2310                 : {
    2311               0 :     if( nSoftTransactionLevel <= 0 )
    2312               0 :         return OGRERR_NONE;
    2313                 : 
    2314               0 :     nSoftTransactionLevel = 1;
    2315                 : 
    2316               0 :     return SoftCommit();
    2317                 : }
    2318                 : 
    2319                 : /************************************************************************/
    2320                 : /*                          GetSRTEXTColName()                        */
    2321                 : /************************************************************************/
    2322                 : 
    2323             120 : const char* OGRSQLiteDataSource::GetSRTEXTColName()
    2324                 : {
    2325             120 :     if( !bIsSpatiaLiteDB || bSpatialite4Layout )
    2326              12 :         return "srtext";
    2327                 : 
    2328                 : /* testing for SRS_WKT column presence */
    2329             108 :     int bHasSrsWkt = FALSE;
    2330                 :     char **papszResult;
    2331                 :     int nRowCount, nColCount;
    2332             108 :     char *pszErrMsg = NULL;
    2333                 :     int rc = sqlite3_get_table( hDB, "PRAGMA table_info(spatial_ref_sys)",
    2334                 :                             &papszResult, &nRowCount, &nColCount,
    2335             108 :                             &pszErrMsg );
    2336                 : 
    2337             108 :     if( rc == SQLITE_OK )
    2338                 :     {
    2339                 :         int iRow;
    2340             752 :         for (iRow = 1; iRow <= nRowCount; iRow++)
    2341                 :         {
    2342             644 :             if (EQUAL("srs_wkt",
    2343                 :                         papszResult[(iRow * nColCount) + 1]))
    2344             104 :                 bHasSrsWkt = TRUE;
    2345                 :         }
    2346             108 :         sqlite3_free_table(papszResult);
    2347                 :     }
    2348                 :     else
    2349                 :     {
    2350               0 :         sqlite3_free( pszErrMsg );
    2351                 :     }
    2352                 : 
    2353             108 :     return bHasSrsWkt ? "srs_wkt" : NULL;
    2354                 : }
    2355                 : 
    2356                 : /************************************************************************/
    2357                 : /*                         AddSRIDToCache()                             */
    2358                 : /*                                                                      */
    2359                 : /*      Note: this will not add a reference on the poSRS object. Make   */
    2360                 : /*      sure it is freshly created, or add a reference yourself if not. */
    2361                 : /************************************************************************/
    2362                 : 
    2363             154 : void OGRSQLiteDataSource::AddSRIDToCache(int nId, OGRSpatialReference * poSRS )
    2364                 : {
    2365                 : /* -------------------------------------------------------------------- */
    2366                 : /*      Add to the cache.                                               */
    2367                 : /* -------------------------------------------------------------------- */
    2368             154 :     panSRID = (int *) CPLRealloc(panSRID,sizeof(int) * (nKnownSRID+1) );
    2369                 :     papoSRS = (OGRSpatialReference **)
    2370             154 :         CPLRealloc(papoSRS, sizeof(void*) * (nKnownSRID + 1) );
    2371             154 :     panSRID[nKnownSRID] = nId;
    2372             154 :     papoSRS[nKnownSRID] = poSRS;
    2373             154 :     nKnownSRID++;
    2374             154 : }
    2375                 : 
    2376                 : /************************************************************************/
    2377                 : /*                             FetchSRSId()                             */
    2378                 : /*                                                                      */
    2379                 : /*      Fetch the id corresponding to an SRS, and if not found, add     */
    2380                 : /*      it to the table.                                                */
    2381                 : /************************************************************************/
    2382                 : 
    2383             179 : int OGRSQLiteDataSource::FetchSRSId( OGRSpatialReference * poSRS )
    2384                 : 
    2385                 : {
    2386             179 :     int                 nSRSId = nUndefinedSRID;
    2387             179 :     const char          *pszAuthorityName, *pszAuthorityCode = NULL;
    2388             179 :     CPLString           osCommand;
    2389                 :     char *pszErrMsg;
    2390                 :     int   rc;
    2391                 :     char **papszResult;
    2392                 :     int nRowCount, nColCount;
    2393                 : 
    2394             179 :     if( poSRS == NULL )
    2395               0 :         return nSRSId;
    2396                 : 
    2397                 : /* -------------------------------------------------------------------- */
    2398                 : /*      First, we look through our SRID cache, is it there?             */
    2399                 : /* -------------------------------------------------------------------- */
    2400                 :     int  i;
    2401                 : 
    2402             323 :     for( i = 0; i < nKnownSRID; i++ )
    2403                 :     {
    2404             145 :         if( papoSRS[i] == poSRS )
    2405               1 :             return panSRID[i];
    2406                 :     }
    2407             179 :     for( i = 0; i < nKnownSRID; i++ )
    2408                 :     {
    2409             143 :         if( papoSRS[i] != NULL && papoSRS[i]->IsSame(poSRS) )
    2410             142 :             return panSRID[i];
    2411                 :     }
    2412                 : 
    2413                 : /* -------------------------------------------------------------------- */
    2414                 : /*      Build a copy since we may call AutoIdentifyEPSG()               */
    2415                 : /* -------------------------------------------------------------------- */
    2416              36 :     OGRSpatialReference oSRS(*poSRS);
    2417              36 :     poSRS = NULL;
    2418                 : 
    2419              36 :     pszAuthorityName = oSRS.GetAuthorityName(NULL);
    2420                 : 
    2421              36 :     if( pszAuthorityName == NULL || strlen(pszAuthorityName) == 0 )
    2422                 :     {
    2423                 : /* -------------------------------------------------------------------- */
    2424                 : /*      Try to identify an EPSG code                                    */
    2425                 : /* -------------------------------------------------------------------- */
    2426              15 :         oSRS.AutoIdentifyEPSG();
    2427                 : 
    2428              15 :         pszAuthorityName = oSRS.GetAuthorityName(NULL);
    2429              15 :         if (pszAuthorityName != NULL && EQUAL(pszAuthorityName, "EPSG"))
    2430                 :         {
    2431               2 :             pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    2432               2 :             if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    2433                 :             {
    2434                 :                 /* Import 'clean' SRS */
    2435               2 :                 oSRS.importFromEPSG( atoi(pszAuthorityCode) );
    2436                 : 
    2437               2 :                 pszAuthorityName = oSRS.GetAuthorityName(NULL);
    2438               2 :                 pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    2439                 :             }
    2440                 :         }
    2441                 :     }
    2442                 : 
    2443                 : /* -------------------------------------------------------------------- */
    2444                 : /*      Check whether the EPSG authority code is already mapped to a    */
    2445                 : /*      SRS ID.                                                         */
    2446                 : /* -------------------------------------------------------------------- */
    2447              36 :     if( pszAuthorityName != NULL && strlen(pszAuthorityName) > 0 )
    2448                 :     {
    2449              23 :         pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    2450                 : 
    2451              23 :         if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    2452                 :         {
    2453                 :             // XXX: We are using case insensitive comparison for "auth_name"
    2454                 :             // values, because there are variety of options exist. By default
    2455                 :             // the driver uses 'EPSG' in upper case, but SpatiaLite extension
    2456                 :             // uses 'epsg' in lower case.
    2457                 :             osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    2458                 :                               "auth_name = '%s' COLLATE NOCASE AND auth_srid = '%s'",
    2459              23 :                               pszAuthorityName, pszAuthorityCode );
    2460                 : 
    2461                 :             rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    2462              23 :                                     &nRowCount, &nColCount, &pszErrMsg );
    2463              23 :             if( rc != SQLITE_OK )
    2464                 :             {
    2465                 :                 /* Retry without COLLATE NOCASE which may not be understood by older sqlite3 */
    2466               0 :                 sqlite3_free( pszErrMsg );
    2467                 : 
    2468                 :                 osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    2469                 :                                   "auth_name = '%s' AND auth_srid = '%s'",
    2470               0 :                                   pszAuthorityName, pszAuthorityCode );
    2471                 : 
    2472                 :                 rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    2473               0 :                                         &nRowCount, &nColCount, &pszErrMsg );
    2474                 : 
    2475                 :                 /* Retry in lower case for SpatiaLite */
    2476               0 :                 if( rc != SQLITE_OK )
    2477                 :                 {
    2478               0 :                     sqlite3_free( pszErrMsg );
    2479                 :                 }
    2480               0 :                 else if ( nRowCount == 0 &&
    2481                 :                           strcmp(pszAuthorityName, "EPSG") == 0)
    2482                 :                 {
    2483                 :                     /* If it's in upper case, look for lower case */
    2484               0 :                     sqlite3_free_table(papszResult);
    2485                 : 
    2486                 :                     osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    2487                 :                                       "auth_name = 'epsg' AND auth_srid = '%s'",
    2488               0 :                                       pszAuthorityCode );
    2489                 : 
    2490                 :                     rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    2491               0 :                                             &nRowCount, &nColCount, &pszErrMsg );
    2492                 : 
    2493               0 :                     if( rc != SQLITE_OK )
    2494                 :                     {
    2495               0 :                         sqlite3_free( pszErrMsg );
    2496                 :                     }
    2497                 :                 }
    2498                 :             }
    2499                 : 
    2500              23 :             if( rc == SQLITE_OK && nRowCount == 1 )
    2501                 :             {
    2502              16 :                 nSRSId = (papszResult[1] != NULL) ? atoi(papszResult[1]) : nUndefinedSRID;
    2503              16 :                 sqlite3_free_table(papszResult);
    2504                 : 
    2505              16 :                 if( nSRSId != nUndefinedSRID)
    2506              16 :                     AddSRIDToCache(nSRSId, new OGRSpatialReference(oSRS));
    2507                 : 
    2508              16 :                 return nSRSId;
    2509                 :             }
    2510               7 :             sqlite3_free_table(papszResult);
    2511                 :         }
    2512                 :     }
    2513                 : 
    2514                 : /* -------------------------------------------------------------------- */
    2515                 : /*      Search for existing record using either WKT definition or       */
    2516                 : /*      PROJ.4 string (SpatiaLite variant).                             */
    2517                 : /* -------------------------------------------------------------------- */
    2518              20 :     CPLString   osWKT, osProj4;
    2519                 : 
    2520                 : /* -------------------------------------------------------------------- */
    2521                 : /*      Translate SRS to WKT.                                           */
    2522                 : /* -------------------------------------------------------------------- */
    2523              20 :     char    *pszWKT = NULL;
    2524                 : 
    2525              20 :     if( oSRS.exportToWkt( &pszWKT ) != OGRERR_NONE )
    2526                 :     {
    2527               0 :         CPLFree(pszWKT);
    2528               0 :         return nUndefinedSRID;
    2529                 :     }
    2530                 : 
    2531              20 :     osWKT = pszWKT;
    2532              20 :     CPLFree( pszWKT );
    2533              20 :     pszWKT = NULL;
    2534                 : 
    2535              20 :     const char* pszSRTEXTColName = GetSRTEXTColName();
    2536                 : 
    2537              20 :     if ( pszSRTEXTColName != NULL )
    2538                 :     {
    2539                 : /* -------------------------------------------------------------------- */
    2540                 : /*      Try to find based on the WKT match.                             */
    2541                 : /* -------------------------------------------------------------------- */
    2542                 :         osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE \"%s\" = ?",
    2543              20 :                           OGRSQLiteEscapeName(pszSRTEXTColName).c_str());
    2544                 :     }
    2545                 : 
    2546                 : /* -------------------------------------------------------------------- */
    2547                 : /*      Handle SpatiaLite (< 4) flavour of the spatial_ref_sys.         */
    2548                 : /* -------------------------------------------------------------------- */
    2549                 :     else
    2550                 :     {
    2551                 : /* -------------------------------------------------------------------- */
    2552                 : /*      Translate SRS to PROJ.4 string.                                 */
    2553                 : /* -------------------------------------------------------------------- */
    2554               0 :         char    *pszProj4 = NULL;
    2555                 : 
    2556               0 :         if( oSRS.exportToProj4( &pszProj4 ) != OGRERR_NONE )
    2557                 :         {
    2558               0 :             CPLFree(pszProj4);
    2559               0 :             return nUndefinedSRID;
    2560                 :         }
    2561                 : 
    2562               0 :         osProj4 = pszProj4;
    2563               0 :         CPLFree( pszProj4 );
    2564               0 :         pszProj4 = NULL;
    2565                 : 
    2566                 : /* -------------------------------------------------------------------- */
    2567                 : /*      Try to find based on the PROJ.4 match.                          */
    2568                 : /* -------------------------------------------------------------------- */
    2569                 :         osCommand.Printf(
    2570               0 :             "SELECT srid FROM spatial_ref_sys WHERE proj4text = ?");
    2571                 :     }
    2572                 : 
    2573              20 :     sqlite3_stmt *hSelectStmt = NULL;
    2574              20 :     rc = sqlite3_prepare( hDB, osCommand, -1, &hSelectStmt, NULL );
    2575                 : 
    2576              20 :     if( rc == SQLITE_OK)
    2577                 :         rc = sqlite3_bind_text( hSelectStmt, 1,
    2578                 :                                 ( pszSRTEXTColName != NULL ) ? osWKT.c_str() : osProj4.c_str(),
    2579              20 :                                 -1, SQLITE_STATIC );
    2580                 : 
    2581              20 :     if( rc == SQLITE_OK)
    2582              20 :         rc = sqlite3_step( hSelectStmt );
    2583                 : 
    2584              20 :     if (rc == SQLITE_ROW)
    2585                 :     {
    2586               0 :         if (sqlite3_column_type( hSelectStmt, 0 ) == SQLITE_INTEGER)
    2587               0 :             nSRSId = sqlite3_column_int( hSelectStmt, 0 );
    2588                 :         else
    2589               0 :             nSRSId = nUndefinedSRID;
    2590                 : 
    2591               0 :         sqlite3_finalize( hSelectStmt );
    2592                 : 
    2593               0 :         if( nSRSId != nUndefinedSRID)
    2594               0 :             AddSRIDToCache(nSRSId, new OGRSpatialReference(oSRS));
    2595                 : 
    2596               0 :         return nSRSId;
    2597                 :     }
    2598                 : 
    2599                 : /* -------------------------------------------------------------------- */
    2600                 : /*      If the command actually failed, then the metadata table is      */
    2601                 : /*      likely missing, so we give up.                                  */
    2602                 : /* -------------------------------------------------------------------- */
    2603              20 :     if (rc != SQLITE_DONE && rc != SQLITE_ROW)
    2604                 :     {
    2605               0 :         sqlite3_finalize( hSelectStmt );
    2606               0 :         return nUndefinedSRID;
    2607                 :     }
    2608                 : 
    2609              20 :     sqlite3_finalize( hSelectStmt );
    2610                 : 
    2611                 : /* -------------------------------------------------------------------- */
    2612                 : /*      If we have an authority code try to assign SRS ID the same      */
    2613                 : /*      as that code.                                                   */
    2614                 : /* -------------------------------------------------------------------- */
    2615              20 :     if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    2616                 :     {
    2617                 :         osCommand.Printf( "SELECT * FROM spatial_ref_sys WHERE auth_srid='%s'",
    2618               7 :                           OGRSQLiteEscape(pszAuthorityCode).c_str() );
    2619                 :         rc = sqlite3_get_table( hDB, osCommand, &papszResult,
    2620               7 :                                 &nRowCount, &nColCount, &pszErrMsg );
    2621                 :         
    2622               7 :         if( rc != SQLITE_OK )
    2623                 :         {
    2624                 :             CPLError( CE_Failure, CPLE_AppDefined,
    2625                 :                       "exec(SELECT '%s' FROM spatial_ref_sys) failed: %s",
    2626               0 :                       pszAuthorityCode, pszErrMsg );
    2627               0 :             sqlite3_free( pszErrMsg );
    2628                 :         }
    2629                 : 
    2630                 : /* -------------------------------------------------------------------- */
    2631                 : /*      If there is no SRS ID with such auth_srid, use it as SRS ID.    */
    2632                 : /* -------------------------------------------------------------------- */
    2633               7 :         if ( nRowCount < 1 )
    2634               7 :             nSRSId = atoi(pszAuthorityCode);
    2635               7 :         sqlite3_free_table(papszResult);
    2636                 :     }
    2637                 : 
    2638                 : /* -------------------------------------------------------------------- */
    2639                 : /*      Otherwise get the current maximum srid in the srs table.        */
    2640                 : /* -------------------------------------------------------------------- */
    2641              20 :     if ( nSRSId == nUndefinedSRID )
    2642                 :     {
    2643                 :         rc = sqlite3_get_table( hDB, "SELECT MAX(srid) FROM spatial_ref_sys", 
    2644                 :                                 &papszResult, &nRowCount, &nColCount,
    2645              13 :                                 &pszErrMsg );
    2646                 :         
    2647              13 :         if( rc != SQLITE_OK )
    2648                 :         {
    2649                 :             CPLError( CE_Failure, CPLE_AppDefined,
    2650               0 :                       "SELECT of the maximum SRS ID failed: %s", pszErrMsg );
    2651               0 :             sqlite3_free( pszErrMsg );
    2652               0 :             return nUndefinedSRID;
    2653                 :         }
    2654                 : 
    2655              18 :         if ( nRowCount < 1 || !papszResult[1] )
    2656               5 :             nSRSId = 50000;
    2657                 :         else
    2658               8 :             nSRSId = atoi(papszResult[1]) + 1;  // Insert as the next SRS ID
    2659              13 :         sqlite3_free_table(papszResult);
    2660                 :     }
    2661                 : 
    2662                 : /* -------------------------------------------------------------------- */
    2663                 : /*      Try adding the SRS to the SRS table.                            */
    2664                 : /* -------------------------------------------------------------------- */
    2665                 : 
    2666              20 :     const char* apszToInsert[] = { NULL, NULL, NULL, NULL, NULL, NULL };
    2667                 : 
    2668              20 :     if ( !bIsSpatiaLiteDB )
    2669                 :     {
    2670              12 :         if( pszAuthorityName != NULL )
    2671                 :         {
    2672                 :             osCommand.Printf(
    2673                 :                 "INSERT INTO spatial_ref_sys (srid,srtext,auth_name,auth_srid) "
    2674                 :                 "                     VALUES (%d, ?, ?, ?)",
    2675               7 :                 nSRSId );
    2676               7 :             apszToInsert[0] = osWKT.c_str();
    2677               7 :             apszToInsert[1] = pszAuthorityName;
    2678               7 :             apszToInsert[2] = pszAuthorityCode;
    2679                 :         }
    2680                 :         else
    2681                 :         {
    2682                 :             osCommand.Printf(
    2683                 :                 "INSERT INTO spatial_ref_sys (srid,srtext) "
    2684                 :                 "                     VALUES (%d, ?)",
    2685               5 :                 nSRSId );
    2686               5 :             apszToInsert[0] = osWKT.c_str();
    2687                 :         }
    2688                 :     }
    2689                 :     else
    2690                 :     {
    2691               8 :         CPLString osSRTEXTColNameWithCommaBefore;
    2692               8 :         if( pszSRTEXTColName != NULL )
    2693               8 :             osSRTEXTColNameWithCommaBefore.Printf(", %s", pszSRTEXTColName);
    2694                 : 
    2695               8 :         const char  *pszProjCS = oSRS.GetAttrValue("PROJCS");
    2696               8 :         if (pszProjCS == NULL)
    2697               1 :             pszProjCS = oSRS.GetAttrValue("GEOGCS");
    2698                 : 
    2699               8 :         if( pszAuthorityName != NULL )
    2700                 :         {
    2701               0 :             if ( pszProjCS )
    2702                 :             {
    2703                 :                 osCommand.Printf(
    2704                 :                     "INSERT INTO spatial_ref_sys "
    2705                 :                     "(srid, auth_name, auth_srid, ref_sys_name, proj4text%s) "
    2706                 :                     "VALUES (%d, ?, ?, ?, ?%s)",
    2707                 :                     (pszSRTEXTColName != NULL) ? osSRTEXTColNameWithCommaBefore.c_str() : "",
    2708                 :                     nSRSId,
    2709               0 :                     (pszSRTEXTColName != NULL) ? ", ?" : "");
    2710               0 :                 apszToInsert[0] = pszAuthorityName;
    2711               0 :                 apszToInsert[1] = pszAuthorityCode;
    2712               0 :                 apszToInsert[2] = pszProjCS;
    2713               0 :                 apszToInsert[3] = osProj4.c_str();
    2714               0 :                 apszToInsert[4] = (pszSRTEXTColName != NULL) ? osWKT.c_str() : NULL;
    2715                 :             }
    2716                 :             else
    2717                 :             {
    2718                 :                 osCommand.Printf(
    2719                 :                     "INSERT INTO spatial_ref_sys "
    2720                 :                     "(srid, auth_name, auth_srid, proj4text%s) "
    2721                 :                     "VALUES (%d, ?, ?, ?%s)",
    2722                 :                     (pszSRTEXTColName != NULL) ? osSRTEXTColNameWithCommaBefore.c_str() : "",
    2723                 :                     nSRSId,
    2724               0 :                     (pszSRTEXTColName != NULL) ? ", ?" : "");
    2725               0 :                 apszToInsert[0] = pszAuthorityName;
    2726               0 :                 apszToInsert[1] = pszAuthorityCode;
    2727               0 :                 apszToInsert[2] = osProj4.c_str();
    2728               0 :                 apszToInsert[3] = (pszSRTEXTColName != NULL) ? osWKT.c_str() : NULL;
    2729                 :             }
    2730                 :         }
    2731                 :         else
    2732                 :         {
    2733                 :             /* SpatiaLite spatial_ref_sys auth_name and auth_srid columns must be NOT NULL */
    2734                 :             /* so insert within a fake OGR "authority" */
    2735               8 :             if ( pszProjCS )
    2736                 :             {
    2737                 :                 osCommand.Printf(
    2738                 :                     "INSERT INTO spatial_ref_sys "
    2739                 :                     "(srid, auth_name, auth_srid, ref_sys_name, proj4text%s) VALUES (%d, 'OGR', %d, ?, ?%s)",
    2740                 :                     (pszSRTEXTColName != NULL) ? osSRTEXTColNameWithCommaBefore.c_str() : "",
    2741                 :                     nSRSId, nSRSId,
    2742               7 :                     (pszSRTEXTColName != NULL) ? ", ?" : "");
    2743               7 :                 apszToInsert[0] = pszProjCS;
    2744               7 :                 apszToInsert[1] = osProj4.c_str();
    2745               7 :                 apszToInsert[2] = (pszSRTEXTColName != NULL) ? osWKT.c_str() : NULL;
    2746                 :             }
    2747                 :             else
    2748                 :             {
    2749                 :                 osCommand.Printf(
    2750                 :                     "INSERT INTO spatial_ref_sys "
    2751                 :                     "(srid, auth_name, auth_srid, proj4text%s) VALUES (%d, 'OGR', %d, ?%s)",
    2752                 :                     (pszSRTEXTColName != NULL) ? osSRTEXTColNameWithCommaBefore.c_str() : "",
    2753                 :                     nSRSId, nSRSId,
    2754               1 :                     (pszSRTEXTColName != NULL) ? ", ?" : "");
    2755               1 :                 apszToInsert[0] = osProj4.c_str();
    2756               1 :                 apszToInsert[1] = (pszSRTEXTColName != NULL) ? osWKT.c_str() : NULL;
    2757                 :             }
    2758               8 :         }
    2759                 :     }
    2760                 : 
    2761              20 :     sqlite3_stmt *hInsertStmt = NULL;
    2762              20 :     rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
    2763                 : 
    2764              69 :     for(i=0;apszToInsert[i]!=NULL;i++)
    2765                 :     {
    2766              49 :         if( rc == SQLITE_OK)
    2767              49 :             rc = sqlite3_bind_text( hInsertStmt, i+1, apszToInsert[i], -1, SQLITE_STATIC );
    2768                 :     }
    2769                 : 
    2770              20 :     if( rc == SQLITE_OK)
    2771              20 :         rc = sqlite3_step( hInsertStmt );
    2772                 : 
    2773              20 :     if( rc != SQLITE_OK && rc != SQLITE_DONE )
    2774                 :     {
    2775                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2776                 :                   "Unable to insert SRID (%s): %s",
    2777               0 :                   osCommand.c_str(), sqlite3_errmsg(hDB) );
    2778                 : 
    2779               0 :         sqlite3_finalize( hInsertStmt );
    2780               0 :         return FALSE;
    2781                 :     }
    2782                 : 
    2783              20 :     sqlite3_finalize( hInsertStmt );
    2784                 : 
    2785              20 :     if( nSRSId != nUndefinedSRID)
    2786              20 :         AddSRIDToCache(nSRSId, new OGRSpatialReference(oSRS));
    2787                 : 
    2788              20 :     return nSRSId;
    2789                 : }
    2790                 : 
    2791                 : /************************************************************************/
    2792                 : /*                              FetchSRS()                              */
    2793                 : /*                                                                      */
    2794                 : /*      Return a SRS corresponding to a particular id.  Note that       */
    2795                 : /*      reference counting should be honoured on the returned           */
    2796                 : /*      OGRSpatialReference, as handles may be cached.                  */
    2797                 : /************************************************************************/
    2798                 : 
    2799             594 : OGRSpatialReference *OGRSQLiteDataSource::FetchSRS( int nId )
    2800                 : 
    2801                 : {
    2802             594 :     if( nId <= 0 )
    2803             208 :         return NULL;
    2804                 : 
    2805                 : /* -------------------------------------------------------------------- */
    2806                 : /*      First, we look through our SRID cache, is it there?             */
    2807                 : /* -------------------------------------------------------------------- */
    2808                 :     int  i;
    2809                 : 
    2810             404 :     for( i = 0; i < nKnownSRID; i++ )
    2811                 :     {
    2812             267 :         if( panSRID[i] == nId )
    2813             249 :             return papoSRS[i];
    2814                 :     }
    2815                 : 
    2816                 : /* -------------------------------------------------------------------- */
    2817                 : /*      Try looking up in spatial_ref_sys table.                        */
    2818                 : /* -------------------------------------------------------------------- */
    2819                 :     char *pszErrMsg;
    2820                 :     int   rc;
    2821                 :     char **papszResult;
    2822                 :     int nRowCount, nColCount;
    2823             137 :     CPLString osCommand;
    2824             137 :     OGRSpatialReference *poSRS = NULL;
    2825                 : 
    2826                 :     osCommand.Printf( "SELECT srtext FROM spatial_ref_sys WHERE srid = %d",
    2827             137 :                       nId );
    2828                 :     rc = sqlite3_get_table( hDB, osCommand, 
    2829             137 :                             &papszResult, &nRowCount, &nColCount, &pszErrMsg );
    2830                 : 
    2831             137 :     if ( rc == SQLITE_OK )
    2832                 :     {
    2833              37 :         if( nRowCount < 1 )
    2834                 :         {
    2835              10 :             sqlite3_free_table(papszResult);
    2836              10 :             return NULL;
    2837                 :         }
    2838                 : 
    2839              27 :         char** papszRow = papszResult + nColCount;
    2840              27 :         if (papszRow[0] != NULL)
    2841                 :         {
    2842              27 :             CPLString osWKT = papszRow[0];
    2843                 : 
    2844                 : /* -------------------------------------------------------------------- */
    2845                 : /*      Translate into a spatial reference.                             */
    2846                 : /* -------------------------------------------------------------------- */
    2847              27 :             char *pszWKT = (char *) osWKT.c_str();
    2848                 : 
    2849              27 :             poSRS = new OGRSpatialReference();
    2850              54 :             if( poSRS->importFromWkt( &pszWKT ) != OGRERR_NONE )
    2851                 :             {
    2852               0 :                 delete poSRS;
    2853               0 :                 poSRS = NULL;
    2854              27 :             }
    2855                 :         }
    2856                 : 
    2857              27 :         sqlite3_free_table(papszResult);
    2858                 :     }
    2859                 : 
    2860                 : /* -------------------------------------------------------------------- */
    2861                 : /*      Next try SpatiaLite flavour. SpatiaLite uses PROJ.4 strings     */
    2862                 : /*      in 'proj4text' column instead of WKT in 'srtext'. Note: recent  */
    2863                 : /*      versions of spatialite have a srs_wkt column too                */
    2864                 : /* -------------------------------------------------------------------- */
    2865                 :     else
    2866                 :     {
    2867             100 :         sqlite3_free( pszErrMsg );
    2868             100 :         pszErrMsg = NULL;
    2869                 : 
    2870             100 :         const char* pszSRTEXTColName = GetSRTEXTColName();
    2871             100 :         CPLString osSRTEXTColNameWithCommaBefore;
    2872             100 :         if( pszSRTEXTColName != NULL )
    2873              96 :             osSRTEXTColNameWithCommaBefore.Printf(", %s", pszSRTEXTColName);
    2874                 : 
    2875                 :         osCommand.Printf(
    2876                 :             "SELECT proj4text, auth_name, auth_srid%s FROM spatial_ref_sys WHERE srid = %d",
    2877             100 :             (pszSRTEXTColName != NULL) ? osSRTEXTColNameWithCommaBefore.c_str() : "", nId );
    2878                 :         rc = sqlite3_get_table( hDB, osCommand, 
    2879                 :                                 &papszResult, &nRowCount,
    2880             100 :                                 &nColCount, &pszErrMsg );
    2881             100 :         if ( rc == SQLITE_OK )
    2882                 :         {
    2883             100 :             if( nRowCount < 1 )
    2884                 :             {
    2885               9 :                 sqlite3_free_table(papszResult);
    2886               9 :                 return NULL;
    2887                 :             }
    2888                 : 
    2889                 : /* -------------------------------------------------------------------- */
    2890                 : /*      Translate into a spatial reference.                             */
    2891                 : /* -------------------------------------------------------------------- */
    2892              91 :             char** papszRow = papszResult + nColCount;
    2893                 : 
    2894              91 :             const char* pszProj4Text = papszRow[0];
    2895              91 :             const char* pszAuthName = papszRow[1];
    2896              91 :             int nAuthSRID = (papszRow[2] != NULL) ? atoi(papszRow[2]) : 0;
    2897              91 :             char* pszWKT = (pszSRTEXTColName != NULL) ? (char*) papszRow[3] : NULL;
    2898                 : 
    2899              91 :             poSRS = new OGRSpatialReference();
    2900                 : 
    2901                 :             /* Try first from EPSG code */
    2902             182 :             if (pszAuthName != NULL &&
    2903                 :                 EQUAL(pszAuthName, "EPSG") &&
    2904                 :                 poSRS->importFromEPSG( nAuthSRID ) == OGRERR_NONE)
    2905                 :             {
    2906                 :                 /* Do nothing */
    2907                 :             }
    2908                 :             /* Then from WKT string */
    2909              15 :             else if( pszWKT != NULL &&
    2910                 :                      poSRS->importFromWkt( &pszWKT ) == OGRERR_NONE )
    2911                 :             {
    2912                 :                 /* Do nothing */
    2913                 :             }
    2914                 :             /* Finally from Proj4 string */
    2915               0 :             else if( pszProj4Text != NULL &&
    2916                 :                      poSRS->importFromProj4( pszProj4Text ) == OGRERR_NONE )
    2917                 :             {
    2918                 :                 /* Do nothing */
    2919                 :             }
    2920                 :             else
    2921                 :             {
    2922               0 :                 delete poSRS;
    2923               0 :                 poSRS = NULL;
    2924                 :             }
    2925                 : 
    2926              91 :             sqlite3_free_table(papszResult);
    2927                 :         }
    2928                 : 
    2929                 : /* -------------------------------------------------------------------- */
    2930                 : /*      No success, report an error.                                    */
    2931                 : /* -------------------------------------------------------------------- */
    2932                 :         else
    2933                 :         {
    2934                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    2935               0 :                       "%s: %s", osCommand.c_str(), pszErrMsg );
    2936               0 :             sqlite3_free( pszErrMsg );
    2937               0 :             return NULL;
    2938               0 :         }
    2939                 :     }
    2940                 : 
    2941                 : /* -------------------------------------------------------------------- */
    2942                 : /*      Add to the cache.                                               */
    2943                 : /* -------------------------------------------------------------------- */
    2944             118 :     AddSRIDToCache(nId, poSRS);
    2945                 : 
    2946             118 :     return poSRS;
    2947                 : }
    2948                 : 
    2949                 : /************************************************************************/
    2950                 : /*                              SetName()                               */
    2951                 : /************************************************************************/
    2952                 : 
    2953               1 : void OGRSQLiteDataSource::SetName(const char* pszNameIn)
    2954                 : {
    2955               1 :     CPLFree(pszName);
    2956               1 :     pszName = CPLStrdup(pszNameIn);
    2957               1 : }
    2958                 : 
    2959                 : /************************************************************************/
    2960                 : /*                       GetEnvelopeFromSQL()                           */
    2961                 : /************************************************************************/
    2962                 : 
    2963              14 : const OGREnvelope* OGRSQLiteDataSource::GetEnvelopeFromSQL(const CPLString& osSQL)
    2964                 : {
    2965              14 :     std::map<CPLString, OGREnvelope>::iterator oIter = oMapSQLEnvelope.find(osSQL);
    2966              14 :     if (oIter != oMapSQLEnvelope.end())
    2967               3 :         return &oIter->second;
    2968                 :     else
    2969              11 :         return NULL;
    2970                 : }
    2971                 : 
    2972                 : /************************************************************************/
    2973                 : /*                         SetEnvelopeForSQL()                          */
    2974                 : /************************************************************************/
    2975                 : 
    2976               7 : void OGRSQLiteDataSource::SetEnvelopeForSQL(const CPLString& osSQL,
    2977                 :                                             const OGREnvelope& oEnvelope)
    2978                 : {
    2979               7 :     oMapSQLEnvelope[osSQL] = oEnvelope;
    2980               7 : }

Generated by: LCOV version 1.7