LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gft - ogrgftdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 243 184 75.7 %
Date: 2013-03-30 Functions: 19 16 84.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgftdatasource.cpp 25483 2013-01-10 17:06:59Z warmerdam $
       3                 :  *
       4                 :  * Project:  Google Fusion Table Translator
       5                 :  * Purpose:  Implements OGRGFTDataSource class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
      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 "ogr_gft.h"
      31                 : 
      32                 : CPL_CVSID("$Id: ogrgftdatasource.cpp 25483 2013-01-10 17:06:59Z warmerdam $");
      33                 : 
      34                 : #define GDAL_API_KEY "AIzaSyA_2h1_wXMOLHNSVeo-jf1ACME-M1XMgP0"
      35                 : #define FUSION_TABLE_SCOPE "https://www.googleapis.com/Fauth/fusiontables"
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                          OGRGFTDataSource()                          */
      39                 : /************************************************************************/
      40                 : 
      41             142 : OGRGFTDataSource::OGRGFTDataSource()
      42                 : 
      43                 : {
      44             142 :     papoLayers = NULL;
      45             142 :     nLayers = 0;
      46                 : 
      47             142 :     pszName = NULL;
      48                 : 
      49             142 :     bReadWrite = FALSE;
      50             142 :     bUseHTTPS = FALSE;
      51                 : 
      52             142 :     bMustCleanPersistant = FALSE;
      53             142 : }
      54                 : 
      55                 : /************************************************************************/
      56                 : /*                         ~OGRGFTDataSource()                          */
      57                 : /************************************************************************/
      58                 : 
      59             142 : OGRGFTDataSource::~OGRGFTDataSource()
      60                 : 
      61                 : {
      62             337 :     for( int i = 0; i < nLayers; i++ )
      63             195 :         delete papoLayers[i];
      64             142 :     CPLFree( papoLayers );
      65                 : 
      66             142 :     if (bMustCleanPersistant)
      67                 :     {
      68               8 :         char** papszOptions = CSLAddString(NULL, CPLSPrintf("CLOSE_PERSISTENT=GFT:%p", this));
      69               8 :         CPLHTTPFetch( GetAPIURL(), papszOptions);
      70               8 :         CSLDestroy(papszOptions);
      71                 :     }
      72                 : 
      73             142 :     CPLFree( pszName );
      74             142 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                           TestCapability()                           */
      78                 : /************************************************************************/
      79                 : 
      80               3 : int OGRGFTDataSource::TestCapability( const char * pszCap )
      81                 : 
      82                 : {
      83               3 :     if( bReadWrite && EQUAL(pszCap,ODsCCreateLayer) )
      84               3 :         return TRUE;
      85               0 :     else if( bReadWrite && EQUAL(pszCap,ODsCDeleteLayer) )
      86               0 :         return TRUE;
      87                 :     else
      88               0 :         return FALSE;
      89                 : }
      90                 : 
      91                 : /************************************************************************/
      92                 : /*                              GetLayer()                              */
      93                 : /************************************************************************/
      94                 : 
      95             175 : OGRLayer *OGRGFTDataSource::GetLayer( int iLayer )
      96                 : 
      97                 : {
      98             175 :     if( iLayer < 0 || iLayer >= nLayers )
      99               0 :         return NULL;
     100                 :     else
     101             175 :         return papoLayers[iLayer];
     102                 : }
     103                 : 
     104                 : /************************************************************************/
     105                 : /*                          GetLayerByName()                            */
     106                 : /************************************************************************/
     107                 : 
     108               8 : OGRLayer *OGRGFTDataSource::GetLayerByName(const char * pszLayerName)
     109                 : {
     110               8 :     OGRLayer* poLayer = OGRDataSource::GetLayerByName(pszLayerName);
     111               8 :     if (poLayer)
     112               5 :         return poLayer;
     113                 :         
     114               3 :     char* pszGeomColumnName = NULL;
     115               3 :     char* pszName = CPLStrdup(pszLayerName);
     116               3 :     char *pszLeftParenthesis = strchr(pszName, '(');
     117               3 :     if( pszLeftParenthesis != NULL )
     118                 :     {
     119               0 :         *pszLeftParenthesis = '\0';
     120               0 :         pszGeomColumnName = CPLStrdup(pszLeftParenthesis+1);
     121               0 :         int len = strlen(pszGeomColumnName);
     122               0 :         if (len > 0 && pszGeomColumnName[len - 1] == ')')
     123               0 :             pszGeomColumnName[len - 1] = '\0';
     124                 :     }
     125                 :     
     126               3 :     CPLString osTableId(pszName);
     127              85 :     for(int i=0;i<nLayers;i++)
     128                 :     {
     129              82 :         if( strcmp(papoLayers[i]->GetName(), pszName) == 0)
     130                 :         {
     131               0 :             osTableId = ((OGRGFTTableLayer*)papoLayers[i])->GetTableId();
     132               0 :             break;
     133                 :         }
     134                 :     }
     135                 : 
     136                 :     poLayer = new OGRGFTTableLayer(this, pszLayerName, osTableId,
     137               3 :                                    pszGeomColumnName);
     138               3 :     CPLFree(pszName);
     139               3 :     CPLFree(pszGeomColumnName);
     140               3 :     if (poLayer->GetLayerDefn()->GetFieldCount() == 0)
     141                 :     {
     142               3 :         delete poLayer;
     143               3 :         return NULL;
     144                 :     }
     145               0 :     papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     146               0 :     papoLayers[nLayers ++] = poLayer;
     147               0 :     return poLayer;
     148                 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                      OGRGFTGetOptionValue()                          */
     152                 : /************************************************************************/
     153                 : 
     154              32 : CPLString OGRGFTGetOptionValue(const char* pszFilename,
     155                 :                                const char* pszOptionName)
     156                 : {
     157              32 :     CPLString osOptionName(pszOptionName);
     158              32 :     osOptionName += "=";
     159              32 :     const char* pszOptionValue = strstr(pszFilename, osOptionName);
     160              32 :     if (!pszOptionValue)
     161              24 :         return "";
     162                 : 
     163               8 :     CPLString osOptionValue(pszOptionValue + strlen(osOptionName));
     164               8 :     const char* pszSpace = strchr(osOptionValue.c_str(), ' ');
     165               8 :     if (pszSpace)
     166               0 :         osOptionValue.resize(pszSpace - osOptionValue.c_str());
     167               8 :     return osOptionValue;
     168                 : }
     169                 : 
     170                 : /************************************************************************/
     171                 : /*                                Open()                                */
     172                 : /************************************************************************/
     173                 : 
     174             142 : int OGRGFTDataSource::Open( const char * pszFilename, int bUpdateIn)
     175                 : 
     176                 : {
     177             142 :     if (!EQUALN(pszFilename, "GFT:", 4))
     178             134 :         return FALSE;
     179                 : 
     180               8 :     bReadWrite = bUpdateIn;
     181                 : 
     182               8 :     pszName = CPLStrdup( pszFilename );
     183                 : 
     184               8 :     osAuth = OGRGFTGetOptionValue(pszFilename, "auth");
     185               8 :     if (osAuth.size() == 0)
     186               8 :         osAuth = CPLGetConfigOption("GFT_AUTH", "");
     187                 : 
     188               8 :     osRefreshToken = OGRGFTGetOptionValue(pszFilename, "refresh");
     189               8 :     if (osRefreshToken.size() == 0)
     190               1 :         osRefreshToken = CPLGetConfigOption("GFT_REFRESH_TOKEN", "");
     191                 : 
     192               8 :     osAPIKey = CPLGetConfigOption("GFT_APIKEY", GDAL_API_KEY);
     193                 : 
     194               8 :     CPLString osTables = OGRGFTGetOptionValue(pszFilename, "tables");
     195                 : 
     196               8 :     bUseHTTPS = TRUE;
     197                 : 
     198              16 :     osAccessToken = OGRGFTGetOptionValue(pszFilename, "access");
     199               8 :     if (osAccessToken.size() == 0)
     200               8 :         osAccessToken = CPLGetConfigOption("GFT_ACCESS_TOKEN","");
     201               8 :     if (osAccessToken.size() == 0 && osRefreshToken.size() > 0) 
     202                 :     {
     203                 :         osAccessToken.Seize(GOA2GetAccessToken(osRefreshToken,
     204               7 :                                                FUSION_TABLE_SCOPE));
     205               7 :         if (osAccessToken.size() == 0)
     206               0 :             return FALSE;
     207                 :     }
     208                 : 
     209               8 :     if (osAccessToken.size() == 0 && osAuth.size() > 0)
     210                 :     {
     211               0 :         osRefreshToken.Seize(GOA2GetRefreshToken(osAuth, FUSION_TABLE_SCOPE));
     212               0 :         if (osRefreshToken.size() == 0)
     213               0 :             return FALSE;
     214                 :     }
     215                 : 
     216               8 :     if (osAccessToken.size() == 0)
     217                 :     {
     218               1 :         if (osTables.size() == 0)
     219                 :         {
     220                 :             CPLError(CE_Failure, CPLE_AppDefined,
     221               0 :                     "Unauthenticated access requires explicit tables= parameter");
     222               0 :             return FALSE;
     223                 :         }
     224                 :     }
     225                 : 
     226               8 :     if (osTables.size() != 0)
     227                 :     {
     228               1 :         char** papszTables = CSLTokenizeString2(osTables, ",", 0);
     229               4 :         for(int i=0;papszTables && papszTables[i];i++)
     230                 :         {
     231               1 :             papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     232               1 :             papoLayers[nLayers ++] = new OGRGFTTableLayer(this, papszTables[i], papszTables[i]);
     233                 :         }
     234               1 :         CSLDestroy(papszTables);
     235               1 :         return TRUE;
     236                 :     }
     237                 : 
     238                 :     /* Get list of tables */
     239               7 :     CPLHTTPResult * psResult = RunSQL("SHOW TABLES");
     240                 : 
     241               7 :     if (psResult == NULL)
     242               0 :         return FALSE;
     243                 : 
     244               7 :     char* pszLine = (char*) psResult->pabyData;
     245               7 :     if (pszLine == NULL ||
     246                 :         psResult->pszErrBuf != NULL ||
     247                 :         strncmp(pszLine, "table id,name", strlen("table id,name")) != 0)
     248                 :     {
     249               0 :         CPLHTTPDestroyResult(psResult);
     250               0 :         return FALSE;
     251                 :     }
     252                 : 
     253               7 :     pszLine = OGRGFTGotoNextLine(pszLine);
     254             236 :     while(pszLine != NULL && *pszLine != 0)
     255                 :     {
     256             222 :         char* pszNextLine = OGRGFTGotoNextLine(pszLine);
     257             222 :         if (pszNextLine)
     258             222 :             pszNextLine[-1] = 0;
     259                 : 
     260             222 :         char** papszTokens = CSLTokenizeString2(pszLine, ",", 0);
     261             222 :         if (CSLCount(papszTokens) == 2)
     262                 :         {
     263             194 :             CPLString osTableId(papszTokens[0]);
     264             194 :             CPLString osLayerName(papszTokens[1]);
     265            2787 :             for(int i=0;i<nLayers;i++)
     266                 :             {
     267            2593 :                 if (strcmp(papoLayers[i]->GetName(), osLayerName) == 0)
     268                 :                 {
     269               0 :                     osLayerName += " (";
     270               0 :                     osLayerName += osTableId;
     271               0 :                     osLayerName += ")";
     272               0 :                     break;
     273                 :                 }
     274                 :             }
     275             194 :             papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     276             194 :             papoLayers[nLayers ++] = new OGRGFTTableLayer(this, osLayerName, osTableId);
     277                 :         }
     278             222 :         CSLDestroy(papszTokens);
     279                 : 
     280             222 :         pszLine = pszNextLine;
     281                 :     }
     282                 : 
     283               7 :     CPLHTTPDestroyResult(psResult);
     284                 : 
     285               7 :     return TRUE;
     286                 : }
     287                 : 
     288                 : /************************************************************************/
     289                 : /*                            GetAPIURL()                               */
     290                 : /************************************************************************/
     291                 : 
     292              48 : const char*  OGRGFTDataSource::GetAPIURL() const
     293                 : {
     294              48 :     const char* pszAPIURL = CPLGetConfigOption("GFT_API_URL", NULL);
     295              48 :     if (pszAPIURL)
     296               0 :         return pszAPIURL;
     297              48 :     else if (bUseHTTPS)
     298              48 :         return "https://www.googleapis.com/fusiontables/v1/query";
     299                 :     else
     300               0 :         return "http://www.googleapis.com/fusiontables/v1/query";
     301                 : }
     302                 : 
     303                 : /************************************************************************/
     304                 : /*                           CreateLayer()                              */
     305                 : /************************************************************************/
     306                 : 
     307               4 : OGRLayer   *OGRGFTDataSource::CreateLayer( const char *pszName,
     308                 :                                            OGRSpatialReference *poSpatialRef,
     309                 :                                            OGRwkbGeometryType eGType,
     310                 :                                            char ** papszOptions )
     311                 : {
     312               4 :     if (!bReadWrite)
     313                 :     {
     314               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode");
     315               0 :         return NULL;
     316                 :     }
     317                 : 
     318               4 :     if (osAccessToken.size() == 0)
     319                 :     {
     320               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in unauthenticated mode");
     321               0 :         return NULL;
     322                 :     }
     323                 : 
     324                 : /* -------------------------------------------------------------------- */
     325                 : /*      Do we already have this layer?  If so, should we blow it        */
     326                 : /*      away?                                                           */
     327                 : /* -------------------------------------------------------------------- */
     328                 :     int iLayer;
     329                 : 
     330             113 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     331                 :     {
     332             109 :         if( EQUAL(pszName,papoLayers[iLayer]->GetName()) )
     333                 :         {
     334               0 :             if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL
     335                 :                 && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") )
     336                 :             {
     337               0 :                 DeleteLayer( pszName );
     338               0 :                 break;
     339                 :             }
     340                 :             else
     341                 :             {
     342                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     343                 :                           "Layer %s already exists, CreateLayer failed.\n"
     344                 :                           "Use the layer creation option OVERWRITE=YES to "
     345                 :                           "replace it.",
     346               0 :                           pszName );
     347               0 :                 return NULL;
     348                 :             }
     349                 :         }
     350                 :     }
     351                 : 
     352               4 :     OGRGFTTableLayer* poLayer = new OGRGFTTableLayer(this, pszName);
     353               4 :     poLayer->SetGeometryType(eGType);
     354               4 :     papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*));
     355               4 :     papoLayers[nLayers ++] = poLayer;
     356               4 :     return poLayer;
     357                 : }
     358                 : 
     359                 : /************************************************************************/
     360                 : /*                            DeleteLayer()                             */
     361                 : /************************************************************************/
     362                 : 
     363               4 : void OGRGFTDataSource::DeleteLayer( const char *pszLayerName )
     364                 : 
     365                 : {
     366                 :     int iLayer;
     367                 : 
     368                 : /* -------------------------------------------------------------------- */
     369                 : /*      Try to find layer.                                              */
     370                 : /* -------------------------------------------------------------------- */
     371              32 :     for( iLayer = 0; iLayer < nLayers; iLayer++ )
     372                 :     {
     373              32 :         if( EQUAL(pszLayerName,papoLayers[iLayer]->GetName()) )
     374               4 :             break;
     375                 :     }
     376                 : 
     377               4 :     if( iLayer == nLayers )
     378                 :     {
     379                 :         CPLError( CE_Failure, CPLE_AppDefined,
     380                 :                   "Attempt to delete layer '%s', but this layer is not known to OGR.",
     381               0 :                   pszLayerName );
     382               0 :         return;
     383                 :     }
     384                 : 
     385               4 :     DeleteLayer(iLayer);
     386                 : }
     387                 : 
     388                 : /************************************************************************/
     389                 : /*                            DeleteLayer()                             */
     390                 : /************************************************************************/
     391                 : 
     392               4 : OGRErr OGRGFTDataSource::DeleteLayer(int iLayer)
     393                 : {
     394               4 :     if (!bReadWrite)
     395                 :     {
     396                 :         CPLError(CE_Failure, CPLE_AppDefined,
     397               0 :                  "Operation not available in read-only mode");
     398               0 :         return OGRERR_FAILURE;
     399                 :     }
     400                 : 
     401               4 :     if (osAccessToken.size() == 0)
     402                 :     {
     403                 :         CPLError(CE_Failure, CPLE_AppDefined,
     404               0 :                  "Operation not available in unauthenticated mode");
     405               0 :         return OGRERR_FAILURE;
     406                 :     }
     407                 : 
     408               4 :     if( iLayer < 0 || iLayer >= nLayers )
     409                 :     {
     410                 :         CPLError( CE_Failure, CPLE_AppDefined,
     411                 :                   "Layer %d not in legal range of 0 to %d.",
     412               0 :                   iLayer, nLayers-1 );
     413               0 :         return OGRERR_FAILURE;
     414                 :     }
     415                 : 
     416               4 :     CPLString osTableId = ((OGRGFTTableLayer*)papoLayers[iLayer])->GetTableId();
     417               4 :     CPLString osLayerName = GetLayer(iLayer)->GetName();
     418                 : 
     419                 : /* -------------------------------------------------------------------- */
     420                 : /*      Blow away our OGR structures related to the layer.  This is     */
     421                 : /*      pretty dangerous if anything has a reference to this layer!     */
     422                 : /* -------------------------------------------------------------------- */
     423               4 :     CPLDebug( "GFT", "DeleteLayer(%s)", osLayerName.c_str() );
     424                 : 
     425               4 :     delete papoLayers[iLayer];
     426                 :     memmove( papoLayers + iLayer, papoLayers + iLayer + 1,
     427               4 :              sizeof(void *) * (nLayers - iLayer - 1) );
     428               4 :     nLayers--;
     429                 : 
     430                 : /* -------------------------------------------------------------------- */
     431                 : /*      Remove from the database.                                       */
     432                 : /* -------------------------------------------------------------------- */
     433                 : 
     434               4 :     CPLString osSQL("DROP TABLE ");
     435               4 :     osSQL += osTableId;
     436                 : 
     437               4 :     CPLHTTPResult* psResult = RunSQL( osSQL );
     438                 : 
     439               4 :     if (psResult == NULL || psResult->nStatus != 0)
     440                 :     {
     441               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table deletion failed (1)");
     442               0 :         CPLHTTPDestroyResult(psResult);
     443               0 :         return OGRERR_FAILURE;
     444                 :     }
     445                 : 
     446               4 :     CPLHTTPDestroyResult(psResult);
     447                 : 
     448               4 :     return OGRERR_NONE;
     449                 : }
     450                 : 
     451                 : /************************************************************************/
     452                 : /*                          AddHTTPOptions()                            */
     453                 : /************************************************************************/
     454                 : 
     455              40 : char** OGRGFTDataSource::AddHTTPOptions(char** papszOptions)
     456                 : {
     457              40 :     bMustCleanPersistant = TRUE;
     458                 : 
     459              40 :     if (strlen(osAccessToken) > 0)
     460                 :       papszOptions = CSLAddString(papszOptions,
     461                 :         CPLSPrintf("HEADERS=Authorization: Bearer %s", 
     462              37 :                    osAccessToken.c_str()));
     463                 : 
     464              40 :     return CSLAddString(papszOptions, CPLSPrintf("PERSISTENT=GFT:%p", this));
     465                 : }
     466                 : 
     467                 : /************************************************************************/
     468                 : /*                               RunSQL()                               */
     469                 : /************************************************************************/
     470                 : 
     471              40 : CPLHTTPResult * OGRGFTDataSource::RunSQL(const char* pszUnescapedSQL)
     472                 : {
     473              40 :     CPLString osSQL("POSTFIELDS=sql=");
     474                 :     /* Do post escaping */
     475            4146 :     for(int i=0;pszUnescapedSQL[i] != 0;i++)
     476                 :     {
     477            4106 :         const int ch = ((unsigned char*)pszUnescapedSQL)[i];
     478            8212 :         if (ch != '&' && ch >= 32 && ch < 128)
     479            4106 :             osSQL += (char)ch;
     480                 :         else
     481               0 :             osSQL += CPLSPrintf("%%%02X", ch);
     482                 :     }
     483                 : 
     484                 : /* -------------------------------------------------------------------- */
     485                 : /*      Provide the API Key - used to rate limit access (see            */
     486                 : /*      GFT_APIKEY config)                                              */
     487                 : /* -------------------------------------------------------------------- */
     488              40 :     osSQL += "&key=";
     489              40 :     osSQL += osAPIKey;
     490                 : 
     491                 : /* -------------------------------------------------------------------- */
     492                 : /*      Force old style CSV output from calls - maybe we want to        */
     493                 : /*      migrate to JSON output at some point?                           */
     494                 : /* -------------------------------------------------------------------- */
     495              40 :     osSQL += "&alt=csv";
     496                 : 
     497                 : /* -------------------------------------------------------------------- */
     498                 : /*      Collection the header options and execute request.              */
     499                 : /* -------------------------------------------------------------------- */
     500              40 :     char** papszOptions = CSLAddString(AddHTTPOptions(), osSQL);
     501              40 :     CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions);
     502              40 :     CSLDestroy(papszOptions);
     503                 : 
     504                 : /* -------------------------------------------------------------------- */
     505                 : /*      Check for some error conditions and report.  HTML Messages      */
     506                 : /*      are transformed info failure.                                   */
     507                 : /* -------------------------------------------------------------------- */
     508              40 :     if (psResult && psResult->pszContentType &&
     509                 :         strncmp(psResult->pszContentType, "text/html", 9) == 0)
     510                 :     {
     511               3 :         CPLDebug( "GFT", "RunSQL HTML Response:%s", psResult->pabyData );
     512                 :         CPLError(CE_Failure, CPLE_AppDefined, 
     513               3 :                  "HTML error page returned by server");
     514               3 :         CPLHTTPDestroyResult(psResult);
     515               3 :         psResult = NULL;
     516                 :     }
     517              40 :     if (psResult && psResult->pszErrBuf != NULL) 
     518                 :     {
     519               0 :         CPLDebug( "GFT", "RunSQL Error Message:%s", psResult->pszErrBuf );
     520                 :     }
     521              40 :     else if (psResult && psResult->nStatus != 0) 
     522                 :     {
     523               0 :         CPLDebug( "GFT", "RunSQL Error Status:%d", psResult->nStatus );
     524                 :     }
     525                 : 
     526              40 :     return psResult;
     527                 : }
     528                 : 
     529                 : /************************************************************************/
     530                 : /*                             ExecuteSQL()                             */
     531                 : /************************************************************************/
     532                 : 
     533               5 : OGRLayer * OGRGFTDataSource::ExecuteSQL( const char *pszSQLCommand,
     534                 :                                           OGRGeometry *poSpatialFilter,
     535                 :                                           const char *pszDialect )
     536                 : 
     537                 : {
     538               5 :     if( pszDialect != NULL && EQUAL(pszDialect,"OGRSQL") )
     539                 :         return OGRDataSource::ExecuteSQL( pszSQLCommand,
     540                 :                                           poSpatialFilter,
     541               0 :                                           pszDialect );
     542                 : 
     543                 : /* -------------------------------------------------------------------- */
     544                 : /*      Special case DELLAYER: command.                                 */
     545                 : /* -------------------------------------------------------------------- */
     546               5 :     if( EQUALN(pszSQLCommand,"DELLAYER:",9) )
     547                 :     {
     548               4 :         const char *pszLayerName = pszSQLCommand + 9;
     549                 : 
     550               8 :         while( *pszLayerName == ' ' )
     551               0 :             pszLayerName++;
     552                 : 
     553               4 :         DeleteLayer( pszLayerName );
     554               4 :         return NULL;
     555                 :     }
     556                 : 
     557                 : /* -------------------------------------------------------------------- */
     558                 : /*      Create layer.                                                   */
     559                 : /* -------------------------------------------------------------------- */
     560               1 :     OGRGFTResultLayer *poLayer = NULL;
     561                 : 
     562               1 :     CPLString osSQL = pszSQLCommand;
     563               1 :     poLayer = new OGRGFTResultLayer( this, osSQL );
     564               2 :     if (!poLayer->RunSQL())
     565                 :     {
     566               0 :         delete poLayer;
     567               0 :         return NULL;
     568                 :     }
     569                 : 
     570               1 :     if( poSpatialFilter != NULL )
     571               0 :         poLayer->SetSpatialFilter( poSpatialFilter );
     572                 : 
     573               1 :     return poLayer;
     574                 : }
     575                 : 
     576                 : /************************************************************************/
     577                 : /*                          ReleaseResultSet()                          */
     578                 : /************************************************************************/
     579                 : 
     580               1 : void OGRGFTDataSource::ReleaseResultSet( OGRLayer * poLayer )
     581                 : 
     582                 : {
     583               1 :     delete poLayer;
     584               1 : }
     585                 : 
     586                 : /************************************************************************/
     587                 : /*                      OGRGFTGotoNextLine()                            */
     588                 : /************************************************************************/
     589                 : 
     590             608 : char* OGRGFTGotoNextLine(char* pszData)
     591                 : {
     592             608 :     char* pszNextLine = strchr(pszData, '\n');
     593             608 :     if (pszNextLine)
     594             608 :         return pszNextLine + 1;
     595               0 :     return NULL;
     596                 : }

Generated by: LCOV version 1.7