1 : /******************************************************************************
2 : * $Id: ogrdatasource.cpp 24813 2012-08-20 21:08:33Z 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 "swq.h"
31 : #include "ogrsf_frmts.h"
32 : #include "ogr_api.h"
33 : #include "ogr_p.h"
34 : #include "ogr_gensql.h"
35 : #include "ogr_attrind.h"
36 : #include "cpl_multiproc.h"
37 : #include "ogrunionlayer.h"
38 :
39 : #ifdef SQLITE_ENABLED
40 : #include "../sqlite/ogrsqliteexecutesql.h"
41 : #endif
42 :
43 : CPL_CVSID("$Id: ogrdatasource.cpp 24813 2012-08-20 21:08:33Z rouault $");
44 :
45 : /************************************************************************/
46 : /* ~OGRDataSource() */
47 : /************************************************************************/
48 :
49 17342 : OGRDataSource::OGRDataSource()
50 :
51 : {
52 17342 : m_poStyleTable = NULL;
53 17342 : m_nRefCount = 0;
54 17342 : m_poDriver = NULL;
55 17342 : m_hMutex = NULL;
56 17342 : }
57 :
58 : /************************************************************************/
59 : /* ~OGRDataSource() */
60 : /************************************************************************/
61 :
62 17342 : OGRDataSource::~OGRDataSource()
63 :
64 : {
65 17342 : if ( m_poStyleTable )
66 : {
67 3 : delete m_poStyleTable;
68 3 : m_poStyleTable = NULL;
69 : }
70 :
71 17342 : if( m_hMutex != NULL )
72 935 : CPLDestroyMutex( m_hMutex );
73 17342 : }
74 :
75 : /************************************************************************/
76 : /* DestroyDataSource() */
77 : /************************************************************************/
78 :
79 696 : void OGRDataSource::DestroyDataSource( OGRDataSource *poDS )
80 :
81 : {
82 696 : delete poDS;
83 696 : }
84 :
85 : /************************************************************************/
86 : /* OGR_DS_Destroy() */
87 : /************************************************************************/
88 :
89 48 : void OGR_DS_Destroy( OGRDataSourceH hDS )
90 :
91 : {
92 48 : VALIDATE_POINTER0( hDS, "OGR_DS_Destroy" );
93 48 : delete (OGRDataSource *) hDS;
94 : }
95 :
96 : /************************************************************************/
97 : /* Release() */
98 : /************************************************************************/
99 :
100 0 : OGRErr OGRDataSource::Release()
101 :
102 : {
103 0 : return OGRSFDriverRegistrar::GetRegistrar()->ReleaseDataSource( this );
104 : }
105 :
106 : /************************************************************************/
107 : /* Reference() */
108 : /************************************************************************/
109 :
110 1486 : int OGRDataSource::Reference()
111 :
112 : {
113 1486 : return ++m_nRefCount;
114 : }
115 :
116 : /************************************************************************/
117 : /* OGR_DS_Reference() */
118 : /************************************************************************/
119 :
120 0 : int OGR_DS_Reference( OGRDataSourceH hDataSource )
121 :
122 : {
123 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_Reference", 0 );
124 :
125 0 : return ((OGRDataSource *) hDataSource)->Reference();
126 : }
127 :
128 : /************************************************************************/
129 : /* Dereference() */
130 : /************************************************************************/
131 :
132 52 : int OGRDataSource::Dereference()
133 :
134 : {
135 52 : return --m_nRefCount;
136 : }
137 :
138 : /************************************************************************/
139 : /* OGR_DS_Dereference() */
140 : /************************************************************************/
141 :
142 0 : int OGR_DS_Dereference( OGRDataSourceH hDataSource )
143 :
144 : {
145 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_Dereference", 0 );
146 :
147 0 : return ((OGRDataSource *) hDataSource)->Dereference();
148 : }
149 :
150 : /************************************************************************/
151 : /* GetRefCount() */
152 : /************************************************************************/
153 :
154 98 : int OGRDataSource::GetRefCount() const
155 :
156 : {
157 98 : return m_nRefCount;
158 : }
159 :
160 : /************************************************************************/
161 : /* OGR_DS_GetRefCount() */
162 : /************************************************************************/
163 :
164 4 : int OGR_DS_GetRefCount( OGRDataSourceH hDataSource )
165 :
166 : {
167 4 : VALIDATE_POINTER1( hDataSource, "OGR_DS_GetRefCount", 0 );
168 :
169 4 : return ((OGRDataSource *) hDataSource)->GetRefCount();
170 : }
171 :
172 : /************************************************************************/
173 : /* GetSummaryRefCount() */
174 : /************************************************************************/
175 :
176 19 : int OGRDataSource::GetSummaryRefCount() const
177 :
178 : {
179 19 : CPLMutexHolderD( (void **) &m_hMutex );
180 19 : int nSummaryCount = m_nRefCount;
181 : int iLayer;
182 19 : OGRDataSource *poUseThis = (OGRDataSource *) this;
183 :
184 38 : for( iLayer=0; iLayer < poUseThis->GetLayerCount(); iLayer++ )
185 19 : nSummaryCount += poUseThis->GetLayer( iLayer )->GetRefCount();
186 :
187 19 : return nSummaryCount;
188 : }
189 :
190 : /************************************************************************/
191 : /* OGR_DS_GetSummaryRefCount() */
192 : /************************************************************************/
193 :
194 0 : int OGR_DS_GetSummaryRefCount( OGRDataSourceH hDataSource )
195 :
196 : {
197 0 : VALIDATE_POINTER1( hDataSource, "OGR_DS_GetSummaryRefCount", 0 );
198 :
199 0 : return ((OGRDataSource *) hDataSource)->GetSummaryRefCount();
200 : }
201 :
202 : /************************************************************************/
203 : /* CreateLayer() */
204 : /************************************************************************/
205 :
206 0 : OGRLayer *OGRDataSource::CreateLayer( const char * pszName,
207 : OGRSpatialReference * poSpatialRef,
208 : OGRwkbGeometryType eGType,
209 : char **papszOptions )
210 :
211 : {
212 : (void) eGType;
213 : (void) poSpatialRef;
214 : (void) pszName;
215 : (void) papszOptions;
216 :
217 : CPLError( CE_Failure, CPLE_NotSupported,
218 0 : "CreateLayer() not supported by this data source." );
219 :
220 0 : return NULL;
221 : }
222 :
223 : /************************************************************************/
224 : /* OGR_DS_CreateLayer() */
225 : /************************************************************************/
226 :
227 1566 : OGRLayerH OGR_DS_CreateLayer( OGRDataSourceH hDS,
228 : const char * pszName,
229 : OGRSpatialReferenceH hSpatialRef,
230 : OGRwkbGeometryType eType,
231 : char ** papszOptions )
232 :
233 : {
234 1566 : VALIDATE_POINTER1( hDS, "OGR_DS_CreateLayer", NULL );
235 :
236 1566 : if (pszName == NULL)
237 : {
238 0 : CPLError ( CE_Failure, CPLE_ObjectNull, "Name was NULL in OGR_DS_CreateLayer");
239 0 : return 0;
240 : }
241 : return (OGRLayerH) ((OGRDataSource *)hDS)->CreateLayer(
242 1566 : pszName, (OGRSpatialReference *) hSpatialRef, eType, papszOptions );
243 : }
244 :
245 : /************************************************************************/
246 : /* CopyLayer() */
247 : /************************************************************************/
248 :
249 37 : OGRLayer *OGRDataSource::CopyLayer( OGRLayer *poSrcLayer,
250 : const char *pszNewName,
251 : char **papszOptions )
252 :
253 : {
254 37 : OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn();
255 37 : OGRLayer *poDstLayer = NULL;
256 :
257 : /* -------------------------------------------------------------------- */
258 : /* Create the layer. */
259 : /* -------------------------------------------------------------------- */
260 37 : if( !TestCapability( ODsCCreateLayer ) )
261 : {
262 : CPLError( CE_Failure, CPLE_NotSupported,
263 0 : "This datasource does not support creation of layers." );
264 0 : return NULL;
265 : }
266 :
267 37 : CPLErrorReset();
268 37 : poDstLayer = CreateLayer( pszNewName, poSrcLayer->GetSpatialRef(),
269 74 : poSrcDefn->GetGeomType(), papszOptions );
270 :
271 37 : if( poDstLayer == NULL )
272 0 : return NULL;
273 :
274 : /* -------------------------------------------------------------------- */
275 : /* Add fields. Default to copy all fields, and make sure to */
276 : /* establish a mapping between indices, rather than names, in */
277 : /* case the target datasource has altered it (e.g. Shapefile */
278 : /* limited to 10 char field names). */
279 : /* -------------------------------------------------------------------- */
280 37 : int nSrcFieldCount = poSrcDefn->GetFieldCount();
281 37 : int nDstFieldCount = 0;
282 : int iField, *panMap;
283 :
284 : // Initialize the index-to-index map to -1's
285 37 : panMap = (int *) CPLMalloc( sizeof(int) * nSrcFieldCount );
286 116 : for( iField=0; iField < nSrcFieldCount; iField++)
287 79 : panMap[iField] = -1;
288 :
289 : /* Caution : at the time of writing, the MapInfo driver */
290 : /* returns NULL until a field has been added */
291 37 : OGRFeatureDefn* poDstFDefn = poDstLayer->GetLayerDefn();
292 37 : if (poDstFDefn)
293 37 : nDstFieldCount = poDstFDefn->GetFieldCount();
294 116 : for( iField = 0; iField < nSrcFieldCount; iField++ )
295 : {
296 79 : OGRFieldDefn* poSrcFieldDefn = poSrcDefn->GetFieldDefn(iField);
297 79 : OGRFieldDefn oFieldDefn( poSrcFieldDefn );
298 :
299 : /* The field may have been already created at layer creation */
300 79 : int iDstField = -1;
301 79 : if (poDstFDefn)
302 79 : iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
303 79 : if (iDstField >= 0)
304 : {
305 0 : panMap[iField] = iDstField;
306 : }
307 79 : else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
308 : {
309 : /* now that we've created a field, GetLayerDefn() won't return NULL */
310 79 : if (poDstFDefn == NULL)
311 0 : poDstFDefn = poDstLayer->GetLayerDefn();
312 :
313 : /* Sanity check : if it fails, the driver is buggy */
314 79 : if (poDstFDefn != NULL &&
315 : poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
316 : {
317 : CPLError(CE_Warning, CPLE_AppDefined,
318 : "The output driver has claimed to have added the %s field, but it did not!",
319 0 : oFieldDefn.GetNameRef() );
320 : }
321 : else
322 : {
323 79 : panMap[iField] = nDstFieldCount;
324 79 : nDstFieldCount ++;
325 : }
326 : }
327 : }
328 :
329 : /* -------------------------------------------------------------------- */
330 : /* Check if the destination layer supports transactions and set a */
331 : /* default number of features in a single transaction. */
332 : /* -------------------------------------------------------------------- */
333 37 : int nGroupTransactions = 0;
334 37 : if( poDstLayer->TestCapability( OLCTransactions ) )
335 4 : nGroupTransactions = 128;
336 :
337 : /* -------------------------------------------------------------------- */
338 : /* Transfer features. */
339 : /* -------------------------------------------------------------------- */
340 : OGRFeature *poFeature;
341 :
342 37 : poSrcLayer->ResetReading();
343 :
344 37 : if( nGroupTransactions <= 0 )
345 : {
346 42 : while( TRUE )
347 : {
348 75 : OGRFeature *poDstFeature = NULL;
349 :
350 75 : poFeature = poSrcLayer->GetNextFeature();
351 :
352 75 : if( poFeature == NULL )
353 : break;
354 :
355 42 : CPLErrorReset();
356 42 : poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
357 :
358 42 : if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
359 : {
360 : CPLError( CE_Failure, CPLE_AppDefined,
361 : "Unable to translate feature %ld from layer %s.\n",
362 0 : poFeature->GetFID(), poSrcDefn->GetName() );
363 0 : OGRFeature::DestroyFeature( poFeature );
364 0 : return poDstLayer;
365 : }
366 :
367 42 : poDstFeature->SetFID( poFeature->GetFID() );
368 :
369 42 : OGRFeature::DestroyFeature( poFeature );
370 :
371 42 : CPLErrorReset();
372 42 : if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE )
373 : {
374 0 : OGRFeature::DestroyFeature( poDstFeature );
375 0 : return poDstLayer;
376 : }
377 :
378 42 : OGRFeature::DestroyFeature( poDstFeature );
379 : }
380 : }
381 : else
382 : {
383 4 : int i, bStopTransfer = FALSE, bStopTransaction = FALSE;
384 4 : int nFeatCount = 0; // Number of features in the temporary array
385 4 : int nFeaturesToAdd = 0;
386 : OGRFeature **papoDstFeature =
387 4 : (OGRFeature **)CPLCalloc(sizeof(OGRFeature *), nGroupTransactions);
388 12 : while( !bStopTransfer )
389 : {
390 : /* -------------------------------------------------------------------- */
391 : /* Fill the array with features */
392 : /* -------------------------------------------------------------------- */
393 76 : for( nFeatCount = 0; nFeatCount < nGroupTransactions; nFeatCount++ )
394 : {
395 76 : poFeature = poSrcLayer->GetNextFeature();
396 :
397 76 : if( poFeature == NULL )
398 : {
399 4 : bStopTransfer = 1;
400 4 : break;
401 : }
402 :
403 72 : CPLErrorReset();
404 72 : papoDstFeature[nFeatCount] =
405 72 : OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
406 :
407 72 : if( papoDstFeature[nFeatCount]->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
408 : {
409 0 : OGRFeature::DestroyFeature( poFeature );
410 : CPLError( CE_Failure, CPLE_AppDefined,
411 : "Unable to translate feature %ld from layer %s.\n",
412 0 : poFeature->GetFID(), poSrcDefn->GetName() );
413 0 : bStopTransfer = TRUE;
414 0 : break;
415 : }
416 :
417 72 : papoDstFeature[nFeatCount]->SetFID( poFeature->GetFID() );
418 :
419 72 : OGRFeature::DestroyFeature( poFeature );
420 : }
421 4 : nFeaturesToAdd = nFeatCount;
422 :
423 4 : CPLErrorReset();
424 4 : bStopTransaction = FALSE;
425 12 : while( !bStopTransaction )
426 : {
427 4 : bStopTransaction = TRUE;
428 4 : poDstLayer->StartTransaction();
429 76 : for( i = 0; i < nFeaturesToAdd; i++ )
430 : {
431 72 : if( poDstLayer->CreateFeature( papoDstFeature[i] ) != OGRERR_NONE )
432 : {
433 0 : nFeaturesToAdd = i;
434 0 : bStopTransfer = TRUE;
435 0 : bStopTransaction = FALSE;
436 : }
437 : }
438 4 : if( bStopTransaction )
439 4 : poDstLayer->CommitTransaction();
440 : else
441 0 : poDstLayer->RollbackTransaction();
442 : }
443 :
444 76 : for( i = 0; i < nFeatCount; i++ )
445 72 : OGRFeature::DestroyFeature( papoDstFeature[i] );
446 : }
447 4 : CPLFree(papoDstFeature);
448 : }
449 :
450 37 : CPLFree(panMap);
451 :
452 37 : return poDstLayer;
453 : }
454 :
455 : /************************************************************************/
456 : /* OGR_DS_CopyLayer() */
457 : /************************************************************************/
458 :
459 4 : OGRLayerH OGR_DS_CopyLayer( OGRDataSourceH hDS,
460 : OGRLayerH hSrcLayer, const char *pszNewName,
461 : char **papszOptions )
462 :
463 : {
464 4 : VALIDATE_POINTER1( hDS, "OGR_DS_CopyLayer", NULL );
465 4 : VALIDATE_POINTER1( hSrcLayer, "OGR_DS_CopyLayer", NULL );
466 4 : VALIDATE_POINTER1( pszNewName, "OGR_DS_CopyLayer", NULL );
467 :
468 : return (OGRLayerH)
469 : ((OGRDataSource *) hDS)->CopyLayer( (OGRLayer *) hSrcLayer,
470 4 : pszNewName, papszOptions );
471 : }
472 :
473 : /************************************************************************/
474 : /* DeleteLayer() */
475 : /************************************************************************/
476 :
477 0 : OGRErr OGRDataSource::DeleteLayer( int iLayer )
478 :
479 : {
480 : (void) iLayer;
481 : CPLError( CE_Failure, CPLE_NotSupported,
482 0 : "DeleteLayer() not supported by this data source." );
483 :
484 0 : return OGRERR_UNSUPPORTED_OPERATION;
485 : }
486 :
487 : /************************************************************************/
488 : /* OGR_DS_DeleteLayer() */
489 : /************************************************************************/
490 :
491 15 : OGRErr OGR_DS_DeleteLayer( OGRDataSourceH hDS, int iLayer )
492 :
493 : {
494 15 : VALIDATE_POINTER1( hDS, "OGR_DS_DeleteLayer", OGRERR_INVALID_HANDLE );
495 :
496 15 : return ((OGRDataSource *) hDS)->DeleteLayer( iLayer );
497 : }
498 :
499 : /************************************************************************/
500 : /* GetLayerByName() */
501 : /************************************************************************/
502 :
503 4018 : OGRLayer *OGRDataSource::GetLayerByName( const char *pszName )
504 :
505 : {
506 4018 : CPLMutexHolderD( &m_hMutex );
507 :
508 4018 : if ( ! pszName )
509 0 : return NULL;
510 :
511 : int i;
512 :
513 : /* first a case sensitive check */
514 261517 : for( i = 0; i < GetLayerCount(); i++ )
515 : {
516 259948 : OGRLayer *poLayer = GetLayer(i);
517 :
518 259948 : if( strcmp( pszName, poLayer->GetName() ) == 0 )
519 2449 : return poLayer;
520 : }
521 :
522 : /* then case insensitive */
523 254047 : for( i = 0; i < GetLayerCount(); i++ )
524 : {
525 252505 : OGRLayer *poLayer = GetLayer(i);
526 :
527 252505 : if( EQUAL( pszName, poLayer->GetName() ) )
528 27 : return poLayer;
529 : }
530 :
531 1542 : return NULL;
532 : }
533 :
534 : /************************************************************************/
535 : /* OGR_DS_GetLayerByName() */
536 : /************************************************************************/
537 :
538 1952 : OGRLayerH OGR_DS_GetLayerByName( OGRDataSourceH hDS, const char *pszName )
539 :
540 : {
541 1952 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerByName", NULL );
542 :
543 1952 : return (OGRLayerH) ((OGRDataSource *) hDS)->GetLayerByName( pszName );
544 : }
545 :
546 : /************************************************************************/
547 : /* ProcessSQLCreateIndex() */
548 : /* */
549 : /* The correct syntax for creating an index in our dialect of */
550 : /* SQL is: */
551 : /* */
552 : /* CREATE INDEX ON <layername> USING <columnname> */
553 : /************************************************************************/
554 :
555 8 : OGRErr OGRDataSource::ProcessSQLCreateIndex( const char *pszSQLCommand )
556 :
557 : {
558 8 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
559 :
560 : /* -------------------------------------------------------------------- */
561 : /* Do some general syntax checking. */
562 : /* -------------------------------------------------------------------- */
563 40 : if( CSLCount(papszTokens) != 6
564 8 : || !EQUAL(papszTokens[0],"CREATE")
565 8 : || !EQUAL(papszTokens[1],"INDEX")
566 8 : || !EQUAL(papszTokens[2],"ON")
567 8 : || !EQUAL(papszTokens[4],"USING") )
568 : {
569 0 : CSLDestroy( papszTokens );
570 : CPLError( CE_Failure, CPLE_AppDefined,
571 : "Syntax error in CREATE INDEX command.\n"
572 : "Was '%s'\n"
573 : "Should be of form 'CREATE INDEX ON <table> USING <field>'",
574 0 : pszSQLCommand );
575 0 : return OGRERR_FAILURE;
576 : }
577 :
578 : /* -------------------------------------------------------------------- */
579 : /* Find the named layer. */
580 : /* -------------------------------------------------------------------- */
581 : int i;
582 8 : OGRLayer *poLayer = NULL;
583 :
584 : {
585 8 : CPLMutexHolderD( &m_hMutex );
586 :
587 8 : for( i = 0; i < GetLayerCount(); i++ )
588 : {
589 8 : poLayer = GetLayer(i);
590 :
591 8 : if( EQUAL(poLayer->GetName(),papszTokens[3]) )
592 8 : break;
593 : }
594 :
595 8 : if( i >= GetLayerCount() )
596 : {
597 : CPLError( CE_Failure, CPLE_AppDefined,
598 : "CREATE INDEX ON failed, no such layer as `%s'.",
599 0 : papszTokens[3] );
600 0 : CSLDestroy( papszTokens );
601 0 : return OGRERR_FAILURE;
602 0 : }
603 : }
604 :
605 : /* -------------------------------------------------------------------- */
606 : /* Does this layer even support attribute indexes? */
607 : /* -------------------------------------------------------------------- */
608 8 : if( poLayer->GetIndex() == NULL )
609 : {
610 : CPLError( CE_Failure, CPLE_AppDefined,
611 0 : "CREATE INDEX ON not supported by this driver." );
612 0 : CSLDestroy( papszTokens );
613 0 : return OGRERR_FAILURE;
614 : }
615 :
616 : /* -------------------------------------------------------------------- */
617 : /* Find the named field. */
618 : /* -------------------------------------------------------------------- */
619 12 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
620 : {
621 12 : if( EQUAL(papszTokens[5],
622 : poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
623 8 : break;
624 : }
625 :
626 8 : CSLDestroy( papszTokens );
627 :
628 8 : if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
629 : {
630 : CPLError( CE_Failure, CPLE_AppDefined,
631 : "`%s' failed, field not found.",
632 0 : pszSQLCommand );
633 0 : return OGRERR_FAILURE;
634 : }
635 :
636 : /* -------------------------------------------------------------------- */
637 : /* Attempt to create the index. */
638 : /* -------------------------------------------------------------------- */
639 : OGRErr eErr;
640 :
641 8 : eErr = poLayer->GetIndex()->CreateIndex( i );
642 8 : if( eErr == OGRERR_NONE )
643 8 : eErr = poLayer->GetIndex()->IndexAllFeatures( i );
644 : else
645 : {
646 0 : if( strlen(CPLGetLastErrorMsg()) == 0 )
647 : CPLError( CE_Failure, CPLE_AppDefined,
648 0 : "Cannot '%s'", pszSQLCommand);
649 : }
650 :
651 8 : return eErr;
652 : }
653 :
654 : /************************************************************************/
655 : /* ProcessSQLDropIndex() */
656 : /* */
657 : /* The correct syntax for droping one or more indexes in */
658 : /* the OGR SQL dialect is: */
659 : /* */
660 : /* DROP INDEX ON <layername> [USING <columnname>] */
661 : /************************************************************************/
662 :
663 2 : OGRErr OGRDataSource::ProcessSQLDropIndex( const char *pszSQLCommand )
664 :
665 : {
666 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
667 :
668 : /* -------------------------------------------------------------------- */
669 : /* Do some general syntax checking. */
670 : /* -------------------------------------------------------------------- */
671 10 : if( (CSLCount(papszTokens) != 4 && CSLCount(papszTokens) != 6)
672 2 : || !EQUAL(papszTokens[0],"DROP")
673 2 : || !EQUAL(papszTokens[1],"INDEX")
674 2 : || !EQUAL(papszTokens[2],"ON")
675 2 : || (CSLCount(papszTokens) == 6 && !EQUAL(papszTokens[4],"USING")) )
676 : {
677 0 : CSLDestroy( papszTokens );
678 : CPLError( CE_Failure, CPLE_AppDefined,
679 : "Syntax error in DROP INDEX command.\n"
680 : "Was '%s'\n"
681 : "Should be of form 'DROP INDEX ON <table> [USING <field>]'",
682 0 : pszSQLCommand );
683 0 : return OGRERR_FAILURE;
684 : }
685 :
686 : /* -------------------------------------------------------------------- */
687 : /* Find the named layer. */
688 : /* -------------------------------------------------------------------- */
689 : int i;
690 2 : OGRLayer *poLayer=NULL;
691 :
692 : {
693 2 : CPLMutexHolderD( &m_hMutex );
694 :
695 2 : for( i = 0; i < GetLayerCount(); i++ )
696 : {
697 2 : poLayer = GetLayer(i);
698 :
699 2 : if( EQUAL(poLayer->GetName(),papszTokens[3]) )
700 2 : break;
701 : }
702 :
703 2 : if( i >= GetLayerCount() )
704 : {
705 : CPLError( CE_Failure, CPLE_AppDefined,
706 : "CREATE INDEX ON failed, no such layer as `%s'.",
707 0 : papszTokens[3] );
708 0 : CSLDestroy( papszTokens );
709 0 : return OGRERR_FAILURE;
710 0 : }
711 : }
712 :
713 : /* -------------------------------------------------------------------- */
714 : /* Does this layer even support attribute indexes? */
715 : /* -------------------------------------------------------------------- */
716 2 : if( poLayer->GetIndex() == NULL )
717 : {
718 : CPLError( CE_Failure, CPLE_AppDefined,
719 0 : "Indexes not supported by this driver." );
720 0 : CSLDestroy( papszTokens );
721 0 : return OGRERR_FAILURE;
722 : }
723 :
724 : /* -------------------------------------------------------------------- */
725 : /* If we weren't given a field name, drop all indexes. */
726 : /* -------------------------------------------------------------------- */
727 : OGRErr eErr;
728 :
729 2 : if( CSLCount(papszTokens) == 4 )
730 : {
731 0 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
732 : {
733 : OGRAttrIndex *poAttrIndex;
734 :
735 0 : poAttrIndex = poLayer->GetIndex()->GetFieldIndex(i);
736 0 : if( poAttrIndex != NULL )
737 : {
738 0 : eErr = poLayer->GetIndex()->DropIndex( i );
739 0 : if( eErr != OGRERR_NONE )
740 0 : return eErr;
741 : }
742 : }
743 :
744 0 : CSLDestroy(papszTokens);
745 0 : return OGRERR_NONE;
746 : }
747 :
748 : /* -------------------------------------------------------------------- */
749 : /* Find the named field. */
750 : /* -------------------------------------------------------------------- */
751 3 : for( i = 0; i < poLayer->GetLayerDefn()->GetFieldCount(); i++ )
752 : {
753 3 : if( EQUAL(papszTokens[5],
754 : poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()) )
755 2 : break;
756 : }
757 :
758 2 : CSLDestroy( papszTokens );
759 :
760 2 : if( i >= poLayer->GetLayerDefn()->GetFieldCount() )
761 : {
762 : CPLError( CE_Failure, CPLE_AppDefined,
763 : "`%s' failed, field not found.",
764 0 : pszSQLCommand );
765 0 : return OGRERR_FAILURE;
766 : }
767 :
768 : /* -------------------------------------------------------------------- */
769 : /* Attempt to drop the index. */
770 : /* -------------------------------------------------------------------- */
771 2 : eErr = poLayer->GetIndex()->DropIndex( i );
772 :
773 2 : return eErr;
774 : }
775 :
776 : /************************************************************************/
777 : /* ProcessSQLDropTable() */
778 : /* */
779 : /* The correct syntax for dropping a table (layer) in the OGR SQL */
780 : /* dialect is: */
781 : /* */
782 : /* DROP TABLE <layername> */
783 : /************************************************************************/
784 :
785 500 : OGRErr OGRDataSource::ProcessSQLDropTable( const char *pszSQLCommand )
786 :
787 : {
788 500 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
789 :
790 : /* -------------------------------------------------------------------- */
791 : /* Do some general syntax checking. */
792 : /* -------------------------------------------------------------------- */
793 1500 : if( CSLCount(papszTokens) != 3
794 500 : || !EQUAL(papszTokens[0],"DROP")
795 500 : || !EQUAL(papszTokens[1],"TABLE") )
796 : {
797 0 : CSLDestroy( papszTokens );
798 : CPLError( CE_Failure, CPLE_AppDefined,
799 : "Syntax error in DROP TABLE command.\n"
800 : "Was '%s'\n"
801 : "Should be of form 'DROP TABLE <table>'",
802 0 : pszSQLCommand );
803 0 : return OGRERR_FAILURE;
804 : }
805 :
806 : /* -------------------------------------------------------------------- */
807 : /* Find the named layer. */
808 : /* -------------------------------------------------------------------- */
809 : int i;
810 500 : OGRLayer *poLayer=NULL;
811 :
812 40199 : for( i = 0; i < GetLayerCount(); i++ )
813 : {
814 40199 : poLayer = GetLayer(i);
815 :
816 40199 : if( EQUAL(poLayer->GetName(),papszTokens[2]) )
817 500 : break;
818 : }
819 :
820 500 : if( i >= GetLayerCount() )
821 : {
822 : CPLError( CE_Failure, CPLE_AppDefined,
823 : "DROP TABLE failed, no such layer as `%s'.",
824 0 : papszTokens[2] );
825 0 : CSLDestroy( papszTokens );
826 0 : return OGRERR_FAILURE;
827 : }
828 :
829 500 : CSLDestroy( papszTokens );
830 :
831 : /* -------------------------------------------------------------------- */
832 : /* Delete it. */
833 : /* -------------------------------------------------------------------- */
834 :
835 500 : return DeleteLayer( i );
836 : }
837 :
838 : /************************************************************************/
839 : /* OGRDataSourceParseSQLType() */
840 : /************************************************************************/
841 :
842 : /* All arguments will be altered */
843 6 : static OGRFieldType OGRDataSourceParseSQLType(char* pszType, int& nWidth, int &nPrecision)
844 : {
845 6 : char* pszParenthesis = strchr(pszType, '(');
846 6 : if (pszParenthesis)
847 : {
848 4 : nWidth = atoi(pszParenthesis + 1);
849 4 : *pszParenthesis = '\0';
850 4 : char* pszComma = strchr(pszParenthesis + 1, ',');
851 4 : if (pszComma)
852 2 : nPrecision = atoi(pszComma + 1);
853 : }
854 :
855 6 : OGRFieldType eType = OFTString;
856 6 : if (EQUAL(pszType, "INTEGER"))
857 0 : eType = OFTInteger;
858 6 : else if (EQUAL(pszType, "INTEGER[]"))
859 0 : eType = OFTIntegerList;
860 8 : else if (EQUAL(pszType, "FLOAT") ||
861 : EQUAL(pszType, "NUMERIC") ||
862 : EQUAL(pszType, "DOUBLE") /* unofficial alias */ ||
863 : EQUAL(pszType, "REAL") /* unofficial alias */)
864 2 : eType = OFTReal;
865 4 : else if (EQUAL(pszType, "FLOAT[]") ||
866 : EQUAL(pszType, "NUMERIC[]") ||
867 : EQUAL(pszType, "DOUBLE[]") /* unofficial alias */ ||
868 : EQUAL(pszType, "REAL[]") /* unofficial alias */)
869 0 : eType = OFTRealList;
870 8 : else if (EQUAL(pszType, "CHARACTER") ||
871 : EQUAL(pszType, "TEXT") /* unofficial alias */ ||
872 : EQUAL(pszType, "STRING") /* unofficial alias */ ||
873 : EQUAL(pszType, "VARCHAR") /* unofficial alias */)
874 4 : eType = OFTString;
875 0 : else if (EQUAL(pszType, "TEXT[]") ||
876 : EQUAL(pszType, "STRING[]") /* unofficial alias */||
877 : EQUAL(pszType, "VARCHAR[]") /* unofficial alias */)
878 0 : eType = OFTStringList;
879 0 : else if (EQUAL(pszType, "DATE"))
880 0 : eType = OFTDate;
881 0 : else if (EQUAL(pszType, "TIME"))
882 0 : eType = OFTTime;
883 0 : else if (EQUAL(pszType, "TIMESTAMP") ||
884 : EQUAL(pszType, "DATETIME") /* unofficial alias */ )
885 0 : eType = OFTDateTime;
886 : else
887 : {
888 : CPLError(CE_Warning, CPLE_NotSupported,
889 : "Unsupported column type '%s'. Defaulting to VARCHAR",
890 0 : pszType);
891 : }
892 6 : return eType;
893 : }
894 :
895 : /************************************************************************/
896 : /* ProcessSQLAlterTableAddColumn() */
897 : /* */
898 : /* The correct syntax for adding a column in the OGR SQL */
899 : /* dialect is: */
900 : /* */
901 : /* ALTER TABLE <layername> ADD [COLUMN] <columnname> <columntype>*/
902 : /************************************************************************/
903 :
904 2 : OGRErr OGRDataSource::ProcessSQLAlterTableAddColumn( const char *pszSQLCommand )
905 :
906 : {
907 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
908 :
909 : /* -------------------------------------------------------------------- */
910 : /* Do some general syntax checking. */
911 : /* -------------------------------------------------------------------- */
912 2 : const char* pszLayerName = NULL;
913 2 : const char* pszColumnName = NULL;
914 2 : char* pszType = NULL;
915 2 : int iTypeIndex = 0;
916 2 : int nTokens = CSLCount(papszTokens);
917 :
918 11 : if( nTokens >= 7
919 2 : && EQUAL(papszTokens[0],"ALTER")
920 2 : && EQUAL(papszTokens[1],"TABLE")
921 2 : && EQUAL(papszTokens[3],"ADD")
922 2 : && EQUAL(papszTokens[4],"COLUMN"))
923 : {
924 1 : pszLayerName = papszTokens[2];
925 1 : pszColumnName = papszTokens[5];
926 1 : iTypeIndex = 6;
927 : }
928 5 : else if( nTokens >= 6
929 1 : && EQUAL(papszTokens[0],"ALTER")
930 1 : && EQUAL(papszTokens[1],"TABLE")
931 1 : && EQUAL(papszTokens[3],"ADD"))
932 : {
933 1 : pszLayerName = papszTokens[2];
934 1 : pszColumnName = papszTokens[4];
935 1 : iTypeIndex = 5;
936 : }
937 : else
938 : {
939 0 : CSLDestroy( papszTokens );
940 : CPLError( CE_Failure, CPLE_AppDefined,
941 : "Syntax error in ALTER TABLE ADD COLUMN command.\n"
942 : "Was '%s'\n"
943 : "Should be of form 'ALTER TABLE <layername> ADD [COLUMN] <columnname> <columntype>'",
944 0 : pszSQLCommand );
945 0 : return OGRERR_FAILURE;
946 : }
947 :
948 : /* -------------------------------------------------------------------- */
949 : /* Merge type components into a single string if there were split */
950 : /* with spaces */
951 : /* -------------------------------------------------------------------- */
952 2 : CPLString osType;
953 6 : for(int i=iTypeIndex;i<nTokens;i++)
954 : {
955 4 : osType += papszTokens[i];
956 4 : CPLFree(papszTokens[i]);
957 : }
958 2 : pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
959 2 : papszTokens[iTypeIndex + 1] = NULL;
960 :
961 : /* -------------------------------------------------------------------- */
962 : /* Find the named layer. */
963 : /* -------------------------------------------------------------------- */
964 2 : OGRLayer *poLayer = GetLayerByName(pszLayerName);
965 2 : if( poLayer == NULL )
966 : {
967 : CPLError( CE_Failure, CPLE_AppDefined,
968 : "%s failed, no such layer as `%s'.",
969 : pszSQLCommand,
970 0 : pszLayerName );
971 0 : CSLDestroy( papszTokens );
972 0 : return OGRERR_FAILURE;
973 : }
974 :
975 : /* -------------------------------------------------------------------- */
976 : /* Add column. */
977 : /* -------------------------------------------------------------------- */
978 :
979 2 : int nWidth = 0, nPrecision = 0;
980 2 : OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
981 2 : OGRFieldDefn oFieldDefn(pszColumnName, eType);
982 2 : oFieldDefn.SetWidth(nWidth);
983 2 : oFieldDefn.SetPrecision(nPrecision);
984 :
985 2 : CSLDestroy( papszTokens );
986 :
987 2 : return poLayer->CreateField( &oFieldDefn );
988 : }
989 :
990 : /************************************************************************/
991 : /* ProcessSQLAlterTableDropColumn() */
992 : /* */
993 : /* The correct syntax for droping a column in the OGR SQL */
994 : /* dialect is: */
995 : /* */
996 : /* ALTER TABLE <layername> DROP [COLUMN] <columnname> */
997 : /************************************************************************/
998 :
999 2 : OGRErr OGRDataSource::ProcessSQLAlterTableDropColumn( const char *pszSQLCommand )
1000 :
1001 : {
1002 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
1003 :
1004 : /* -------------------------------------------------------------------- */
1005 : /* Do some general syntax checking. */
1006 : /* -------------------------------------------------------------------- */
1007 2 : const char* pszLayerName = NULL;
1008 2 : const char* pszColumnName = NULL;
1009 6 : if( CSLCount(papszTokens) == 6
1010 1 : && EQUAL(papszTokens[0],"ALTER")
1011 1 : && EQUAL(papszTokens[1],"TABLE")
1012 1 : && EQUAL(papszTokens[3],"DROP")
1013 1 : && EQUAL(papszTokens[4],"COLUMN"))
1014 : {
1015 1 : pszLayerName = papszTokens[2];
1016 1 : pszColumnName = papszTokens[5];
1017 : }
1018 4 : else if( CSLCount(papszTokens) == 5
1019 1 : && EQUAL(papszTokens[0],"ALTER")
1020 1 : && EQUAL(papszTokens[1],"TABLE")
1021 1 : && EQUAL(papszTokens[3],"DROP"))
1022 : {
1023 1 : pszLayerName = papszTokens[2];
1024 1 : pszColumnName = papszTokens[4];
1025 : }
1026 : else
1027 : {
1028 0 : CSLDestroy( papszTokens );
1029 : CPLError( CE_Failure, CPLE_AppDefined,
1030 : "Syntax error in ALTER TABLE DROP COLUMN command.\n"
1031 : "Was '%s'\n"
1032 : "Should be of form 'ALTER TABLE <layername> DROP [COLUMN] <columnname>'",
1033 0 : pszSQLCommand );
1034 0 : return OGRERR_FAILURE;
1035 : }
1036 :
1037 : /* -------------------------------------------------------------------- */
1038 : /* Find the named layer. */
1039 : /* -------------------------------------------------------------------- */
1040 2 : OGRLayer *poLayer = GetLayerByName(pszLayerName);
1041 2 : if( poLayer == NULL )
1042 : {
1043 : CPLError( CE_Failure, CPLE_AppDefined,
1044 : "%s failed, no such layer as `%s'.",
1045 : pszSQLCommand,
1046 0 : pszLayerName );
1047 0 : CSLDestroy( papszTokens );
1048 0 : return OGRERR_FAILURE;
1049 : }
1050 :
1051 : /* -------------------------------------------------------------------- */
1052 : /* Find the field. */
1053 : /* -------------------------------------------------------------------- */
1054 :
1055 2 : int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
1056 2 : if( nFieldIndex < 0 )
1057 : {
1058 : CPLError( CE_Failure, CPLE_AppDefined,
1059 : "%s failed, no such field as `%s'.",
1060 : pszSQLCommand,
1061 0 : pszColumnName );
1062 0 : CSLDestroy( papszTokens );
1063 0 : return OGRERR_FAILURE;
1064 : }
1065 :
1066 :
1067 : /* -------------------------------------------------------------------- */
1068 : /* Remove it. */
1069 : /* -------------------------------------------------------------------- */
1070 :
1071 2 : CSLDestroy( papszTokens );
1072 :
1073 2 : return poLayer->DeleteField( nFieldIndex );
1074 : }
1075 :
1076 : /************************************************************************/
1077 : /* ProcessSQLAlterTableRenameColumn() */
1078 : /* */
1079 : /* The correct syntax for renaming a column in the OGR SQL */
1080 : /* dialect is: */
1081 : /* */
1082 : /* ALTER TABLE <layername> RENAME [COLUMN] <oldname> TO <newname> */
1083 : /************************************************************************/
1084 :
1085 2 : OGRErr OGRDataSource::ProcessSQLAlterTableRenameColumn( const char *pszSQLCommand )
1086 :
1087 : {
1088 2 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
1089 :
1090 : /* -------------------------------------------------------------------- */
1091 : /* Do some general syntax checking. */
1092 : /* -------------------------------------------------------------------- */
1093 2 : const char* pszLayerName = NULL;
1094 2 : const char* pszOldColName = NULL;
1095 2 : const char* pszNewColName = NULL;
1096 7 : if( CSLCount(papszTokens) == 8
1097 1 : && EQUAL(papszTokens[0],"ALTER")
1098 1 : && EQUAL(papszTokens[1],"TABLE")
1099 1 : && EQUAL(papszTokens[3],"RENAME")
1100 1 : && EQUAL(papszTokens[4],"COLUMN")
1101 1 : && EQUAL(papszTokens[6],"TO"))
1102 : {
1103 1 : pszLayerName = papszTokens[2];
1104 1 : pszOldColName = papszTokens[5];
1105 1 : pszNewColName = papszTokens[7];
1106 : }
1107 5 : else if( CSLCount(papszTokens) == 7
1108 1 : && EQUAL(papszTokens[0],"ALTER")
1109 1 : && EQUAL(papszTokens[1],"TABLE")
1110 1 : && EQUAL(papszTokens[3],"RENAME")
1111 1 : && EQUAL(papszTokens[5],"TO"))
1112 : {
1113 1 : pszLayerName = papszTokens[2];
1114 1 : pszOldColName = papszTokens[4];
1115 1 : pszNewColName = papszTokens[6];
1116 : }
1117 : else
1118 : {
1119 0 : CSLDestroy( papszTokens );
1120 : CPLError( CE_Failure, CPLE_AppDefined,
1121 : "Syntax error in ALTER TABLE RENAME COLUMN command.\n"
1122 : "Was '%s'\n"
1123 : "Should be of form 'ALTER TABLE <layername> RENAME [COLUMN] <columnname> TO <newname>'",
1124 0 : pszSQLCommand );
1125 0 : return OGRERR_FAILURE;
1126 : }
1127 :
1128 : /* -------------------------------------------------------------------- */
1129 : /* Find the named layer. */
1130 : /* -------------------------------------------------------------------- */
1131 2 : OGRLayer *poLayer = GetLayerByName(pszLayerName);
1132 2 : if( poLayer == NULL )
1133 : {
1134 : CPLError( CE_Failure, CPLE_AppDefined,
1135 : "%s failed, no such layer as `%s'.",
1136 : pszSQLCommand,
1137 0 : pszLayerName );
1138 0 : CSLDestroy( papszTokens );
1139 0 : return OGRERR_FAILURE;
1140 : }
1141 :
1142 : /* -------------------------------------------------------------------- */
1143 : /* Find the field. */
1144 : /* -------------------------------------------------------------------- */
1145 :
1146 2 : int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszOldColName);
1147 2 : if( nFieldIndex < 0 )
1148 : {
1149 : CPLError( CE_Failure, CPLE_AppDefined,
1150 : "%s failed, no such field as `%s'.",
1151 : pszSQLCommand,
1152 0 : pszOldColName );
1153 0 : CSLDestroy( papszTokens );
1154 0 : return OGRERR_FAILURE;
1155 : }
1156 :
1157 : /* -------------------------------------------------------------------- */
1158 : /* Rename column. */
1159 : /* -------------------------------------------------------------------- */
1160 2 : OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
1161 2 : OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
1162 2 : oNewFieldDefn.SetName(pszNewColName);
1163 :
1164 2 : CSLDestroy( papszTokens );
1165 :
1166 2 : return poLayer->AlterFieldDefn( nFieldIndex, &oNewFieldDefn, ALTER_NAME_FLAG );
1167 : }
1168 :
1169 : /************************************************************************/
1170 : /* ProcessSQLAlterTableAlterColumn() */
1171 : /* */
1172 : /* The correct syntax for altering the type of a column in the */
1173 : /* OGR SQL dialect is: */
1174 : /* */
1175 : /* ALTER TABLE <layername> ALTER [COLUMN] <columnname> TYPE <newtype> */
1176 : /************************************************************************/
1177 :
1178 4 : OGRErr OGRDataSource::ProcessSQLAlterTableAlterColumn( const char *pszSQLCommand )
1179 :
1180 : {
1181 4 : char **papszTokens = CSLTokenizeString( pszSQLCommand );
1182 :
1183 : /* -------------------------------------------------------------------- */
1184 : /* Do some general syntax checking. */
1185 : /* -------------------------------------------------------------------- */
1186 4 : const char* pszLayerName = NULL;
1187 4 : const char* pszColumnName = NULL;
1188 4 : char* pszType = NULL;
1189 4 : int iTypeIndex = 0;
1190 4 : int nTokens = CSLCount(papszTokens);
1191 :
1192 16 : if( nTokens >= 8
1193 2 : && EQUAL(papszTokens[0],"ALTER")
1194 2 : && EQUAL(papszTokens[1],"TABLE")
1195 2 : && EQUAL(papszTokens[3],"ALTER")
1196 2 : && EQUAL(papszTokens[4],"COLUMN")
1197 2 : && EQUAL(papszTokens[6],"TYPE"))
1198 : {
1199 2 : pszLayerName = papszTokens[2];
1200 2 : pszColumnName = papszTokens[5];
1201 2 : iTypeIndex = 7;
1202 : }
1203 12 : else if( nTokens >= 7
1204 2 : && EQUAL(papszTokens[0],"ALTER")
1205 2 : && EQUAL(papszTokens[1],"TABLE")
1206 2 : && EQUAL(papszTokens[3],"ALTER")
1207 2 : && EQUAL(papszTokens[5],"TYPE"))
1208 : {
1209 2 : pszLayerName = papszTokens[2];
1210 2 : pszColumnName = papszTokens[4];
1211 2 : iTypeIndex = 6;
1212 : }
1213 : else
1214 : {
1215 0 : CSLDestroy( papszTokens );
1216 : CPLError( CE_Failure, CPLE_AppDefined,
1217 : "Syntax error in ALTER TABLE ALTER COLUMN command.\n"
1218 : "Was '%s'\n"
1219 : "Should be of form 'ALTER TABLE <layername> ALTER [COLUMN] <columnname> TYPE <columntype>'",
1220 0 : pszSQLCommand );
1221 0 : return OGRERR_FAILURE;
1222 : }
1223 :
1224 : /* -------------------------------------------------------------------- */
1225 : /* Merge type components into a single string if there were split */
1226 : /* with spaces */
1227 : /* -------------------------------------------------------------------- */
1228 4 : CPLString osType;
1229 8 : for(int i=iTypeIndex;i<nTokens;i++)
1230 : {
1231 4 : osType += papszTokens[i];
1232 4 : CPLFree(papszTokens[i]);
1233 : }
1234 4 : pszType = papszTokens[iTypeIndex] = CPLStrdup(osType);
1235 4 : papszTokens[iTypeIndex + 1] = NULL;
1236 :
1237 : /* -------------------------------------------------------------------- */
1238 : /* Find the named layer. */
1239 : /* -------------------------------------------------------------------- */
1240 4 : OGRLayer *poLayer = GetLayerByName(pszLayerName);
1241 4 : if( poLayer == NULL )
1242 : {
1243 : CPLError( CE_Failure, CPLE_AppDefined,
1244 : "%s failed, no such layer as `%s'.",
1245 : pszSQLCommand,
1246 0 : pszLayerName );
1247 0 : CSLDestroy( papszTokens );
1248 0 : return OGRERR_FAILURE;
1249 : }
1250 :
1251 : /* -------------------------------------------------------------------- */
1252 : /* Find the field. */
1253 : /* -------------------------------------------------------------------- */
1254 :
1255 4 : int nFieldIndex = poLayer->GetLayerDefn()->GetFieldIndex(pszColumnName);
1256 4 : if( nFieldIndex < 0 )
1257 : {
1258 : CPLError( CE_Failure, CPLE_AppDefined,
1259 : "%s failed, no such field as `%s'.",
1260 : pszSQLCommand,
1261 0 : pszColumnName );
1262 0 : CSLDestroy( papszTokens );
1263 0 : return OGRERR_FAILURE;
1264 : }
1265 :
1266 : /* -------------------------------------------------------------------- */
1267 : /* Alter column. */
1268 : /* -------------------------------------------------------------------- */
1269 :
1270 4 : OGRFieldDefn* poOldFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(nFieldIndex);
1271 4 : OGRFieldDefn oNewFieldDefn(poOldFieldDefn);
1272 :
1273 4 : int nWidth = 0, nPrecision = 0;
1274 4 : OGRFieldType eType = OGRDataSourceParseSQLType(pszType, nWidth, nPrecision);
1275 4 : oNewFieldDefn.SetType(eType);
1276 4 : oNewFieldDefn.SetWidth(nWidth);
1277 4 : oNewFieldDefn.SetPrecision(nPrecision);
1278 :
1279 4 : int nFlags = 0;
1280 4 : if (poOldFieldDefn->GetType() != oNewFieldDefn.GetType())
1281 2 : nFlags |= ALTER_TYPE_FLAG;
1282 4 : if (poOldFieldDefn->GetWidth() != oNewFieldDefn.GetWidth() ||
1283 : poOldFieldDefn->GetPrecision() != oNewFieldDefn.GetPrecision())
1284 4 : nFlags |= ALTER_WIDTH_PRECISION_FLAG;
1285 :
1286 4 : CSLDestroy( papszTokens );
1287 :
1288 4 : if (nFlags == 0)
1289 0 : return OGRERR_NONE;
1290 : else
1291 4 : return poLayer->AlterFieldDefn( nFieldIndex, &oNewFieldDefn, nFlags );
1292 : }
1293 :
1294 : /************************************************************************/
1295 : /* ExecuteSQL() */
1296 : /************************************************************************/
1297 :
1298 1337 : OGRLayer * OGRDataSource::ExecuteSQL( const char *pszStatement,
1299 : OGRGeometry *poSpatialFilter,
1300 : const char *pszDialect )
1301 :
1302 : {
1303 1337 : swq_select *psSelectInfo = NULL;
1304 :
1305 1337 : if( pszDialect != NULL && EQUAL(pszDialect, "SQLite") )
1306 : {
1307 : #ifdef SQLITE_ENABLED
1308 222 : return OGRSQLiteExecuteSQL( this, pszStatement, poSpatialFilter, pszDialect );
1309 : #else
1310 : CPLError(CE_Failure, CPLE_NotSupported,
1311 : "The SQLite driver needs to be compiled to support the SQLite SQL dialect");
1312 : return NULL;
1313 : #endif
1314 : }
1315 :
1316 : /* -------------------------------------------------------------------- */
1317 : /* Handle CREATE INDEX statements specially. */
1318 : /* -------------------------------------------------------------------- */
1319 1115 : if( EQUALN(pszStatement,"CREATE INDEX",12) )
1320 : {
1321 8 : ProcessSQLCreateIndex( pszStatement );
1322 8 : return NULL;
1323 : }
1324 :
1325 : /* -------------------------------------------------------------------- */
1326 : /* Handle DROP INDEX statements specially. */
1327 : /* -------------------------------------------------------------------- */
1328 1107 : if( EQUALN(pszStatement,"DROP INDEX",10) )
1329 : {
1330 2 : ProcessSQLDropIndex( pszStatement );
1331 2 : return NULL;
1332 : }
1333 :
1334 : /* -------------------------------------------------------------------- */
1335 : /* Handle DROP TABLE statements specially. */
1336 : /* -------------------------------------------------------------------- */
1337 1105 : if( EQUALN(pszStatement,"DROP TABLE",10) )
1338 : {
1339 500 : ProcessSQLDropTable( pszStatement );
1340 500 : return NULL;
1341 : }
1342 :
1343 : /* -------------------------------------------------------------------- */
1344 : /* Handle ALTER TABLE statements specially. */
1345 : /* -------------------------------------------------------------------- */
1346 605 : if( EQUALN(pszStatement,"ALTER TABLE",11) )
1347 : {
1348 10 : char **papszTokens = CSLTokenizeString( pszStatement );
1349 20 : if( CSLCount(papszTokens) >= 4 &&
1350 10 : EQUAL(papszTokens[3],"ADD") )
1351 : {
1352 2 : ProcessSQLAlterTableAddColumn( pszStatement );
1353 2 : CSLDestroy(papszTokens);
1354 2 : return NULL;
1355 : }
1356 16 : else if( CSLCount(papszTokens) >= 4 &&
1357 8 : EQUAL(papszTokens[3],"DROP") )
1358 : {
1359 2 : ProcessSQLAlterTableDropColumn( pszStatement );
1360 2 : CSLDestroy(papszTokens);
1361 2 : return NULL;
1362 : }
1363 12 : else if( CSLCount(papszTokens) >= 4 &&
1364 6 : EQUAL(papszTokens[3],"RENAME") )
1365 : {
1366 2 : ProcessSQLAlterTableRenameColumn( pszStatement );
1367 2 : CSLDestroy(papszTokens);
1368 2 : return NULL;
1369 : }
1370 8 : else if( CSLCount(papszTokens) >= 4 &&
1371 4 : EQUAL(papszTokens[3],"ALTER") )
1372 : {
1373 4 : ProcessSQLAlterTableAlterColumn( pszStatement );
1374 4 : CSLDestroy(papszTokens);
1375 4 : return NULL;
1376 : }
1377 : else
1378 : {
1379 : CPLError( CE_Failure, CPLE_AppDefined,
1380 : "Unsupported ALTER TABLE command : %s",
1381 0 : pszStatement );
1382 0 : CSLDestroy(papszTokens);
1383 0 : return NULL;
1384 : }
1385 : }
1386 :
1387 : /* -------------------------------------------------------------------- */
1388 : /* Preparse the SQL statement. */
1389 : /* -------------------------------------------------------------------- */
1390 595 : psSelectInfo = new swq_select();
1391 595 : if( psSelectInfo->preparse( pszStatement ) != CPLE_None )
1392 : {
1393 121 : delete psSelectInfo;
1394 121 : return NULL;
1395 : }
1396 :
1397 : /* -------------------------------------------------------------------- */
1398 : /* If there is no UNION ALL, build result layer. */
1399 : /* -------------------------------------------------------------------- */
1400 474 : if( psSelectInfo->poOtherSelect == NULL )
1401 : {
1402 : return BuildLayerFromSelectInfo(psSelectInfo,
1403 : poSpatialFilter,
1404 472 : pszDialect);
1405 : }
1406 :
1407 : /* -------------------------------------------------------------------- */
1408 : /* Build result union layer. */
1409 : /* -------------------------------------------------------------------- */
1410 2 : int nSrcLayers = 0;
1411 2 : OGRLayer** papoSrcLayers = NULL;
1412 :
1413 4 : do
1414 : {
1415 4 : swq_select* psNextSelectInfo = psSelectInfo->poOtherSelect;
1416 4 : psSelectInfo->poOtherSelect = NULL;
1417 :
1418 : OGRLayer* poLayer = BuildLayerFromSelectInfo(psSelectInfo,
1419 : poSpatialFilter,
1420 4 : pszDialect);
1421 4 : if( poLayer == NULL )
1422 : {
1423 : /* Each source layer owns an independant select info */
1424 0 : for(int i=0;i<nSrcLayers;i++)
1425 0 : delete papoSrcLayers[i];
1426 0 : CPLFree(papoSrcLayers);
1427 :
1428 : /* So we just have to destroy the remaining select info */
1429 0 : delete psNextSelectInfo;
1430 :
1431 0 : return NULL;
1432 : }
1433 : else
1434 : {
1435 : papoSrcLayers = (OGRLayer**) CPLRealloc(papoSrcLayers,
1436 4 : sizeof(OGRLayer*) * (nSrcLayers + 1));
1437 4 : papoSrcLayers[nSrcLayers] = poLayer;
1438 4 : nSrcLayers ++;
1439 :
1440 4 : psSelectInfo = psNextSelectInfo;
1441 : }
1442 : }
1443 : while( psSelectInfo != NULL );
1444 :
1445 : return new OGRUnionLayer("SELECT",
1446 : nSrcLayers,
1447 : papoSrcLayers,
1448 2 : TRUE);
1449 : }
1450 :
1451 : /************************************************************************/
1452 : /* BuildLayerFromSelectInfo() */
1453 : /************************************************************************/
1454 :
1455 476 : OGRLayer* OGRDataSource::BuildLayerFromSelectInfo(void* psSelectInfoIn,
1456 : OGRGeometry *poSpatialFilter,
1457 : const char *pszDialect)
1458 : {
1459 476 : swq_select* psSelectInfo = (swq_select*) psSelectInfoIn;
1460 :
1461 : swq_field_list sFieldList;
1462 476 : int nFIDIndex = 0;
1463 476 : OGRGenSQLResultsLayer *poResults = NULL;
1464 476 : char *pszWHERE = NULL;
1465 :
1466 476 : memset( &sFieldList, 0, sizeof(sFieldList) );
1467 :
1468 : /* -------------------------------------------------------------------- */
1469 : /* Validate that all the source tables are recognised, count */
1470 : /* fields. */
1471 : /* -------------------------------------------------------------------- */
1472 476 : int nFieldCount = 0, iTable, iField;
1473 : int iEDS;
1474 476 : int nExtraDSCount = 0;
1475 476 : OGRDataSource** papoExtraDS = NULL;
1476 476 : OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
1477 :
1478 970 : for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
1479 : {
1480 499 : swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
1481 : OGRLayer *poSrcLayer;
1482 499 : OGRDataSource *poTableDS = this;
1483 :
1484 499 : if( psTableDef->data_source != NULL )
1485 : {
1486 : poTableDS = (OGRDataSource *)
1487 5 : OGROpenShared( psTableDef->data_source, FALSE, NULL );
1488 5 : if( poTableDS == NULL )
1489 : {
1490 0 : if( strlen(CPLGetLastErrorMsg()) == 0 )
1491 : CPLError( CE_Failure, CPLE_AppDefined,
1492 : "Unable to open secondary datasource\n"
1493 : "`%s' required by JOIN.",
1494 0 : psTableDef->data_source );
1495 :
1496 0 : delete psSelectInfo;
1497 0 : goto end;
1498 : }
1499 :
1500 : /* Keep in an array to release at the end of this function */
1501 : papoExtraDS = (OGRDataSource** )CPLRealloc(papoExtraDS,
1502 5 : sizeof(OGRDataSource*) * (nExtraDSCount + 1));
1503 5 : papoExtraDS[nExtraDSCount++] = poTableDS;
1504 : }
1505 :
1506 499 : poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
1507 :
1508 499 : if( poSrcLayer == NULL )
1509 : {
1510 : CPLError( CE_Failure, CPLE_AppDefined,
1511 : "SELECT from table %s failed, no such table/featureclass.",
1512 5 : psTableDef->table_name );
1513 5 : delete psSelectInfo;
1514 5 : goto end;
1515 : }
1516 :
1517 494 : nFieldCount += poSrcLayer->GetLayerDefn()->GetFieldCount();
1518 : }
1519 :
1520 : /* -------------------------------------------------------------------- */
1521 : /* Build the field list for all indicated tables. */
1522 : /* -------------------------------------------------------------------- */
1523 :
1524 471 : sFieldList.table_count = psSelectInfo->table_count;
1525 471 : sFieldList.table_defs = psSelectInfo->table_defs;
1526 :
1527 471 : sFieldList.count = 0;
1528 471 : sFieldList.names = (char **) CPLMalloc( sizeof(char *) * (nFieldCount+SPECIAL_FIELD_COUNT) );
1529 : sFieldList.types = (swq_field_type *)
1530 471 : CPLMalloc( sizeof(swq_field_type) * (nFieldCount+SPECIAL_FIELD_COUNT) );
1531 : sFieldList.table_ids = (int *)
1532 471 : CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
1533 : sFieldList.ids = (int *)
1534 471 : CPLMalloc( sizeof(int) * (nFieldCount+SPECIAL_FIELD_COUNT) );
1535 :
1536 964 : for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
1537 : {
1538 493 : swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
1539 493 : OGRDataSource *poTableDS = this;
1540 : OGRLayer *poSrcLayer;
1541 :
1542 493 : if( psTableDef->data_source != NULL )
1543 : {
1544 : poTableDS = (OGRDataSource *)
1545 5 : OGROpenShared( psTableDef->data_source, FALSE, NULL );
1546 5 : CPLAssert( poTableDS != NULL );
1547 5 : poTableDS->Dereference();
1548 : }
1549 :
1550 493 : poSrcLayer = poTableDS->GetLayerByName( psTableDef->table_name );
1551 :
1552 5922 : for( iField = 0;
1553 2961 : iField < poSrcLayer->GetLayerDefn()->GetFieldCount();
1554 : iField++ )
1555 : {
1556 2468 : OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField);
1557 2468 : int iOutField = sFieldList.count++;
1558 2468 : sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef();
1559 2468 : if( poFDefn->GetType() == OFTInteger )
1560 694 : sFieldList.types[iOutField] = SWQ_INTEGER;
1561 1774 : else if( poFDefn->GetType() == OFTReal )
1562 530 : sFieldList.types[iOutField] = SWQ_FLOAT;
1563 1244 : else if( poFDefn->GetType() == OFTString )
1564 1155 : sFieldList.types[iOutField] = SWQ_STRING;
1565 : else
1566 89 : sFieldList.types[iOutField] = SWQ_OTHER;
1567 :
1568 2468 : sFieldList.table_ids[iOutField] = iTable;
1569 2468 : sFieldList.ids[iOutField] = iField;
1570 : }
1571 :
1572 493 : if( iTable == 0 )
1573 471 : nFIDIndex = poSrcLayer->GetLayerDefn()->GetFieldCount();
1574 : }
1575 :
1576 : /* -------------------------------------------------------------------- */
1577 : /* Expand '*' in 'SELECT *' now before we add the pseudo fields */
1578 : /* -------------------------------------------------------------------- */
1579 471 : if( psSelectInfo->expand_wildcard( &sFieldList ) != CE_None )
1580 : {
1581 0 : delete psSelectInfo;
1582 0 : goto end;
1583 : }
1584 :
1585 2826 : for (iField = 0; iField < SPECIAL_FIELD_COUNT; iField++)
1586 : {
1587 2355 : sFieldList.names[sFieldList.count] = (char*) SpecialFieldNames[iField];
1588 2355 : sFieldList.types[sFieldList.count] = SpecialFieldTypes[iField];
1589 2355 : sFieldList.table_ids[sFieldList.count] = 0;
1590 2355 : sFieldList.ids[sFieldList.count] = nFIDIndex + iField;
1591 2355 : sFieldList.count++;
1592 : }
1593 :
1594 : /* -------------------------------------------------------------------- */
1595 : /* Finish the parse operation. */
1596 : /* -------------------------------------------------------------------- */
1597 471 : if( psSelectInfo->parse( &sFieldList, 0 ) != CE_None )
1598 : {
1599 24 : delete psSelectInfo;
1600 24 : goto end;
1601 : }
1602 :
1603 : /* -------------------------------------------------------------------- */
1604 : /* Extract the WHERE expression to use separately. */
1605 : /* -------------------------------------------------------------------- */
1606 447 : if( psSelectInfo->where_expr != NULL )
1607 : {
1608 831 : if (m_poDriver && (
1609 277 : EQUAL(m_poDriver->GetName(), "PostgreSQL") ||
1610 277 : EQUAL(m_poDriver->GetName(), "FileGDB" )) )
1611 16 : pszWHERE = psSelectInfo->where_expr->Unparse( &sFieldList, '"' );
1612 : else
1613 261 : pszWHERE = psSelectInfo->where_expr->Unparse( &sFieldList, '\'' );
1614 : //CPLDebug( "OGR", "Unparse() -> %s", pszWHERE );
1615 : }
1616 :
1617 : /* -------------------------------------------------------------------- */
1618 : /* Everything seems OK, try to instantiate a results layer. */
1619 : /* -------------------------------------------------------------------- */
1620 :
1621 : poResults = new OGRGenSQLResultsLayer( this, psSelectInfo,
1622 : poSpatialFilter,
1623 : pszWHERE,
1624 447 : pszDialect );
1625 :
1626 447 : CPLFree( pszWHERE );
1627 :
1628 : // Eventually, we should keep track of layers to cleanup.
1629 :
1630 : end:
1631 476 : CPLFree( sFieldList.names );
1632 476 : CPLFree( sFieldList.types );
1633 476 : CPLFree( sFieldList.table_ids );
1634 476 : CPLFree( sFieldList.ids );
1635 :
1636 : /* Release the datasets we have opened with OGROpenShared() */
1637 : /* It is safe to do that as the 'new OGRGenSQLResultsLayer' itself */
1638 : /* has taken a reference on them, which it will release in its */
1639 : /* destructor */
1640 481 : for(iEDS = 0; iEDS < nExtraDSCount; iEDS++)
1641 5 : poReg->ReleaseDataSource( papoExtraDS[iEDS] );
1642 476 : CPLFree(papoExtraDS);
1643 :
1644 476 : return poResults;
1645 : }
1646 :
1647 : /************************************************************************/
1648 : /* OGR_DS_ExecuteSQL() */
1649 : /************************************************************************/
1650 :
1651 2139 : OGRLayerH OGR_DS_ExecuteSQL( OGRDataSourceH hDS,
1652 : const char *pszStatement,
1653 : OGRGeometryH hSpatialFilter,
1654 : const char *pszDialect )
1655 :
1656 : {
1657 2139 : VALIDATE_POINTER1( hDS, "OGR_DS_ExecuteSQL", NULL );
1658 :
1659 : return (OGRLayerH)
1660 : ((OGRDataSource *)hDS)->ExecuteSQL( pszStatement,
1661 : (OGRGeometry *) hSpatialFilter,
1662 2139 : pszDialect );
1663 : }
1664 :
1665 : /************************************************************************/
1666 : /* ReleaseResultSet() */
1667 : /************************************************************************/
1668 :
1669 610 : void OGRDataSource::ReleaseResultSet( OGRLayer * poResultsSet )
1670 :
1671 : {
1672 610 : delete poResultsSet;
1673 610 : }
1674 :
1675 : /************************************************************************/
1676 : /* OGR_DS_ReleaseResultSet() */
1677 : /************************************************************************/
1678 :
1679 1008 : void OGR_DS_ReleaseResultSet( OGRDataSourceH hDS, OGRLayerH hLayer )
1680 :
1681 : {
1682 1008 : VALIDATE_POINTER0( hDS, "OGR_DS_ReleaseResultSet" );
1683 :
1684 1008 : ((OGRDataSource *) hDS)->ReleaseResultSet( (OGRLayer *) hLayer );
1685 : }
1686 :
1687 : /************************************************************************/
1688 : /* OGR_DS_TestCapability() */
1689 : /************************************************************************/
1690 :
1691 54 : int OGR_DS_TestCapability( OGRDataSourceH hDS, const char *pszCap )
1692 :
1693 : {
1694 54 : VALIDATE_POINTER1( hDS, "OGR_DS_TestCapability", 0 );
1695 54 : VALIDATE_POINTER1( pszCap, "OGR_DS_TestCapability", 0 );
1696 :
1697 54 : return ((OGRDataSource *) hDS)->TestCapability( pszCap );
1698 : }
1699 :
1700 : /************************************************************************/
1701 : /* OGR_DS_GetLayerCount() */
1702 : /************************************************************************/
1703 :
1704 260 : int OGR_DS_GetLayerCount( OGRDataSourceH hDS )
1705 :
1706 : {
1707 260 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayerCount", 0 );
1708 :
1709 260 : return ((OGRDataSource *)hDS)->GetLayerCount();
1710 : }
1711 :
1712 : /************************************************************************/
1713 : /* OGR_DS_GetLayer() */
1714 : /************************************************************************/
1715 :
1716 5083 : OGRLayerH OGR_DS_GetLayer( OGRDataSourceH hDS, int iLayer )
1717 :
1718 : {
1719 5083 : VALIDATE_POINTER1( hDS, "OGR_DS_GetLayer", NULL );
1720 :
1721 5083 : return (OGRLayerH) ((OGRDataSource*)hDS)->GetLayer( iLayer );
1722 : }
1723 :
1724 : /************************************************************************/
1725 : /* OGR_DS_GetName() */
1726 : /************************************************************************/
1727 :
1728 31 : const char *OGR_DS_GetName( OGRDataSourceH hDS )
1729 :
1730 : {
1731 31 : VALIDATE_POINTER1( hDS, "OGR_DS_GetName", NULL );
1732 :
1733 31 : return ((OGRDataSource*)hDS)->GetName();
1734 : }
1735 :
1736 : /************************************************************************/
1737 : /* SyncToDisk() */
1738 : /************************************************************************/
1739 :
1740 0 : OGRErr OGRDataSource::SyncToDisk()
1741 :
1742 : {
1743 0 : CPLMutexHolderD( &m_hMutex );
1744 : int i;
1745 : OGRErr eErr;
1746 :
1747 0 : for( i = 0; i < GetLayerCount(); i++ )
1748 : {
1749 0 : OGRLayer *poLayer = GetLayer(i);
1750 :
1751 0 : if( poLayer )
1752 : {
1753 0 : eErr = poLayer->SyncToDisk();
1754 0 : if( eErr != OGRERR_NONE )
1755 0 : return eErr;
1756 : }
1757 : }
1758 :
1759 0 : return OGRERR_NONE;
1760 : }
1761 :
1762 : /************************************************************************/
1763 : /* OGR_DS_SyncToDisk() */
1764 : /************************************************************************/
1765 :
1766 0 : OGRErr OGR_DS_SyncToDisk( OGRDataSourceH hDS )
1767 :
1768 : {
1769 0 : VALIDATE_POINTER1( hDS, "OGR_DS_SyncToDisk", OGRERR_INVALID_HANDLE );
1770 :
1771 0 : return ((OGRDataSource *) hDS)->SyncToDisk();
1772 : }
1773 :
1774 : /************************************************************************/
1775 : /* GetDriver() */
1776 : /************************************************************************/
1777 :
1778 4395 : OGRSFDriver *OGRDataSource::GetDriver() const
1779 :
1780 : {
1781 4395 : return m_poDriver;
1782 : }
1783 :
1784 : /************************************************************************/
1785 : /* OGR_DS_GetDriver() */
1786 : /************************************************************************/
1787 :
1788 110 : OGRSFDriverH OGR_DS_GetDriver( OGRDataSourceH hDS )
1789 :
1790 : {
1791 110 : VALIDATE_POINTER1( hDS, "OGR_DS_GetDriver", NULL );
1792 :
1793 110 : return (OGRSFDriverH) ((OGRDataSource *) hDS)->GetDriver();
1794 : }
1795 :
1796 : /************************************************************************/
1797 : /* SetDriver() */
1798 : /************************************************************************/
1799 :
1800 586 : void OGRDataSource::SetDriver( OGRSFDriver *poDriver )
1801 :
1802 : {
1803 586 : m_poDriver = poDriver;
1804 586 : }
1805 :
1806 : /************************************************************************/
1807 : /* GetStyleTable() */
1808 : /************************************************************************/
1809 :
1810 83 : OGRStyleTable *OGRDataSource::GetStyleTable()
1811 : {
1812 83 : return m_poStyleTable;
1813 : }
1814 :
1815 : /************************************************************************/
1816 : /* SetStyleTableDirectly() */
1817 : /************************************************************************/
1818 :
1819 0 : void OGRDataSource::SetStyleTableDirectly( OGRStyleTable *poStyleTable )
1820 : {
1821 0 : if ( m_poStyleTable )
1822 0 : delete m_poStyleTable;
1823 0 : m_poStyleTable = poStyleTable;
1824 0 : }
1825 :
1826 : /************************************************************************/
1827 : /* SetStyleTable() */
1828 : /************************************************************************/
1829 :
1830 83 : void OGRDataSource::SetStyleTable(OGRStyleTable *poStyleTable)
1831 : {
1832 83 : if ( m_poStyleTable )
1833 0 : delete m_poStyleTable;
1834 83 : if ( poStyleTable )
1835 0 : m_poStyleTable = poStyleTable->Clone();
1836 83 : }
1837 :
1838 : /************************************************************************/
1839 : /* OGR_DS_GetStyleTable() */
1840 : /************************************************************************/
1841 :
1842 0 : OGRStyleTableH OGR_DS_GetStyleTable( OGRDataSourceH hDS )
1843 :
1844 : {
1845 0 : VALIDATE_POINTER1( hDS, "OGR_DS_GetStyleTable", NULL );
1846 :
1847 0 : return (OGRStyleTableH) ((OGRDataSource *) hDS)->GetStyleTable( );
1848 : }
1849 :
1850 : /************************************************************************/
1851 : /* OGR_DS_SetStyleTableDirectly() */
1852 : /************************************************************************/
1853 :
1854 0 : void OGR_DS_SetStyleTableDirectly( OGRDataSourceH hDS,
1855 : OGRStyleTableH hStyleTable )
1856 :
1857 : {
1858 0 : VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTableDirectly" );
1859 :
1860 0 : ((OGRDataSource *) hDS)->SetStyleTableDirectly( (OGRStyleTable *) hStyleTable);
1861 : }
1862 :
1863 : /************************************************************************/
1864 : /* OGR_DS_SetStyleTable() */
1865 : /************************************************************************/
1866 :
1867 0 : void OGR_DS_SetStyleTable( OGRDataSourceH hDS, OGRStyleTableH hStyleTable )
1868 :
1869 : {
1870 0 : VALIDATE_POINTER0( hDS, "OGR_DS_SetStyleTable" );
1871 0 : VALIDATE_POINTER0( hStyleTable, "OGR_DS_SetStyleTable" );
1872 :
1873 0 : ((OGRDataSource *) hDS)->SetStyleTable( (OGRStyleTable *) hStyleTable);
1874 : }
|