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 : }
|