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