LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gft - ogrgftresultlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 130 72 55.4 %
Date: 2012-12-26 Functions: 9 5 55.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgftresultlayer.cpp 24343 2012-04-29 11:31:01Z rouault $
       3                 :  *
       4                 :  * Project:  GFT Translator
       5                 :  * Purpose:  Implements OGRGFTResultLayer 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: ogrgftresultlayer.cpp 24343 2012-04-29 11:31:01Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                        OGRGFTResultLayer()                           */
      36                 : /************************************************************************/
      37                 : 
      38               1 : OGRGFTResultLayer::OGRGFTResultLayer(OGRGFTDataSource* poDS,
      39               1 :                                      const char* pszSQL) : OGRGFTLayer(poDS)
      40                 : 
      41                 : {
      42               1 :     osSQL = PatchSQL(pszSQL);
      43                 : 
      44               1 :     bGotAllRows = FALSE;
      45                 : 
      46               1 :     poFeatureDefn = new OGRFeatureDefn( "result" );
      47               1 :     poFeatureDefn->Reference();
      48               1 :     poFeatureDefn->SetGeomType( wkbUnknown );
      49               1 : }
      50                 : 
      51                 : /************************************************************************/
      52                 : /*                       ~OGRGFTResultLayer()                           */
      53                 : /************************************************************************/
      54                 : 
      55               1 : OGRGFTResultLayer::~OGRGFTResultLayer()
      56                 : 
      57                 : {
      58               1 : }
      59                 : 
      60                 : /************************************************************************/
      61                 : /*                            ResetReading()                            */
      62                 : /************************************************************************/
      63                 : 
      64               2 : void OGRGFTResultLayer::ResetReading()
      65                 : 
      66                 : {
      67               2 :     nNextInSeq = 0;
      68               2 :     nOffset = 0;
      69               2 :     if (!bGotAllRows)
      70                 :     {
      71               0 :         aosRows.resize(0);
      72               0 :         bEOF = FALSE;
      73                 :     }
      74               2 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                           FetchNextRows()                            */
      78                 : /************************************************************************/
      79                 : 
      80               0 : int OGRGFTResultLayer::FetchNextRows()
      81                 : {
      82               0 :     if (!EQUALN(osSQL.c_str(), "SELECT", 6))
      83               0 :         return FALSE;
      84                 : 
      85               0 :     aosRows.resize(0);
      86                 : 
      87               0 :     CPLString osChangedSQL(osSQL);
      88               0 :     if (osSQL.ifind(" OFFSET ") == std::string::npos &&
      89                 :         osSQL.ifind(" LIMIT ") == std::string::npos)
      90                 :     {
      91                 :         osChangedSQL += CPLSPrintf(" OFFSET %d LIMIT %d",
      92               0 :                                    nOffset, GetFeaturesToFetch());
      93                 :     }
      94                 : 
      95               0 :     CPLPushErrorHandler(CPLQuietErrorHandler);
      96               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL);
      97               0 :     CPLPopErrorHandler();
      98                 : 
      99               0 :     if (psResult == NULL)
     100                 :     {
     101               0 :         bEOF = TRUE;
     102               0 :         return FALSE;
     103                 :     }
     104                 : 
     105               0 :     char* pszLine = (char*) psResult->pabyData;
     106               0 :     if (pszLine == NULL ||
     107                 :         psResult->pszErrBuf != NULL)
     108                 :     {
     109               0 :         CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed");
     110               0 :         CPLHTTPDestroyResult(psResult);
     111               0 :         bEOF = TRUE;
     112               0 :         return FALSE;
     113                 :     }
     114                 : 
     115               0 :     pszLine = OGRGFTGotoNextLine(pszLine);
     116               0 :     if (pszLine == NULL)
     117                 :     {
     118               0 :         CPLHTTPDestroyResult(psResult);
     119               0 :         bEOF = TRUE;
     120               0 :         return FALSE;
     121                 :     }
     122                 : 
     123               0 :     ParseCSVResponse(pszLine, aosRows);
     124                 : 
     125               0 :     CPLHTTPDestroyResult(psResult);
     126                 : 
     127               0 :     bEOF = (int)aosRows.size() < GetFeaturesToFetch();
     128                 : 
     129               0 :     return TRUE;
     130                 : }
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                         OGRGFTExtractTableID()                        */
     134                 : /************************************************************************/
     135                 : 
     136               1 : static CPLString OGRGFTExtractTableID(const char* pszTableID,
     137                 :                                       CPLString& osReminder)
     138                 : {
     139               1 :     CPLString osTableId(pszTableID);
     140               1 :     if (osTableId.size() > 1 &&
     141                 :         (osTableId[0] == '"' || osTableId[0] == '\''))
     142                 :     {
     143               0 :         char chFirstChar = osTableId[0];
     144               0 :         osTableId.erase(0, 1);
     145               0 :         for(int i=0;i<(int)osTableId.size();i++)
     146                 :         {
     147               0 :             if (osTableId[i] == chFirstChar)
     148                 :             {
     149               0 :                 osReminder = osTableId.substr(i+1);
     150               0 :                 osTableId.resize(i);
     151               0 :                 break;
     152                 :             }
     153                 :         }
     154                 :     }
     155                 :     else
     156                 :     {
     157               7 :         for(int i=0;i<(int)osTableId.size();i++)
     158                 :         {
     159               7 :             if (osTableId[i] == ' ')
     160                 :             {
     161               1 :                 osReminder = osTableId.substr(i);
     162               1 :                 osTableId.resize(i);
     163               1 :                 break;
     164                 :             }
     165                 :         }
     166                 :     }
     167               0 :     return osTableId;
     168                 : }
     169                 : 
     170                 : /************************************************************************/
     171                 : /*                               RunSQL()                               */
     172                 : /************************************************************************/
     173                 : 
     174               1 : int OGRGFTResultLayer::RunSQL()
     175                 : {
     176               1 :     CPLString osChangedSQL(osSQL);
     177               1 :     int bHasSetLimit = FALSE;
     178               1 :     OGRGFTTableLayer* poTableLayer = NULL;
     179               1 :     OGRFeatureDefn* poTableDefn = NULL;
     180               1 :     CPLString osTableId;
     181               1 :     if (EQUALN(osSQL.c_str(), "SELECT", 6))
     182                 :     {
     183               1 :         size_t nPosFROM = osSQL.ifind(" FROM ");
     184               1 :         if (nPosFROM == std::string::npos)
     185                 :         {
     186               0 :             CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed. Missing FROM in SELECT");
     187               0 :             return FALSE;
     188                 :         }
     189               1 :         CPLString osReminder;
     190               1 :         nPosFROM += 6;
     191               1 :         osTableId = OGRGFTExtractTableID(osSQL.c_str() + nPosFROM, osReminder);
     192                 : 
     193               1 :         poTableLayer = (OGRGFTTableLayer*) poDS->GetLayerByName(osTableId);
     194               1 :         if (poTableLayer != NULL)
     195               1 :             poTableDefn = poTableLayer->GetLayerDefn();
     196                 : 
     197               1 :         if (poTableLayer != NULL &&
     198                 :             poTableLayer->GetTableId().size() &&
     199                 :             !EQUAL(osTableId, poTableLayer->GetTableId()))
     200                 :         {
     201               0 :             osChangedSQL = osSQL;
     202               0 :             osChangedSQL.resize(nPosFROM);
     203               0 :             osChangedSQL += poTableLayer->GetTableId();
     204               0 :             osChangedSQL += osReminder;
     205               0 :             osSQL = osChangedSQL;
     206                 :             CPLDebug("GFT", "Patching table name (%s) to table id (%s)",
     207               0 :                      osTableId.c_str(), poTableLayer->GetTableId().c_str());
     208                 :         }
     209                 : 
     210               1 :         int nFeaturesToFetch = GetFeaturesToFetch();
     211               1 :         if (osSQL.ifind(" OFFSET ") == std::string::npos &&
     212                 :             osSQL.ifind(" LIMIT ") == std::string::npos &&
     213                 :             nFeaturesToFetch > 0)
     214                 :         {
     215               1 :             osChangedSQL += CPLSPrintf(" LIMIT %d", nFeaturesToFetch);
     216               1 :             bHasSetLimit = TRUE;
     217               1 :         }
     218                 :     }
     219                 :     else
     220                 :     {
     221               0 :         bGotAllRows = bEOF = TRUE;
     222               0 :         poFeatureDefn->SetGeomType( wkbNone );
     223                 :     }
     224                 : 
     225               1 :     CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL);
     226                 : 
     227               1 :     if (psResult == NULL)
     228               0 :         return FALSE;
     229                 : 
     230               1 :     char* pszLine = (char*) psResult->pabyData;
     231               1 :     if (pszLine == NULL ||
     232                 :         psResult->pszErrBuf != NULL)
     233                 :     {
     234               0 :         CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed");
     235               0 :         CPLHTTPDestroyResult(psResult);
     236               0 :         return FALSE;
     237                 :     }
     238                 : 
     239               1 :     if (EQUALN(osSQL.c_str(), "SELECT", 6) ||
     240                 :         EQUAL(osSQL.c_str(), "SHOW TABLES") ||
     241                 :         EQUALN(osSQL.c_str(), "DESCRIBE", 8))
     242                 :     {
     243               1 :         ParseCSVResponse(pszLine, aosRows);
     244               1 :         if (aosRows.size() > 0)
     245                 :         {
     246               1 :             char** papszTokens = OGRGFTCSVSplitLine(aosRows[0], ',');
     247               3 :             for(int i=0;papszTokens && papszTokens[i];i++)
     248                 :             {
     249               2 :                 CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
     250               2 :                 int iIndex = (poTableDefn) ? poTableDefn->GetFieldIndex(osLaunderedColName) : -1;
     251               2 :                 if (iIndex >= 0)
     252                 :                 {
     253               2 :                     poFeatureDefn->AddFieldDefn(poTableDefn->GetFieldDefn(iIndex));
     254               2 :                     if (iIndex == poTableLayer->GetGeometryFieldIndex())
     255               1 :                         iGeometryField = i;
     256               2 :                     if (iIndex == poTableLayer->GetLatitudeFieldIndex())
     257               1 :                         iLatitudeField = i;
     258               2 :                     if (iIndex == poTableLayer->GetLongitudeFieldIndex())
     259               1 :                         iLongitudeField = i;
     260                 :                 }
     261                 :                 else
     262                 :                 {
     263               0 :                     OGRFieldType eType = OFTString;
     264               0 :                     if (EQUAL(osLaunderedColName, "COUNT()"))
     265               0 :                         eType = OFTInteger;
     266               0 :                     OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
     267               0 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
     268                 :                 }
     269                 :             }
     270               1 :             CSLDestroy(papszTokens);
     271                 : 
     272               1 :             aosRows.erase(aosRows.begin());
     273                 :         }
     274                 : 
     275               1 :         if (iLatitudeField >= 0 && iLongitudeField >= 0)
     276                 :         {
     277               1 :             iGeometryField = iLatitudeField;
     278               1 :             poFeatureDefn->SetGeomType( wkbPoint );
     279                 :         }
     280                 : 
     281               1 :         if (bHasSetLimit)
     282               1 :             bGotAllRows = bEOF = (int)aosRows.size() < GetFeaturesToFetch();
     283                 :         else
     284               0 :             bGotAllRows = bEOF = TRUE;
     285                 :     }
     286                 : 
     287               1 :     CPLHTTPDestroyResult(psResult);
     288                 : 
     289               1 :     return TRUE;
     290                 : }

Generated by: LCOV version 1.7