LCOV - code coverage report
Current view: directory - apps - test_ogrsf.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 817 568 69.5 %
Date: 2012-04-28 Functions: 15 14 93.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: test_ogrsf.cpp 24313 2012-04-24 20:11:21Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Formal test harnass for OGRLayer implementations.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      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 "ogrsf_frmts.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "ogr_api.h"
      33                 : #include "ogr_p.h"
      34                 : 
      35                 : CPL_CVSID("$Id: test_ogrsf.cpp 24313 2012-04-24 20:11:21Z rouault $");
      36                 : 
      37                 : int     bReadOnly = FALSE;
      38                 : int     bVerbose = TRUE;
      39                 : 
      40                 : static void Usage();
      41                 : static int TestOGRLayer( OGRDataSource * poDS, OGRLayer * poLayer, int bIsSQLLayer );
      42                 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers );
      43                 : static int TestErrorConditions( OGRDataSource * poDS );
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                                main()                                */
      47                 : /************************************************************************/
      48                 : 
      49              56 : int main( int nArgc, char ** papszArgv )
      50                 : 
      51                 : {
      52              56 :     const char  *pszDataSource = NULL;
      53              56 :     char** papszLayers = NULL;
      54              56 :     const char  *pszSQLStatement = NULL;
      55              56 :     const char  *pszDialect = NULL;
      56              56 :     int bRet = TRUE;
      57                 : 
      58                 :     /* Must process OGR_SKIP before OGRRegisterAll(), but we can't call */
      59                 :     /* OGRGeneralCmdLineProcessor before it needs the drivers to be registered */
      60                 :     /* for the --format or --formats options */
      61             178 :     for( int iArg = 1; iArg < nArgc; iArg++ )
      62                 :     {
      63             132 :         if( EQUAL(papszArgv[iArg], "--config") && iArg + 2 < nArgc &&
      64               6 :             EQUAL(papszArgv[iArg+1], "OGR_SKIP") )
      65                 :         {
      66               4 :             CPLSetConfigOption(papszArgv[iArg+1], papszArgv[iArg+2]);
      67               4 :             break;
      68                 :         }
      69                 :     }
      70                 :     
      71                 : /* -------------------------------------------------------------------- */
      72                 : /*      Register format(s).                                             */
      73                 : /* -------------------------------------------------------------------- */
      74              56 :     OGRRegisterAll();
      75                 : 
      76                 : /* -------------------------------------------------------------------- */
      77                 : /*      Processing command line arguments.                              */
      78                 : /* -------------------------------------------------------------------- */
      79              56 :     nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
      80                 : 
      81              56 :     if( nArgc < 1 )
      82               0 :         exit( -nArgc );
      83                 : 
      84                 : /* -------------------------------------------------------------------- */
      85                 : /*      Processing command line arguments.                              */
      86                 : /* -------------------------------------------------------------------- */
      87             170 :     for( int iArg = 1; iArg < nArgc; iArg++ )
      88                 :     {
      89             116 :         if( EQUAL(papszArgv[iArg], "--utility_version") )
      90                 :         {
      91                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
      92               2 :                    papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
      93               2 :             return 0;
      94                 :         }
      95             114 :         else if( EQUAL(papszArgv[iArg],"-ro") )
      96              32 :             bReadOnly = TRUE;
      97              82 :         else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet"))
      98               0 :             bVerbose = FALSE;
      99              90 :         else if( EQUAL(papszArgv[iArg],"-sql") && iArg + 1 < nArgc)
     100               8 :             pszSQLStatement = papszArgv[++iArg];
     101              74 :         else if( EQUAL(papszArgv[iArg],"-dialect") && papszArgv[iArg+1] != NULL )
     102                 :         {
     103               0 :             pszDialect = papszArgv[++iArg];
     104                 :         }
     105              74 :         else if( papszArgv[iArg][0] == '-' )
     106                 :         {
     107               0 :             Usage();
     108                 :         }
     109              74 :         else if (pszDataSource == NULL)
     110              54 :             pszDataSource = papszArgv[iArg];
     111                 :         else
     112              20 :             papszLayers = CSLAddString(papszLayers, papszArgv[iArg]);
     113                 :     }
     114                 : 
     115              54 :     if( pszDataSource == NULL )
     116               0 :         Usage();
     117                 : 
     118                 : /* -------------------------------------------------------------------- */
     119                 : /*      Open data source.                                               */
     120                 : /* -------------------------------------------------------------------- */
     121                 :     OGRDataSource       *poDS;
     122                 :     OGRSFDriver         *poDriver;
     123                 : 
     124              54 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, !bReadOnly, &poDriver );
     125              54 :     if( poDS == NULL && !bReadOnly )
     126                 :     {
     127               0 :         poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, &poDriver );
     128               0 :         if( poDS != NULL && bVerbose )
     129                 :         {
     130               0 :             printf( "Had to open data source read-only.\n" );
     131               0 :             bReadOnly = TRUE;
     132                 :         }
     133                 :     }
     134                 : 
     135                 : /* -------------------------------------------------------------------- */
     136                 : /*      Report failure                                                  */
     137                 : /* -------------------------------------------------------------------- */
     138              54 :     if( poDS == NULL )
     139                 :     {
     140               0 :         OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
     141                 :         
     142                 :         printf( "FAILURE:\n"
     143                 :                 "Unable to open datasource `%s' with the following drivers.\n",
     144               0 :                 pszDataSource );
     145                 : 
     146               0 :         for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
     147                 :         {
     148               0 :             printf( "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
     149                 :         }
     150                 : 
     151               0 :         exit( 1 );
     152                 :     }
     153                 : 
     154                 : /* -------------------------------------------------------------------- */
     155                 : /*      Some information messages.                                      */
     156                 : /* -------------------------------------------------------------------- */
     157              54 :     if( bVerbose )
     158                 :         printf( "INFO: Open of `%s' using driver `%s' successful.\n",
     159              54 :                 pszDataSource, poDriver->GetName() );
     160                 : 
     161              54 :     if( bVerbose && !EQUAL(pszDataSource,poDS->GetName()) )
     162                 :     {
     163                 :         printf( "INFO: Internal data source name `%s'\n"
     164                 :                 "      different from user name `%s'.\n",
     165               0 :                 poDS->GetName(), pszDataSource );
     166                 :     }
     167                 :     
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      Process optionnal SQL request.                                  */
     170                 : /* -------------------------------------------------------------------- */
     171              54 :     if (pszSQLStatement != NULL)
     172                 :     {
     173               8 :         OGRLayer  *poResultSet = poDS->ExecuteSQL(pszSQLStatement, NULL, pszDialect);
     174               8 :         if (poResultSet == NULL)
     175               0 :             exit(1);
     176                 :             
     177                 :         printf( "INFO: Testing layer %s.\n",
     178               8 :                     poResultSet->GetName() );
     179               8 :         bRet = TestOGRLayer( poDS, poResultSet, TRUE );
     180                 :         
     181               8 :         poDS->ReleaseResultSet(poResultSet);
     182                 :     }
     183                 : /* -------------------------------------------------------------------- */
     184                 : /*      Process each data source layer.                                 */
     185                 : /* -------------------------------------------------------------------- */
     186              46 :     else if (papszLayers == NULL)
     187                 :     {
     188             202 :         for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
     189                 :         {
     190             166 :             OGRLayer        *poLayer = poDS->GetLayer(iLayer);
     191                 : 
     192             166 :             if( poLayer == NULL )
     193                 :             {
     194                 :                 printf( "FAILURE: Couldn't fetch advertised layer %d!\n",
     195               0 :                         iLayer );
     196               0 :                 exit( 1 );
     197                 :             }
     198                 : 
     199                 :             printf( "INFO: Testing layer %s.\n",
     200             166 :                     poLayer->GetName() );
     201             166 :             bRet &= TestOGRLayer( poDS, poLayer, FALSE );
     202                 :         }
     203                 : 
     204              36 :         if (poDS->GetLayerCount() >= 2)
     205                 :         {
     206              18 :             OGRDataSource::DestroyDataSource(poDS);
     207              18 :             poDS = NULL;
     208              18 :             bRet &= TestInterleavedReading( pszDataSource, NULL );
     209                 :         }
     210                 :     }
     211                 :     else
     212                 :     {
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      Or process layers specified by the user                         */
     215                 : /* -------------------------------------------------------------------- */
     216              10 :         char** papszLayerIter = papszLayers;
     217              40 :         while (*papszLayerIter)
     218                 :         {
     219              20 :             OGRLayer        *poLayer = poDS->GetLayerByName(*papszLayerIter);
     220                 : 
     221              20 :             if( poLayer == NULL )
     222                 :             {
     223                 :                 printf( "FAILURE: Couldn't fetch requested layer %s!\n",
     224               0 :                         *papszLayerIter );
     225               0 :                 exit( 1 );
     226                 :             }
     227                 :             
     228                 :             printf( "INFO: Testing layer %s.\n",
     229              20 :                     poLayer->GetName() );
     230              20 :             bRet &= TestOGRLayer( poDS, poLayer, FALSE );
     231                 :             
     232              20 :             papszLayerIter ++;
     233                 :         }
     234                 : 
     235              10 :         bRet &= TestErrorConditions(poDS);
     236                 : 
     237              10 :         if (CSLCount(papszLayers) >= 2)
     238                 :         {
     239               6 :             OGRDataSource::DestroyDataSource(poDS);
     240               6 :             poDS = NULL;
     241               6 :             bRet &= TestInterleavedReading( pszDataSource, papszLayers );
     242                 :         }
     243                 :     }
     244                 : 
     245                 : /* -------------------------------------------------------------------- */
     246                 : /*      Close down.                                                     */
     247                 : /* -------------------------------------------------------------------- */
     248              54 :     OGRDataSource::DestroyDataSource(poDS);
     249                 : 
     250              54 :     OGRCleanupAll();
     251                 : 
     252              54 :     CSLDestroy(papszLayers);
     253              54 :     CSLDestroy(papszArgv);
     254                 :     
     255                 : #ifdef DBMALLOC
     256                 :     malloc_dump(1);
     257                 : #endif
     258                 :     
     259              54 :     return (bRet) ? 0 : 1;
     260                 : }
     261                 : 
     262                 : /************************************************************************/
     263                 : /*                               Usage()                                */
     264                 : /************************************************************************/
     265                 : 
     266               0 : static void Usage()
     267                 : 
     268                 : {
     269                 :     printf( "Usage: test_ogrsf [-ro] [-q] datasource_name \n"
     270               0 :             "                  [[layer1_name, layer2_name, ...] | [-sql statement] [-dialect dialect]]\n" );
     271               0 :     exit( 1 );
     272                 : }
     273                 : 
     274                 : /************************************************************************/
     275                 : /*                      TestOGRLayerFeatureCount()                      */
     276                 : /*                                                                      */
     277                 : /*      Verify that the feature count matches the actual number of      */
     278                 : /*      features returned during sequential reading.                    */
     279                 : /************************************************************************/
     280                 : 
     281             194 : static int TestOGRLayerFeatureCount( OGRDataSource* poDS, OGRLayer *poLayer, int bIsSQLLayer )
     282                 : 
     283                 : {
     284             194 :     int bRet = TRUE;
     285             194 :     int         nFC = 0, nClaimedFC = poLayer->GetFeatureCount();
     286                 :     OGRFeature  *poFeature;
     287             194 :     OGRSpatialReference * poSRS = poLayer->GetSpatialRef();
     288             194 :     int         bWarnAboutSRS = FALSE;
     289             194 :     OGRFeatureDefn* poLayerDefn = poLayer->GetLayerDefn();
     290                 : 
     291             194 :     poLayer->ResetReading();
     292                 : 
     293          291356 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     294                 :     {
     295          290968 :         nFC++;
     296                 : 
     297          290968 :         if (poFeature->GetDefnRef() != poLayerDefn)
     298                 :         {
     299               0 :             bRet = FALSE;
     300                 :             printf( "ERROR: Feature defn differs from layer defn.\n"
     301                 :                     "Feature defn = %p\n"
     302                 :                     "Layer defn = %p\n",
     303               0 :                      poFeature->GetDefnRef(), poLayerDefn);
     304                 :         }
     305                 : 
     306          290968 :         if( poFeature->GetGeometryRef() != NULL
     307                 :             && poFeature->GetGeometryRef()->getSpatialReference() != poSRS
     308                 :             && !bWarnAboutSRS )
     309                 :         {
     310                 :             char        *pszLayerSRSWKT, *pszFeatureSRSWKT;
     311                 :             
     312               0 :             bWarnAboutSRS = TRUE;
     313                 : 
     314               0 :             if( poSRS != NULL )
     315               0 :                 poSRS->exportToWkt( &pszLayerSRSWKT );
     316                 :             else
     317               0 :                 pszLayerSRSWKT = CPLStrdup("(NULL)");
     318                 : 
     319               0 :             if( poFeature->GetGeometryRef()->getSpatialReference() != NULL )
     320                 :                 poFeature->GetGeometryRef()->
     321               0 :                     getSpatialReference()->exportToWkt( &pszFeatureSRSWKT );
     322                 :             else
     323               0 :                 pszFeatureSRSWKT = CPLStrdup("(NULL)");
     324                 : 
     325               0 :             bRet = FALSE;
     326                 :             printf( "ERROR: Feature SRS differs from layer SRS.\n"
     327                 :                     "Feature SRS = %s (%p)\n"
     328                 :                     "Layer SRS = %s (%p)\n",
     329                 :                     pszFeatureSRSWKT, poFeature->GetGeometryRef()->getSpatialReference(),
     330               0 :                     pszLayerSRSWKT, poSRS );
     331               0 :             CPLFree( pszLayerSRSWKT );
     332               0 :             CPLFree( pszFeatureSRSWKT );
     333                 :         }
     334                 :         
     335          290968 :         OGRFeature::DestroyFeature(poFeature);
     336                 :     }
     337                 : 
     338             194 :     if( nFC != nClaimedFC )
     339                 :     {
     340               0 :         bRet = FALSE;
     341                 :         printf( "ERROR: Claimed feature count %d doesn't match actual, %d.\n",
     342               0 :                 nClaimedFC, nFC );
     343                 :     }
     344             194 :     else if( nFC != poLayer->GetFeatureCount() )
     345                 :     {
     346               0 :         bRet = FALSE;
     347                 :         printf( "ERROR: Feature count at end of layer %d differs "
     348                 :                 "from at start, %d.\n",
     349               0 :                 nFC, poLayer->GetFeatureCount() );
     350                 :     }
     351             194 :     else if( bVerbose )
     352             194 :         printf( "INFO: Feature count verified.\n" );
     353                 :         
     354             194 :     if (!bIsSQLLayer)
     355                 :     {
     356             186 :         CPLString osSQL;
     357             186 :         const char* pszLayerName = poLayer->GetName();
     358                 :         int i;
     359                 :         char ch;
     360            1720 :         for(i=0;(ch = pszLayerName[i]) != 0;i++)
     361                 :         {
     362            1632 :             if (ch >= '0' && ch <= '9')
     363                 :             {
     364              64 :                 if (i == 0)
     365               0 :                     break;
     366                 :             }
     367            1504 :             else if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')))
     368              34 :                 break;
     369                 :         }
     370                 :         /* Only quote if needed. Quoting conventions depend on the driver... */
     371             186 :         if (ch == 0)
     372             152 :             osSQL.Printf("SELECT COUNT(*) FROM %s", pszLayerName);
     373                 :         else
     374                 :         {
     375              34 :             if (EQUAL(poDS->GetDriver()->GetName(), "MYSQL"))
     376               0 :                 osSQL.Printf("SELECT COUNT(*) FROM `%s`", pszLayerName);
     377              34 :             else if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
     378                 :                      strchr(pszLayerName, '.'))
     379                 :             {
     380               0 :                 char** papszTokens = CSLTokenizeStringComplex(pszLayerName, ".", 0, 0);
     381               0 :                 if (CSLCount(papszTokens) == 2)
     382                 :                 {
     383               0 :                     osSQL.Printf("SELECT COUNT(*) FROM \"%s\".\"%s\"", papszTokens[0], papszTokens[1]);
     384                 :                 }
     385                 :                 else
     386               0 :                     osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
     387               0 :                 CSLDestroy(papszTokens);
     388                 :             }
     389              34 :             else if (EQUAL(poDS->GetDriver()->GetName(), "SQLAnywhere"))
     390               0 :                 osSQL.Printf("SELECT COUNT(*) FROM %s", pszLayerName);
     391                 :             else
     392              34 :                 osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
     393                 :         }
     394             186 :         OGRLayer* poSQLLyr = poDS->ExecuteSQL(osSQL.c_str(), NULL, NULL);
     395             186 :         if (poSQLLyr)
     396                 :         {
     397             186 :             OGRFeature* poFeatCount = poSQLLyr->GetNextFeature();
     398             186 :             if (poFeatCount == NULL)
     399                 :             {
     400               0 :                 bRet = FALSE;
     401               0 :                 printf( "ERROR: '%s' failed.\n", osSQL.c_str() );
     402                 :             }
     403             186 :             else if (nClaimedFC != poFeatCount->GetFieldAsInteger(0))
     404                 :             {
     405               0 :                 bRet = FALSE;
     406                 :                 printf( "ERROR: Claimed feature count %d doesn't match '%s' one, %d.\n",
     407               0 :                         nClaimedFC, osSQL.c_str(), poFeatCount->GetFieldAsInteger(0) );
     408                 :             }
     409             186 :             OGRFeature::DestroyFeature(poFeatCount);
     410             186 :             poDS->ReleaseResultSet(poSQLLyr);
     411             186 :         }
     412                 :     }
     413                 : 
     414             194 :     if( bVerbose && !bWarnAboutSRS )
     415                 :     {
     416             194 :         printf("INFO: Feature/layer spatial ref. consistency verified.\n");
     417                 :     }
     418                 : 
     419             194 :     return bRet;
     420                 : }
     421                 : 
     422                 : /************************************************************************/
     423                 : /*                       TestOGRLayerRandomRead()                       */
     424                 : /*                                                                      */
     425                 : /*      Read the first 5 features, and then try to use random           */
     426                 : /*      reading to reread 2 and 5 and verify that this works OK.        */
     427                 : /*      Don't attempt if there aren't at least 5 features.              */
     428                 : /************************************************************************/
     429                 : 
     430             136 : static int TestOGRLayerRandomRead( OGRLayer *poLayer )
     431                 : 
     432                 : {
     433             136 :     int bRet = TRUE;
     434             136 :     OGRFeature  *papoFeatures[5], *poFeature = NULL;
     435                 :     int         iFeature;
     436                 : 
     437             136 :     poLayer->SetSpatialFilter( NULL );
     438                 :     
     439             136 :     if( poLayer->GetFeatureCount() < 5 )
     440                 :     {
     441              48 :         if( bVerbose )
     442                 :             printf( "INFO: Only %d features on layer,"
     443                 :                     "skipping random read test.\n",
     444              48 :                     poLayer->GetFeatureCount() );
     445                 :         
     446              48 :         return bRet;
     447                 :     }
     448                 : 
     449                 : /* -------------------------------------------------------------------- */
     450                 : /*      Fetch five features.                                            */
     451                 : /* -------------------------------------------------------------------- */
     452              88 :     poLayer->ResetReading();
     453                 :     
     454             528 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     455                 :     {
     456             440 :         papoFeatures[iFeature] = NULL;
     457                 :     }
     458             528 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     459                 :     {
     460             440 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     461             440 :         if( papoFeatures[iFeature] == NULL )
     462                 :         {
     463               0 :             if( bVerbose )
     464                 :                 printf( "INFO: Only %d features on layer,"
     465                 :                         "skipping random read test.\n",
     466               0 :                         iFeature );
     467               0 :             goto end;
     468                 :         }
     469                 :     }
     470                 : 
     471                 : /* -------------------------------------------------------------------- */
     472                 : /*      Test feature 2.                                                 */
     473                 : /* -------------------------------------------------------------------- */
     474              88 :     poFeature = poLayer->GetFeature( papoFeatures[1]->GetFID() );
     475              88 :     if (poFeature == NULL)
     476                 :     {
     477                 :         printf( "ERROR: Cannot fetch feature %ld.\n",
     478               0 :                  papoFeatures[1]->GetFID() );
     479               0 :         goto end;
     480                 :     }
     481                 : 
     482              88 :     if( !poFeature->Equal( papoFeatures[1] ) )
     483                 :     {
     484               0 :         bRet = FALSE;
     485                 :         printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
     486                 :                 "       have returned a different feature than sequential\n"
     487                 :                 "       reading indicates should have happened.\n",
     488               0 :                 papoFeatures[1]->GetFID() );
     489               0 :         poFeature->DumpReadable(stdout);
     490               0 :         papoFeatures[1]->DumpReadable(stdout);
     491                 : 
     492               0 :         goto end;
     493                 :     }
     494                 : 
     495              88 :     OGRFeature::DestroyFeature(poFeature);
     496                 : 
     497                 : /* -------------------------------------------------------------------- */
     498                 : /*      Test feature 5.                                                 */
     499                 : /* -------------------------------------------------------------------- */
     500              88 :     poFeature = poLayer->GetFeature( papoFeatures[4]->GetFID() );
     501              88 :     if( !poFeature->Equal( papoFeatures[4] ) )
     502                 :     {
     503               0 :         bRet = FALSE;
     504                 :         printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
     505                 :                 "       have returned a different feature than sequential\n"
     506                 :                 "       reading indicates should have happened.\n",
     507               0 :                 papoFeatures[4]->GetFID() );
     508                 : 
     509               0 :         goto end;
     510                 :     }
     511                 : 
     512              88 :     if( bVerbose )
     513              88 :         printf( "INFO: Random read test passed.\n" );
     514                 : 
     515                 : end:
     516              88 :     OGRFeature::DestroyFeature(poFeature);
     517                 : 
     518                 : /* -------------------------------------------------------------------- */
     519                 : /*      Cleanup.                                                        */
     520                 : /* -------------------------------------------------------------------- */
     521             528 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     522             440 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     523                 : 
     524              88 :     return bRet;
     525                 : }
     526                 : 
     527                 : 
     528                 : /************************************************************************/
     529                 : /*                       TestOGRLayerSetNextByIndex()                   */
     530                 : /*                                                                      */
     531                 : /************************************************************************/
     532                 : 
     533              52 : static int TestOGRLayerSetNextByIndex( OGRLayer *poLayer )
     534                 : 
     535                 : {
     536              52 :     int bRet = TRUE;
     537              52 :     OGRFeature  *papoFeatures[5], *poFeature = NULL;
     538                 :     int         iFeature;
     539                 : 
     540              52 :     memset(papoFeatures, 0, sizeof(papoFeatures));
     541                 : 
     542              52 :     poLayer->SetSpatialFilter( NULL );
     543                 :     
     544              52 :     if( poLayer->GetFeatureCount() < 5 )
     545                 :     {
     546              32 :         if( bVerbose )
     547                 :             printf( "INFO: Only %d features on layer,"
     548                 :                     "skipping SetNextByIndex test.\n",
     549              32 :                     poLayer->GetFeatureCount() );
     550                 :         
     551              32 :         return bRet;
     552                 :     }
     553                 : 
     554                 : /* -------------------------------------------------------------------- */
     555                 : /*      Fetch five features.                                            */
     556                 : /* -------------------------------------------------------------------- */
     557              20 :     poLayer->ResetReading();
     558                 :     
     559             120 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     560                 :     {
     561             100 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     562             100 :         if( papoFeatures[iFeature] == NULL )
     563                 :         {
     564               0 :             bRet = FALSE;
     565               0 :             printf( "ERROR: Cannot get feature %d.\n", iFeature );
     566               0 :             goto end;
     567                 :         }
     568                 :     }
     569                 : 
     570                 : /* -------------------------------------------------------------------- */
     571                 : /*      Test feature at index 1.                                        */
     572                 : /* -------------------------------------------------------------------- */
     573              20 :     if (poLayer->SetNextByIndex(1) != OGRERR_NONE)
     574                 :     {
     575               0 :         bRet = FALSE;
     576               0 :         printf( "ERROR: SetNextByIndex(%d) failed.\n", 1 );
     577               0 :         goto end;
     578                 :     }
     579                 :     
     580              20 :     poFeature = poLayer->GetNextFeature();
     581              20 :     if( !poFeature->Equal( papoFeatures[1] ) )
     582                 :     {
     583               0 :         bRet = FALSE;
     584                 :         printf( "ERROR: Attempt to read feature at index %d appears to\n"
     585                 :                 "       have returned a different feature than sequential\n"
     586                 :                 "       reading indicates should have happened.\n",
     587               0 :                 1 );
     588                 : 
     589               0 :         goto end;
     590                 :     }
     591                 : 
     592              20 :     OGRFeature::DestroyFeature(poFeature);
     593                 :     
     594              20 :     poFeature = poLayer->GetNextFeature();
     595              20 :     if( !poFeature->Equal( papoFeatures[2] ) )
     596                 :     {
     597               0 :         bRet = FALSE;
     598                 :         printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
     599                 :                 "       have returned a different feature than sequential\n"
     600                 :                 "       reading indicates should have happened.\n",
     601               0 :                 1 );
     602                 : 
     603               0 :         goto end;
     604                 :     }
     605                 : 
     606              20 :     OGRFeature::DestroyFeature(poFeature);
     607              20 :     poFeature = NULL;
     608                 :     
     609                 : /* -------------------------------------------------------------------- */
     610                 : /*      Test feature at index 3.                                        */
     611                 : /* -------------------------------------------------------------------- */
     612              20 :     if (poLayer->SetNextByIndex(3) != OGRERR_NONE)
     613                 :     {
     614               0 :         bRet = FALSE;
     615               0 :         printf( "ERROR: SetNextByIndex(%d) failed.\n", 3 );
     616               0 :         goto end;
     617                 :     }
     618                 :     
     619              20 :     poFeature = poLayer->GetNextFeature();
     620              20 :     if( !poFeature->Equal( papoFeatures[3] ) )
     621                 :     {
     622               0 :         bRet = FALSE;
     623                 :         printf( "ERROR: Attempt to read feature at index %d appears to\n"
     624                 :                 "       have returned a different feature than sequential\n"
     625                 :                 "       reading indicates should have happened.\n",
     626               0 :                 3 );
     627                 : 
     628               0 :         goto end;
     629                 :     }
     630                 : 
     631              20 :     OGRFeature::DestroyFeature(poFeature);
     632                 :     
     633              20 :     poFeature = poLayer->GetNextFeature();
     634              20 :     if( !poFeature->Equal( papoFeatures[4] ) )
     635                 :     {
     636               0 :         bRet = FALSE;
     637                 :         printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
     638                 :                 "       have returned a different feature than sequential\n"
     639                 :                 "       reading indicates should have happened.\n",
     640               0 :                 3 );
     641                 : 
     642               0 :         goto end;
     643                 :     }
     644                 : 
     645                 : 
     646              20 :     if( bVerbose )
     647              20 :         printf( "INFO: SetNextByIndex() read test passed.\n" );
     648                 : 
     649                 : end:
     650              20 :     OGRFeature::DestroyFeature(poFeature);
     651                 : 
     652                 : /* -------------------------------------------------------------------- */
     653                 : /*      Cleanup.                                                        */
     654                 : /* -------------------------------------------------------------------- */
     655             120 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     656             100 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     657                 : 
     658              20 :     return bRet;
     659                 : }
     660                 : 
     661                 : /************************************************************************/
     662                 : /*                      TestOGRLayerRandomWrite()                       */
     663                 : /*                                                                      */
     664                 : /*      Test random writing by trying to switch the 2nd and 5th         */
     665                 : /*      features.                                                       */
     666                 : /************************************************************************/
     667                 : 
     668              50 : static int TestOGRLayerRandomWrite( OGRLayer *poLayer )
     669                 : 
     670                 : {
     671              50 :     int bRet = TRUE;
     672                 :     OGRFeature  *papoFeatures[5], *poFeature;
     673                 :     int         iFeature;
     674                 :     long        nFID2, nFID5;
     675                 : 
     676              50 :     memset(papoFeatures, 0, sizeof(papoFeatures));
     677                 : 
     678              50 :     poLayer->SetSpatialFilter( NULL );
     679                 : 
     680              50 :     if( poLayer->GetFeatureCount() < 5 )
     681                 :     {
     682              14 :         if( bVerbose )
     683                 :             printf( "INFO: Only %d features on layer,"
     684                 :                     "skipping random write test.\n",
     685              14 :                     poLayer->GetFeatureCount() );
     686                 :         
     687              14 :         return bRet;
     688                 :     }
     689                 : 
     690              36 :     if( !poLayer->TestCapability( OLCRandomRead ) )
     691                 :     {
     692               0 :         if( bVerbose )
     693                 :             printf( "INFO: Skipping random write test since this layer "
     694               0 :                     "doesn't support random read.\n" );
     695               0 :         return bRet;
     696                 :     }
     697                 : 
     698                 : /* -------------------------------------------------------------------- */
     699                 : /*      Fetch five features.                                            */
     700                 : /* -------------------------------------------------------------------- */
     701              36 :     poLayer->ResetReading();
     702                 :     
     703             216 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     704                 :     {
     705             180 :         papoFeatures[iFeature] = poLayer->GetNextFeature();
     706             180 :         if( papoFeatures[iFeature] == NULL )
     707                 :         {
     708               0 :             bRet = FALSE;
     709               0 :             printf( "ERROR: Cannot get feature %d.\n", iFeature );
     710               0 :             goto end;
     711                 :         }
     712                 :     }
     713                 : 
     714                 : /* -------------------------------------------------------------------- */
     715                 : /*      Switch feature ids of feature 2 and 5.                          */
     716                 : /* -------------------------------------------------------------------- */
     717              36 :     nFID2 = papoFeatures[1]->GetFID();
     718              36 :     nFID5 = papoFeatures[4]->GetFID();
     719                 : 
     720              36 :     papoFeatures[1]->SetFID( nFID5 );
     721              36 :     papoFeatures[4]->SetFID( nFID2 );
     722                 : 
     723                 : /* -------------------------------------------------------------------- */
     724                 : /*      Rewrite them.                                                   */
     725                 : /* -------------------------------------------------------------------- */
     726              36 :     if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
     727                 :     {
     728               0 :         bRet = FALSE;
     729               0 :         printf( "ERROR: Attempt to SetFeature(1) failed.\n" );
     730               0 :         goto end;
     731                 :     }
     732              36 :     if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
     733                 :     {
     734               0 :         bRet = FALSE;
     735               0 :         printf( "ERROR: Attempt to SetFeature(4) failed.\n" );
     736               0 :         goto end;
     737                 :     }
     738                 : 
     739                 : /* -------------------------------------------------------------------- */
     740                 : /*      Now re-read feature 2 to verify the effect stuck.               */
     741                 : /* -------------------------------------------------------------------- */
     742              36 :     poFeature = poLayer->GetFeature( nFID5 );
     743              36 :     if(poFeature == NULL)
     744                 :     {
     745               0 :         bRet = FALSE;
     746               0 :         printf( "ERROR: Attempt to GetFeature( nFID5 ) failed.\n" );
     747               0 :         goto end;
     748                 :     }
     749              36 :     if( !poFeature->Equal(papoFeatures[1]) )
     750                 :     {
     751               0 :         bRet = FALSE;
     752               0 :         printf( "ERROR: Written feature didn't seem to retain value.\n" );
     753                 :     }
     754                 :     else
     755                 :     {
     756              36 :         printf( "INFO: Random write test passed.\n" );
     757                 :     }
     758              36 :     OGRFeature::DestroyFeature(poFeature);
     759                 : 
     760                 : /* -------------------------------------------------------------------- */
     761                 : /*      Re-invert the features to restore to original state             */
     762                 : /* -------------------------------------------------------------------- */
     763                 : 
     764              36 :     papoFeatures[1]->SetFID( nFID2 );
     765              36 :     papoFeatures[4]->SetFID( nFID5 );
     766                 : 
     767              36 :     if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
     768                 :     {
     769               0 :         bRet = FALSE;
     770               0 :         printf( "ERROR: Attempt to restore SetFeature(1) failed.\n" );
     771                 :     }
     772              36 :     if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
     773                 :     {
     774               0 :         bRet = FALSE;
     775               0 :         printf( "ERROR: Attempt to restore SetFeature(4) failed.\n" );
     776                 :     }
     777                 : 
     778                 : end:
     779                 : /* -------------------------------------------------------------------- */
     780                 : /*      Cleanup.                                                        */
     781                 : /* -------------------------------------------------------------------- */
     782                 : 
     783             216 :     for( iFeature = 0; iFeature < 5; iFeature++ )
     784             180 :         OGRFeature::DestroyFeature(papoFeatures[iFeature]);
     785                 : 
     786              36 :     return bRet;
     787                 : }
     788                 : 
     789                 : /************************************************************************/
     790                 : /*                         TestSpatialFilter()                          */
     791                 : /*                                                                      */
     792                 : /*      This is intended to be a simple test of the spatial             */
     793                 : /*      filtering.  We read the first feature.  Then construct a        */
     794                 : /*      spatial filter geometry which includes it, install and          */
     795                 : /*      verify that we get the feature.  Next install a spatial         */
     796                 : /*      filter that doesn't include this feature, and test again.       */
     797                 : /************************************************************************/
     798                 : 
     799             194 : static int TestSpatialFilter( OGRLayer *poLayer )
     800                 : 
     801                 : {
     802             194 :     int bRet = TRUE;
     803                 :     OGRFeature  *poFeature, *poTargetFeature;
     804             194 :     OGRPolygon  oInclusiveFilter, oExclusiveFilter;
     805             194 :     OGRLinearRing oRing;
     806             194 :     OGREnvelope sEnvelope;
     807                 :     int         nInclusiveCount;
     808                 : 
     809                 : /* -------------------------------------------------------------------- */
     810                 : /*      Read the target feature.                                        */
     811                 : /* -------------------------------------------------------------------- */
     812             194 :     poLayer->ResetReading();
     813             194 :     poTargetFeature = poLayer->GetNextFeature();
     814                 : 
     815             194 :     if( poTargetFeature == NULL )
     816                 :     {
     817                 :         printf( "INFO: Skipping Spatial Filter test for %s.\n"
     818                 :                 "      No features in layer.\n",
     819              12 :                 poLayer->GetName() );
     820              12 :         return bRet;
     821                 :     }
     822                 : 
     823             182 :     if( poTargetFeature->GetGeometryRef() == NULL )
     824                 :     {
     825                 :         printf( "INFO: Skipping Spatial Filter test for %s,\n"
     826                 :                 "      target feature has no geometry.\n",
     827              70 :                 poTargetFeature->GetDefnRef()->GetName() );
     828              70 :         OGRFeature::DestroyFeature(poTargetFeature);
     829              70 :         return bRet;
     830                 :     }
     831                 : 
     832             112 :     poTargetFeature->GetGeometryRef()->getEnvelope( &sEnvelope );
     833                 : 
     834                 : /* -------------------------------------------------------------------- */
     835                 : /*      Construct inclusive filter.                                     */
     836                 : /* -------------------------------------------------------------------- */
     837                 :     
     838             112 :     oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     839             112 :     oRing.setPoint( 1, sEnvelope.MinX - 20.0, sEnvelope.MaxY + 10.0 );
     840             112 :     oRing.setPoint( 2, sEnvelope.MaxX + 10.0, sEnvelope.MaxY + 10.0 );
     841             112 :     oRing.setPoint( 3, sEnvelope.MaxX + 10.0, sEnvelope.MinY - 20.0 );
     842             112 :     oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     843                 :     
     844             112 :     oInclusiveFilter.addRing( &oRing );
     845                 : 
     846             112 :     poLayer->SetSpatialFilter( &oInclusiveFilter );
     847                 : 
     848                 : /* -------------------------------------------------------------------- */
     849                 : /*      Verify that we can find the target feature.                     */
     850                 : /* -------------------------------------------------------------------- */
     851             112 :     poLayer->ResetReading();
     852                 : 
     853             224 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     854                 :     {
     855             112 :         if( poFeature->Equal(poTargetFeature) )
     856                 :         {
     857             112 :             OGRFeature::DestroyFeature(poFeature);
     858             112 :             break;
     859                 :         }
     860                 :         else
     861               0 :             OGRFeature::DestroyFeature(poFeature);
     862                 :     }
     863                 : 
     864             112 :     if( poFeature == NULL )
     865                 :     {
     866               0 :         bRet = FALSE;
     867               0 :         printf( "ERROR: Spatial filter eliminated a feature unexpectedly!\n");
     868                 :     }
     869             112 :     else if( bVerbose )
     870                 :     {
     871             112 :         printf( "INFO: Spatial filter inclusion seems to work.\n" );
     872                 :     }
     873                 : 
     874             112 :     nInclusiveCount = poLayer->GetFeatureCount();
     875                 : 
     876                 : /* -------------------------------------------------------------------- */
     877                 : /*      Construct exclusive filter.                                     */
     878                 : /* -------------------------------------------------------------------- */
     879             112 :     oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     880             112 :     oRing.setPoint( 1, sEnvelope.MinX - 10.0, sEnvelope.MinY - 20.0 );
     881             112 :     oRing.setPoint( 2, sEnvelope.MinX - 10.0, sEnvelope.MinY - 10.0 );
     882             112 :     oRing.setPoint( 3, sEnvelope.MinX - 20.0, sEnvelope.MinY - 10.0 );
     883             112 :     oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
     884                 :     
     885             112 :     oExclusiveFilter.addRing( &oRing );
     886                 : 
     887             112 :     poLayer->SetSpatialFilter( &oExclusiveFilter );
     888                 : 
     889                 : /* -------------------------------------------------------------------- */
     890                 : /*      Verify that we can find the target feature.                     */
     891                 : /* -------------------------------------------------------------------- */
     892             112 :     poLayer->ResetReading();
     893                 : 
     894             540 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
     895                 :     {
     896             316 :         if( poFeature->Equal(poTargetFeature) )
     897                 :         {
     898               0 :             OGRFeature::DestroyFeature(poFeature);
     899               0 :             break;
     900                 :         }
     901                 :         else
     902             316 :             OGRFeature::DestroyFeature(poFeature);
     903                 :     }
     904                 : 
     905             112 :     if( poFeature != NULL )
     906                 :     {
     907               0 :         bRet = FALSE;
     908                 :         printf( "ERROR: Spatial filter failed to eliminate"
     909               0 :                 "a feature unexpectedly!\n");
     910                 :     }
     911             112 :     else if( poLayer->GetFeatureCount() >= nInclusiveCount )
     912                 :     {
     913               0 :         bRet = FALSE;
     914                 :         printf( "ERROR: GetFeatureCount() may not be taking spatial "
     915               0 :                 "filter into account.\n" );
     916                 :     }
     917             112 :     else if( bVerbose )
     918                 :     {
     919             112 :         printf( "INFO: Spatial filter exclusion seems to work.\n" );
     920                 :     }
     921                 : 
     922             112 :     OGRFeature::DestroyFeature(poTargetFeature);
     923                 : 
     924             112 :     poLayer->SetSpatialFilter( NULL );
     925                 : 
     926             112 :     return bRet;
     927                 : }
     928                 : 
     929                 : 
     930                 : /************************************************************************/
     931                 : /*                      TestAttributeFilter()                           */
     932                 : /*                                                                      */
     933                 : /*      This is intended to be a simple test of the attribute           */
     934                 : /*      filtering.  We read the first feature.  Then construct a        */
     935                 : /*      attribute filter which includes it, install and                 */
     936                 : /*      verify that we get the feature.  Next install a attribute       */
     937                 : /*      filter that doesn't include this feature, and test again.       */
     938                 : /************************************************************************/
     939                 : 
     940             194 : static int TestAttributeFilter( OGRDataSource* poDS, OGRLayer *poLayer )
     941                 : 
     942                 : {
     943             194 :     int bRet = TRUE;
     944                 :     OGRFeature  *poFeature, *poTargetFeature;
     945                 :     int         nInclusiveCount, nExclusiveCount, nTotalCount;
     946             194 :     CPLString osAttributeFilter;
     947                 : 
     948                 : /* -------------------------------------------------------------------- */
     949                 : /*      Read the target feature.                                        */
     950                 : /* -------------------------------------------------------------------- */
     951             194 :     poLayer->ResetReading();
     952             194 :     poTargetFeature = poLayer->GetNextFeature();
     953                 : 
     954             194 :     if( poTargetFeature == NULL )
     955                 :     {
     956                 :         printf( "INFO: Skipping Attribute Filter test for %s.\n"
     957                 :                 "      No features in layer.\n",
     958              12 :                 poLayer->GetName() );
     959              12 :         return bRet;
     960                 :     }
     961                 : 
     962                 :     int i;
     963             182 :     OGRFieldType eType = OFTString;
     964             198 :     for(i=0;i<poTargetFeature->GetFieldCount();i++)
     965                 :     {
     966             180 :         eType = poTargetFeature->GetFieldDefnRef(i)->GetType();
     967             180 :         if (poTargetFeature->IsFieldSet(i) &&
     968                 :             (eType == OFTString || eType == OFTInteger || eType == OFTReal))
     969                 :         {
     970             164 :             break;
     971                 :         }
     972                 :     }
     973             182 :     if( i == poTargetFeature->GetFieldCount() )
     974                 :     {
     975                 :         printf( "INFO: Skipping Attribute Filter test for %s.\n"
     976                 :                 "      Could not find non NULL field.\n",
     977              18 :                 poLayer->GetName() );
     978              18 :         OGRFeature::DestroyFeature(poTargetFeature);
     979              18 :         return bRet;
     980                 :     }
     981                 : 
     982             164 :     const char* pszFieldName = poTargetFeature->GetFieldDefnRef(i)->GetNameRef();
     983             164 :     CPLString osValue = poTargetFeature->GetFieldAsString(i);
     984                 : 
     985                 : /* -------------------------------------------------------------------- */
     986                 : /*      Construct inclusive filter.                                     */
     987                 : /* -------------------------------------------------------------------- */
     988                 : 
     989             164 :     if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
     990                 :         (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
     991                 :     {
     992               0 :         osAttributeFilter = "\"";
     993               0 :         osAttributeFilter += pszFieldName;
     994               0 :         osAttributeFilter += "\"";
     995                 :     }
     996             164 :     else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
     997                 :     {
     998               0 :         osAttributeFilter = "'";
     999               0 :         osAttributeFilter += pszFieldName;
    1000               0 :         osAttributeFilter += "'";
    1001                 :     }
    1002                 :     else
    1003             164 :         osAttributeFilter = pszFieldName;
    1004             164 :     osAttributeFilter += " = ";
    1005             164 :     if (eType == OFTString)
    1006              94 :         osAttributeFilter += "'";
    1007             164 :     osAttributeFilter += osValue;
    1008             164 :     if (eType == OFTString)
    1009              94 :         osAttributeFilter += "'";
    1010                 :     /* Make sure that the literal will be recognized as a float value */
    1011                 :     /* to avoid int underflow/overflow */
    1012              70 :     else if (eType == OFTReal && strchr(osValue, '.') == NULL)
    1013               0 :         osAttributeFilter += ".";
    1014             164 :     poLayer->SetAttributeFilter( osAttributeFilter );
    1015                 : 
    1016                 : /* -------------------------------------------------------------------- */
    1017                 : /*      Verify that we can find the target feature.                     */
    1018                 : /* -------------------------------------------------------------------- */
    1019             164 :     poLayer->ResetReading();
    1020                 : 
    1021             328 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
    1022                 :     {
    1023             164 :         if( poFeature->Equal(poTargetFeature) )
    1024                 :         {
    1025             164 :             OGRFeature::DestroyFeature(poFeature);
    1026             164 :             break;
    1027                 :         }
    1028                 :         else
    1029               0 :             OGRFeature::DestroyFeature(poFeature);
    1030                 :     }
    1031                 : 
    1032             164 :     if( poFeature == NULL )
    1033                 :     {
    1034               0 :         bRet = FALSE;
    1035               0 :         printf( "ERROR: Attribute filter eliminated a feature unexpectedly!\n");
    1036                 :     }
    1037             164 :     else if( bVerbose )
    1038                 :     {
    1039             164 :         printf( "INFO: Attribute filter inclusion seems to work.\n" );
    1040                 :     }
    1041                 : 
    1042             164 :     nInclusiveCount = poLayer->GetFeatureCount();
    1043                 : 
    1044                 : /* -------------------------------------------------------------------- */
    1045                 : /*      Construct exclusive filter.                                     */
    1046                 : /* -------------------------------------------------------------------- */
    1047             164 :     if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
    1048                 :         (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
    1049                 :     {
    1050               0 :         osAttributeFilter = "\"";
    1051               0 :         osAttributeFilter += pszFieldName;
    1052               0 :         osAttributeFilter += "\"";
    1053                 :     }
    1054             164 :     else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
    1055                 :     {
    1056               0 :         osAttributeFilter = "'";
    1057               0 :         osAttributeFilter += pszFieldName;
    1058               0 :         osAttributeFilter += "'";
    1059                 :     }
    1060                 :     else
    1061             164 :         osAttributeFilter = pszFieldName;
    1062             164 :     osAttributeFilter += " <> ";
    1063             164 :     if (eType == OFTString)
    1064              94 :         osAttributeFilter += "'";
    1065             164 :     osAttributeFilter += osValue;
    1066             164 :     if (eType == OFTString)
    1067              94 :         osAttributeFilter += "'";
    1068                 :     /* Make sure that the literal will be recognized as a float value */
    1069                 :     /* to avoid int underflow/overflow */
    1070              70 :     else if (eType == OFTReal && strchr(osValue, '.') == NULL)
    1071               0 :         osAttributeFilter += ".";
    1072             164 :     poLayer->SetAttributeFilter( osAttributeFilter );
    1073                 : 
    1074                 : /* -------------------------------------------------------------------- */
    1075                 : /*      Verify that we can find the target feature.                     */
    1076                 : /* -------------------------------------------------------------------- */
    1077             164 :     poLayer->ResetReading();
    1078                 : 
    1079             164 :     int nExclusiveCountWhileIterating = 0;
    1080           41522 :     while( (poFeature = poLayer->GetNextFeature()) != NULL )
    1081                 :     {
    1082           41194 :         if( poFeature->Equal(poTargetFeature) )
    1083                 :         {
    1084               0 :             OGRFeature::DestroyFeature(poFeature);
    1085               0 :             break;
    1086                 :         }
    1087                 :         else
    1088           41194 :             OGRFeature::DestroyFeature(poFeature);
    1089           41194 :         nExclusiveCountWhileIterating ++;
    1090                 :     }
    1091                 : 
    1092             164 :     nExclusiveCount = poLayer->GetFeatureCount();
    1093                 : 
    1094             164 :     poLayer->SetAttributeFilter( NULL );
    1095                 : 
    1096             164 :     nTotalCount = poLayer->GetFeatureCount();
    1097                 : 
    1098             164 :     if( poFeature != NULL )
    1099                 :     {
    1100               0 :         bRet = FALSE;
    1101                 :         printf( "ERROR: Attribute filter failed to eliminate "
    1102               0 :                 "a feature unexpectedly!\n");
    1103                 :     }
    1104             164 :     else if( nExclusiveCountWhileIterating != nExclusiveCount ||
    1105                 :              nExclusiveCount >= nTotalCount ||
    1106                 :              nInclusiveCount > nTotalCount ||
    1107                 :              (nInclusiveCount == nTotalCount && nExclusiveCount != 0))
    1108                 :     {
    1109               0 :         bRet = FALSE;
    1110                 :         printf( "ERROR: GetFeatureCount() may not be taking attribute "
    1111                 :                 "filter into account (nInclusiveCount = %d, nExclusiveCount = %d, nExclusiveCountWhileIterating = %d, nTotalCount = %d).\n",
    1112               0 :                  nInclusiveCount, nExclusiveCount, nExclusiveCountWhileIterating, nTotalCount);
    1113                 :     }
    1114             164 :     else if( bVerbose )
    1115                 :     {
    1116             164 :         printf( "INFO: Attribute filter exclusion seems to work.\n" );
    1117                 :     }
    1118                 : 
    1119             164 :     OGRFeature::DestroyFeature(poTargetFeature);
    1120                 : 
    1121             164 :     return bRet;
    1122                 : }
    1123                 : 
    1124                 : /************************************************************************/
    1125                 : /*                         TestOGRLayerUTF8()                           */
    1126                 : /************************************************************************/
    1127                 : 
    1128             194 : static int TestOGRLayerUTF8 ( OGRLayer *poLayer )
    1129                 : {
    1130             194 :     int bRet = TRUE;
    1131                 : 
    1132             194 :     poLayer->SetSpatialFilter( NULL );
    1133             194 :     poLayer->SetAttributeFilter( NULL );
    1134             194 :     poLayer->ResetReading();
    1135                 : 
    1136             194 :     int bIsAdvertizedAsUTF8 = poLayer->TestCapability( OLCStringsAsUTF8 );
    1137             194 :     int nFields = poLayer->GetLayerDefn()->GetFieldCount();
    1138             194 :     int bFoundString = FALSE;
    1139             194 :     int bFoundNonASCII = FALSE;
    1140             194 :     int bFoundUTF8 = FALSE;
    1141             194 :     int bCanAdvertizeUTF8 = TRUE;
    1142                 : 
    1143             194 :     OGRFeature* poFeature = NULL;
    1144          291356 :     while( bRet && (poFeature = poLayer->GetNextFeature()) != NULL )
    1145                 :     {
    1146         4709180 :         for(int i = 0; i<nFields; i++)
    1147                 :         {
    1148         4418212 :             if (!poFeature->IsFieldSet(i))
    1149         1868704 :                 continue;
    1150         2549508 :             if (poFeature->GetFieldDefnRef(i)->GetType() == OFTString)
    1151                 :             {
    1152          937956 :                 const char* pszVal = poFeature->GetFieldAsString(i);
    1153          937956 :                 if (pszVal[0] != 0)
    1154                 :                 {
    1155          936892 :                     bFoundString = TRUE;
    1156          936892 :                     const GByte* pszIter = (const GByte*) pszVal;
    1157          936892 :                     int bIsASCII = TRUE;
    1158         7206020 :                     while(*pszIter)
    1159                 :                     {
    1160         5332376 :                         if (*pszIter >= 128)
    1161                 :                         {
    1162             140 :                             bFoundNonASCII = TRUE;
    1163             140 :                             bIsASCII = FALSE;
    1164             140 :                             break;
    1165                 :                         }
    1166         5332236 :                         pszIter ++;
    1167                 :                     }
    1168          936892 :                     int bIsUTF8 = CPLIsUTF8(pszVal, -1);
    1169          936892 :                     if (bIsUTF8 && !bIsASCII)
    1170             140 :                         bFoundUTF8 = TRUE;
    1171          936892 :                     if (bIsAdvertizedAsUTF8)
    1172                 :                     {
    1173             740 :                         if (!bIsUTF8)
    1174                 :                         {
    1175                 :                             printf( "ERROR: Found non-UTF8 content at field %d of feature %ld, but layer is advertized as UTF-8.\n",
    1176               0 :                                     i, poFeature->GetFID() );
    1177               0 :                             bRet = FALSE;
    1178               0 :                             break;
    1179                 :                         }
    1180                 :                     }
    1181                 :                     else
    1182                 :                     {
    1183          936152 :                         if (!bIsUTF8)
    1184               0 :                             bCanAdvertizeUTF8 = FALSE;
    1185                 :                     }
    1186                 :                 }
    1187                 :             }
    1188                 :         }
    1189          290968 :         OGRFeature::DestroyFeature(poFeature);
    1190                 :     }
    1191                 : 
    1192             194 :     if (!bFoundString)
    1193                 :     {
    1194                 :     }
    1195             172 :     else if (bCanAdvertizeUTF8)
    1196                 :     {
    1197             172 :         if (bIsAdvertizedAsUTF8)
    1198                 :         {
    1199             100 :             if (bFoundUTF8)
    1200                 :             {
    1201              34 :                 printf( "INFO: Layer has UTF-8 content and is consistently declared as having UTF-8 content.\n" );
    1202                 :             }
    1203              66 :             else if (!bFoundNonASCII)
    1204                 :             {
    1205              66 :                 printf( "INFO: Layer has ASCII only content and is consistently declared as having UTF-8 content.\n" );
    1206                 :             }
    1207                 :         }
    1208                 :         else
    1209                 :         {
    1210              72 :             if (bFoundUTF8)
    1211                 :             {
    1212               2 :                 printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (and it has non-ASCII UTF-8 content).\n" );
    1213                 :             }
    1214              70 :             else if (!bFoundNonASCII)
    1215                 :             {
    1216              70 :                 printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (it has only ASCII content).\n" );
    1217                 :             }
    1218                 :         }
    1219                 :     }
    1220                 :     else
    1221                 :     {
    1222               0 :         printf( "INFO: Layer has non UTF-8 content (and is consistently declared as not being UTF-8 compatible).\n" );
    1223                 :     }
    1224                 : 
    1225             194 :     return bRet;
    1226                 : }
    1227                 : 
    1228                 : /************************************************************************/
    1229                 : /*                         TestGetExtent()                              */
    1230                 : /************************************************************************/
    1231                 : 
    1232             194 : static int TestGetExtent ( OGRLayer *poLayer )
    1233                 : {
    1234             194 :     int bRet = TRUE;
    1235                 : 
    1236             194 :     poLayer->SetSpatialFilter( NULL );
    1237             194 :     poLayer->SetAttributeFilter( NULL );
    1238             194 :     poLayer->ResetReading();
    1239                 : 
    1240             194 :     OGREnvelope sExtent;
    1241             194 :     OGREnvelope sExtentSlow;
    1242                 : 
    1243             194 :     OGRErr eErr = poLayer->GetExtent(&sExtent, TRUE);
    1244             194 :     OGRErr eErr2 = poLayer->OGRLayer::GetExtent(&sExtentSlow, TRUE);
    1245                 : 
    1246             194 :     if (eErr != eErr2)
    1247                 :     {
    1248               8 :         if (eErr == OGRERR_NONE && eErr2 != OGRERR_NONE)
    1249                 :         {
    1250                 :             /* with the LIBKML driver and test_ogrsf ../autotest/ogr/data/samples.kml "Styles and Markup" */
    1251               4 :             printf("INFO: GetExtent() succeeded but OGRLayer::GetExtent() failed.\n");
    1252                 :         }
    1253                 :         else
    1254                 :         {
    1255               0 :             bRet = FALSE;
    1256               0 :             printf("ERROR: GetExtent() failed but OGRLayer::GetExtent() succeeded.\n");
    1257                 :         }
    1258                 :     }
    1259             190 :     else if (eErr == OGRERR_NONE)
    1260                 :     {
    1261             218 :         if (fabs(sExtentSlow.MinX - sExtent.MinX) < 1e-10 &&
    1262                 :             fabs(sExtentSlow.MinY - sExtent.MinY) < 1e-10 &&
    1263                 :             fabs(sExtentSlow.MaxX - sExtent.MaxX) < 1e-10 &&
    1264                 :             fabs(sExtentSlow.MaxY - sExtent.MaxY) < 1e-10)
    1265                 :         {
    1266             106 :             printf("INFO: GetExtent() test passed.\n");
    1267                 :         }
    1268                 :         else
    1269                 :         {
    1270               6 :             if (sExtentSlow.Contains(sExtent))
    1271                 :             {
    1272               2 :                 printf("INFO: sExtentSlow.Contains(sExtent)\n");
    1273                 :             }
    1274               4 :             else if (sExtent.Contains(sExtentSlow))
    1275                 :             {
    1276               4 :                 printf("INFO: sExtent.Contains(sExtentSlow)\n");
    1277                 :             }
    1278                 :             else
    1279                 :             {
    1280               0 :                 printf("INFO: unknown relationship between sExtent and sExentSlow.\n");
    1281                 :             }
    1282               6 :             printf("INFO: sExtentSlow.MinX = %.15f\n", sExtentSlow.MinX);
    1283               6 :             printf("INFO: sExtentSlow.MinY = %.15f\n", sExtentSlow.MinY);
    1284               6 :             printf("INFO: sExtentSlow.MaxX = %.15f\n", sExtentSlow.MaxX);
    1285               6 :             printf("INFO: sExtentSlow.MaxY = %.15f\n", sExtentSlow.MaxY);
    1286               6 :             printf("INFO: sExtent.MinX = %.15f\n", sExtent.MinX);
    1287               6 :             printf("INFO: sExtent.MinY = %.15f\n", sExtent.MinY);
    1288               6 :             printf("INFO: sExtent.MaxX = %.15f\n", sExtent.MaxX);
    1289               6 :             printf("INFO: sExtent.MaxY = %.15f\n", sExtent.MaxY);
    1290                 :         }
    1291                 :     }
    1292                 : 
    1293             194 :     return bRet;
    1294                 : }
    1295                 : 
    1296                 : /*************************************************************************/
    1297                 : /*             TestOGRLayerDeleteAndCreateFeature()                      */
    1298                 : /*                                                                       */
    1299                 : /*      Test delete feature by trying to delete the last feature and     */
    1300                 : /*      recreate it.                                                     */
    1301                 : /*************************************************************************/
    1302                 : 
    1303              50 : static int TestOGRLayerDeleteAndCreateFeature( OGRLayer *poLayer )
    1304                 : 
    1305                 : {
    1306              50 :     int bRet = TRUE;
    1307              50 :     OGRFeature  * poFeature = NULL;
    1308              50 :     OGRFeature  * poFeatureTest = NULL;
    1309                 :     long        nFID;
    1310                 : 
    1311              50 :     poLayer->SetSpatialFilter( NULL );
    1312                 :     
    1313              50 :     if( !poLayer->TestCapability( OLCRandomRead ) )
    1314                 :     {
    1315               0 :         if( bVerbose )
    1316                 :             printf( "INFO: Skipping delete feature test since this layer "
    1317               0 :                     "doesn't support random read.\n" );
    1318               0 :         return bRet;
    1319                 :     }
    1320                 : 
    1321              50 :     if( poLayer->GetFeatureCount() == 0 )
    1322                 :     {
    1323               2 :         if( bVerbose )
    1324                 :             printf( "INFO: No feature available on layer '%s',"
    1325                 :                     "skipping delete/create feature test.\n",
    1326               2 :                     poLayer->GetName() );
    1327                 :         
    1328               2 :         return bRet;
    1329                 :     }
    1330                 : /* -------------------------------------------------------------------- */
    1331                 : /*      Fetch the last feature                                          */
    1332                 : /* -------------------------------------------------------------------- */
    1333              48 :     poLayer->ResetReading();
    1334                 : 
    1335              48 :     poLayer->SetNextByIndex(poLayer->GetFeatureCount() - 1);
    1336              48 :     poFeature = poLayer->GetNextFeature();
    1337              48 :     if (poFeature == NULL)
    1338                 :     {
    1339               0 :         bRet = FALSE;
    1340               0 :         printf( "ERROR: Could not get last feature of layer.\n" );
    1341               0 :         goto end;
    1342                 :     }
    1343                 : 
    1344                 : /* -------------------------------------------------------------------- */
    1345                 : /*      Get the feature ID of the last feature                          */
    1346                 : /* -------------------------------------------------------------------- */
    1347              48 :     nFID = poFeature->GetFID();
    1348                 : 
    1349                 : /* -------------------------------------------------------------------- */
    1350                 : /*      Delete the feature.                                             */
    1351                 : /* -------------------------------------------------------------------- */
    1352              48 :     if( poLayer->DeleteFeature( nFID ) != OGRERR_NONE )
    1353                 :     {
    1354               0 :         bRet = FALSE;
    1355               0 :         printf( "ERROR: Attempt to DeleteFeature() failed.\n" );
    1356               0 :         goto end;
    1357                 :     }
    1358                 :     
    1359                 : /* -------------------------------------------------------------------- */
    1360                 : /*      Now re-read the feature to verify the delete effect worked.     */
    1361                 : /* -------------------------------------------------------------------- */
    1362              48 :     CPLPushErrorHandler(CPLQuietErrorHandler); /* silent legitimate error message */
    1363              48 :     poFeatureTest = poLayer->GetFeature( nFID );
    1364              48 :     CPLPopErrorHandler();
    1365              48 :     if( poFeatureTest != NULL)
    1366                 :     {
    1367              12 :         bRet = FALSE;
    1368              12 :         printf( "ERROR: The feature was not deleted.\n" );
    1369                 :     }
    1370                 :     else
    1371                 :     {
    1372              36 :         printf( "INFO: Delete Feature test passed.\n" );
    1373                 :     }
    1374              48 :     OGRFeature::DestroyFeature(poFeatureTest);
    1375                 : 
    1376                 : /* -------------------------------------------------------------------- */
    1377                 : /*      Re-insert the features to restore to original state             */
    1378                 : /* -------------------------------------------------------------------- */
    1379              48 :     if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
    1380                 :     {
    1381               0 :         bRet = FALSE;
    1382               0 :         printf( "ERROR: Attempt to restore feature failed.\n" );
    1383                 :     }
    1384                 : 
    1385              48 :     if( poFeature->GetFID() != nFID )
    1386                 :     {
    1387                 :         /* Case of shapefile driver for example that will not try to */
    1388                 :         /* reuse the existing FID, but will assign a new one */
    1389              30 :         printf( "INFO: Feature was created, but with not its original FID.\n" );
    1390              30 :         nFID = poFeature->GetFID();
    1391                 :     }
    1392                 : 
    1393                 : /* -------------------------------------------------------------------- */
    1394                 : /*      Now re-read the feature to verify the create effect worked.     */
    1395                 : /* -------------------------------------------------------------------- */
    1396              48 :     poFeatureTest = poLayer->GetFeature( nFID );
    1397              48 :     if( poFeatureTest == NULL)
    1398                 :     {
    1399               0 :         bRet = FALSE;
    1400               0 :         printf( "ERROR: The feature was not created.\n" );
    1401                 :     }
    1402                 :     else
    1403                 :     {
    1404              48 :         printf( "INFO: Create Feature test passed.\n" );
    1405                 :     }
    1406              48 :     OGRFeature::DestroyFeature(poFeatureTest);
    1407                 :     
    1408                 : end:
    1409                 : /* -------------------------------------------------------------------- */
    1410                 : /*      Cleanup.                                                        */
    1411                 : /* -------------------------------------------------------------------- */
    1412                 : 
    1413              48 :     OGRFeature::DestroyFeature(poFeature);
    1414                 : 
    1415              48 :     return bRet;
    1416                 : }
    1417                 : 
    1418                 : /*************************************************************************/
    1419                 : /*                         TestTransactions()                            */
    1420                 : /*************************************************************************/
    1421                 : 
    1422              52 : static int TestTransactions( OGRLayer *poLayer )
    1423                 : 
    1424                 : {
    1425              52 :     OGRFeature* poFeature = NULL;
    1426              52 :     int nInitialFeatureCount = poLayer->GetFeatureCount();
    1427                 : 
    1428              52 :     OGRErr eErr = poLayer->StartTransaction();
    1429              52 :     if (eErr == OGRERR_NONE)
    1430                 :     {
    1431              52 :         if (poLayer->TestCapability(OLCTransactions) == FALSE)
    1432                 :         {
    1433              42 :             eErr = poLayer->RollbackTransaction();
    1434              42 :             if (eErr == OGRERR_UNSUPPORTED_OPERATION && poLayer->TestCapability(OLCTransactions) == FALSE)
    1435                 :             {
    1436                 :                 /* The default implementation has a dummy StartTransaction(), but RollbackTransaction() returns */
    1437                 :                 /* OGRERR_UNSUPPORTED_OPERATION */
    1438              42 :                 printf( "INFO: Transactions test skipped due to lack of transaction support.\n" );
    1439              42 :                 return FALSE;
    1440                 :             }
    1441                 :             else
    1442                 :             {
    1443               0 :                 printf("WARN: StartTransaction() is supported, but TestCapability(OLCTransactions) returns FALSE.\n");
    1444                 :             }
    1445                 :         }
    1446                 :     }
    1447               0 :     else if (eErr == OGRERR_FAILURE)
    1448                 :     {
    1449               0 :         if (poLayer->TestCapability(OLCTransactions) == TRUE)
    1450                 :         {
    1451               0 :             printf("ERROR: StartTransaction() failed, but TestCapability(OLCTransactions) returns TRUE.\n");
    1452               0 :             return FALSE;
    1453                 :         }
    1454                 :         else
    1455                 :         {
    1456               0 :             return TRUE;
    1457                 :         }
    1458                 :     }
    1459                 : 
    1460              10 :     eErr = poLayer->RollbackTransaction();
    1461              10 :     if (eErr != OGRERR_NONE)
    1462                 :     {
    1463               0 :         printf("ERROR: RollbackTransaction() failed after successfull StartTransaction().\n");
    1464               0 :         return FALSE;
    1465                 :     }
    1466                 : 
    1467                 :     /* ---------------- */
    1468                 : 
    1469              10 :     eErr = poLayer->StartTransaction();
    1470              10 :     if (eErr != OGRERR_NONE)
    1471                 :     {
    1472               0 :         printf("ERROR: StartTransaction() failed.\n");
    1473               0 :         return FALSE;
    1474                 :     }
    1475                 : 
    1476              10 :     eErr = poLayer->CommitTransaction();
    1477              10 :     if (eErr != OGRERR_NONE)
    1478                 :     {
    1479               0 :         printf("ERROR: CommitTransaction() failed after successfull StartTransaction().\n");
    1480               0 :         return FALSE;
    1481                 :     }
    1482                 : 
    1483                 :     /* ---------------- */
    1484                 : 
    1485              10 :     eErr = poLayer->StartTransaction();
    1486              10 :     if (eErr != OGRERR_NONE)
    1487                 :     {
    1488               0 :         printf("ERROR: StartTransaction() failed.\n");
    1489               0 :         return FALSE;
    1490                 :     }
    1491                 : 
    1492              10 :     poFeature = new OGRFeature(poLayer->GetLayerDefn());
    1493              10 :     if (poLayer->GetLayerDefn()->GetFieldCount() > 0)
    1494               8 :         poFeature->SetField(0, "0");
    1495              10 :     eErr = poLayer->CreateFeature(poFeature);
    1496              10 :     delete poFeature;
    1497              10 :     poFeature = NULL;
    1498                 : 
    1499              10 :     if (eErr == OGRERR_FAILURE)
    1500                 :     {
    1501               4 :         printf("INFO: CreateFeature() failed. Exiting this test now.\n");
    1502               4 :         poLayer->RollbackTransaction();
    1503               4 :         return FALSE;
    1504                 :     }
    1505                 : 
    1506               6 :     eErr = poLayer->RollbackTransaction();
    1507               6 :     if (eErr != OGRERR_NONE)
    1508                 :     {
    1509               0 :         printf("ERROR: RollbackTransaction() failed after successfull StartTransaction().\n");
    1510               0 :         return FALSE;
    1511                 :     }
    1512                 : 
    1513               6 :     if (poLayer->GetFeatureCount() != nInitialFeatureCount)
    1514                 :     {
    1515               0 :         printf("INFO: GetFeatureCount() should have returned its initial value after RollbackTransaction().\n");
    1516               0 :         poLayer->RollbackTransaction();
    1517               0 :         return FALSE;
    1518                 :     }
    1519                 : 
    1520                 :     /* ---------------- */
    1521                 : 
    1522               6 :     if( poLayer->TestCapability( OLCDeleteFeature ) )
    1523                 :     {
    1524               6 :         eErr = poLayer->StartTransaction();
    1525               6 :         if (eErr != OGRERR_NONE)
    1526                 :         {
    1527               0 :             printf("ERROR: StartTransaction() failed.\n");
    1528               0 :             return FALSE;
    1529                 :         }
    1530                 : 
    1531               6 :         poFeature = new OGRFeature(poLayer->GetLayerDefn());
    1532               6 :         if (poLayer->GetLayerDefn()->GetFieldCount() > 0)
    1533               6 :             poFeature->SetField(0, "0");
    1534               6 :         eErr = poLayer->CreateFeature(poFeature);
    1535               6 :         int nFID = poFeature->GetFID();
    1536               6 :         delete poFeature;
    1537               6 :         poFeature = NULL;
    1538                 : 
    1539               6 :         if (eErr == OGRERR_FAILURE)
    1540                 :         {
    1541               0 :             printf("INFO: CreateFeature() failed. Exiting this test now.\n");
    1542               0 :             poLayer->RollbackTransaction();
    1543               0 :             return FALSE;
    1544                 :         }
    1545                 : 
    1546               6 :         eErr = poLayer->CommitTransaction();
    1547               6 :         if (eErr != OGRERR_NONE)
    1548                 :         {
    1549               0 :             printf("ERROR: CommitTransaction() failed after successfull StartTransaction().\n");
    1550               0 :             return FALSE;
    1551                 :         }
    1552                 : 
    1553               6 :         if (poLayer->GetFeatureCount() != nInitialFeatureCount + 1)
    1554                 :         {
    1555               0 :             printf("INFO: GetFeatureCount() should have returned its initial value + 1 after CommitTransaction().\n");
    1556               0 :             poLayer->RollbackTransaction();
    1557               0 :             return FALSE;
    1558                 :         }
    1559                 : 
    1560               6 :         eErr = poLayer->DeleteFeature(nFID);
    1561               6 :         if (eErr != OGRERR_NONE)
    1562                 :         {
    1563               0 :             printf("ERROR: DeleteFeature() failed.\n");
    1564               0 :             return FALSE;
    1565                 :         }
    1566                 : 
    1567               6 :         if (poLayer->GetFeatureCount() != nInitialFeatureCount)
    1568                 :         {
    1569               0 :             printf("INFO: GetFeatureCount() should have returned its initial value after DeleteFeature().\n");
    1570               0 :             poLayer->RollbackTransaction();
    1571               0 :             return FALSE;
    1572                 :         }
    1573                 :     }
    1574                 : 
    1575                 :     /* ---------------- */
    1576                 : 
    1577               6 :     printf( "INFO: Transactions test passed.\n" );
    1578                 : 
    1579               6 :     return TRUE;
    1580                 : }
    1581                 : 
    1582                 : /************************************************************************/
    1583                 : /*                            TestOGRLayer()                            */
    1584                 : /************************************************************************/
    1585                 : 
    1586             194 : static int TestOGRLayer( OGRDataSource* poDS, OGRLayer * poLayer, int bIsSQLLayer )
    1587                 : 
    1588                 : {
    1589             194 :     int bRet = TRUE;
    1590                 : 
    1591                 : /* -------------------------------------------------------------------- */
    1592                 : /*      Verify that there is no spatial filter in place by default.     */
    1593                 : /* -------------------------------------------------------------------- */
    1594             194 :     if( poLayer->GetSpatialFilter() != NULL )
    1595                 :     {
    1596                 :         printf( "WARN: Spatial filter in place by default on layer %s.\n",
    1597               0 :                 poLayer->GetName() );
    1598               0 :         poLayer->SetSpatialFilter( NULL );
    1599                 :     }
    1600                 : 
    1601                 : /* -------------------------------------------------------------------- */
    1602                 : /*      Test feature count accuracy.                                    */
    1603                 : /* -------------------------------------------------------------------- */
    1604             194 :     bRet &= TestOGRLayerFeatureCount( poDS, poLayer, bIsSQLLayer );
    1605                 : 
    1606                 : /* -------------------------------------------------------------------- */
    1607                 : /*      Test spatial filtering                                          */
    1608                 : /* -------------------------------------------------------------------- */
    1609             194 :     bRet &= TestSpatialFilter( poLayer );
    1610                 : 
    1611                 : /* -------------------------------------------------------------------- */
    1612                 : /*      Test attribute filtering                                        */
    1613                 : /* -------------------------------------------------------------------- */
    1614             194 :     bRet &= TestAttributeFilter( poDS, poLayer );
    1615                 : 
    1616                 : /* -------------------------------------------------------------------- */
    1617                 : /*      Test GetExtent()                                                */
    1618                 : /* -------------------------------------------------------------------- */
    1619             194 :     bRet &= TestGetExtent( poLayer );
    1620                 : 
    1621                 : /* -------------------------------------------------------------------- */
    1622                 : /*      Test random reading.                                            */
    1623                 : /* -------------------------------------------------------------------- */
    1624             194 :     if( poLayer->TestCapability( OLCRandomRead ) )
    1625                 :     {
    1626             136 :         bRet &= TestOGRLayerRandomRead( poLayer );
    1627                 :     }
    1628                 :     
    1629                 : /* -------------------------------------------------------------------- */
    1630                 : /*      Test SetNextByIndex.                                            */
    1631                 : /* -------------------------------------------------------------------- */
    1632             194 :     if( poLayer->TestCapability( OLCFastSetNextByIndex ) )
    1633                 :     {
    1634              52 :         bRet &= TestOGRLayerSetNextByIndex( poLayer );
    1635                 :     }
    1636                 :     
    1637                 : /* -------------------------------------------------------------------- */
    1638                 : /*      Test delete feature.                                            */
    1639                 : /* -------------------------------------------------------------------- */
    1640             194 :     if( poLayer->TestCapability( OLCDeleteFeature ) )
    1641                 :     {
    1642              50 :         bRet &= TestOGRLayerDeleteAndCreateFeature( poLayer );
    1643                 :     }
    1644                 :     
    1645                 : /* -------------------------------------------------------------------- */
    1646                 : /*      Test random writing.                                            */
    1647                 : /* -------------------------------------------------------------------- */
    1648             194 :     if( poLayer->TestCapability( OLCRandomWrite ) )
    1649                 :     {
    1650              50 :         bRet &= TestOGRLayerRandomWrite( poLayer );
    1651                 :     }
    1652                 : 
    1653                 : /* -------------------------------------------------------------------- */
    1654                 : /*      Test UTF-8 reporting                                            */
    1655                 : /* -------------------------------------------------------------------- */
    1656             194 :     bRet &= TestOGRLayerUTF8( poLayer );
    1657                 : 
    1658                 : /* -------------------------------------------------------------------- */
    1659                 : /*      Test TestTransactions()                                         */
    1660                 : /* -------------------------------------------------------------------- */
    1661             194 :     if( poLayer->TestCapability( OLCSequentialWrite ) )
    1662                 :     {
    1663              52 :         bRet &= TestTransactions( poLayer );
    1664                 :     }
    1665                 : 
    1666             194 :     return bRet;
    1667                 : }
    1668                 : 
    1669                 : /************************************************************************/
    1670                 : /*                        TestInterleavedReading()                      */
    1671                 : /************************************************************************/
    1672                 : 
    1673              24 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers )
    1674                 : {
    1675              24 :     int bRet = TRUE;
    1676              24 :     OGRDataSource* poDS = NULL;
    1677              24 :     OGRDataSource* poDS2 = NULL;
    1678              24 :     OGRLayer* poLayer1 = NULL;
    1679              24 :     OGRLayer* poLayer2 = NULL;
    1680              24 :     OGRFeature* poFeature11_Ref = NULL;
    1681              24 :     OGRFeature* poFeature12_Ref = NULL;
    1682              24 :     OGRFeature* poFeature21_Ref = NULL;
    1683              24 :     OGRFeature* poFeature22_Ref = NULL;
    1684              24 :     OGRFeature* poFeature11 = NULL;
    1685              24 :     OGRFeature* poFeature12 = NULL;
    1686              24 :     OGRFeature* poFeature21 = NULL;
    1687              24 :     OGRFeature* poFeature22 = NULL;
    1688                 : 
    1689                 :     /* Check that we have 2 layers with at least 2 features */
    1690              24 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1691              24 :     if (poDS == NULL)
    1692                 :     {
    1693               0 :         printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
    1694               0 :         goto bye;
    1695                 :     }
    1696                 : 
    1697              24 :     poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
    1698              24 :     poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
    1699              70 :     if (poLayer1 == NULL || poLayer2 == NULL ||
    1700              46 :         poLayer1->GetFeatureCount() < 2 || poLayer2->GetFeatureCount() < 2)
    1701                 :     {
    1702              10 :         printf( "INFO: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1703              10 :         goto bye;
    1704                 :     }
    1705                 : 
    1706                 :     /* Test normal reading */
    1707              14 :     OGRDataSource::DestroyDataSource(poDS);
    1708              14 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1709              14 :     poDS2 = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
    1710              14 :     if (poDS == NULL || poDS2 == NULL)
    1711                 :     {
    1712               0 :         printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
    1713               0 :         goto bye;
    1714                 :     }
    1715                 : 
    1716              14 :     poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
    1717              14 :     poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
    1718              14 :     if (poLayer1 == NULL || poLayer2 == NULL)
    1719                 :     {
    1720               0 :         printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1721               0 :         bRet = FALSE;
    1722               0 :         goto bye;
    1723                 :     }
    1724                 : 
    1725              14 :     poFeature11_Ref = poLayer1->GetNextFeature();
    1726              14 :     poFeature12_Ref = poLayer1->GetNextFeature();
    1727              14 :     poFeature21_Ref = poLayer2->GetNextFeature();
    1728              14 :     poFeature22_Ref = poLayer2->GetNextFeature();
    1729              14 :     if (poFeature11_Ref == NULL || poFeature12_Ref == NULL || poFeature21_Ref == NULL || poFeature22_Ref == NULL)
    1730                 :     {
    1731                 :         printf( "ERROR: TestInterleavedReading() failed: poFeature11_Ref=%p, poFeature12_Ref=%p, poFeature21_Ref=%p, poFeature22_Ref=%p\n",
    1732               0 :                 poFeature11_Ref, poFeature12_Ref, poFeature21_Ref, poFeature22_Ref);
    1733               0 :         bRet = FALSE;
    1734               0 :         goto bye;
    1735                 :     }
    1736                 : 
    1737                 :     /* Test interleaved reading */
    1738              14 :     poLayer1 = papszLayers ? poDS2->GetLayerByName(papszLayers[0]) : poDS2->GetLayer(0);
    1739              14 :     poLayer2 = papszLayers ? poDS2->GetLayerByName(papszLayers[1]) : poDS2->GetLayer(1);
    1740              14 :     if (poLayer1 == NULL || poLayer2 == NULL)
    1741                 :     {
    1742               0 :         printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
    1743               0 :         bRet = FALSE;
    1744               0 :         goto bye;
    1745                 :     }
    1746                 : 
    1747              14 :     poFeature11 = poLayer1->GetNextFeature();
    1748              14 :     poFeature21 = poLayer2->GetNextFeature();
    1749              14 :     poFeature12 = poLayer1->GetNextFeature();
    1750              14 :     poFeature22 = poLayer2->GetNextFeature();
    1751                 : 
    1752              14 :     if (poFeature11 == NULL || poFeature21 == NULL || poFeature12 == NULL || poFeature22 == NULL)
    1753                 :     {
    1754                 :         printf( "ERROR: TestInterleavedReading() failed: poFeature11=%p, poFeature21=%p, poFeature12=%p, poFeature22=%p\n",
    1755               0 :                 poFeature11, poFeature21, poFeature12, poFeature22);
    1756               0 :         bRet = FALSE;
    1757               0 :         goto bye;
    1758                 :     }
    1759                 : 
    1760              14 :     if (poFeature12->Equal(poFeature11))
    1761                 :     {
    1762                 :         printf( "WARN: TestInterleavedReading() failed: poFeature12 == poFeature11. "
    1763               2 :                 "The datasource resets the layer reading when interleaved layer reading pattern is detected. Acceptable but could be improved\n" );
    1764               2 :         goto bye;
    1765                 :     }
    1766                 : 
    1767                 :     /* We cannot directly compare the feature as they don't share */
    1768                 :     /* the same (pointer) layer definition, so just compare FIDs */
    1769              12 :     if (poFeature12_Ref->GetFID() != poFeature12->GetFID())
    1770                 :     {
    1771               0 :         printf( "ERROR: TestInterleavedReading() failed: poFeature12_Ref != poFeature12\n" );
    1772               0 :         poFeature12_Ref->DumpReadable(stdout, NULL);
    1773               0 :         poFeature12->DumpReadable(stdout, NULL);
    1774               0 :         bRet = FALSE;
    1775               0 :         goto bye;
    1776                 :     }
    1777                 : 
    1778              12 :     if( bVerbose )
    1779                 :     {
    1780              12 :         printf("INFO: TestInterleavedReading() successfull.\n");
    1781                 :     }
    1782                 : 
    1783                 : bye:
    1784              24 :     OGRFeature::DestroyFeature(poFeature11_Ref);
    1785              24 :     OGRFeature::DestroyFeature(poFeature12_Ref);
    1786              24 :     OGRFeature::DestroyFeature(poFeature21_Ref);
    1787              24 :     OGRFeature::DestroyFeature(poFeature22_Ref);
    1788              24 :     OGRFeature::DestroyFeature(poFeature11);
    1789              24 :     OGRFeature::DestroyFeature(poFeature21);
    1790              24 :     OGRFeature::DestroyFeature(poFeature12);
    1791              24 :     OGRFeature::DestroyFeature(poFeature22);
    1792              24 :     OGRDataSource::DestroyDataSource(poDS);
    1793              24 :     OGRDataSource::DestroyDataSource(poDS2);
    1794              24 :     return bRet;
    1795                 : }
    1796                 : 
    1797                 : /************************************************************************/
    1798                 : /*                          TestErrorConditions()                       */
    1799                 : /************************************************************************/
    1800                 : 
    1801              10 : static int TestErrorConditions( OGRDataSource * poDS )
    1802                 : {
    1803              10 :     int bRet = TRUE;
    1804                 :     OGRLayer* poLyr;
    1805                 : 
    1806              10 :     CPLPushErrorHandler(CPLQuietErrorHandler);
    1807                 : 
    1808              10 :     if (poDS->TestCapability("fake_capability"))
    1809                 :     {
    1810               0 :         printf( "ERROR: TestCapability(\"fake_capability\") should have returned FALSE\n" );
    1811               0 :         bRet = FALSE;
    1812               0 :         goto bye;
    1813                 :     }
    1814                 : 
    1815              10 :     if (poDS->GetLayer(-1) != NULL)
    1816                 :     {
    1817               0 :         printf( "ERROR: GetLayer(-1) should have returned NULL\n" );
    1818               0 :         bRet = FALSE;
    1819               0 :         goto bye;
    1820                 :     }
    1821                 : 
    1822              10 :     if (poDS->GetLayer(poDS->GetLayerCount()) != NULL)
    1823                 :     {
    1824               0 :         printf( "ERROR: GetLayer(poDS->GetLayerCount()) should have returned NULL\n" );
    1825               0 :         bRet = FALSE;
    1826               0 :         goto bye;
    1827                 :     }
    1828                 : 
    1829              10 :     if (poDS->GetLayerByName("non_existing_layer") != NULL)
    1830                 :     {
    1831               0 :         printf( "ERROR: GetLayerByName(\"non_existing_layer\") should have returned NULL\n" );
    1832               0 :         bRet = FALSE;
    1833               0 :         goto bye;
    1834                 :     }
    1835                 : 
    1836              10 :     poLyr = poDS->ExecuteSQL("a fake SQL command", NULL, NULL);
    1837              10 :     if (poLyr != NULL)
    1838                 :     {
    1839               0 :         poDS->ReleaseResultSet(poLyr);
    1840               0 :         printf( "ERROR: ExecuteSQL(\"a fake SQL command\") should have returned NULL\n" );
    1841               0 :         bRet = FALSE;
    1842               0 :         goto bye;
    1843                 :     }
    1844                 : 
    1845              10 :     poLyr = poDS->GetLayer(0);
    1846              10 :     if (poLyr == NULL)
    1847               0 :         goto bye;
    1848                 : 
    1849              10 :     if (poLyr->TestCapability("fake_capability"))
    1850                 :     {
    1851               0 :         printf( "ERROR: poLyr->TestCapability(\"fake_capability\") should have returned FALSE\n" );
    1852               0 :         bRet = FALSE;
    1853               0 :         goto bye;
    1854                 :     }
    1855                 : 
    1856              10 :     if (poLyr->GetFeature(-10) != NULL)
    1857                 :     {
    1858               0 :         printf( "ERROR: GetFeature(-10) should have returned NULL\n" );
    1859               0 :         bRet = FALSE;
    1860               0 :         goto bye;
    1861                 :     }
    1862                 : 
    1863              10 :     if (poLyr->GetFeature(2000000000) != NULL)
    1864                 :     {
    1865               0 :         printf( "ERROR: GetFeature(2000000000) should have returned NULL\n" );
    1866               0 :         bRet = FALSE;
    1867               0 :         goto bye;
    1868                 :     }
    1869                 : 
    1870                 : #if 0
    1871                 :     /* PG driver doesn't issue errors when the feature doesn't exist */
    1872                 :     /* So, not sure if emitting error is expected or not */
    1873                 : 
    1874                 :     if (poLyr->DeleteFeature(-10) == OGRERR_NONE)
    1875                 :     {
    1876                 :         printf( "ERROR: DeleteFeature(-10) should have returned an error\n" );
    1877                 :         bRet = FALSE;
    1878                 :         goto bye;
    1879                 :     }
    1880                 : 
    1881                 :     if (poLyr->DeleteFeature(2000000000) == OGRERR_NONE)
    1882                 :     {
    1883                 :         printf( "ERROR: DeleteFeature(2000000000) should have returned an error\n" );
    1884                 :         bRet = FALSE;
    1885                 :         goto bye;
    1886                 :     }
    1887                 : #endif
    1888                 : 
    1889              10 :     if (poLyr->SetNextByIndex(-10) != OGRERR_FAILURE)
    1890                 :     {
    1891               0 :         printf( "ERROR: SetNextByIndex(-10) should have returned OGRERR_FAILURE\n" );
    1892               0 :         bRet = FALSE;
    1893               0 :         goto bye;
    1894                 :     }
    1895                 : 
    1896              10 :     if (poLyr->SetNextByIndex(2000000000) == OGRERR_NONE &&
    1897               0 :         poLyr->GetNextFeature() != NULL)
    1898                 :     {
    1899               0 :         printf( "ERROR: SetNextByIndex(2000000000) and then GetNextFeature() should have returned NULL\n" );
    1900               0 :         bRet = FALSE;
    1901                 :         goto bye;
    1902                 :     }
    1903                 : 
    1904                 : bye:
    1905              10 :     CPLPopErrorHandler();
    1906              10 :     return bRet;
    1907                 : }

Generated by: LCOV version 1.7