LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitedatasource.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 527
Code covered: 73.8 % Executed lines: 389

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitedatasource.cpp 19800 2010-06-04 21:38:03Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRSQLiteDataSource class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_sqlite.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "cpl_hash_set.h"
      34                 : 
      35                 : #ifdef HAVE_SPATIALITE
      36                 : #include "spatialite.h"
      37                 : #endif
      38                 : 
      39                 : static int bSpatialiteLoaded = FALSE;
      40                 : 
      41                 : CPL_CVSID("$Id: ogrsqlitedatasource.cpp 19800 2010-06-04 21:38:03Z rouault $");
      42                 : 
      43                 : /************************************************************************/
      44                 : /*                        OGRSQLiteDataSource()                         */
      45                 : /************************************************************************/
      46                 : 
      47              89 : OGRSQLiteDataSource::OGRSQLiteDataSource()
      48                 : 
      49                 : {
      50              89 :     pszName = NULL;
      51              89 :     papoLayers = NULL;
      52              89 :     nLayers = 0;
      53                 : 
      54              89 :     nSoftTransactionLevel = 0;
      55                 : 
      56              89 :     nKnownSRID = 0;
      57              89 :     panSRID = NULL;
      58              89 :     papoSRS = NULL;
      59                 : 
      60              89 :     bHaveGeometryColumns = FALSE;
      61              89 :     bIsSpatiaLite = FALSE;
      62              89 : }
      63                 : 
      64                 : /************************************************************************/
      65                 : /*                        ~OGRSQLiteDataSource()                        */
      66                 : /************************************************************************/
      67                 : 
      68              89 : OGRSQLiteDataSource::~OGRSQLiteDataSource()
      69                 : 
      70                 : {
      71                 :     int         i;
      72                 : 
      73              89 :     CPLFree( pszName );
      74                 : 
      75             669 :     for( i = 0; i < nLayers; i++ )
      76             580 :         delete papoLayers[i];
      77                 :     
      78              89 :     CPLFree( papoLayers );
      79                 : 
      80             164 :     for( i = 0; i < nKnownSRID; i++ )
      81                 :     {
      82              75 :         if( papoSRS[i] != NULL )
      83              75 :             papoSRS[i]->Release();
      84                 :     }
      85              89 :     CPLFree( panSRID );
      86              89 :     CPLFree( papoSRS );
      87                 : 
      88              89 :     if( hDB != NULL )
      89              89 :         sqlite3_close( hDB );
      90              89 : }
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                     SpatiaLiteToOGRGeomType()                        */
      94                 : /*      Map SpatiaLite geometry format strings to corresponding         */
      95                 : /*      OGR constants.                                                  */
      96                 : /************************************************************************/
      97                 : 
      98                 : OGRwkbGeometryType
      99              70 : OGRSQLiteDataSource::SpatiaLiteToOGRGeomType( const char *pszGeomType )
     100                 : {
     101              70 :     if ( EQUAL(pszGeomType, "POINT") )
     102               0 :         return wkbPoint;
     103              70 :     else if ( EQUAL(pszGeomType, "LINESTRING") )
     104               0 :         return wkbLineString;
     105              70 :     else if ( EQUAL(pszGeomType, "POLYGON") )
     106              46 :         return wkbPolygon;
     107              24 :     else if ( EQUAL(pszGeomType, "MULTIPOINT") )
     108               0 :         return wkbMultiPoint;
     109              24 :     else if ( EQUAL(pszGeomType, "MULTILINESTRING") )
     110               0 :         return wkbMultiLineString;
     111              24 :     else if ( EQUAL(pszGeomType, "MULTIPOLYGON") )
     112               0 :         return wkbMultiPolygon;
     113              24 :     else if ( EQUAL(pszGeomType, "GEOMETRYCOLLECTION") )
     114               0 :         return wkbGeometryCollection;
     115                 :     else
     116              24 :         return wkbUnknown;
     117                 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                     OGRToSpatiaLiteGeomType()                        */
     121                 : /*      Map OGR geometry format constants to corresponding              */
     122                 : /*      SpatiaLite strings                                              */
     123                 : /************************************************************************/
     124                 : 
     125                 : const char *
     126               4 : OGRSQLiteDataSource::OGRToSpatiaLiteGeomType( OGRwkbGeometryType eGeomType )
     127                 : {
     128               4 :     switch ( wkbFlatten(eGeomType) )
     129                 :     {
     130                 :         case wkbUnknown:
     131               4 :             return "GEOMETRY";
     132                 :         case wkbPoint:
     133               0 :             return "POINT";
     134                 :         case wkbLineString:
     135               0 :             return "LINESTRING";
     136                 :         case wkbPolygon:
     137               0 :             return "POLYGON";
     138                 :         case wkbMultiPoint:
     139               0 :             return "MULTIPOINT";
     140                 :         case wkbMultiLineString:
     141               0 :             return "MULTILINESTRING";
     142                 :         case wkbMultiPolygon:
     143               0 :             return "MULTIPOLYGON";
     144                 :         case wkbGeometryCollection:
     145               0 :             return "GEOMETRYCOLLECTION";
     146                 :         default:
     147               0 :             return "";
     148                 :     }
     149                 : }
     150                 : 
     151                 : /************************************************************************/
     152                 : /*                                Open()                                */
     153                 : /*                                                                      */
     154                 : /*      Note, the Open() will implicitly create the database if it      */
     155                 : /*      does not already exist.                                         */
     156                 : /************************************************************************/
     157                 : 
     158              89 : int OGRSQLiteDataSource::Open( const char * pszNewName )
     159                 : 
     160                 : {
     161              89 :     CPLAssert( nLayers == 0 );
     162                 : 
     163              89 :     pszName = CPLStrdup( pszNewName );
     164                 : 
     165                 : /* -------------------------------------------------------------------- */
     166                 : /*      Try loading SpatiaLite.                                         */
     167                 : /* -------------------------------------------------------------------- */
     168                 : #ifdef HAVE_SPATIALITE
     169              89 :     if (!bSpatialiteLoaded && CSLTestBoolean(CPLGetConfigOption("SPATIALITE_LOAD", "TRUE")))
     170                 :     {
     171               1 :         bSpatialiteLoaded = TRUE;
     172               1 :         spatialite_init(CSLTestBoolean(CPLGetConfigOption("SPATIALITE_INIT_VERBOSE", "FALSE")));
     173                 :     }
     174                 : #endif
     175                 : 
     176              89 :     int bListAllTables = CSLTestBoolean(CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "NO"));
     177                 : 
     178                 : /* -------------------------------------------------------------------- */
     179                 : /*      Try to open the sqlite database properly now.                   */
     180                 : /* -------------------------------------------------------------------- */
     181                 :     int rc;
     182                 : 
     183              89 :     hDB = NULL;
     184              89 :     rc = sqlite3_open( pszNewName, &hDB );
     185              89 :     if( rc != SQLITE_OK )
     186                 :     {
     187                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     188                 :                   "sqlite3_open(%s) failed: %s", 
     189               0 :                   pszNewName, sqlite3_errmsg( hDB ) );
     190                 :                   
     191               0 :         return FALSE;
     192                 :     }
     193                 :     
     194              89 :     CPLHashSet* hSet = CPLHashSetNew(CPLHashSetHashStr, CPLHashSetEqualStr, CPLFree);
     195                 : 
     196                 : /* -------------------------------------------------------------------- */
     197                 : /*      If we have a GEOMETRY_COLUMNS tables, initialize on the basis   */
     198                 : /*      of that.                                                        */
     199                 : /* -------------------------------------------------------------------- */
     200                 :     char **papszResult;
     201                 :     int nRowCount, iRow, nColCount;
     202                 :     char *pszErrMsg;
     203                 : 
     204                 :     rc = sqlite3_get_table( 
     205                 :         hDB,
     206                 :         "SELECT f_table_name, f_geometry_column, geometry_type, coord_dimension, geometry_format, srid"
     207                 :         " FROM geometry_columns",
     208              89 :         &papszResult, &nRowCount, &nColCount, &pszErrMsg );
     209                 : 
     210              89 :     if( rc == SQLITE_OK )
     211                 :     {
     212              11 :         CPLDebug("SQLITE", "OGR style SQLite DB found !");
     213                 :     
     214              11 :         bHaveGeometryColumns = TRUE;
     215                 : 
     216              43 :         for( iRow = 0; iRow < nRowCount; iRow++ )
     217                 :         {
     218              32 :             char **papszRow = papszResult + iRow * 6 + 6;
     219              32 :             OGRwkbGeometryType eGeomType = wkbUnknown;
     220              32 :             int nSRID = 0;
     221                 : 
     222              32 :             if (papszRow[0] == NULL ||
     223                 :                 papszRow[1] == NULL ||
     224                 :                 papszRow[2] == NULL ||
     225                 :                 papszRow[3] == NULL)
     226               0 :                 continue;
     227                 : 
     228              32 :             eGeomType = (OGRwkbGeometryType) atoi(papszRow[2]);
     229                 : 
     230              32 :             if( atoi(papszRow[3]) > 2 )
     231               0 :                 eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit);
     232                 : 
     233              32 :             if( papszRow[5] != NULL )
     234               8 :                 nSRID = atoi(papszRow[5]);
     235                 : 
     236                 :             OpenTable( papszRow[0], papszRow[1], eGeomType, papszRow[4],
     237              32 :                        FetchSRS( nSRID ) );
     238                 :                        
     239              32 :             if (bListAllTables)
     240               0 :                 CPLHashSetInsert(hSet, CPLStrdup(papszRow[0]));
     241                 :         }
     242                 : 
     243              11 :         sqlite3_free_table(papszResult);
     244                 : 
     245              11 :         if (bListAllTables)
     246               0 :             goto all_tables;
     247                 :             
     248              11 :         CPLHashSetDestroy(hSet);
     249                 :         
     250              11 :         return TRUE;
     251                 :     }
     252                 : 
     253                 : /* -------------------------------------------------------------------- */
     254                 : /*      Otherwise we can deal with SpatiaLite database.                 */
     255                 : /* -------------------------------------------------------------------- */
     256              78 :     sqlite3_free( pszErrMsg );
     257                 :     rc = sqlite3_get_table( hDB,
     258                 :                             "SELECT f_table_name, f_geometry_column, "
     259                 :                             "type, coord_dimension, srid, "
     260                 :                             "spatial_index_enabled FROM geometry_columns",
     261                 :                             &papszResult, &nRowCount, 
     262              78 :                             &nColCount, &pszErrMsg );
     263                 : 
     264              78 :     if ( rc == SQLITE_OK )
     265                 :     {
     266              78 :         CPLDebug("SQLITE", "SpatiaLite-style SQLite DB found !");
     267                 :         
     268              78 :         bIsSpatiaLite = TRUE;
     269              78 :         bHaveGeometryColumns = TRUE;
     270                 : 
     271             148 :         for ( iRow = 0; iRow < nRowCount; iRow++ )
     272                 :         {
     273              70 :             char **papszRow = papszResult + iRow * 6 + 6;
     274                 :             OGRwkbGeometryType eGeomType;
     275              70 :             int nSRID = 0;
     276              70 :             int bHasSpatialIndex = FALSE;
     277                 : 
     278              70 :             if (papszRow[0] == NULL ||
     279                 :                 papszRow[1] == NULL ||
     280                 :                 papszRow[2] == NULL ||
     281                 :                 papszRow[3] == NULL)
     282               0 :                 continue;
     283                 : 
     284              70 :             eGeomType = SpatiaLiteToOGRGeomType(papszRow[2]);
     285                 : 
     286              70 :             if( atoi(papszRow[3]) > 2 )
     287               0 :                 eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit);
     288                 : 
     289              70 :             if( papszRow[4] != NULL )
     290              70 :                 nSRID = atoi(papszRow[4]);
     291                 : 
     292                 :             /* Only look for presence of a spatial index if linked against SpatiaLite */
     293              70 :             if( bSpatialiteLoaded && papszRow[5] != NULL )
     294              70 :                 bHasSpatialIndex = atoi(papszRow[5]);
     295                 : 
     296                 :             OpenTable( papszRow[0], papszRow[1], eGeomType, "SpatiaLite",
     297              70 :                        FetchSRS( nSRID ), nSRID, bHasSpatialIndex );
     298                 :                        
     299              70 :             if (bListAllTables)
     300              46 :                 CPLHashSetInsert(hSet, CPLStrdup(papszRow[0]));
     301                 :         }
     302                 : 
     303              78 :         sqlite3_free_table(papszResult);
     304                 : 
     305                 : /* -------------------------------------------------------------------- */
     306                 : /*      Detect VirtualShape layers                                      */
     307                 : /* -------------------------------------------------------------------- */
     308                 : #ifdef HAVE_SPATIALITE
     309              78 :         if (bSpatialiteLoaded)
     310                 :         {
     311                 :             rc = sqlite3_get_table( hDB,
     312                 :                                 "SELECT name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE % USING %VirtualShape%'",
     313                 :                                 &papszResult, &nRowCount, 
     314              78 :                                 &nColCount, &pszErrMsg );
     315                 : 
     316              78 :             if ( rc == SQLITE_OK )
     317                 :             {
     318              80 :                 for( iRow = 0; iRow < nRowCount; iRow++ )
     319                 :                 {
     320               2 :                     OpenTable( papszResult[iRow+1] );
     321                 :                     
     322               2 :                     if (bListAllTables)
     323               0 :                         CPLHashSetInsert(hSet, CPLStrdup(papszResult[iRow+1]));
     324                 :                 }
     325                 :             }
     326                 :             else
     327                 :             {
     328                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     329                 :                         "Unable to fetch list of tables: %s", 
     330               0 :                         pszErrMsg );
     331               0 :                 sqlite3_free( pszErrMsg );
     332                 :             }
     333                 : 
     334              78 :             sqlite3_free_table(papszResult);
     335                 :         }
     336                 : #endif
     337                 : 
     338              78 :         if (bListAllTables)
     339              64 :             goto all_tables;
     340                 : 
     341              14 :         CPLHashSetDestroy(hSet);
     342                 :         
     343              14 :         return TRUE;
     344                 :     }
     345                 : 
     346                 : /* -------------------------------------------------------------------- */
     347                 : /*      Otherwise our final resort is to return all tables and views    */
     348                 : /*      as non-spatial tables.                                          */
     349                 : /* -------------------------------------------------------------------- */
     350               0 :     sqlite3_free( pszErrMsg );
     351                 :     
     352              64 : all_tables:
     353                 :     rc = sqlite3_get_table( hDB,
     354                 :                             "SELECT name FROM sqlite_master "
     355                 :                             "WHERE type IN ('table','view') "
     356                 :                             "UNION ALL "
     357                 :                             "SELECT name FROM sqlite_temp_master "
     358                 :                             "WHERE type IN ('table','view') "
     359                 :                             "ORDER BY 1",
     360                 :                             &papszResult, &nRowCount, 
     361              64 :                             &nColCount, &pszErrMsg );
     362                 : 
     363              64 :     if( rc != SQLITE_OK )
     364                 :     {
     365                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     366                 :                   "Unable to fetch list of tables: %s", 
     367               0 :                   pszErrMsg );
     368               0 :         sqlite3_free( pszErrMsg );
     369               0 :         CPLHashSetDestroy(hSet);
     370               0 :         return FALSE;
     371                 :     }
     372                 :     
     373             582 :     for( iRow = 0; iRow < nRowCount; iRow++ )
     374                 :     {
     375             518 :         if (CPLHashSetLookup(hSet, papszResult[iRow+1]) == NULL)
     376             472 :             OpenTable( papszResult[iRow+1] );
     377                 :     }
     378                 :     
     379              64 :     sqlite3_free_table(papszResult);
     380              64 :     CPLHashSetDestroy(hSet);
     381                 : 
     382              64 :     return TRUE;
     383                 : }
     384                 : 
     385                 : /************************************************************************/
     386                 : /*                             OpenTable()                              */
     387                 : /************************************************************************/
     388                 : 
     389                 : int OGRSQLiteDataSource::OpenTable( const char *pszNewName, 
     390                 :                                     const char *pszGeomCol,
     391                 :                                     OGRwkbGeometryType eGeomType,
     392                 :                                     const char *pszGeomFormat,
     393                 :                                     OGRSpatialReference *poSRS, int nSRID,
     394             576 :                                     int bHasSpatialIndex)
     395                 : 
     396                 : {
     397                 : /* -------------------------------------------------------------------- */
     398                 : /*      Create the layer object.                                        */
     399                 : /* -------------------------------------------------------------------- */
     400                 :     OGRSQLiteTableLayer  *poLayer;
     401                 : 
     402             576 :     poLayer = new OGRSQLiteTableLayer( this );
     403                 : 
     404             576 :     if( poLayer->Initialize( pszNewName, pszGeomCol, 
     405                 :                              eGeomType, pszGeomFormat,
     406                 :                              poSRS, nSRID, bHasSpatialIndex ) )
     407                 :     {
     408               0 :         delete poLayer;
     409               0 :         return FALSE;
     410                 :     }
     411                 : 
     412                 : /* -------------------------------------------------------------------- */
     413                 : /*      Add layer to data source layer list.                            */
     414                 : /* -------------------------------------------------------------------- */
     415                 :     papoLayers = (OGRSQLiteLayer **)
     416             576 :         CPLRealloc( papoLayers,  sizeof(OGRSQLiteLayer *) * (nLayers+1) );
     417             576 :     papoLayers[nLayers++] = poLayer;
     418                 :     
     419             576 :     return TRUE;
     420                 : }
     421                 : 
     422                 : /************************************************************************/
     423                 : /*                           TestCapability()                           */
     424                 : /************************************************************************/
     425                 : 
     426               2 : int OGRSQLiteDataSource::TestCapability( const char * pszCap )
     427                 : 
     428                 : {
     429               2 :     if( EQUAL(pszCap,ODsCCreateLayer) )
     430               2 :         return TRUE;
     431                 :     else
     432               0 :         return FALSE;
     433                 : }
     434                 : 
     435                 : /************************************************************************/
     436                 : /*                              GetLayer()                              */
     437                 : /************************************************************************/
     438                 : 
     439            1188 : OGRLayer *OGRSQLiteDataSource::GetLayer( int iLayer )
     440                 : 
     441                 : {
     442            1188 :     if( iLayer < 0 || iLayer >= nLayers )
     443               0 :         return NULL;
     444                 :     else
     445            1188 :         return papoLayers[iLayer];
     446                 : }
     447                 : 
     448                 : /************************************************************************/
     449                 : /*                             ExecuteSQL()                             */
     450                 : /************************************************************************/
     451                 : 
     452                 : static const char* apszSpatialiteFuncs[] =
     453                 : {
     454                 :     "InitSpatialMetaData",
     455                 :     "AddGeometryColumn",
     456                 :     "RecoverGeometryColumn",
     457                 :     "DiscardGeometryColumn",
     458                 :     "CreateSpatialIndex",
     459                 :     "CreateMbrCache",
     460                 :     "DisableSpatialIndex"
     461                 : };
     462                 : 
     463                 : OGRLayer * OGRSQLiteDataSource::ExecuteSQL( const char *pszSQLCommand,
     464                 :                                           OGRGeometry *poSpatialFilter,
     465             301 :                                           const char *pszDialect )
     466                 : 
     467                 : {
     468             301 :     if( pszDialect != NULL && EQUAL(pszDialect,"OGRSQL") )
     469                 :         return OGRDataSource::ExecuteSQL( pszSQLCommand, 
     470                 :                                           poSpatialFilter, 
     471               0 :                                           pszDialect );
     472                 : 
     473                 : /* -------------------------------------------------------------------- */
     474                 : /*      Special case DELLAYER: command.                                 */
     475                 : /* -------------------------------------------------------------------- */
     476             301 :     if( EQUALN(pszSQLCommand,"DELLAYER:",9) )
     477                 :     {
     478              11 :         const char *pszLayerName = pszSQLCommand + 9;
     479                 : 
     480              22 :         while( *pszLayerName == ' ' )
     481               0 :             pszLayerName++;
     482                 : 
     483              11 :         DeleteLayer( pszLayerName );
     484              11 :         return NULL;
     485                 :     }
     486                 : 
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*      Prepare statement.                                              */
     489                 : /* -------------------------------------------------------------------- */
     490                 :     int rc;
     491             290 :     sqlite3_stmt *hSQLStmt = NULL;
     492                 : 
     493                 :     rc = sqlite3_prepare( GetDB(), pszSQLCommand, strlen(pszSQLCommand),
     494             290 :                           &hSQLStmt, NULL );
     495                 : 
     496             290 :     if( rc != SQLITE_OK )
     497                 :     {
     498                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     499                 :                 "In ExecuteSQL(): sqlite3_prepare(%s):\n  %s", 
     500               0 :                 pszSQLCommand, sqlite3_errmsg(GetDB()) );
     501                 : 
     502               0 :         if( hSQLStmt != NULL )
     503                 :         {
     504               0 :             sqlite3_finalize( hSQLStmt );
     505                 :         }
     506                 : 
     507               0 :         return NULL;
     508                 :     }
     509                 : 
     510                 : /* -------------------------------------------------------------------- */
     511                 : /*      Do we get a resultset?                                          */
     512                 : /* -------------------------------------------------------------------- */
     513             290 :     rc = sqlite3_step( hSQLStmt );
     514             290 :     if( rc != SQLITE_ROW )
     515                 :     {
     516             135 :         if ( rc != SQLITE_DONE )
     517                 :         {
     518                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     519                 :                   "In ExecuteSQL(): sqlite3_step(%s):\n  %s", 
     520               0 :                   pszSQLCommand, sqlite3_errmsg(GetDB()) );
     521                 :         }
     522             135 :         sqlite3_finalize( hSQLStmt );
     523             135 :         return NULL;
     524                 :     }
     525                 :     
     526                 : /* -------------------------------------------------------------------- */
     527                 : /*      Special case for some spatialite functions which must be run    */
     528                 : /*      only once                                                       */
     529                 : /* -------------------------------------------------------------------- */
     530             155 :     if( EQUALN(pszSQLCommand,"SELECT ",7) &&
     531                 :         bIsSpatiaLite && bSpatialiteLoaded )
     532                 :     {
     533                 :         unsigned int i;
     534            1021 :         for(i=0;i<sizeof(apszSpatialiteFuncs)/
     535                 :                   sizeof(apszSpatialiteFuncs[0]);i++)
     536                 :         {
     537             910 :             if( EQUALN(apszSpatialiteFuncs[i], pszSQLCommand + 7,
     538                 :                        strlen(apszSpatialiteFuncs[i])) )
     539                 :             {
     540              37 :                 if (sqlite3_column_count( hSQLStmt ) == 1 &&
     541                 :                     sqlite3_column_type( hSQLStmt, 0 ) == SQLITE_INTEGER )
     542                 :                 {
     543              37 :                     int ret = sqlite3_column_int( hSQLStmt, 0 );
     544                 : 
     545              37 :                     sqlite3_finalize( hSQLStmt );
     546                 : 
     547                 :                     return new OGRSQLiteSingleFeatureLayer
     548              37 :                                         ( apszSpatialiteFuncs[i], ret );
     549                 :                 }
     550                 :             }
     551                 :         }
     552                 :     }
     553                 : 
     554                 : /* -------------------------------------------------------------------- */
     555                 : /*      Create layer.                                                   */
     556                 : /* -------------------------------------------------------------------- */
     557             118 :     OGRSQLiteSelectLayer *poLayer = NULL;
     558                 :         
     559             118 :     CPLString osSQL = pszSQLCommand;
     560             118 :     poLayer = new OGRSQLiteSelectLayer( this, osSQL, hSQLStmt );
     561                 : 
     562             118 :     if( poSpatialFilter != NULL )
     563               0 :         poLayer->SetSpatialFilter( poSpatialFilter );
     564                 :     
     565             118 :     return poLayer;
     566                 : }
     567                 : 
     568                 : /************************************************************************/
     569                 : /*                          ReleaseResultSet()                          */
     570                 : /************************************************************************/
     571                 : 
     572             155 : void OGRSQLiteDataSource::ReleaseResultSet( OGRLayer * poLayer )
     573                 : 
     574                 : {
     575             155 :     delete poLayer;
     576             155 : }
     577                 : 
     578                 : /************************************************************************/
     579                 : /*                            CreateLayer()                             */
     580                 : /************************************************************************/
     581                 : 
     582                 : OGRLayer *
     583                 : OGRSQLiteDataSource::CreateLayer( const char * pszLayerNameIn,
     584                 :                                   OGRSpatialReference *poSRS,
     585                 :                                   OGRwkbGeometryType eType,
     586              14 :                                   char ** papszOptions )
     587                 : 
     588                 : {
     589                 :     char                *pszLayerName;
     590                 :     const char          *pszGeomFormat;
     591                 : 
     592              14 :     if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) )
     593              14 :         pszLayerName = LaunderName( pszLayerNameIn );
     594                 :     else
     595               0 :         pszLayerName = CPLStrdup( pszLayerNameIn );
     596                 :     
     597              14 :     pszGeomFormat = CSLFetchNameValue( papszOptions, "FORMAT" );
     598              14 :     if( pszGeomFormat == NULL )
     599                 :     {
     600              11 :         if ( !bIsSpatiaLite )
     601               7 :             pszGeomFormat = "WKB";
     602                 :         else
     603               4 :             pszGeomFormat = "SpatiaLite";
     604                 :     }
     605                 : 
     606              14 :     if( !EQUAL(pszGeomFormat,"WKT") 
     607                 :         && !EQUAL(pszGeomFormat,"WKB")
     608                 :         && !EQUAL(pszGeomFormat, "SpatiaLite") )
     609                 :     {
     610                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     611                 :                   "FORMAT=%s not recognised or supported.", 
     612               0 :                   pszGeomFormat );
     613               0 :         return NULL;
     614                 :     }
     615                 : 
     616                 : /* -------------------------------------------------------------------- */
     617                 : /*      Do we already have this layer?  If so, should we blow it        */
     618                 : /*      away?                                                           */
     619                 : /* -------------------------------------------------------------------- */
     620                 :     int iLayer;
     621                 : 
     622              55 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     623                 :     {
     624              41 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) )
     625                 :         {
     626               0 :             if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL
     627                 :                 && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") )
     628                 :             {
     629               0 :                 DeleteLayer( pszLayerName );
     630                 :             }
     631                 :             else
     632                 :             {
     633                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     634                 :                           "Layer %s already exists, CreateLayer failed.\n"
     635                 :                           "Use the layer creation option OVERWRITE=YES to "
     636                 :                           "replace it.",
     637               0 :                           pszLayerName );
     638               0 :                 CPLFree( pszLayerName );
     639               0 :                 return NULL;
     640                 :             }
     641                 :         }
     642                 :     }
     643                 : 
     644                 : /* -------------------------------------------------------------------- */
     645                 : /*      Try to get the SRS Id of this spatial reference system,         */
     646                 : /*      adding to the srs table if needed.                              */
     647                 : /* -------------------------------------------------------------------- */
     648              14 :     int nSRSId = -1;
     649                 : 
     650              14 :     if( poSRS != NULL )
     651               7 :         nSRSId = FetchSRSId( poSRS );
     652                 : 
     653                 : /* -------------------------------------------------------------------- */
     654                 : /*      Create a basic table with the FID.  Also include the            */
     655                 : /*      geometry if this is not a PostGIS enabled table.                */
     656                 : /* -------------------------------------------------------------------- */
     657                 :     int rc;
     658                 :     char *pszErrMsg;
     659              14 :     const char *pszGeomCol = NULL;
     660              14 :     CPLString osCommand;
     661                 : 
     662              14 :     if( eType == wkbNone )
     663                 :         osCommand.Printf( 
     664                 :             "CREATE TABLE '%s' ( OGC_FID INTEGER PRIMARY KEY )", 
     665               0 :             pszLayerName );
     666                 :     else
     667                 :     {
     668              14 :         if( EQUAL(pszGeomFormat,"WKT") )
     669                 :         {
     670               1 :             pszGeomCol = "WKT_GEOMETRY";
     671                 :             osCommand.Printf(
     672                 :                 "CREATE TABLE '%s' ( "
     673                 :                 "  OGC_FID INTEGER PRIMARY KEY,"
     674                 :                 "  %s VARCHAR )", 
     675               1 :                 pszLayerName, pszGeomCol );
     676                 :         }
     677                 :         else
     678                 :         {
     679              13 :             pszGeomCol = "GEOMETRY";
     680                 :             osCommand.Printf(
     681                 :                 "CREATE TABLE '%s' ( "
     682                 :                 "  OGC_FID INTEGER PRIMARY KEY,"
     683                 :                 "  %s BLOB )", 
     684              13 :                 pszLayerName, pszGeomCol );
     685                 :         }
     686                 :     }
     687                 : 
     688                 : #ifdef DEBUG
     689              14 :     CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
     690                 : #endif
     691                 : 
     692              14 :     rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     693              14 :     if( rc != SQLITE_OK )
     694                 :     {
     695                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     696                 :                   "Unable to create table %s: %s",
     697               0 :                   pszLayerName, pszErrMsg );
     698               0 :         sqlite3_free( pszErrMsg );
     699              14 :         return FALSE;
     700                 :     }
     701                 : 
     702                 : /* -------------------------------------------------------------------- */
     703                 : /*      Eventually we should be adding this table to a table of         */
     704                 : /*      "geometric layers", capturing the WKT projection, and           */
     705                 : /*      perhaps some other housekeeping.                                */
     706                 : /* -------------------------------------------------------------------- */
     707              14 :     if( bHaveGeometryColumns && eType != wkbNone )
     708                 :     {
     709                 :         int nCoordDim;
     710                 : 
     711                 :         /* Sometimes there is an old cruft entry in the geometry_columns
     712                 :          * table if things were not properly cleaned up before.  We make
     713                 :          * an effort to clean out such cruft.
     714                 :          */
     715                 :         osCommand.Printf(
     716                 :             "DELETE FROM geometry_columns WHERE f_table_name = '%s'", 
     717              14 :             pszLayerName );
     718                 :                  
     719                 : #ifdef DEBUG
     720              14 :         CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
     721                 : #endif
     722                 : 
     723              14 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     724              14 :         if( rc != SQLITE_OK )
     725                 :         {
     726               0 :             sqlite3_free( pszErrMsg );
     727               0 :             return FALSE;
     728                 :         }
     729                 :         
     730              14 :         if( eType == wkbFlatten(eType) )
     731              14 :             nCoordDim = 2;
     732                 :         else
     733               0 :             nCoordDim = 3;
     734                 : 
     735              14 :         if( nSRSId > 0 )
     736                 :         {
     737               7 :             if ( bIsSpatiaLite )
     738                 :                 osCommand.Printf(
     739                 :                     "INSERT INTO geometry_columns "
     740                 :                     "(f_table_name, f_geometry_column, type, "
     741                 :                     "coord_dimension, srid, spatial_index_enabled) "
     742                 :                     "VALUES ('%s','%s', '%s', %d, %d, 0)", 
     743                 :                     pszLayerName, pszGeomCol, OGRToSpatiaLiteGeomType(eType),
     744               4 :                     nCoordDim, nSRSId );
     745                 :             else
     746                 :                 osCommand.Printf(
     747                 :                     "INSERT INTO geometry_columns "
     748                 :                     "(f_table_name, f_geometry_column, geometry_format, "
     749                 :                     "geometry_type, coord_dimension, srid) VALUES "
     750                 :                     "('%s','%s','%s', %d, %d, %d)", 
     751                 :                     pszLayerName, pszGeomCol, pszGeomFormat,
     752               3 :                     (int) wkbFlatten(eType), nCoordDim, nSRSId );
     753                 :         }
     754                 :         else
     755                 :         {
     756               7 :             if ( bIsSpatiaLite )
     757                 :                 osCommand.Printf(
     758                 :                     "INSERT INTO geometry_columns "
     759                 :                     "(f_table_name, f_geometry_column, type, "
     760                 :                     "coord_dimension, spatial_index_enabled) "
     761                 :                     "VALUES ('%s','%s', '%s', %d, 0)", 
     762                 :                     pszLayerName, pszGeomCol, OGRToSpatiaLiteGeomType(eType),
     763               0 :                     nCoordDim );
     764                 :             else
     765                 :                 osCommand.Printf(
     766                 :                     "INSERT INTO geometry_columns "
     767                 :                     "(f_table_name, f_geometry_column, geometry_format, "
     768                 :                     "geometry_type, coord_dimension) VALUES "
     769                 :                     "('%s','%s','%s', %d, %d)", 
     770                 :                     pszLayerName, pszGeomCol, pszGeomFormat,
     771               7 :                     (int) wkbFlatten(eType), nCoordDim );
     772                 :         }
     773                 : 
     774                 : #ifdef DEBUG
     775              14 :         CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
     776                 : #endif
     777                 : 
     778              14 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     779              14 :         if( rc != SQLITE_OK )
     780                 :         {
     781                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     782                 :                       "Unable to add %s table to geometry_columns:\n%s",
     783               0 :                       pszLayerName, pszErrMsg );
     784               0 :             sqlite3_free( pszErrMsg );
     785               0 :             return FALSE;
     786                 :         }
     787                 : 
     788                 : /* -------------------------------------------------------------------- */
     789                 : /*      Create the spatial index.                                       */
     790                 : /*                                                                      */
     791                 : /*      We're doing this before we add geometry and record to the table */
     792                 : /*      so this may not be exactly the best way to do it.               */
     793                 : /* -------------------------------------------------------------------- */
     794                 : #ifdef HAVE_SPATIALITE
     795                 :         /* Only if linked against SpatiaLite and the datasource was created as a SpatiaLite DB */
     796              14 :         if ( bIsSpatiaLite && bSpatialiteLoaded )
     797                 : #else
     798                 :         if ( 0 )
     799                 : #endif
     800                 :         {
     801               4 :             const char* pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" );
     802               4 :             if( pszSI == NULL || CSLTestBoolean(pszSI) )
     803                 :             {
     804                 :                 osCommand.Printf("SELECT CreateSpatialIndex('%s', '%s')",
     805               4 :                                  pszLayerName, pszGeomCol);
     806                 : 
     807               4 :                 rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     808               4 :                 if( rc != SQLITE_OK )
     809                 :                 {
     810                 :                     CPLError( CE_Failure, CPLE_AppDefined, 
     811               0 :                             "Unable to create spatial index:\n%s", pszErrMsg );
     812               0 :                     sqlite3_free( pszErrMsg );
     813               0 :                     return FALSE;
     814                 :                 }
     815                 :             }
     816                 :         }
     817                 :     }
     818                 : 
     819                 : /* -------------------------------------------------------------------- */
     820                 : /*      Create the layer object.                                        */
     821                 : /* -------------------------------------------------------------------- */
     822                 :     OGRSQLiteTableLayer     *poLayer;
     823                 : 
     824              14 :     poLayer = new OGRSQLiteTableLayer( this );
     825                 : 
     826                 :     poLayer->Initialize( pszLayerName, pszGeomCol, eType, pszGeomFormat, 
     827              28 :                          FetchSRS(nSRSId), nSRSId );
     828                 : 
     829              14 :     poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) );
     830                 : 
     831                 : /* -------------------------------------------------------------------- */
     832                 : /*      Add layer to data source layer list.                            */
     833                 : /* -------------------------------------------------------------------- */
     834                 :     papoLayers = (OGRSQLiteLayer **)
     835              14 :         CPLRealloc( papoLayers,  sizeof(OGRSQLiteLayer *) * (nLayers+1) );
     836                 :     
     837              14 :     papoLayers[nLayers++] = poLayer;
     838                 : 
     839              14 :     CPLFree( pszLayerName );
     840                 : 
     841              14 :     return poLayer;
     842                 : }
     843                 : 
     844                 : /************************************************************************/
     845                 : /*                            LaunderName()                             */
     846                 : /************************************************************************/
     847                 : 
     848              33 : char *OGRSQLiteDataSource::LaunderName( const char *pszSrcName )
     849                 : 
     850                 : {
     851              33 :     char    *pszSafeName = CPLStrdup( pszSrcName );
     852                 :     int     i;
     853                 : 
     854             280 :     for( i = 0; pszSafeName[i] != '\0'; i++ )
     855                 :     {
     856             247 :         pszSafeName[i] = (char) tolower( pszSafeName[i] );
     857             247 :         if( pszSafeName[i] == '-' || pszSafeName[i] == '#' )
     858               0 :             pszSafeName[i] = '_';
     859                 :     }
     860                 : 
     861              33 :     return pszSafeName;
     862                 : }
     863                 : 
     864                 : /************************************************************************/
     865                 : /*                            DeleteLayer()                             */
     866                 : /************************************************************************/
     867                 : 
     868              11 : void OGRSQLiteDataSource::DeleteLayer( const char *pszLayerName )
     869                 : 
     870                 : {
     871                 :     int iLayer;
     872                 : 
     873                 : /* -------------------------------------------------------------------- */
     874                 : /*      Try to find layer.                                              */
     875                 : /* -------------------------------------------------------------------- */
     876              28 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     877                 :     {
     878              27 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) )
     879              10 :             break;
     880                 :     }
     881                 : 
     882              11 :     if( iLayer == nLayers )
     883                 :     {
     884                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     885                 :                   "Attempt to delete layer '%s', but this layer is not known to OGR.", 
     886               1 :                   pszLayerName );
     887               1 :         return;
     888                 :     }
     889                 : 
     890                 : /* -------------------------------------------------------------------- */
     891                 : /*      Blow away our OGR structures related to the layer.  This is     */
     892                 : /*      pretty dangerous if anything has a reference to this layer!     */
     893                 : /* -------------------------------------------------------------------- */
     894              10 :     CPLDebug( "OGR_SQLITE", "DeleteLayer(%s)", pszLayerName );
     895                 : 
     896              10 :     delete papoLayers[iLayer];
     897                 :     memmove( papoLayers + iLayer, papoLayers + iLayer + 1, 
     898              10 :              sizeof(void *) * (nLayers - iLayer - 1) );
     899              10 :     nLayers--;
     900                 : 
     901                 : /* -------------------------------------------------------------------- */
     902                 : /*      Remove from the database.                                       */
     903                 : /* -------------------------------------------------------------------- */
     904                 :     int rc;
     905                 :     char *pszErrMsg;
     906                 : 
     907                 :     rc = sqlite3_exec( hDB, CPLSPrintf( "DROP TABLE '%s'", pszLayerName ),
     908              10 :                        NULL, NULL, &pszErrMsg );
     909              10 :     if( rc != SQLITE_OK )
     910                 :     {
     911                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     912                 :                   "Unable to drop table %s: %s",
     913               0 :                   pszLayerName, pszErrMsg );
     914               0 :         sqlite3_free( pszErrMsg );
     915               0 :         return;
     916                 :     }
     917                 : 
     918                 : /* -------------------------------------------------------------------- */
     919                 : /*      Drop from geometry_columns table.                               */
     920                 : /* -------------------------------------------------------------------- */
     921              10 :     if( bHaveGeometryColumns )
     922                 :     {
     923              10 :         CPLString osCommand;
     924                 : 
     925                 :         osCommand.Printf( 
     926                 :             "DELETE FROM geometry_columns WHERE f_table_name = '%s'",
     927              10 :             pszLayerName );
     928                 :         
     929              10 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     930              10 :         if( rc != SQLITE_OK )
     931                 :         {
     932                 :             CPLError( CE_Warning, CPLE_AppDefined,
     933                 :                       "Removal from geometry_columns failed.\n%s: %s", 
     934               0 :                       osCommand.c_str(), pszErrMsg );
     935               0 :             sqlite3_free( pszErrMsg );
     936              10 :         }
     937                 :     }
     938                 : }
     939                 : 
     940                 : /************************************************************************/
     941                 : /*                        SoftStartTransaction()                        */
     942                 : /*                                                                      */
     943                 : /*      Create a transaction scope.  If we already have a               */
     944                 : /*      transaction active this isn't a real transaction, but just      */
     945                 : /*      an increment to the scope count.                                */
     946                 : /************************************************************************/
     947                 : 
     948              27 : OGRErr OGRSQLiteDataSource::SoftStartTransaction()
     949                 : 
     950                 : {
     951              27 :     nSoftTransactionLevel++;
     952                 : 
     953              27 :     if( nSoftTransactionLevel == 1 )
     954                 :     {
     955                 :         int rc;
     956                 :         char *pszErrMsg;
     957                 :         
     958                 : #ifdef DEBUG
     959              27 :         CPLDebug( "OGR_SQLITE", "BEGIN Transaction" );
     960                 : #endif
     961                 : 
     962              27 :         rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, &pszErrMsg );
     963              27 :         if( rc != SQLITE_OK )
     964                 :         {
     965               0 :             nSoftTransactionLevel--;
     966                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     967                 :                       "BEGIN transaction failed: %s",
     968               0 :                       pszErrMsg );
     969               0 :             sqlite3_free( pszErrMsg );
     970               0 :             return OGRERR_FAILURE;
     971                 :         }
     972                 :     }
     973                 : 
     974              27 :     return OGRERR_NONE;
     975                 : }
     976                 : 
     977                 : /************************************************************************/
     978                 : /*                             SoftCommit()                             */
     979                 : /*                                                                      */
     980                 : /*      Commit the current transaction if we are at the outer           */
     981                 : /*      scope.                                                          */
     982                 : /************************************************************************/
     983                 : 
     984              26 : OGRErr OGRSQLiteDataSource::SoftCommit()
     985                 : 
     986                 : {
     987              26 :     if( nSoftTransactionLevel <= 0 )
     988                 :     {
     989               0 :         CPLDebug( "OGR_SQLITE", "SoftCommit() with no transaction active." );
     990               0 :         return OGRERR_FAILURE;
     991                 :     }
     992                 : 
     993              26 :     nSoftTransactionLevel--;
     994                 : 
     995              26 :     if( nSoftTransactionLevel == 0 )
     996                 :     {
     997                 :         int rc;
     998                 :         char *pszErrMsg;
     999                 :         
    1000                 : #ifdef DEBUG
    1001              26 :         CPLDebug( "OGR_SQLITE", "COMMIT Transaction" );
    1002                 : #endif
    1003                 : 
    1004              26 :         rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, &pszErrMsg );
    1005              26 :         if( rc != SQLITE_OK )
    1006                 :         {
    1007                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1008                 :                       "COMMIT transaction failed: %s",
    1009               0 :                       pszErrMsg );
    1010               0 :             sqlite3_free( pszErrMsg );
    1011               0 :             return OGRERR_FAILURE;
    1012                 :         }
    1013                 :     }
    1014                 : 
    1015              26 :     return OGRERR_NONE;
    1016                 : }
    1017                 : 
    1018                 : /************************************************************************/
    1019                 : /*                            SoftRollback()                            */
    1020                 : /*                                                                      */
    1021                 : /*      Force a rollback of the current transaction if there is one,    */
    1022                 : /*      even if we are nested several levels deep.                      */
    1023                 : /************************************************************************/
    1024                 : 
    1025               1 : OGRErr OGRSQLiteDataSource::SoftRollback()
    1026                 : 
    1027                 : {
    1028               1 :     if( nSoftTransactionLevel <= 0 )
    1029                 :     {
    1030               0 :         CPLDebug( "OGR_SQLITE", "SoftRollback() with no transaction active." );
    1031               0 :         return OGRERR_FAILURE;
    1032                 :     }
    1033                 : 
    1034               1 :     nSoftTransactionLevel = 0;
    1035                 : 
    1036                 :     int rc;
    1037                 :     char *pszErrMsg;
    1038                 :     
    1039                 : #ifdef DEBUG
    1040               1 :     CPLDebug( "OGR_SQLITE", "ROLLBACK Transaction" );
    1041                 : #endif
    1042                 : 
    1043               1 :     rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, &pszErrMsg );
    1044               1 :     if( rc != SQLITE_OK )
    1045                 :     {
    1046                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1047                 :                   "ROLLBACK transaction failed: %s",
    1048               0 :                   pszErrMsg );
    1049               0 :         sqlite3_free( pszErrMsg );
    1050               0 :         return OGRERR_FAILURE;
    1051                 :     }
    1052                 :     
    1053               1 :     return OGRERR_NONE;
    1054                 : }
    1055                 : 
    1056                 : /************************************************************************/
    1057                 : /*                        FlushSoftTransaction()                        */
    1058                 : /*                                                                      */
    1059                 : /*      Force the unwinding of any active transaction, and it's         */
    1060                 : /*      commit.                                                         */
    1061                 : /************************************************************************/
    1062                 : 
    1063               0 : OGRErr OGRSQLiteDataSource::FlushSoftTransaction()
    1064                 : 
    1065                 : {
    1066               0 :     if( nSoftTransactionLevel <= 0 )
    1067               0 :         return OGRERR_NONE;
    1068                 : 
    1069               0 :     nSoftTransactionLevel = 1;
    1070                 : 
    1071               0 :     return SoftCommit();
    1072                 : }
    1073                 : 
    1074                 : /************************************************************************/
    1075                 : /*                             FetchSRSId()                             */
    1076                 : /*                                                                      */
    1077                 : /*      Fetch the id corresponding to an SRS, and if not found, add     */
    1078                 : /*      it to the table.                                                */
    1079                 : /************************************************************************/
    1080                 : 
    1081               7 : int OGRSQLiteDataSource::FetchSRSId( OGRSpatialReference * poSRS )
    1082                 : 
    1083                 : {
    1084               7 :     int                 nSRSId = -1;
    1085               7 :     const char          *pszAuthorityName, *pszAuthorityCode = NULL;
    1086               7 :     CPLString           osCommand;
    1087                 :     char *pszErrMsg;
    1088                 :     int   rc;
    1089                 :     char **papszResult;
    1090                 :     int nRowCount, nColCount;
    1091                 : 
    1092               7 :     if( poSRS == NULL )
    1093               0 :         return -1;
    1094                 : 
    1095               7 :     OGRSpatialReference oSRS(*poSRS);
    1096               7 :     poSRS = NULL;
    1097                 : 
    1098               7 :     pszAuthorityName = oSRS.GetAuthorityName(NULL);
    1099                 : 
    1100               7 :     if( pszAuthorityName == NULL || strlen(pszAuthorityName) == 0 )
    1101                 :     {
    1102                 : /* -------------------------------------------------------------------- */
    1103                 : /*      Try to identify an EPSG code                                    */
    1104                 : /* -------------------------------------------------------------------- */
    1105               2 :         oSRS.AutoIdentifyEPSG();
    1106                 : 
    1107               2 :         pszAuthorityName = oSRS.GetAuthorityName(NULL);
    1108               2 :         if (pszAuthorityName != NULL && EQUAL(pszAuthorityName, "EPSG"))
    1109                 :         {
    1110               1 :             pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    1111               1 :             if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    1112                 :             {
    1113                 :                 /* Import 'clean' SRS */
    1114               1 :                 oSRS.importFromEPSG( atoi(pszAuthorityCode) );
    1115                 : 
    1116               1 :                 pszAuthorityName = oSRS.GetAuthorityName(NULL);
    1117               1 :                 pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    1118                 :             }
    1119                 :         }
    1120                 :     }
    1121                 : 
    1122                 : /* -------------------------------------------------------------------- */
    1123                 : /*      Check whether the EPSG authority code is already mapped to a    */
    1124                 : /*      SRS ID.                                                         */
    1125                 : /* -------------------------------------------------------------------- */
    1126               7 :     if( pszAuthorityName != NULL && strlen(pszAuthorityName) > 0 )
    1127                 :     {
    1128               6 :         pszAuthorityCode = oSRS.GetAuthorityCode(NULL);
    1129                 : 
    1130               6 :         if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    1131                 :         {
    1132                 :             // XXX: We are using case insensitive comparison for "auth_name"
    1133                 :             // values, because there are variety of options exist. By default
    1134                 :             // the driver uses 'EPSG' in upper case, but SpatiaLite extension
    1135                 :             // uses 'epsg' in lower case.
    1136                 :             osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    1137                 :                               "auth_name = '%s' COLLATE NOCASE AND auth_srid = '%s'",
    1138               6 :                               pszAuthorityName, pszAuthorityCode );
    1139                 : 
    1140                 :             rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    1141               6 :                                     &nRowCount, &nColCount, &pszErrMsg );
    1142               6 :             if( rc != SQLITE_OK )
    1143                 :             {
    1144                 :                 /* Retry without COLLATE NOCASE which may not be understood by older sqlite3 */
    1145               0 :                 sqlite3_free( pszErrMsg );
    1146                 : 
    1147                 :                 osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    1148                 :                                   "auth_name = '%s' AND auth_srid = '%s'",
    1149               0 :                                   pszAuthorityName, pszAuthorityCode );
    1150                 : 
    1151                 :                 rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    1152               0 :                                         &nRowCount, &nColCount, &pszErrMsg );
    1153                 : 
    1154                 :                 /* Retry in lower case for SpatiaLite */
    1155               0 :                 if( rc != SQLITE_OK )
    1156                 :                 {
    1157               0 :                     sqlite3_free( pszErrMsg );
    1158                 :                 }
    1159               0 :                 else if ( nRowCount == 0 &&
    1160                 :                           strcmp(pszAuthorityName, "EPSG") == 0)
    1161                 :                 {
    1162                 :                     /* If it's in upper case, look for lower case */
    1163               0 :                     sqlite3_free_table(papszResult);
    1164                 : 
    1165                 :                     osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE "
    1166                 :                                       "auth_name = 'epsg' AND auth_srid = '%s'",
    1167               0 :                                       pszAuthorityCode );
    1168                 : 
    1169                 :                     rc = sqlite3_get_table( hDB, osCommand, &papszResult, 
    1170               0 :                                             &nRowCount, &nColCount, &pszErrMsg );
    1171                 : 
    1172               0 :                     if( rc != SQLITE_OK )
    1173                 :                     {
    1174               0 :                         sqlite3_free( pszErrMsg );
    1175                 :                     }
    1176                 :                 }
    1177                 :             }
    1178                 : 
    1179               6 :             if( rc == SQLITE_OK && nRowCount == 1 )
    1180                 :             {
    1181               4 :                 nSRSId = (papszResult[1] != NULL) ? atoi(papszResult[1]) : -1;
    1182               4 :                 sqlite3_free_table(papszResult);
    1183               4 :                 return nSRSId;
    1184                 :             }
    1185               2 :             sqlite3_free_table(papszResult);
    1186                 :         }
    1187                 :     }
    1188                 : 
    1189                 : /* -------------------------------------------------------------------- */
    1190                 : /*      Search for existing record using either WKT definition or       */
    1191                 : /*      PROJ.4 string (SpatiaLite variant).                             */
    1192                 : /* -------------------------------------------------------------------- */
    1193               3 :     CPLString   osSRS;
    1194                 : 
    1195               3 :     if ( !bIsSpatiaLite )
    1196                 :     {
    1197                 : /* -------------------------------------------------------------------- */
    1198                 : /*      Translate SRS to WKT.                                           */
    1199                 : /* -------------------------------------------------------------------- */
    1200               1 :         char    *pszWKT = NULL;
    1201                 : 
    1202               1 :         if( oSRS.exportToWkt( &pszWKT ) != OGRERR_NONE )
    1203                 :         {
    1204               0 :             CPLFree(pszWKT);
    1205               0 :             return -1;
    1206                 :         }
    1207                 : 
    1208               1 :         osSRS = pszWKT;
    1209               1 :         CPLFree( pszWKT );
    1210               1 :         pszWKT = NULL;
    1211                 : 
    1212                 : /* -------------------------------------------------------------------- */
    1213                 : /*      Try to find based on the WKT match.                             */
    1214                 : /* -------------------------------------------------------------------- */
    1215               1 :         osCommand.Printf( "SELECT srid FROM spatial_ref_sys WHERE srtext = ?");
    1216                 :     }
    1217                 : 
    1218                 : /* -------------------------------------------------------------------- */
    1219                 : /*      Handle SpatiaLite flavour of the spatial_ref_sys.               */
    1220                 : /* -------------------------------------------------------------------- */
    1221                 :     else
    1222                 :     {
    1223                 : /* -------------------------------------------------------------------- */
    1224                 : /*      Translate SRS to PROJ.4 string.                                 */
    1225                 : /* -------------------------------------------------------------------- */
    1226               2 :         char    *pszProj4 = NULL;
    1227                 : 
    1228               2 :         if( oSRS.exportToProj4( &pszProj4 ) != OGRERR_NONE )
    1229                 :         {
    1230               0 :             CPLFree(pszProj4);
    1231               0 :             return -1;
    1232                 :         }
    1233                 : 
    1234               2 :         osSRS = pszProj4;
    1235               2 :         CPLFree( pszProj4 );
    1236               2 :         pszProj4 = NULL;
    1237                 : 
    1238                 : /* -------------------------------------------------------------------- */
    1239                 : /*      Try to find based on the PROJ.4 match.                          */
    1240                 : /* -------------------------------------------------------------------- */
    1241                 :         osCommand.Printf(
    1242               2 :             "SELECT srid FROM spatial_ref_sys WHERE proj4text = ?");
    1243                 :     }
    1244                 : 
    1245               3 :     sqlite3_stmt *hSelectStmt = NULL;
    1246               3 :     rc = sqlite3_prepare( hDB, osCommand, -1, &hSelectStmt, NULL );
    1247                 : 
    1248               3 :     if( rc == SQLITE_OK)
    1249               3 :         rc = sqlite3_bind_text( hSelectStmt, 1, osSRS.c_str(), -1, SQLITE_STATIC );
    1250                 : 
    1251               3 :     if( rc == SQLITE_OK)
    1252               3 :         rc = sqlite3_step( hSelectStmt );
    1253                 : 
    1254               3 :     if (rc == SQLITE_ROW)
    1255                 :     {
    1256               0 :         if (sqlite3_column_type( hSelectStmt, 0 ) == SQLITE_INTEGER)
    1257               0 :             nSRSId = sqlite3_column_int( hSelectStmt, 0 );
    1258                 :         else
    1259               0 :             nSRSId = -1;
    1260                 : 
    1261               0 :         sqlite3_finalize( hSelectStmt );
    1262               0 :         return nSRSId;
    1263                 :     }
    1264                 : 
    1265                 : /* -------------------------------------------------------------------- */
    1266                 : /*      If the command actually failed, then the metadata table is      */
    1267                 : /*      likely missing, so we give up.                                  */
    1268                 : /* -------------------------------------------------------------------- */
    1269               3 :     if (rc != SQLITE_DONE && rc != SQLITE_ROW)
    1270                 :     {
    1271               0 :         sqlite3_finalize( hSelectStmt );
    1272               0 :         return -1;
    1273                 :     }
    1274                 : 
    1275               3 :     sqlite3_finalize( hSelectStmt );
    1276                 : 
    1277                 : /* -------------------------------------------------------------------- */
    1278                 : /*      If we have an authority code try to assign SRS ID the same      */
    1279                 : /*      as that code.                                                   */
    1280                 : /* -------------------------------------------------------------------- */
    1281               3 :     if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
    1282                 :     {
    1283                 :         osCommand.Printf( "SELECT * FROM spatial_ref_sys WHERE auth_srid='%s'",
    1284               2 :                           pszAuthorityCode );
    1285                 :         rc = sqlite3_get_table( hDB, osCommand, &papszResult,
    1286               2 :                                 &nRowCount, &nColCount, &pszErrMsg );
    1287                 :         
    1288               2 :         if( rc != SQLITE_OK )
    1289                 :         {
    1290                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1291                 :                       "exec(SELECT '%s' FROM spatial_ref_sys) failed: %s",
    1292               0 :                       pszAuthorityCode, pszErrMsg );
    1293               0 :             sqlite3_free( pszErrMsg );
    1294                 :         }
    1295                 : 
    1296                 : /* -------------------------------------------------------------------- */
    1297                 : /*      If there is no SRS ID with such auth_srid, use it as SRS ID.    */
    1298                 : /* -------------------------------------------------------------------- */
    1299               2 :         if ( nRowCount < 1 )
    1300               2 :             nSRSId = atoi(pszAuthorityCode);
    1301               2 :         sqlite3_free_table(papszResult);
    1302                 :     }
    1303                 : 
    1304                 : /* -------------------------------------------------------------------- */
    1305                 : /*      Otherwise get the current maximum srid in the srs table.        */
    1306                 : /* -------------------------------------------------------------------- */
    1307               3 :     if ( nSRSId == -1 )
    1308                 :     {
    1309                 :         rc = sqlite3_get_table( hDB, "SELECT MAX(srid) FROM spatial_ref_sys", 
    1310                 :                                 &papszResult, &nRowCount, &nColCount,
    1311               1 :                                 &pszErrMsg );
    1312                 :         
    1313               1 :         if( rc != SQLITE_OK )
    1314                 :         {
    1315                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1316               0 :                       "SELECT of the maximum SRS ID failed: %s", pszErrMsg );
    1317               0 :             sqlite3_free( pszErrMsg );
    1318               0 :             return -1;
    1319                 :         }
    1320                 : 
    1321               1 :         if ( nRowCount < 1 || !papszResult[1] )
    1322               0 :             nSRSId = 50000;
    1323                 :         else
    1324               1 :             nSRSId = atoi(papszResult[1]) + 1;  // Insert as the next SRS ID
    1325               1 :         sqlite3_free_table(papszResult);
    1326                 :     }
    1327                 : 
    1328                 : /* -------------------------------------------------------------------- */
    1329                 : /*      Try adding the SRS to the SRS table.                            */
    1330                 : /* -------------------------------------------------------------------- */
    1331                 : 
    1332               3 :     const char* apszToInsert[] = { NULL, NULL, NULL, NULL, NULL };
    1333                 : 
    1334               3 :     if ( !bIsSpatiaLite )
    1335                 :     {
    1336               1 :         if( pszAuthorityName != NULL )
    1337                 :         {
    1338                 :             osCommand.Printf(
    1339                 :                 "INSERT INTO spatial_ref_sys (srid,srtext,auth_name,auth_srid) "
    1340                 :                 "                     VALUES (%d, ?, ?, ?)",
    1341               1 :                 nSRSId );
    1342               1 :             apszToInsert[0] = osSRS.c_str();
    1343               1 :             apszToInsert[1] = pszAuthorityName;
    1344               1 :             apszToInsert[2] = pszAuthorityCode;
    1345                 :         }
    1346                 :         else
    1347                 :         {
    1348                 :             osCommand.Printf(
    1349                 :                 "INSERT INTO spatial_ref_sys (srid,srtext) "
    1350                 :                 "                     VALUES (%d, ?)",
    1351               0 :                 nSRSId );
    1352               0 :             apszToInsert[0] = osSRS.c_str();
    1353                 :         }
    1354                 :     }
    1355                 :     else
    1356                 :     {
    1357               2 :         const char  *pszProjCS = oSRS.GetAttrValue("PROJCS");
    1358               2 :         if (pszProjCS == NULL)
    1359               1 :             pszProjCS = oSRS.GetAttrValue("GEOGCS");
    1360                 : 
    1361               2 :         if( pszAuthorityName != NULL )
    1362                 :         {
    1363               1 :             if ( pszProjCS )
    1364                 :             {
    1365                 :                 osCommand.Printf(
    1366                 :                     "INSERT INTO spatial_ref_sys "
    1367                 :                     "(srid, auth_name, auth_srid, ref_sys_name, proj4text) "
    1368                 :                     "VALUES (%d, ?, ?, ?, ?)",
    1369               1 :                     nSRSId );
    1370               1 :                 apszToInsert[0] = pszAuthorityName;
    1371               1 :                 apszToInsert[1] = pszAuthorityCode;
    1372               1 :                 apszToInsert[2] = pszProjCS;
    1373               1 :                 apszToInsert[3] = osSRS.c_str();
    1374                 :             }
    1375                 :             else
    1376                 :             {
    1377                 :                 osCommand.Printf(
    1378                 :                     "INSERT INTO spatial_ref_sys "
    1379                 :                     "(srid, auth_name, auth_srid, proj4text) "
    1380                 :                     "VALUES (%d, ?, ?, ?)",
    1381               0 :                     nSRSId );
    1382               0 :                 apszToInsert[0] = pszAuthorityName;
    1383               0 :                 apszToInsert[1] = pszAuthorityCode;
    1384               0 :                 apszToInsert[2] = osSRS.c_str();
    1385                 :             }
    1386                 :         }
    1387                 :         else
    1388                 :         {
    1389                 :             /* SpatiaLite spatial_ref_sys auth_name and auth_srid columns must be NOT NULL */
    1390                 :             /* so insert within a fake OGR "authority" */
    1391               1 :             if ( pszProjCS )
    1392                 :             {
    1393                 :                 osCommand.Printf(
    1394                 :                     "INSERT INTO spatial_ref_sys "
    1395                 :                     "(srid, auth_name, auth_srid, ref_sys_name, proj4text) VALUES (%d, 'OGR', %d, ?, ?)",
    1396               1 :                     nSRSId, nSRSId );
    1397               1 :                 apszToInsert[0] = pszProjCS;
    1398               1 :                 apszToInsert[1] = osSRS.c_str();
    1399                 :             }
    1400                 :             else
    1401                 :             {
    1402                 :                 osCommand.Printf(
    1403                 :                     "INSERT INTO spatial_ref_sys "
    1404                 :                     "(srid, auth_name, auth_srid, proj4text) VALUES (%d, 'OGR', %d, ?)",
    1405               0 :                     nSRSId, nSRSId );
    1406               0 :                 apszToInsert[0] = osSRS.c_str();
    1407                 :             }
    1408                 :         }
    1409                 :     }
    1410                 : 
    1411               3 :     sqlite3_stmt *hInsertStmt = NULL;
    1412               3 :     rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
    1413                 : 
    1414                 :     int i;
    1415              12 :     for(i=0;apszToInsert[i]!=NULL;i++)
    1416                 :     {
    1417               9 :         if( rc == SQLITE_OK)
    1418               9 :             rc = sqlite3_bind_text( hInsertStmt, i+1, apszToInsert[i], -1, SQLITE_STATIC );
    1419                 :     }
    1420                 : 
    1421               3 :     if( rc == SQLITE_OK)
    1422               3 :         rc = sqlite3_step( hInsertStmt );
    1423                 : 
    1424               3 :     if( rc != SQLITE_OK && rc != SQLITE_DONE )
    1425                 :     {
    1426                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1427                 :                   "Unable to insert SRID (%s): %s",
    1428               0 :                   osCommand.c_str(), sqlite3_errmsg(hDB) );
    1429                 : 
    1430               0 :         sqlite3_finalize( hInsertStmt );
    1431               0 :         return FALSE;
    1432                 :     }
    1433                 : 
    1434               3 :     sqlite3_finalize( hInsertStmt );
    1435                 : 
    1436               3 :     return nSRSId;
    1437                 : }
    1438                 : 
    1439                 : /************************************************************************/
    1440                 : /*                              FetchSRS()                              */
    1441                 : /*                                                                      */
    1442                 : /*      Return a SRS corresponding to a particular id.  Note that       */
    1443                 : /*      reference counting should be honoured on the returned           */
    1444                 : /*      OGRSpatialReference, as handles may be cached.                  */
    1445                 : /************************************************************************/
    1446                 : 
    1447             116 : OGRSpatialReference *OGRSQLiteDataSource::FetchSRS( int nId )
    1448                 : 
    1449                 : {
    1450             116 :     if( nId <= 0 )
    1451              31 :         return NULL;
    1452                 : 
    1453                 : /* -------------------------------------------------------------------- */
    1454                 : /*      First, we look through our SRID cache, is it there?             */
    1455                 : /* -------------------------------------------------------------------- */
    1456                 :     int  i;
    1457                 : 
    1458              94 :     for( i = 0; i < nKnownSRID; i++ )
    1459                 :     {
    1460              19 :         if( panSRID[i] == nId )
    1461              10 :             return papoSRS[i];
    1462                 :     }
    1463                 : 
    1464                 : /* -------------------------------------------------------------------- */
    1465                 : /*      Try looking up in spatial_ref_sys table.                        */
    1466                 : /* -------------------------------------------------------------------- */
    1467                 :     char *pszErrMsg;
    1468                 :     int   rc;
    1469                 :     char **papszResult;
    1470                 :     int nRowCount, nColCount;
    1471              75 :     CPLString osCommand;
    1472              75 :     OGRSpatialReference *poSRS = NULL;
    1473                 : 
    1474                 :     osCommand.Printf( "SELECT srtext FROM spatial_ref_sys WHERE srid = %d",
    1475              75 :                       nId );
    1476                 :     rc = sqlite3_get_table( hDB, osCommand, 
    1477              75 :                             &papszResult, &nRowCount, &nColCount, &pszErrMsg );
    1478                 : 
    1479              75 :     if ( rc == SQLITE_OK )
    1480                 :     {
    1481               7 :         if( nRowCount < 1 )
    1482                 :         {
    1483               0 :             sqlite3_free_table(papszResult);
    1484              75 :             return NULL;
    1485                 :         }
    1486                 : 
    1487               7 :         char** papszRow = papszResult + nColCount;
    1488               7 :         if (papszRow[0] != NULL)
    1489                 :         {
    1490               7 :             CPLString osWKT = papszRow[0];
    1491                 : 
    1492                 : /* -------------------------------------------------------------------- */
    1493                 : /*      Translate into a spatial reference.                             */
    1494                 : /* -------------------------------------------------------------------- */
    1495               7 :             char *pszWKT = (char *) osWKT.c_str();
    1496                 : 
    1497               7 :             poSRS = new OGRSpatialReference();
    1498              14 :             if( poSRS->importFromWkt( &pszWKT ) != OGRERR_NONE )
    1499                 :             {
    1500               0 :                 delete poSRS;
    1501               0 :                 poSRS = NULL;
    1502               7 :             }
    1503                 :         }
    1504                 : 
    1505               7 :         sqlite3_free_table(papszResult);
    1506                 :     }
    1507                 : 
    1508                 : /* -------------------------------------------------------------------- */
    1509                 : /*      Next try SpatiaLite flavour. SpatiaLite uses PROJ.4 strings     */
    1510                 : /*      in 'proj4text' column instead of WKT in 'srtext'.               */
    1511                 : /* -------------------------------------------------------------------- */
    1512                 :     else
    1513                 :     {
    1514              68 :         sqlite3_free( pszErrMsg );
    1515              68 :         pszErrMsg = NULL;
    1516                 : 
    1517                 :         osCommand.Printf(
    1518              68 :             "SELECT proj4text, auth_name, auth_srid FROM spatial_ref_sys WHERE srid = %d", nId );
    1519                 :         rc = sqlite3_get_table( hDB, osCommand, 
    1520                 :                                 &papszResult, &nRowCount,
    1521              68 :                                 &nColCount, &pszErrMsg );
    1522              68 :         if ( rc == SQLITE_OK )
    1523                 :         {
    1524              68 :             if( nRowCount < 1 )
    1525                 :             {
    1526               0 :                 sqlite3_free_table(papszResult);
    1527               0 :                 return NULL;
    1528                 :             }
    1529                 : 
    1530                 : /* -------------------------------------------------------------------- */
    1531                 : /*      Translate into a spatial reference.                             */
    1532                 : /* -------------------------------------------------------------------- */
    1533              68 :             char** papszRow = papszResult + nColCount;
    1534                 : 
    1535              68 :             const char* pszProj4Text = papszRow[0];
    1536              68 :             if (pszProj4Text != NULL)
    1537                 :             {
    1538              68 :                 const char* pszAuthName = papszRow[1];
    1539              68 :                 int nAuthSRID = (papszRow[2] != NULL) ? atoi(papszRow[2]) : 0;
    1540                 : 
    1541              68 :                 poSRS = new OGRSpatialReference();
    1542                 : 
    1543                 :                 /* Try first from EPSG code */
    1544             136 :                 if (pszAuthName != NULL &&
    1545                 :                     EQUAL(pszAuthName, "EPSG") &&
    1546                 :                     poSRS->importFromEPSG( nAuthSRID ) == OGRERR_NONE)
    1547                 :                 {
    1548                 :                     /* Do nothing */
    1549                 :                 }
    1550                 :                 /* Then from Proj4 string */
    1551               9 :                 else if( poSRS->importFromProj4( pszProj4Text ) != OGRERR_NONE )
    1552                 :                 {
    1553               0 :                     delete poSRS;
    1554               0 :                     poSRS = NULL;
    1555                 :                 }
    1556                 :             }
    1557                 : 
    1558              68 :             sqlite3_free_table(papszResult);
    1559                 :         }
    1560                 : 
    1561                 : /* -------------------------------------------------------------------- */
    1562                 : /*      No success, report an error.                                    */
    1563                 : /* -------------------------------------------------------------------- */
    1564                 :         else
    1565                 :         {
    1566                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    1567               0 :                       "%s: %s", osCommand.c_str(), pszErrMsg );
    1568               0 :             sqlite3_free( pszErrMsg );
    1569               0 :             return NULL;
    1570                 :         }
    1571                 :     }
    1572                 : 
    1573                 : /* -------------------------------------------------------------------- */
    1574                 : /*      Add to the cache.                                               */
    1575                 : /* -------------------------------------------------------------------- */
    1576              75 :     panSRID = (int *) CPLRealloc(panSRID,sizeof(int) * (nKnownSRID+1) );
    1577                 :     papoSRS = (OGRSpatialReference **)
    1578              75 :         CPLRealloc(papoSRS, sizeof(void*) * (nKnownSRID + 1) );
    1579              75 :     panSRID[nKnownSRID] = nId;
    1580              75 :     papoSRS[nKnownSRID] = poSRS;
    1581              75 :     nKnownSRID++;
    1582                 : 
    1583              75 :     return poSRS;
    1584                 : }

Generated by: LTP GCOV extension version 1.5