LCOV - code coverage report
Current view: directory - apps - test_ogrsf.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 910 639 70.2 %
Date: 2012-12-26 Functions: 20 19 95.0 %

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

Generated by: LCOV version 1.7