LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 336 211 62.8 %
Date: 2010-01-09 Functions: 40 26 65.0 %

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

Generated by: LCOV version 1.7