LCOV - code coverage report
Current view: directory - apps - test_ogrsf.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 954 667 69.9 %
Date: 2013-03-30 Functions: 20 19 95.0 %

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

Generated by: LCOV version 1.7