1 : /******************************************************************************
2 : * $Id: ogrdatasource.cpp 16933 2009-05-03 19:49:41Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: The generic portions of the OGRDataSource class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
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 "ogr_api.h"
32 : #include "ogr_p.h"
33 : #include "ogr_gensql.h"
34 : #include "ogr_attrind.h"
35 : #include "cpl_multiproc.h"
36 :
37 : CPL_CVSID("$Id: ogrdatasource.cpp 16933 2009-05-03 19:49:41Z rouault $");
38 :
39 : /************************************************************************/
40 : /* ~OGRDataSource() */
41 : /************************************************************************/
42 :
43 2869 : OGRDataSource::OGRDataSource()
44 :
45 : {
46 2869 : m_poStyleTable = NULL;
47 2869 : m_nRefCount = 0;
48 2869 : m_poDriver = NULL;
49 2869 : m_hMutex = NULL;
50 2869 : }
51 :
52 : /************************************************************************/
53 : /* ~OGRDataSource() */
54 : /************************************************************************/
55 :
56 2869 : OGRDataSource::~OGRDataSource()
57 :
58 : {
59 2869 : if ( m_poStyleTable )
60 : {
61 0 : delete m_poStyleTable;
62 0 : m_poStyleTable = NULL;
63 : }
64 :
65 2869 : if( m_hMutex != NULL )
66 206 : CPLDestroyMutex( m_hMutex );
67 2869 : }
68 :
69 : /************************************************************************/
70 : /* DestroyDataSource() */
71 : /************************************************************************/
72 :
73 74 : void OGRDataSource::DestroyDataSource( OGRDataSource *poDS )
74 :
75 : {
76 74 : delete poDS;
77 74 : }
78 :
79 : /************************************************************************/
80 : /* OGR_DS_Destroy() */
81 : /************************************************************************/
82 :
83 16 : void OGR_DS_Destroy( OGRDataSourceH hDS )
84 :
85 : {
86 16 : VALIDATE_POINTER0( hDS, "OGR_DS_Destroy" );
87 16 : delete (OGRDataSource *) hDS;
88 : }
89 :
90 : /************************************************************************/
91 : /* Release() */
92 : /************************************************************************/
93 :
94 0 : OGRErr OGRDataSource::Release()
95 :
96 : {
97 0 : return OGRSFDriverRegistrar::GetRegistrar()->ReleaseDataSource( this );
98 : }
99 :
100 : /************************************************************************/
101 : /* Reference() */
102 : /************************************************************************/
103 :
104 345 : int OGRDataSource::Reference()
105 :
106 : {
107 345 : return ++m_nRefCount;
108 : }
109 :
110 : /************************************************************************/
111 : /* OGR_DS_Reference() */
112 : /************************************************************************/
113 :
114 0 : int OGR_DS_Reference( OGRDataSourceH hDataSource )
115 :
116 : {
117 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_Reference", 0 );
118 :
119 0 : return ((OGRDataSource *) hDataSource)->Reference();
120 : }
121 :
122 : /************************************************************************/
123 : /* Dereference() */
124 : /************************************************************************/
125 :
126 22 : int OGRDataSource::Dereference()
127 :
128 : {
129 22 : return --m_nRefCount;
130 : }
131 :
132 : /************************************************************************/
133 : /* OGR_DS_Dereference() */
134 : /************************************************************************/
135 :
136 0 : int OGR_DS_Dereference( OGRDataSourceH hDataSource )
137 :
138 : {
139 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_Dereference", 0 );
140 :
141 0 : return ((OGRDataSource *) hDataSource)->Dereference();
142 : }
143 :
144 : /************************************************************************/
145 : /* GetRefCount() */
146 : /************************************************************************/
147 :
148 40 : int OGRDataSource::GetRefCount() const
149 :
150 : {
151 40 : return m_nRefCount;
152 : }
153 :
154 : /************************************************************************/
155 : /* OGR_DS_GetRefCount() */
156 : /************************************************************************/
157 :
158 4 : int OGR_DS_GetRefCount( OGRDataSourceH hDataSource )
159 :
160 : {
161 4 : VALIDATE_POINTER1( hDataSource, "OGR_DS_GetRefCount", 0 );
162 :
163 4 : return ((OGRDataSource *) hDataSource)->GetRefCount();
164 : }
165 :
166 : /************************************************************************/
167 : /* GetSummaryRefCount() */
168 : /************************************************************************/
169 :
170 8 : int OGRDataSource::GetSummaryRefCount() const
171 :
172 : {
173 8 : CPLMutexHolderD( (void **) &m_hMutex );
174 8 : int nSummaryCount = m_nRefCount;
175 : int iLayer;
176 8 : OGRDataSource *poUseThis = (OGRDataSource *) this;
177 :
178 16 : for( iLayer=0; iLayer < poUseThis->GetLayerCount(); iLayer++ )
179 8 : nSummaryCount += poUseThis->GetLayer( iLayer )->GetRefCount();
180 :
181 8 : return nSummaryCount;
182 : }
183 :
184 : /************************************************************************/
185 : /* OGR_DS_GetSummaryRefCount() */
186 : /************************************************************************/
187 :
188 0 : int OGR_DS_GetSummaryRefCount( OGRDataSourceH hDataSource )
189 :
190 : {
191 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_GetSummaryRefCount", 0 );
192 :
193 0 : return ((OGRDataSource *) hDataSource)->GetSummaryRefCount();
194 : }
195 :
196 : /************************************************************************/
197 : /* CreateLayer() */
198 : /************************************************************************/
199 :
200 0 : OGRLayer *OGRDataSource::CreateLayer( const char * pszName,
201 : OGRSpatialReference * poSpatialRef,
202 : OGRwkbGeometryType eGType,
203 : char **papszOptions )
204 :
205 : {
206 : (void) eGType;
207 : (void) poSpatialRef;
208 : (void) pszName;
209 : (void) papszOptions;
210 :
211 : CPLError( CE_Failure, CPLE_NotSupported,
212 0 : "CreateLayer() not supported by this data source." );
213 :
214 0 : return NULL;
215 : }
216 :
217 : /************************************************************************/
218 : /* OGR_DS_CreateLayer() */
219 : /************************************************************************/
220 :
221 171 : OGRLayerH OGR_DS_CreateLayer( OGRDataSourceH hDS,
222 : const char * pszName,
223 : OGRSpatialReferenceH hSpatialRef,
224 : OGRwkbGeometryType eType,
225 : char ** papszOptions )
226 :
227 : {
228 171 : VALIDATE_POINTER1( hDS, "OGR_DS_CreateLayer", NULL );
229 :
230 171 : if (pszName == NULL)
231 : {
232 0 : CPLError ( CE_Failure, CPLE_ObjectNull, "Name was NULL in OGR_DS_CreateLayer");
233 0 : return 0;
234 : }
235 : return (OGRLayerH) ((OGRDataSource *)hDS)->CreateLayer(
236 171 : pszName, (OGRSpatialReference *) hSpatialRef, eType, papszOptions );
237 : }
238 :
239 : /************************************************************************/
240 : /* CopyLayer() */
241 : /************************************************************************/
242 :
243 0 : OGRLayer *OGRDataSource::CopyLayer( OGRLayer *poSrcLayer,
244 : const char *pszNewName,
245 : char **papszOptions )
246 :
247 : {
248 0 : OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn();
249 0 : OGRLayer *poDstLayer = NULL;
250 :
251 : /* -------------------------------------------------------------------- */
252 : /* Create the layer. */
253 : /* -------------------------------------------------------------------- */
254 0 : if( !TestCapability( ODsCCreateLayer ) )
255 : {
256 : CPLError( CE_Failure, CPLE_NotSupported,
257 0 : "This datasource does not support creation of layers." );
258 0 : return NULL;
259 : }
260 :
261 0 : CPLErrorReset();
262 0 : poDstLayer = CreateLayer( pszNewName, poSrcLayer->GetSpatialRef(),
263 0 : poSrcDefn->GetGeomType(), papszOptions );
264 :
265 0 : if( poDstLayer == NULL )
266 0 : return NULL;
267 :
268 : /* -------------------------------------------------------------------- */
269 : /* Add fields. Default to copy all field. */
270 : /* If only a subset of all fields requested, then output only */
271 : /* the selected fields, and in the order that they were */
272 : /* selected. */
273 : /* -------------------------------------------------------------------- */
274 : int iField;
275 :
276 0 : for( iField = 0; iField < poSrcDefn->GetFieldCount(); iField++ )
277 0 : poDstLayer->CreateField( poSrcDefn->GetFieldDefn(iField) );
278 :
279 : /* -------------------------------------------------------------------- */
280 : /* Transfer features. */
281 : /* -------------------------------------------------------------------- */
282 : OGRFeature *poFeature;
283 :
284 0 : poSrcLayer->ResetReading();
285 :
286 0 : while( TRUE )
287 : {
288 0 : OGRFeature *poDstFeature = NULL;
289 :
290 0 : poFeature = poSrcLayer->GetNextFeature();
291 :
292 0 : if( poFeature == NULL )
293 : break;
294 :
295 0 : CPLErrorReset();
296 0 : poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
297 :
298 0 : if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE )
299 : {
300 0 : delete poFeature;
301 : CPLError( CE_Failure, CPLE_AppDefined,
302 : "Unable to translate feature %ld from layer %s.\n",
303 0 : poFeature->GetFID(), poSrcDefn->GetName() );
304 0 : return poDstLayer;
305 : }
306 :
307 0 : poDstFeature->SetFID( poFeature->GetFID() );
308 :
309 0 : OGRFeature::DestroyFeature( poFeature );
310 :
311 0 : CPLErrorReset();
312 0 : if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
313 : {
314 0 : OGRFeature::DestroyFeature( poDstFeature );
315 0 : return poDstLayer;
316 : }
317 :
318 0 : OGRFeature::DestroyFeature( poDstFeature );
319 : }
320 :
321 0 : return poDstLayer;
322 : }
323 :
324 : /************************************************************************/
325 : /* OGR_DS_CopyLayer() */
326 : /************************************************************************/
327 :
328 0 : OGRLayerH OGR_DS_CopyLayer( OGRDataSourceH hDS,
329 : OGRLayerH hSrcLayer, const char *pszNewName,
330 : char **papszOptions )
331 :
332 : {
333 0 : VALIDATE_POINTER1( hDS, "OGR_DS_CopyLayer", NULL );
334 0 : VALIDATE_POINTER1( hSrcLayer, "OGR_DS_CopyLayer", NULL );
335 :
336 : return (OGRLayerH)
337 : ((OGRDataSource *) hDS)->CopyLayer( (OGRLayer *) hSrcLayer,
338 0 : pszNewName, papszOptions );
339 : }
340 :
341 : /************************************************************************/
342 : /* DeleteLayer() */
343 : /************************************************************************/
344 :
345 0 : OGRErr OGRDataSource::DeleteLayer( int iLayer )
346 :
347 : {
348 : (void) iLayer;
349 : CPLError( CE_Failure, CPLE_NotSupported,
350 0 : "DeleteLayer() not supported by this data source." );
351 :
352 0 : return OGRERR_UNSUPPORTED_OPERATION;
353 : }
354 :
355 : /************************************************************************/
356 : /* OGR_DS_DeleteLayer() */
357 : /************************************************************************/
358 :
359 1 : OGRErr OGR_DS_DeleteLayer( OGRDataSourceH hDS, int iLayer )
360 :
361 : {
362 1 : VALIDATE_POINTER1( hDS, "OGR_DS_DeleteLayer", OGRERR_INVALID_HANDLE );
363 :
364 1 : return ((OGRDataSource *) hDS)->DeleteLayer( iLayer );
365 : }
366 :
367 : /************************************************************************/
368 : /* GetLayerByName() */
369 : /************************************************************************/
370 :
371 495 : OGRLayer *OGRDataSource::GetLayerByName( const char *pszName )
372 :
373 : {
374 495 : CPLMutexHolderD( &m_hMutex );
375 :
376 495 : if ( ! pszName )
377 0 : return NULL;
378 :
379 : int i;
380 :
381 : /* first a case sensitive check */
382 2473 : for( i = 0; i < GetLayerCount(); i++ )
383 : {
384 2451 : OGRLayer *poLayer = GetLayer(i);
385 :
386 2451 : if( strcmp( pszName, poLayer->GetLayerDefn()->GetName() ) == 0 )
387 473 : return poLayer;
388 : }
389 :
390 : /* then case insensitive */
391 83 : for( i = 0; i < GetLayerCount(); i++ )
392 : {
393 64 : OGRLayer *poLayer = GetLayer(i);
394 :
395 64 : if( EQUAL( pszName, poLayer->GetLayerDefn()->GetName() ) )
396 3 : return poLayer;
397 : }
398 :
399 19 : return NULL;
400 : }
401 :
402 : /************************************************************************/
403 : /* OGR_DS_GetLayerByName() */
404 : /************************************************************************/
405 :
406 347 : OGRLayerH OGR_DS_GetLayerByName( OGRDataSourceH hDS, const char *pszName )
407 :
408 : {
409 347 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerByName", NULL );
410 :
411 347 : return (OGRLayerH) ((OGRDataSource *) hDS)->GetLayerByName( pszName );
412 : }
413 :
414 : /************************************************************************/
415 : /* ProcessSQLCreateIndex() */
416 : /* */
417 : /* The correct syntax for creating an index in our dialect of */
418 : /* SQL is: */
419 : /* */
420 : /* CREATE INDEX ON <layername> USING <columnname> */
421 : /************************************************************************/
422 :
423 2 : OGRErr OGRDataSource::ProcessSQLCreateIndex( const char *pszSQLCommand )
424 :
425 : {
426 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
427 :
428 : /* -------------------------------------------------------------------- */
429 : /* Do some general syntax checking. */
430 : /* -------------------------------------------------------------------- */
431 10 : if( CSLCount(papszTokens) != 6
432 2 : || !EQUAL(papszTokens[0],"CREATE")
433 2 : || !EQUAL(papszTokens[1],"INDEX")
434 2 : || !EQUAL(papszTokens[2],"ON")
435 2 : || !EQUAL(papszTokens[4],"USING") )
436 : {
437 0 : CSLDestroy( papszTokens );
438 : CPLError( CE_Failure, CPLE_AppDefined,
439 : "Syntax error in CREATE INDEX command.\n"
440 : "Was '%s'\n"
441 : "Should be of form 'CREATE INDEX ON <table> USING <field>'",
442 0 : pszSQLCommand );
443 0 : return OGRERR_FAILURE;
444 : }
445 :
446 : /* -------------------------------------------------------------------- */
447 : /* Find the named layer. */
448 : /* -------------------------------------------------------------------- */
449 : int i;
450 2 : OGRLayer *poLayer = NULL;
451 :
452 : {
453 2 : CPLMutexHolderD( &m_hMutex );
454 :
455 2 : for( i = 0; i < GetLayerCount(); i++ )
456 : {
457 2 : poLayer = GetLayer(i);
458 :
459 2 : if( EQUAL(poLayer->GetLayerDefn()->GetName(),papszTokens[3]) )
460 2 : break;
461 : }
462 :
463 2 : if( i >= GetLayerCount() )
464 : {
465 : CPLError( CE_Failure, CPLE_AppDefined,
466 : "CREATE INDEX ON failed, no such layer as `%s'.",
467 0 : papszTokens[3] );
468 0 : CSLDestroy( papszTokens );
469 0 : return OGRERR_FAILURE;
470 0 : }
471 : }
472 :
473 : /* -------------------------------------------------------------------- */
474 : /* Does this layer even support attribute indexes? */
475 : /* -------------------------------------------------------------------- */
476 2 : if( poLayer->GetIndex() == NULL )
477 : {
478 : CPLError( CE_Failure, CPLE_AppDefined,
479 0 : "CREATE INDEX ON not supported by this driver." );
480 0 : CSLDestroy( papszTokens );
481 0 : return OGRERR_FAILURE;
482 : }
483 :
484 : /* -------------------------------------------------------------------- */
485 : /* Find the named field. */
486 : /* -------------------------------------------------------------------- */
487 3 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
488 : {
489 3 : if( EQUAL(papszTokens[5],
490 : poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
491 2 : break;
492 : }
493 :
494 2 : CSLDestroy( papszTokens );
495 :
496 2 : if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
497 : {
498 : CPLError( CE_Failure, CPLE_AppDefined,
499 : "`%s' failed, field not found.",
500 0 : pszSQLCommand );
501 0 : return OGRERR_FAILURE;
502 : }
503 :
504 : /* -------------------------------------------------------------------- */
505 : /* Attempt to create the index. */
506 : /* -------------------------------------------------------------------- */
507 : OGRErr eErr;
508 :
509 2 : eErr = poLayer->GetIndex()->CreateIndex( i );
510 2 : if( eErr == OGRERR_NONE )
511 2 : eErr = poLayer->GetIndex()->IndexAllFeatures( i );
512 :
513 2 : return eErr;
514 : }
515 :
516 : /************************************************************************/
517 : /* ProcessSQLDropIndex() */
518 : /* */
519 : /* The correct syntax for droping one or more indexes in */
520 : /* the OGR SQL dialect is: */
521 : /* */
522 : /* DROP INDEX ON <layername> [USING <columnname>] */
523 : /************************************************************************/
524 :
525 2 : OGRErr OGRDataSource::ProcessSQLDropIndex( const char *pszSQLCommand )
526 :
527 : {
528 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
529 :
530 : /* -------------------------------------------------------------------- */
531 : /* Do some general syntax checking. */
532 : /* -------------------------------------------------------------------- */
533 10 : if( (CSLCount(papszTokens) != 4 && CSLCount(papszTokens) != 6)
534 2 : || !EQUAL(papszTokens[0],"DROP")
535 2 : || !EQUAL(papszTokens[1],"INDEX")
536 2 : || !EQUAL(papszTokens[2],"ON")
537 2 : || (CSLCount(papszTokens) == 6 && !EQUAL(papszTokens[4],"USING")) )
538 : {
539 0 : CSLDestroy( papszTokens );
540 : CPLError( CE_Failure, CPLE_AppDefined,
541 : "Syntax error in DROP INDEX command.\n"
542 : "Was '%s'\n"
543 : "Should be of form 'DROP INDEX ON <table> [USING <field>]'",
544 0 : pszSQLCommand );
545 0 : return OGRERR_FAILURE;
546 : }
547 :
548 : /* -------------------------------------------------------------------- */
549 : /* Find the named layer. */
550 : /* -------------------------------------------------------------------- */
551 : int i;
552 2 : OGRLayer *poLayer=NULL;
553 :
554 : {
555 2 : CPLMutexHolderD( &m_hMutex );
556 :
557 2 : for( i = 0; i < GetLayerCount(); i++ )
558 : {
559 2 : poLayer = GetLayer(i);
560 :
561 2 : if( EQUAL(poLayer->GetLayerDefn()->GetName(),papszTokens[3]) )
562 2 : break;
563 : }
564 :
565 2 : if( i >= GetLayerCount() )
566 : {
567 : CPLError( CE_Failure, CPLE_AppDefined,
568 : "CREATE INDEX ON failed, no such layer as `%s'.",
569 0 : papszTokens[3] );
570 0 : CSLDestroy( papszTokens );
571 0 : return OGRERR_FAILURE;
572 0 : }
573 : }
574 :
575 : /* -------------------------------------------------------------------- */
576 : /* Does this layer even support attribute indexes? */
577 : /* -------------------------------------------------------------------- */
578 2 : if( poLayer->GetIndex() == NULL )
579 : {
580 : CPLError( CE_Failure, CPLE_AppDefined,
581 0 : "Indexes not supported by this driver." );
582 0 : CSLDestroy( papszTokens );
583 0 : return OGRERR_FAILURE;
584 : }
585 :
586 : /* -------------------------------------------------------------------- */
587 : /* If we weren't given a field name, drop all indexes. */
588 : /* -------------------------------------------------------------------- */
589 : OGRErr eErr;
590 :
591 2 : if( CSLCount(papszTokens) == 4 )
592 : {
593 0 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
594 : {
595 : OGRAttrIndex *poAttrIndex;
596 :
597 0 : poAttrIndex = poLayer->GetIndex()->GetFieldIndex(i);
598 0 : if( poAttrIndex != NULL )
599 : {
600 0 : eErr = poLayer->GetIndex()->DropIndex( i );
601 0 : if( eErr != OGRERR_NONE )
602 0 : return eErr;
603 : }
604 : }
605 :
606 0 : CSLDestroy(papszTokens);
607 0 : return OGRERR_NONE;
608 : }
609 :
610 : /* -------------------------------------------------------------------- */
611 : /* Find the named field. */
612 : /* -------------------------------------------------------------------- */
613 3 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
614 : {
615 3 : if( EQUAL(papszTokens[5],
616 : poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
617 2 : break;
618 : }
619 :
620 2 : CSLDestroy( papszTokens );
621 :
622 2 : if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
623 : {
624 : CPLError( CE_Failure, CPLE_AppDefined,
625 : "`%s' failed, field not found.",
626 0 : pszSQLCommand );
627 0 : return OGRERR_FAILURE;
628 : }
629 :
630 : /* -------------------------------------------------------------------- */
631 : /* Attempt to drop the index. */
632 : /* -------------------------------------------------------------------- */
633 2 : eErr = poLayer->GetIndex()->DropIndex( i );
634 :
635 2 : return eErr;
636 : }
637 :
638 : /************************************************************************/
639 : /* ExecuteSQL() */
640 : /************************************************************************/
641 :
642 54 : OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement,
643 : OGRGeometry *poSpatialFilter,
644 : const char *pszDialect )
645 :
646 : {
647 : const char *pszError;
648 54 : swq_select *psSelectInfo = NULL;
649 :
650 : (void) pszDialect;
651 :
652 : swq_field_list sFieldList;
653 54 : int nFIDIndex = 0;
654 54 : OGRGenSQLResultsLayer *poResults = NULL;
655 :
656 54 : memset( &sFieldList, 0, sizeof(sFieldList) );
657 :
658 : /* -------------------------------------------------------------------- */
659 : /* Handle CREATE INDEX statements specially. */
660 : /* -------------------------------------------------------------------- */
661 54 : if( EQUALN(pszStatement,"CREATE INDEX",12) )
662 : {
663 2 : ProcessSQLCreateIndex( pszStatement );
664 2 : return NULL;
665 : }
666 :
667 : /* -------------------------------------------------------------------- */
668 : /* Handle DROP INDEX statements specially. */
669 : /* -------------------------------------------------------------------- */
670 52 : if( EQUALN(pszStatement,"DROP INDEX",10) )
671 : {
672 2 : ProcessSQLDropIndex( pszStatement );
673 2 : return NULL;
674 : }
675 :
676 : /* -------------------------------------------------------------------- */
677 : /* Preparse the SQL statement. */
678 : /* -------------------------------------------------------------------- */
679 50 : pszError = swq_select_preparse( pszStatement, &psSelectInfo );
680 50 : if( pszError != NULL )
681 : {
682 : CPLError( CE_Failure, CPLE_AppDefined,
683 1 : "SQL: %s", pszError );
684 1 : return NULL;
685 : }
686 :
687 : /* -------------------------------------------------------------------- */
688 : /* Validate that all the source tables are recognised, count */
689 : /* fields. */
690 : /* -------------------------------------------------------------------- */
691 49 : int nFieldCount = 0, iTable, iField;
692 : int iEDS;
693 49 : int nExtraDSCount = 0;
694 49 : OGRDataSource** papoExtraDS = NULL;
695 49 : OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
696 :
697 111 : for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
698 : {
699 62 : swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
700 : OGRLayer *poSrcLayer;
701 62 : OGRDataSource *poTableDS = this;
702 :
703 62 : if( psTableDef->data_source != NULL )
704 : {
705 : poTableDS = (OGRDataSource *)
706 4 : OGROpenShared( psTableDef->data_source, FALSE, NULL );
707 4 : if( poTableDS == NULL )
708 : {
709 0 : if( strlen(CPLGetLastErrorMsg()) == 0 )
710 : CPLError( CE_Failure, CPLE_AppDefined,
711 : "Unable to open secondary datasource\n"
712 : "`%s' required by JOIN.",
713 0 : psTableDef->data_source );
714 :
715 0 : swq_select_free( psSelectInfo );
716 0 : goto end;
717 : }
718 :
719 : /* Keep in an array to release at the end of this function */
720 : papoExtraDS = (OGRDataSource** )CPLRealloc(papoExtraDS,
721 4 : sizeof(OGRDataSource*) * (nExtraDSCount + 1));
722 4 : papoExtraDS[nExtraDSCount++] = poTableDS;
723 : }
724 :
725 62 : poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
726 :
727 62 : if( poSrcLayer == NULL )
728 : {
729 : CPLError( CE_Failure, CPLE_AppDefined,
730 : "SELECT from table %s failed, no such table/featureclass.",
731 0 : psTableDef->table_name );
732 0 : swq_select_free( psSelectInfo );
733 0 : goto end;
734 : }
735 :
736 62 : nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount();
737 : }
738 :
739 : /* -------------------------------------------------------------------- */
740 : /* Build the field list for all indicated tables. */
741 : /* -------------------------------------------------------------------- */
742 :
743 49 : sFieldList.table_count = psSelectInfo->table_count;
744 49 : sFieldList.table_defs = psSelectInfo->table_defs;
745 :
746 49 : sFieldList.count = 0;
747 49 : sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+SPECIAL_FIELD_COUNT) );
748 : sFieldList.types = (swq_field_type *)
749 49 : CPLMalloc( sizeof(swq_field_type) * (nFieldCount+SPECIAL_FIELD_COUNT) );
750 : sFieldList.table_ids = (int *)
751 49 : CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
752 : sFieldList.ids = (int *)
753 49 : CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
754 :
755 111 : for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
756 : {
757 62 : swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
758 62 : OGRDataSource *poTableDS = this;
759 : OGRLayer *poSrcLayer;
760 :
761 62 : if( psTableDef->data_source != NULL )
762 : {
763 : poTableDS = (OGRDataSource *)
764 4 : OGROpenShared( psTableDef->data_source, FALSE, NULL );
765 : CPLAssert( poTableDS != NULL );
766 4 : poTableDS->Dereference();
767 : }
768 :
769 62 : poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
770 :
771 486 : for( iField = 0;
772 243 : iField < poSrcLayer->GetLayerDefn()->GetFieldCount();
773 : iField++ )
774 : {
775 181 : OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField);
776 181 : int iOutField = sFieldList.count++;
777 181 : sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef();
778 181 : if( poFDefn->GetType() == OFTInteger )
779 40 : sFieldList.types[iOutField] = SWQ_INTEGER;
780 141 : else if( poFDefn->GetType() == OFTReal )
781 69 : sFieldList.types[iOutField] = SWQ_FLOAT;
782 72 : else if( poFDefn->GetType() == OFTString )
783 70 : sFieldList.types[iOutField] = SWQ_STRING;
784 : else
785 2 : sFieldList.types[iOutField] = SWQ_OTHER;
786 :
787 181 : sFieldList.table_ids[iOutField] = iTable;
788 181 : sFieldList.ids[iOutField] = iField;
789 : }
790 :
791 62 : if( iTable == 0 )
792 49 : nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount();
793 : }
794 :
795 : /* -------------------------------------------------------------------- */
796 : /* Expand '*' in 'SELECT *' now before we add the pseudo fields */
797 : /* -------------------------------------------------------------------- */
798 : pszError =
799 49 : swq_select_expand_wildcard( psSelectInfo, &sFieldList );
800 :
801 49 : if( pszError != NULL )
802 : {
803 0 : swq_select_free( psSelectInfo );
804 : CPLError( CE_Failure, CPLE_AppDefined,
805 0 : "SQL: %s", pszError );
806 0 : goto end;
807 : }
808 :
809 294 : for (iField = 0; iField < SPECIAL_FIELD_COUNT; iField++)
810 : {
811 245 : sFieldList.names[sFieldList.count] = (char*) SpecialFieldNames[iField];
812 245 : sFieldList.types[sFieldList.count] = SpecialFieldTypes[iField];
813 245 : sFieldList.table_ids[sFieldList.count] = 0;
814 245 : sFieldList.ids[sFieldList.count] = nFIDIndex + iField;
815 245 : sFieldList.count++;
816 : }
817 :
818 : /* -------------------------------------------------------------------- */
819 : /* Finish the parse operation. */
820 : /* -------------------------------------------------------------------- */
821 :
822 49 : pszError = swq_select_parse( psSelectInfo, &sFieldList, 0 );
823 :
824 49 : if( pszError != NULL )
825 : {
826 0 : swq_select_free( psSelectInfo );
827 : CPLError( CE_Failure, CPLE_AppDefined,
828 0 : "SQL: %s", pszError );
829 0 : goto end;
830 : }
831 :
832 : /* -------------------------------------------------------------------- */
833 : /* Everything seems OK, try to instantiate a results layer. */
834 : /* -------------------------------------------------------------------- */
835 :
836 : poResults = new OGRGenSQLResultsLayer( this, psSelectInfo,
837 49 : poSpatialFilter );
838 :
839 : // Eventually, we should keep track of layers to cleanup.
840 :
841 : end:
842 49 : CPLFree( sFieldList.names );
843 49 : CPLFree( sFieldList.types );
844 49 : CPLFree( sFieldList.table_ids );
845 49 : CPLFree( sFieldList.ids );
846 :
847 : /* Release the datasets we have opened with OGROpenShared() */
848 : /* It is safe to do that as the 'new OGRGenSQLResultsLayer' itself */
849 : /* has taken a reference on them, which it will release in its */
850 : /* destructor */
851 53 : for(iEDS = 0; iEDS < nExtraDSCount; iEDS++)
852 4 : poReg->ReleaseDataSource( papoExtraDS[iEDS] );
853 49 : CPLFree(papoExtraDS);
854 :
855 49 : return poResults;
856 : }
857 :
858 : /************************************************************************/
859 : /* OGR_DS_ExecuteSQL() */
860 : /************************************************************************/
861 :
862 419 : OGRLayerH OGR_DS_ExecuteSQL( OGRDataSourceH hDS,
863 : const char *pszStatement,
864 : OGRGeometryH hSpatialFilter,
865 : const char *pszDialect )
866 :
867 : {
868 419 : VALIDATE_POINTER1( hDS, "OGR_DS_ExecuteSQL", NULL );
869 :
870 : return (OGRLayerH)
871 : ((OGRDataSource *)hDS)->ExecuteSQL( pszStatement,
872 : (OGRGeometry *) hSpatialFilter,
873 419 : pszDialect );
874 : }
875 :
876 : /************************************************************************/
877 : /* ReleaseResultSet() */
878 : /************************************************************************/
879 :
880 49 : void OGRDataSource::ReleaseResultSet( OGRLayer * poResultsSet )
881 :
882 : {
883 49 : delete poResultsSet;
884 49 : }
885 :
886 : /************************************************************************/
887 : /* OGR_DS_ReleaseResultSet() */
888 : /************************************************************************/
889 :
890 96 : void OGR_DS_ReleaseResultSet( OGRDataSourceH hDS, OGRLayerH hLayer )
891 :
892 : {
893 96 : VALIDATE_POINTER0( hDS, "OGR_DS_ReleaseResultSet" );
894 :
895 96 : ((OGRDataSource *) hDS)->ReleaseResultSet( (OGRLayer *) hLayer );
896 : }
897 :
898 : /************************************************************************/
899 : /* OGR_DS_TestCapability() */
900 : /************************************************************************/
901 :
902 4 : int OGR_DS_TestCapability( OGRDataSourceH hDS, const char *pszCap )
903 :
904 : {
905 4 : VALIDATE_POINTER1( hDS, "OGR_DS_TestCapability", 0 );
906 4 : VALIDATE_POINTER1( pszCap, "OGR_DS_TestCapability", 0 );
907 :
908 4 : return ((OGRDataSource *) hDS)->TestCapability( pszCap );
909 : }
910 :
911 : /************************************************************************/
912 : /* OGR_DS_GetLayerCount() */
913 : /************************************************************************/
914 :
915 74 : int OGR_DS_GetLayerCount( OGRDataSourceH hDS )
916 :
917 : {
918 74 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerCount", 0 );
919 :
920 74 : return ((OGRDataSource *)hDS)->GetLayerCount();
921 : }
922 :
923 : /************************************************************************/
924 : /* OGR_DS_GetLayer() */
925 : /************************************************************************/
926 :
927 453 : OGRLayerH OGR_DS_GetLayer( OGRDataSourceH hDS, int iLayer )
928 :
929 : {
930 453 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayer", NULL );
931 :
932 453 : return (OGRLayerH) ((OGRDataSource*)hDS)->GetLayer( iLayer );
933 : }
934 :
935 : /************************************************************************/
936 : /* OGR_DS_GetName() */
937 : /************************************************************************/
938 :
939 15 : const char *OGR_DS_GetName( OGRDataSourceH hDS )
940 :
941 : {
942 15 : VALIDATE_POINTER1( hDS, "OGR_DS_GetName", NULL );
943 :
944 15 : return ((OGRDataSource*)hDS)->GetName();
945 : }
946 :
947 : /************************************************************************/
948 : /* SyncToDisk() */
949 : /************************************************************************/
950 :
951 0 : OGRErr OGRDataSource::SyncToDisk()
952 :
953 : {
954 0 : CPLMutexHolderD( &m_hMutex );
955 : int i;
956 : OGRErr eErr;
957 :
958 0 : for( i = 0; i < GetLayerCount(); i++ )
959 : {
960 0 : OGRLayer *poLayer = GetLayer(i);
961 :
962 0 : if( poLayer )
963 : {
964 0 : eErr = poLayer->SyncToDisk();
965 0 : if( eErr != OGRERR_NONE )
966 0 : return eErr;
967 : }
968 : }
969 :
970 0 : return OGRERR_NONE;
971 : }
972 :
973 : /************************************************************************/
974 : /* OGR_DS_SyncToDisk() */
975 : /************************************************************************/
976 :
977 0 : OGRErr OGR_DS_SyncToDisk( OGRDataSourceH hDS )
978 :
979 : {
980 0 : VALIDATE_POINTER1( hDS, "OGR_DS_SyncToDisk", OGRERR_INVALID_HANDLE );
981 :
982 0 : return ((OGRDataSource *) hDS)->SyncToDisk();
983 : }
984 :
985 : /************************************************************************/
986 : /* GetDriver() */
987 : /************************************************************************/
988 :
989 713 : OGRSFDriver *OGRDataSource::GetDriver() const
990 :
991 : {
992 713 : return m_poDriver;
993 : }
994 :
995 : /************************************************************************/
996 : /* OGR_DS_GetDriver() */
997 : /************************************************************************/
998 :
999 2 : OGRSFDriverH OGR_DS_GetDriver( OGRDataSourceH hDS )
1000 :
1001 : {
1002 2 : VALIDATE_POINTER1( hDS, "OGR_DS_GetDriver", NULL );
1003 :
1004 2 : return (OGRSFDriverH) ((OGRDataSource *) hDS)->GetDriver();
1005 : }
1006 :
1007 : /************************************************************************/
1008 : /* SetDriver() */
1009 : /************************************************************************/
1010 :
1011 125 : void OGRDataSource::SetDriver( OGRSFDriver *poDriver )
1012 :
1013 : {
1014 125 : m_poDriver = poDriver;
1015 125 : }
1016 :
1017 : /************************************************************************/
1018 : /* OGR_DS_GetStyleTable() */
1019 : /************************************************************************/
1020 :
1021 0 : OGRStyleTableH OGR_DS_GetStyleTable( OGRDataSourceH hDS )
1022 :
1023 : {
1024 0 : VALIDATE_POINTER1( hDS, "OGR_DS_GetStyleTable", NULL );
1025 :
1026 0 : return (OGRStyleTableH) ((OGRDataSource *) hDS)->GetStyleTable( );
1027 : }
1028 :
1029 : /************************************************************************/
1030 : /* OGR_DS_SetStyleTableDirectly() */
1031 : /************************************************************************/
1032 :
1033 0 : void OGR_DS_SetStyleTableDirectly( OGRDataSourceH hDS,
1034 : OGRStyleTableH hStyleTable )
1035 :
1036 : {
1037 0 : VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTableDirectly" );
1038 :
1039 0 : ((OGRDataSource *) hDS)->SetStyleTableDirectly( (OGRStyleTable *) hStyleTable);
1040 : }
1041 :
1042 : /************************************************************************/
1043 : /* OGR_DS_SetStyleTable() */
1044 : /************************************************************************/
1045 :
1046 0 : void OGR_DS_SetStyleTable( OGRDataSourceH hDS, OGRStyleTableH hStyleTable )
1047 :
1048 : {
1049 0 : VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTable" );
1050 0 : VALIDATE_POINTER0( hStyleTable, "OGR_DS_SetStyleTable" );
1051 :
1052 0 : ((OGRDataSource *) hDS)->SetStyleTable( (OGRStyleTable *) hStyleTable);
1053 : }
|