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