LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gft - ogrgfttablelayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 597 113 18.9 %
Date: 2012-12-26 Functions: 25 11 44.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgfttablelayer.cpp 22407 2011-05-20 19:31:11Z rouault $
       3                 :  *
       4                 :  * Project:  GFT Translator
       5                 :  * Purpose:  Implements OGRGFTTableLayer 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: ogrgfttablelayer.cpp 22407 2011-05-20 19:31:11Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                         OGRGFTTableLayer()                           */
      36                 : /************************************************************************/
      37                 : 
      38               1 : OGRGFTTableLayer::OGRGFTTableLayer(OGRGFTDataSource* poDS,
      39                 :                          const char* pszTableName,
      40                 :                          const char* pszTableId,
      41               1 :                          const char* pszGeomColumnName) : OGRGFTLayer(poDS)
      42                 : 
      43                 : {
      44               1 :     osTableName = pszTableName;
      45               1 :     osTableId = pszTableId;
      46               1 :     osGeomColumnName = pszGeomColumnName ? pszGeomColumnName : "";
      47                 : 
      48               1 :     bHasTriedCreateTable = FALSE;
      49               1 :     bInTransaction = FALSE;
      50               1 :     nFeaturesInTransaction = 0;
      51                 : 
      52               1 :     bFirstTokenIsFID = TRUE;
      53               1 :     eGTypeForCreation = wkbUnknown;
      54               1 : }
      55                 : 
      56                 : /************************************************************************/
      57                 : /*                        ~OGRGFTTableLayer()                           */
      58                 : /************************************************************************/
      59                 : 
      60               1 : OGRGFTTableLayer::~OGRGFTTableLayer()
      61                 : 
      62                 : {
      63               1 :     CreateTableIfNecessary();
      64               1 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                            ResetReading()                            */
      68                 : /************************************************************************/
      69                 : 
      70               2 : void OGRGFTTableLayer::ResetReading()
      71                 : 
      72                 : {
      73               2 :     OGRGFTLayer::ResetReading();
      74               2 :     aosRows.resize(0);
      75               2 : }
      76                 : 
      77                 : /************************************************************************/
      78                 : /*                           TestCapability()                           */
      79                 : /************************************************************************/
      80                 : 
      81               0 : int OGRGFTTableLayer::TestCapability( const char * pszCap )
      82                 : 
      83                 : {
      84               0 :     if( EQUAL(pszCap,OLCRandomRead) )
      85               0 :         return TRUE;
      86                 : 
      87               0 :     else if( EQUAL(pszCap,OLCSequentialWrite)
      88                 :              || EQUAL(pszCap,OLCRandomWrite)
      89                 :              || EQUAL(pszCap,OLCDeleteFeature) )
      90               0 :         return poDS->IsReadWrite();
      91                 : 
      92               0 :     else if( EQUAL(pszCap,OLCCreateField) )
      93               0 :         return poDS->IsReadWrite();
      94                 : 
      95               0 :     else if( EQUAL(pszCap, OLCTransactions) )
      96               0 :         return poDS->IsReadWrite();
      97                 : 
      98               0 :     return OGRGFTLayer::TestCapability(pszCap);
      99                 : }
     100                 : 
     101                 : /************************************************************************/
     102                 : /*                           FetchDescribe()                            */
     103                 : /************************************************************************/
     104                 : 
     105               1 : int OGRGFTTableLayer::FetchDescribe()
     106                 : {
     107               1 :     poFeatureDefn = new OGRFeatureDefn( osTableName );
     108               1 :     poFeatureDefn->Reference();
     109                 : 
     110               1 :     const CPLString& osAuth = poDS->GetAuth();
     111               1 :     std::vector<CPLString> aosHeaderAndFirstDataLine;
     112               2 :     if (osAuth.size())
     113                 :     {
     114               0 :         CPLString osSQL("DESCRIBE ");
     115               0 :         osSQL += osTableId;
     116               0 :         CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     117                 : 
     118               0 :         if (psResult == NULL)
     119               0 :             return FALSE;
     120                 : 
     121               0 :         char* pszLine = (char*) psResult->pabyData;
     122               0 :         if (pszLine == NULL ||
     123                 :             psResult->pszErrBuf != NULL ||
     124                 :             strncmp(pszLine, "column id,name,type",
     125                 :                     strlen("column id,name,type")) != 0)
     126                 :         {
     127               0 :             CPLHTTPDestroyResult(psResult);
     128               0 :             return FALSE;
     129                 :         }
     130                 : 
     131               0 :         pszLine = OGRGFTGotoNextLine(pszLine);
     132                 : 
     133               0 :         std::vector<CPLString> aosLines;
     134               0 :         ParseCSVResponse(pszLine, aosLines);
     135               0 :         for(int i=0;i<(int)aosLines.size();i++)
     136                 :         {
     137               0 :             char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ',');
     138               0 :             if (CSLCount(papszTokens) == 3)
     139                 :             {
     140               0 :                 aosColumnInternalName.push_back(papszTokens[0]);
     141                 : 
     142                 :                 //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]);
     143               0 :                 OGRFieldType eType = OFTString;
     144               0 :                 if (EQUAL(papszTokens[2], "number"))
     145               0 :                     eType = OFTReal;
     146               0 :                 else if (EQUAL(papszTokens[2], "datetime"))
     147               0 :                     eType = OFTDateTime;
     148                 : 
     149               0 :                 if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0)
     150                 :                 {
     151               0 :                     if (iGeometryField < 0)
     152               0 :                         iGeometryField = poFeatureDefn->GetFieldCount();
     153                 :                     else
     154                 :                         CPLDebug("GFT", "Multiple geometry fields detected. "
     155               0 :                                          "Only first encountered one is handled");
     156                 :                 }
     157                 : 
     158               0 :                 CPLString osLaunderedColName(LaunderColName(papszTokens[1]));
     159               0 :                 OGRFieldDefn oFieldDefn(osLaunderedColName, eType);
     160               0 :                 poFeatureDefn->AddFieldDefn(&oFieldDefn);
     161                 :             }
     162               0 :             CSLDestroy(papszTokens);
     163                 :         }
     164                 : 
     165               0 :         CPLHTTPDestroyResult(psResult);
     166                 :     }
     167                 :     else
     168                 :     {
     169                 :         /* http://code.google.com/intl/fr/apis/fusiontables/docs/developers_guide.html#Exploring states */
     170                 :         /* that DESCRIBE should work on public tables without authentication, but it is not true... */
     171               1 :         CPLString osSQL("SELECT * FROM ");
     172               1 :         osSQL += osTableId;
     173               1 :         osSQL += " OFFSET 0 LIMIT 1";
     174                 : 
     175               1 :         CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     176                 : 
     177               1 :         if (psResult == NULL)
     178               0 :             return FALSE;
     179                 : 
     180               1 :         char* pszLine = (char*) psResult->pabyData;
     181               1 :         if (pszLine == NULL || psResult->pszErrBuf != NULL)
     182                 :         {
     183               0 :             CPLHTTPDestroyResult(psResult);
     184               0 :             return FALSE;
     185                 :         }
     186                 : 
     187               1 :         ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine);
     188               1 :         if (aosHeaderAndFirstDataLine.size() > 0)
     189                 :         {
     190               1 :             char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ',');
     191              31 :             for(int i=0;papszTokens && papszTokens[i];i++)
     192                 :             {
     193              30 :                 CPLString osLaunderedColName(LaunderColName(papszTokens[i]));
     194              30 :                 OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString);
     195              30 :                 poFeatureDefn->AddFieldDefn(&oFieldDefn);
     196                 :             }
     197               1 :             CSLDestroy(papszTokens);
     198                 :         }
     199                 : 
     200               1 :         CPLHTTPDestroyResult(psResult);
     201                 :     }
     202                 :     
     203               1 :     if (osGeomColumnName.size() > 0)
     204                 :     {
     205               0 :         iGeometryField = poFeatureDefn->GetFieldIndex(osGeomColumnName);
     206               0 :         if (iGeometryField < 0)
     207                 :         {
     208                 :             CPLError(CE_Warning, CPLE_AppDefined,
     209               0 :                      "Cannot find column called %s", osGeomColumnName.c_str());
     210                 :         }
     211                 :     }
     212                 : 
     213              31 :     for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
     214                 :     {
     215              30 :         const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
     216              31 :         if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
     217                 :             EQUAL(pszName, "latdec"))
     218               1 :             iLatitudeField = i;
     219              29 :         else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
     220                 :                  EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
     221               1 :             iLongitudeField = i;
     222                 :     }
     223                 : 
     224               2 :     if (iLatitudeField >= 0 && iLongitudeField >= 0)
     225                 :     {
     226               1 :         if (iGeometryField < 0)
     227               1 :             iGeometryField = iLatitudeField;
     228               1 :         poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal);
     229               1 :         poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal);
     230               1 :         poFeatureDefn->SetGeomType( wkbPoint );
     231                 :     }
     232               0 :     else if (iGeometryField < 0 && osGeomColumnName.size() == 0)
     233                 :     {
     234               0 :         iLatitudeField = iLongitudeField = -1;
     235                 : 
     236                 :         /* In the unauthentified case, we try to parse the first record to */
     237                 :         /* autodetect the geometry field */
     238               0 :         OGRwkbGeometryType eType = wkbUnknown;
     239               0 :         if (aosHeaderAndFirstDataLine.size() == 2)
     240                 :         {
     241               0 :             char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[1], ',');
     242               0 :             if (CSLCount(papszTokens) == poFeatureDefn->GetFieldCount())
     243                 :             {
     244               0 :                 for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
     245                 :                 {
     246               0 :                     const char* pszVal = papszTokens[i];
     247               0 :                     if (pszVal != NULL &&
     248                 :                         (strncmp(pszVal, "<Point>", 7) == 0 ||
     249                 :                          strncmp(pszVal, "<LineString>", 12) == 0 ||
     250                 :                          strncmp(pszVal, "<Polygon>", 9) == 0 ||
     251                 :                          strncmp(pszVal, "<MultiGeometry>", 15) == 0))
     252                 :                     {
     253               0 :                         if (iGeometryField < 0)
     254                 :                         {
     255               0 :                             iGeometryField = i;
     256                 :                         }
     257                 :                         else
     258                 :                         {
     259                 :                             CPLDebug("GFT", "Multiple geometry fields detected. "
     260               0 :                                      "Only first encountered one is handled");
     261                 :                         }
     262                 :                     }
     263               0 :                     else if (pszVal)
     264                 :                     {
     265                 :                         /* http://www.google.com/fusiontables/DataSource?dsrcid=423292 */
     266               0 :                         char** papszTokens2 = CSLTokenizeString2(pszVal, " ,", 0);
     267               0 :                         if (CSLCount(papszTokens2) == 2 &&
     268               0 :                             CPLGetValueType(papszTokens2[0]) == CPL_VALUE_REAL &&
     269               0 :                             CPLGetValueType(papszTokens2[1]) == CPL_VALUE_REAL &&
     270               0 :                             fabs(CPLAtof(papszTokens2[0])) <= 90 &&
     271               0 :                             fabs(CPLAtof(papszTokens2[1])) <= 180 )
     272                 :                         {
     273               0 :                             if (iGeometryField < 0)
     274                 :                             {
     275               0 :                                 iGeometryField = i;
     276               0 :                                 eType = wkbPoint;
     277                 :                             }
     278                 :                             else
     279                 :                             {
     280                 :                                 CPLDebug("GFT", "Multiple geometry fields detected. "
     281               0 :                                          "Only first encountered one is handled");
     282                 :                             }
     283                 :                         }
     284               0 :                         CSLDestroy(papszTokens2);
     285                 :                     }
     286                 :                 }
     287                 :             }
     288               0 :             CSLDestroy(papszTokens);
     289                 :         }
     290                 :         
     291               0 :         if (iGeometryField < 0)
     292               0 :             poFeatureDefn->SetGeomType( wkbNone );
     293                 :         else
     294               0 :             poFeatureDefn->SetGeomType( eType );
     295                 :     }
     296                 : 
     297               1 :     return TRUE;
     298                 : }
     299                 : 
     300                 : /************************************************************************/
     301                 : /*                         EscapeAndQuote()                             */
     302                 : /************************************************************************/
     303                 : 
     304               2 : static CPLString EscapeAndQuote(const char* pszStr)
     305                 : {
     306                 :     char ch;
     307               2 :     CPLString osRes("'");
     308              20 :     while((ch = *pszStr) != 0)
     309                 :     {
     310              16 :         if (ch == '\'')
     311               0 :             osRes += "\\\'";
     312                 :         else
     313              16 :             osRes += ch;
     314              16 :         pszStr ++;
     315                 :     }
     316               2 :     osRes += "'";
     317               0 :     return osRes;
     318                 : }
     319                 : 
     320                 : /************************************************************************/
     321                 : /*                           FetchNextRows()                            */
     322                 : /************************************************************************/
     323                 : 
     324               0 : int OGRGFTTableLayer::FetchNextRows()
     325                 : {
     326               0 :     aosRows.resize(0);
     327                 : 
     328               0 :     CPLString osSQL("SELECT ROWID");
     329               0 :     for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
     330                 :     {
     331               0 :         osSQL += ",";
     332                 : 
     333               0 :         if (i < (int)aosColumnInternalName.size())
     334               0 :             osSQL += aosColumnInternalName[i];
     335                 :         else
     336                 :         {
     337                 :             const char* pszFieldName =
     338               0 :                 poFeatureDefn->GetFieldDefn(i)->GetNameRef();
     339               0 :             osSQL += EscapeAndQuote(pszFieldName);
     340                 :         }
     341                 :     }
     342               0 :     if (bHiddenGeometryField)
     343                 :     {
     344               0 :         osSQL += ",";
     345               0 :         osSQL += EscapeAndQuote(GetGeometryColumn());
     346                 :     }
     347               0 :     osSQL += " FROM ";
     348               0 :     osSQL += osTableId;
     349               0 :     if (osWHERE.size())
     350                 :     {
     351               0 :         osSQL += " ";
     352               0 :         osSQL += osWHERE;
     353                 :     }
     354                 : 
     355               0 :     int nFeaturesToFetch = GetFeaturesToFetch();
     356               0 :     if (nFeaturesToFetch > 0)
     357               0 :         osSQL += CPLSPrintf(" OFFSET %d LIMIT %d", nOffset, nFeaturesToFetch);
     358                 : 
     359               0 :     CPLPushErrorHandler(CPLQuietErrorHandler);
     360               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     361               0 :     CPLPopErrorHandler();
     362                 : 
     363               0 :     if (psResult == NULL)
     364                 :     {
     365               0 :         bEOF = TRUE;
     366               0 :         return FALSE;
     367                 :     }
     368                 : 
     369               0 :     char* pszLine = (char*) psResult->pabyData;
     370               0 :     if (pszLine == NULL || psResult->pszErrBuf != NULL)
     371                 :     {
     372               0 :         CPLDebug("GFT", "Error : %s", pszLine ? pszLine : psResult->pszErrBuf);
     373               0 :         CPLHTTPDestroyResult(psResult);
     374               0 :         bEOF = TRUE;
     375               0 :         return FALSE;
     376                 :     }
     377                 : 
     378               0 :     ParseCSVResponse(pszLine, aosRows);
     379                 : 
     380               0 :     if (aosRows.size() > 0)
     381               0 :         aosRows.erase(aosRows.begin());
     382                 : 
     383               0 :     if (nFeaturesToFetch > 0)
     384               0 :         bEOF = (int)aosRows.size() < GetFeaturesToFetch();
     385                 :     else
     386               0 :         bEOF = TRUE;
     387                 : 
     388               0 :     CPLHTTPDestroyResult(psResult);
     389                 : 
     390               0 :     return TRUE;
     391                 : }
     392                 : /************************************************************************/
     393                 : /*                            GetFeature()                              */
     394                 : /************************************************************************/
     395                 : 
     396               0 : OGRFeature * OGRGFTTableLayer::GetFeature( long nFID )
     397                 : {
     398               0 :     GetLayerDefn();
     399                 : 
     400               0 :     CPLString osSQL("SELECT ROWID");
     401               0 :     for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
     402                 :     {
     403               0 :         osSQL += ",";
     404                 : 
     405                 :         const char* pszFieldName =
     406               0 :             poFeatureDefn->GetFieldDefn(i)->GetNameRef();
     407               0 :         osSQL += EscapeAndQuote(pszFieldName);
     408                 :     }
     409               0 :     if (bHiddenGeometryField)
     410                 :     {
     411               0 :         osSQL += ",";
     412               0 :         osSQL += EscapeAndQuote(GetGeometryColumn());
     413                 :     }
     414               0 :     osSQL += " FROM ";
     415               0 :     osSQL += osTableId;
     416               0 :     osSQL += CPLSPrintf(" WHERE ROWID='%ld'", nFID);
     417                 : 
     418               0 :     CPLPushErrorHandler(CPLQuietErrorHandler);
     419               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     420               0 :     CPLPopErrorHandler();
     421                 : 
     422               0 :     if (psResult == NULL)
     423               0 :         return NULL;
     424                 : 
     425               0 :     char* pszLine = (char*) psResult->pabyData;
     426               0 :     if (pszLine == NULL || psResult->pszErrBuf != NULL)
     427                 :     {
     428               0 :         CPLHTTPDestroyResult(psResult);
     429               0 :         return NULL;
     430                 :     }
     431                 : 
     432                 :     /* skip header line */
     433               0 :     pszLine = OGRGFTGotoNextLine(pszLine);
     434               0 :     if (pszLine == NULL || pszLine[0] == 0)
     435                 :     {
     436               0 :         CPLHTTPDestroyResult(psResult);
     437               0 :         return NULL;
     438                 :     }
     439                 : 
     440               0 :     int nLen = (int)strlen(pszLine);
     441               0 :     if (nLen > 0 && pszLine[nLen-1] == '\n')
     442               0 :         pszLine[nLen-1] = '\0';
     443                 : 
     444               0 :     OGRFeature* poFeature = BuildFeatureFromSQL(pszLine);
     445                 : 
     446               0 :     CPLHTTPDestroyResult(psResult);
     447                 : 
     448               0 :     return poFeature;
     449                 : }
     450                 : 
     451                 : /************************************************************************/
     452                 : /*                           GetLayerDefn()                             */
     453                 : /************************************************************************/
     454                 : 
     455               6 : OGRFeatureDefn * OGRGFTTableLayer::GetLayerDefn()
     456                 : {
     457               6 :     if (poFeatureDefn == NULL)
     458                 :     {
     459               1 :         if (osTableId.size() == 0)
     460               0 :             return NULL;
     461               1 :         FetchDescribe();
     462                 :     }
     463                 : 
     464               6 :     return poFeatureDefn;
     465                 : }
     466                 : 
     467                 : /************************************************************************/
     468                 : /*                          GetFeatureCount()                           */
     469                 : /************************************************************************/
     470                 : 
     471               1 : int OGRGFTTableLayer::GetFeatureCount(int bForce)
     472                 : {
     473               1 :     GetLayerDefn();
     474                 : 
     475               1 :     CPLString osSQL("SELECT COUNT() FROM ");
     476               1 :     osSQL += osTableId;
     477               1 :     if (osWHERE.size())
     478                 :     {
     479               1 :         osSQL += " ";
     480               1 :         osSQL += osWHERE;
     481                 :     }
     482                 : 
     483               1 :     CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     484                 : 
     485               1 :     if (psResult == NULL)
     486               0 :         return 0;
     487                 : 
     488               1 :     char* pszLine = (char*) psResult->pabyData;
     489               1 :     if (pszLine == NULL ||
     490                 :         strncmp(pszLine, "count()", 7) != 0 ||
     491                 :         psResult->pszErrBuf != NULL)
     492                 :     {
     493               0 :         CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed");
     494               0 :         CPLHTTPDestroyResult(psResult);
     495               0 :         return 0;
     496                 :     }
     497                 : 
     498               1 :     pszLine = OGRGFTGotoNextLine(pszLine);
     499               1 :     if (pszLine == NULL)
     500                 :     {
     501               0 :         CPLError(CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed");
     502               0 :         CPLHTTPDestroyResult(psResult);
     503               0 :         return 0;
     504                 :     }
     505                 : 
     506               1 :     char* pszNextLine = OGRGFTGotoNextLine(pszLine);
     507               1 :     if (pszNextLine)
     508               1 :         pszNextLine[-1] = 0;
     509                 : 
     510               1 :     int nFeatureCount = atoi(pszLine);
     511                 : 
     512               1 :     CPLHTTPDestroyResult(psResult);
     513                 : 
     514               1 :     return nFeatureCount;
     515                 : }
     516                 : 
     517                 : /************************************************************************/
     518                 : /*                            CreateField()                             */
     519                 : /************************************************************************/
     520                 : 
     521               0 : OGRErr OGRGFTTableLayer::CreateField( OGRFieldDefn *poField,
     522                 :                                  int bApproxOK )
     523                 : {
     524                 : 
     525               0 :     if (!poDS->IsReadWrite())
     526                 :     {
     527                 :         CPLError(CE_Failure, CPLE_AppDefined,
     528               0 :                  "Operation not available in read-only mode");
     529               0 :         return OGRERR_FAILURE;
     530                 :     }
     531                 : 
     532               0 :     if (osTableId.size() != 0)
     533                 :     {
     534                 :         CPLError(CE_Failure, CPLE_NotSupported,
     535               0 :                  "Cannot add field to already created table");
     536               0 :         return OGRERR_FAILURE;
     537                 :     }
     538                 : 
     539               0 :     if (poDS->GetAuth().size() == 0)
     540                 :     {
     541                 :         CPLError(CE_Failure, CPLE_AppDefined,
     542               0 :                  "Operation not available in unauthenticated mode");
     543               0 :         return OGRERR_FAILURE;
     544                 :     }
     545                 : 
     546               0 :     if (poFeatureDefn == NULL)
     547                 :     {
     548               0 :         poFeatureDefn = new OGRFeatureDefn( osTableName );
     549               0 :         poFeatureDefn->Reference();
     550                 :     }
     551                 : 
     552               0 :     poFeatureDefn->AddFieldDefn(poField);
     553                 : 
     554               0 :     return OGRERR_NONE;
     555                 : }
     556                 : 
     557                 : /************************************************************************/
     558                 : /*                       CreateTableIfNecessary()                       */
     559                 : /************************************************************************/
     560                 : 
     561               1 : void OGRGFTTableLayer::CreateTableIfNecessary()
     562                 : {
     563               1 :     if (bHasTriedCreateTable || osTableId.size() != 0)
     564               1 :         return;
     565                 : 
     566               0 :     bHasTriedCreateTable = TRUE;
     567                 : 
     568               0 :     CPLString osSQL("CREATE TABLE '");
     569               0 :     osSQL += osTableName;
     570               0 :     osSQL += "' (";
     571                 : 
     572                 :     int i;
     573                 : 
     574               0 :     if (poFeatureDefn == NULL)
     575                 :     {
     576                 :         /* In case CreateField() hasn't yet been called */
     577               0 :         poFeatureDefn = new OGRFeatureDefn( osTableName );
     578               0 :         poFeatureDefn->Reference();
     579                 :     }
     580                 : 
     581                 :     /* If there are longitude and latitude fields, use the latitude */
     582                 :     /* field as the LOCATION field */
     583               0 :     for(i=0;i<poFeatureDefn->GetFieldCount();i++)
     584                 :     {
     585               0 :         const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef();
     586               0 :         if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") ||
     587                 :             EQUAL(pszName, "latdec"))
     588               0 :             iLatitudeField = i;
     589               0 :         else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") ||
     590                 :                  EQUAL(pszName, "londec") || EQUAL(pszName, "long"))
     591               0 :             iLongitudeField = i;
     592                 :     }
     593                 : 
     594               0 :     if (iLatitudeField >= 0 && iLongitudeField >= 0)
     595                 :     {
     596               0 :         iGeometryField = iLatitudeField;
     597               0 :         poFeatureDefn->SetGeomType( wkbPoint );
     598                 :     }
     599                 :     /* If no longitude/latitude field exist, let's look at a column */
     600                 :     /* named 'geometry' and use it as the LOCATION column if the layer */
     601                 :     /* hasn't been created with a none geometry type */
     602               0 :     else if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
     603                 :     {
     604               0 :         iGeometryField = poFeatureDefn->GetFieldIndex(GetDefaultGeometryColumnName());
     605               0 :         poFeatureDefn->SetGeomType( eGTypeForCreation );
     606                 :     }
     607                 :     /* The user doesn't want geometries, so don't create one */
     608               0 :     else if (eGTypeForCreation == wkbNone)
     609                 :     {
     610               0 :         poFeatureDefn->SetGeomType( eGTypeForCreation );
     611                 :     }
     612                 : 
     613               0 :     for(i=0;i<poFeatureDefn->GetFieldCount();i++)
     614                 :     {
     615               0 :         if (i > 0)
     616               0 :             osSQL += ", ";
     617                 : 
     618                 :         const char* pszFieldName =
     619               0 :             poFeatureDefn->GetFieldDefn(i)->GetNameRef();
     620               0 :         osSQL += EscapeAndQuote(pszFieldName);
     621               0 :         osSQL += ": ";
     622                 : 
     623               0 :         if (iGeometryField == i)
     624                 :         {
     625               0 :             osSQL += "LOCATION";
     626                 :         }
     627                 :         else
     628                 :         {
     629               0 :             switch(poFeatureDefn->GetFieldDefn(i)->GetType())
     630                 :             {
     631                 :                 case OFTInteger:
     632                 :                 case OFTReal:
     633               0 :                     osSQL += "NUMBER";
     634               0 :                     break;
     635                 :                 default:
     636               0 :                     osSQL += "STRING";
     637                 :             }
     638                 :         }
     639                 :     }
     640                 : 
     641                 :     /* If there's not yet a geometry field and the user didn't forbid */
     642                 :     /* the creation of one, then let's add it to the CREATE TABLE, but */
     643                 :     /* DO NOT add it to the feature defn as a feature might already have */
     644                 :     /* been created with it, so it is not safe to alter it at that point. */
     645                 :     /* So we set the bHiddenGeometryField flag to be able to fetch/set this */
     646                 :     /* column but not try to get/set a related feature field */
     647               0 :     if (iGeometryField < 0 && eGTypeForCreation != wkbNone)
     648                 :     {
     649               0 :         if (i > 0)
     650               0 :             osSQL += ", ";
     651               0 :         osSQL += EscapeAndQuote(GetDefaultGeometryColumnName());
     652               0 :         osSQL += ": LOCATION";
     653                 : 
     654               0 :         iGeometryField = poFeatureDefn->GetFieldCount();
     655               0 :         bHiddenGeometryField = TRUE;
     656                 :     }
     657               0 :     osSQL += ")";
     658                 : 
     659               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osSQL);
     660               0 :     if (psResult == NULL)
     661                 :     {
     662               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
     663                 :         return;
     664                 :     }
     665                 : 
     666               0 :     char* pszLine = (char*) psResult->pabyData;
     667               0 :     if (pszLine == NULL ||
     668                 :         strncmp(pszLine, "tableid", 7) != 0 ||
     669                 :         psResult->pszErrBuf != NULL)
     670                 :     {
     671               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
     672               0 :         CPLHTTPDestroyResult(psResult);
     673                 :         return;
     674                 :     }
     675                 : 
     676               0 :     pszLine = OGRGFTGotoNextLine(pszLine);
     677               0 :     if (pszLine == NULL)
     678                 :     {
     679               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Table creation failed");
     680               0 :         CPLHTTPDestroyResult(psResult);
     681                 :         return;
     682                 :     }
     683                 : 
     684               0 :     char* pszNextLine = OGRGFTGotoNextLine(pszLine);
     685               0 :     if (pszNextLine)
     686               0 :         pszNextLine[-1] = 0;
     687                 : 
     688               0 :     osTableId = pszLine;
     689               0 :     CPLDebug("GFT", "Table %s --> id = %s", osTableName.c_str(), osTableId.c_str());
     690                 : 
     691               0 :     CPLHTTPDestroyResult(psResult);
     692                 : }
     693                 : 
     694                 : /************************************************************************/
     695                 : /*                           CreateFeature()                            */
     696                 : /************************************************************************/
     697                 : 
     698               0 : OGRErr OGRGFTTableLayer::CreateFeature( OGRFeature *poFeature )
     699                 : 
     700                 : {
     701               0 :     if (!poDS->IsReadWrite())
     702                 :     {
     703                 :         CPLError(CE_Failure, CPLE_AppDefined,
     704               0 :                  "Operation not available in read-only mode");
     705               0 :         return OGRERR_FAILURE;
     706                 :     }
     707                 : 
     708               0 :     if (osTableId.size() == 0)
     709                 :     {
     710               0 :         CreateTableIfNecessary();
     711               0 :         if (osTableId.size() == 0)
     712                 :         {
     713                 :             CPLError(CE_Failure, CPLE_NotSupported,
     714               0 :                     "Cannot add feature to non-created table");
     715               0 :             return OGRERR_FAILURE;
     716                 :         }
     717                 :     }
     718                 : 
     719               0 :     if (poDS->GetAuth().size() == 0)
     720                 :     {
     721                 :         CPLError(CE_Failure, CPLE_AppDefined,
     722               0 :                  "Operation not available in unauthenticated mode");
     723               0 :         return OGRERR_FAILURE;
     724                 :     }
     725                 : 
     726               0 :     CPLString      osCommand;
     727                 : 
     728               0 :     osCommand += "INSERT INTO ";
     729               0 :     osCommand += osTableId;
     730               0 :     osCommand += " (";
     731                 : 
     732                 :     int iField;
     733               0 :     int nFieldCount = poFeatureDefn->GetFieldCount();
     734               0 :     for(iField = 0; iField < nFieldCount; iField++)
     735                 :     {
     736               0 :         if (iField > 0)
     737               0 :             osCommand += ", ";
     738                 : 
     739                 :         const char* pszFieldName =
     740               0 :             poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
     741               0 :         osCommand += EscapeAndQuote(pszFieldName);
     742                 :     }
     743               0 :     if (bHiddenGeometryField)
     744                 :     {
     745               0 :         if (iField > 0)
     746               0 :             osCommand += ", ";
     747               0 :         osCommand += EscapeAndQuote(GetGeometryColumn());
     748                 :     }
     749               0 :     osCommand += ") VALUES (";
     750               0 :     for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
     751                 :     {
     752               0 :         if (iField > 0)
     753               0 :             osCommand += ", ";
     754                 : 
     755               0 :         OGRGeometry* poGeom = poFeature->GetGeometryRef();
     756                 :         /* If there's a geometry, let's use it in priority over the textual */
     757                 :         /* content of the field. */
     758               0 :         if (iGeometryField != iLatitudeField && iField == iGeometryField &&
     759                 :             (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
     760                 :         {
     761               0 :             if (poGeom == NULL)
     762               0 :                 osCommand += "''";
     763                 :             else
     764                 :             {
     765                 :                 char* pszKML;
     766               0 :                 if (poGeom->getSpatialReference() != NULL &&
     767                 :                     !poGeom->getSpatialReference()->IsSame(poSRS))
     768                 :                 {
     769               0 :                     OGRGeometry* poGeom4326 = poGeom->clone();
     770               0 :                     poGeom4326->transformTo(poSRS);
     771               0 :                     pszKML = poGeom4326->exportToKML();
     772               0 :                     delete poGeom4326;
     773                 :                 }
     774                 :                 else
     775                 :                 {
     776               0 :                     pszKML = poGeom->exportToKML();
     777                 :                 }
     778               0 :                 osCommand += "'";
     779               0 :                 osCommand += pszKML;
     780               0 :                 osCommand += "'";
     781               0 :                 CPLFree(pszKML);
     782                 :             }
     783               0 :             continue;
     784                 :         }
     785                 : 
     786               0 :         if( !poFeature->IsFieldSet( iField ) )
     787                 :         {
     788               0 :             osCommand += "''";
     789                 :         }
     790                 :         else
     791                 :         {
     792               0 :             OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
     793               0 :             if (eType != OFTInteger && eType != OFTReal)
     794                 :             {
     795               0 :                 CPLString osTmp;
     796               0 :                 const char* pszVal = poFeature->GetFieldAsString(iField);
     797                 : 
     798               0 :                 if (!CPLIsUTF8(pszVal, -1))
     799                 :                 {
     800                 :                     static int bFirstTime = TRUE;
     801               0 :                     if (bFirstTime)
     802                 :                     {
     803               0 :                         bFirstTime = FALSE;
     804                 :                         CPLError(CE_Warning, CPLE_AppDefined,
     805                 :                                 "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
     806               0 :                                 "This warning won't be issued anymore", pszVal);
     807                 :                     }
     808                 :                     else
     809                 :                     {
     810                 :                         CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
     811               0 :                                 pszVal);
     812                 :                     }
     813               0 :                     char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
     814               0 :                     osTmp = pszEscaped;
     815               0 :                     CPLFree(pszEscaped);
     816               0 :                     pszVal = osTmp.c_str();
     817                 :                 }
     818                 : 
     819               0 :                 osCommand += EscapeAndQuote(pszVal);
     820                 :             }
     821                 :             else
     822               0 :                 osCommand += poFeature->GetFieldAsString(iField);
     823                 :         }
     824                 :     }
     825                 : 
     826               0 :     osCommand += ")";
     827                 : 
     828                 :     //CPLDebug("GFT", "%s",  osCommand.c_str());
     829                 : 
     830               0 :     if (bInTransaction)
     831                 :     {
     832               0 :         nFeaturesInTransaction ++;
     833               0 :         if (nFeaturesInTransaction > 1)
     834               0 :             osTransaction += "; ";
     835               0 :         osTransaction += osCommand;
     836               0 :         return OGRERR_NONE;
     837                 :     }
     838                 : 
     839               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
     840               0 :     if (psResult == NULL)
     841                 :     {
     842               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
     843               0 :         return OGRERR_FAILURE;
     844                 :     }
     845                 : 
     846               0 :     char* pszLine = (char*) psResult->pabyData;
     847               0 :     if (pszLine == NULL ||
     848                 :         strncmp(pszLine, "rowid", 5) != 0 ||
     849                 :         psResult->pszErrBuf != NULL)
     850                 :     {
     851               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
     852               0 :         CPLHTTPDestroyResult(psResult);
     853               0 :         return OGRERR_FAILURE;
     854                 :     }
     855                 : 
     856               0 :     pszLine = OGRGFTGotoNextLine(pszLine);
     857               0 :     if (pszLine == NULL)
     858                 :     {
     859               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature creation failed");
     860               0 :         CPLHTTPDestroyResult(psResult);
     861               0 :         return OGRERR_FAILURE;
     862                 :     }
     863                 : 
     864               0 :     char* pszNextLine = OGRGFTGotoNextLine(pszLine);
     865               0 :     if (pszNextLine)
     866               0 :         pszNextLine[-1] = 0;
     867                 : 
     868               0 :     CPLDebug("GFT", "Feature id = %s",  pszLine);
     869                 : 
     870               0 :     int nFID = atoi(pszLine);
     871               0 :     if (strcmp(CPLSPrintf("%d", nFID), pszLine) == 0)
     872               0 :         poFeature->SetFID(nFID);
     873                 : 
     874               0 :     CPLHTTPDestroyResult(psResult);
     875                 : 
     876               0 :     return OGRERR_NONE;
     877                 : }
     878                 : 
     879                 : /************************************************************************/
     880                 : /*                           SetFeature()                               */
     881                 : /************************************************************************/
     882                 : 
     883               0 : OGRErr      OGRGFTTableLayer::SetFeature( OGRFeature *poFeature )
     884                 : {
     885               0 :     GetLayerDefn();
     886                 : 
     887               0 :     if (!poDS->IsReadWrite())
     888                 :     {
     889                 :         CPLError(CE_Failure, CPLE_AppDefined,
     890               0 :                  "Operation not available in read-only mode");
     891               0 :         return OGRERR_FAILURE;
     892                 :     }
     893                 : 
     894               0 :     if (osTableId.size() == 0)
     895                 :     {
     896                 :         CPLError(CE_Failure, CPLE_NotSupported,
     897               0 :                 "Cannot set feature to non-created table");
     898               0 :         return OGRERR_FAILURE;
     899                 :     }
     900                 : 
     901               0 :     if (poDS->GetAuth().size() == 0)
     902                 :     {
     903                 :         CPLError(CE_Failure, CPLE_AppDefined,
     904               0 :                  "Operation not available in unauthenticated mode");
     905               0 :         return OGRERR_FAILURE;
     906                 :     }
     907                 : 
     908               0 :     if (poFeature->GetFID() == OGRNullFID)
     909                 :     {
     910                 :         CPLError( CE_Failure, CPLE_AppDefined,
     911               0 :                   "FID required on features given to SetFeature()." );
     912               0 :         return OGRERR_FAILURE;
     913                 :     }
     914                 : 
     915               0 :     CPLString      osCommand;
     916                 : 
     917               0 :     osCommand += "UPDATE ";
     918               0 :     osCommand += osTableId;
     919               0 :     osCommand += " SET ";
     920                 : 
     921                 :     int iField;
     922               0 :     int nFieldCount = poFeatureDefn->GetFieldCount();
     923               0 :     for(iField = 0; iField < nFieldCount + bHiddenGeometryField; iField++)
     924                 :     {
     925               0 :         if (iField > 0)
     926               0 :             osCommand += ", ";
     927                 : 
     928               0 :         if (iField == nFieldCount)
     929                 :         {
     930               0 :             osCommand += EscapeAndQuote(GetGeometryColumn());
     931                 :         }
     932                 :         else
     933                 :         {
     934                 :             const char* pszFieldName =
     935               0 :                 poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
     936               0 :             osCommand += EscapeAndQuote(pszFieldName);
     937                 :         }
     938                 : 
     939               0 :         osCommand += " = ";
     940                 : 
     941               0 :         OGRGeometry* poGeom = poFeature->GetGeometryRef();
     942               0 :         if (iGeometryField != iLatitudeField && iField == iGeometryField &&
     943                 :             (iField == nFieldCount || poGeom != NULL || !poFeature->IsFieldSet( iField )))
     944                 :         {
     945               0 :             if (poGeom == NULL)
     946               0 :                 osCommand += "''";
     947                 :             else
     948                 :             {
     949                 :                 char* pszKML;
     950               0 :                 if (poGeom->getSpatialReference() != NULL &&
     951                 :                     !poGeom->getSpatialReference()->IsSame(poSRS))
     952                 :                 {
     953               0 :                     OGRGeometry* poGeom4326 = poGeom->clone();
     954               0 :                     poGeom4326->transformTo(poSRS);
     955               0 :                     pszKML = poGeom4326->exportToKML();
     956               0 :                     delete poGeom4326;
     957                 :                 }
     958                 :                 else
     959                 :                 {
     960               0 :                     pszKML = poGeom->exportToKML();
     961                 :                 }
     962               0 :                 osCommand += "'";
     963               0 :                 osCommand += pszKML;
     964               0 :                 osCommand += "'";
     965               0 :                 CPLFree(pszKML);
     966                 :             }
     967               0 :             continue;
     968                 :         }
     969                 : 
     970               0 :         if( !poFeature->IsFieldSet( iField ) )
     971                 :         {
     972               0 :             osCommand += "''";
     973                 :         }
     974                 :         else
     975                 :         {
     976               0 :             OGRFieldType eType = poFeatureDefn->GetFieldDefn(iField)->GetType();
     977               0 :             if (eType != OFTInteger && eType != OFTReal)
     978                 :             {
     979               0 :                 CPLString osTmp;
     980               0 :                 const char* pszVal = poFeature->GetFieldAsString(iField);
     981                 : 
     982               0 :                 if (!CPLIsUTF8(pszVal, -1))
     983                 :                 {
     984                 :                     static int bFirstTime = TRUE;
     985               0 :                     if (bFirstTime)
     986                 :                     {
     987               0 :                         bFirstTime = FALSE;
     988                 :                         CPLError(CE_Warning, CPLE_AppDefined,
     989                 :                                 "%s is not a valid UTF-8 string. Forcing it to ASCII.\n"
     990               0 :                                 "This warning won't be issued anymore", pszVal);
     991                 :                     }
     992                 :                     else
     993                 :                     {
     994                 :                         CPLDebug("OGR", "%s is not a valid UTF-8 string. Forcing it to ASCII",
     995               0 :                                 pszVal);
     996                 :                     }
     997               0 :                     char* pszEscaped = CPLForceToASCII(pszVal, -1, '?');
     998               0 :                     osTmp = pszEscaped;
     999               0 :                     CPLFree(pszEscaped);
    1000               0 :                     pszVal = osTmp.c_str();
    1001                 :                 }
    1002                 : 
    1003               0 :                 osCommand += EscapeAndQuote(pszVal);
    1004                 :             }
    1005                 :             else
    1006               0 :                 osCommand += poFeature->GetFieldAsString(iField);
    1007                 :         }
    1008                 :     }
    1009                 : 
    1010               0 :     osCommand += " WHERE ROWID = '";
    1011               0 :     osCommand += CPLSPrintf("%ld", poFeature->GetFID());
    1012               0 :     osCommand += "'";
    1013                 : 
    1014                 :     //CPLDebug("GFT", "%s",  osCommand.c_str());
    1015                 : 
    1016               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    1017               0 :     if (psResult == NULL)
    1018                 :     {
    1019               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed");
    1020               0 :         return OGRERR_FAILURE;
    1021                 :     }
    1022                 : 
    1023               0 :     char* pszLine = (char*) psResult->pabyData;
    1024               0 :     if (pszLine == NULL ||
    1025                 :         strncmp(pszLine, "OK", 2) != 0 ||
    1026                 :         psResult->pszErrBuf != NULL)
    1027                 :     {
    1028               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature update failed");
    1029               0 :         CPLHTTPDestroyResult(psResult);
    1030               0 :         return OGRERR_FAILURE;
    1031                 :     }
    1032                 : 
    1033               0 :     CPLHTTPDestroyResult(psResult);
    1034                 : 
    1035               0 :     return OGRERR_NONE;
    1036                 : }
    1037                 : 
    1038                 : /************************************************************************/
    1039                 : /*                          DeleteFeature()                             */
    1040                 : /************************************************************************/
    1041                 : 
    1042               0 : OGRErr OGRGFTTableLayer::DeleteFeature( long nFID )
    1043                 : {
    1044               0 :     GetLayerDefn();
    1045                 : 
    1046               0 :     if (!poDS->IsReadWrite())
    1047                 :     {
    1048                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1049               0 :                  "Operation not available in read-only mode");
    1050               0 :         return OGRERR_FAILURE;
    1051                 :     }
    1052                 : 
    1053               0 :     if (osTableId.size() == 0)
    1054                 :     {
    1055                 :         CPLError(CE_Failure, CPLE_NotSupported,
    1056               0 :                 "Cannot delete feature in non-created table");
    1057               0 :         return OGRERR_FAILURE;
    1058                 :     }
    1059                 : 
    1060               0 :     if (poDS->GetAuth().size() == 0)
    1061                 :     {
    1062                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1063               0 :                  "Operation not available in unauthenticated mode");
    1064               0 :         return OGRERR_FAILURE;
    1065                 :     }
    1066                 : 
    1067               0 :     CPLString      osCommand;
    1068                 : 
    1069               0 :     osCommand += "DELETE FROM ";
    1070               0 :     osCommand += osTableId;
    1071               0 :     osCommand += " WHERE ROWID = '";
    1072               0 :     osCommand += CPLSPrintf("%ld", nFID);
    1073               0 :     osCommand += "'";
    1074                 : 
    1075                 :     //CPLDebug("GFT", "%s",  osCommand.c_str());
    1076                 : 
    1077               0 :     CPLHTTPResult * psResult = poDS->RunSQL(osCommand);
    1078               0 :     if (psResult == NULL)
    1079                 :     {
    1080               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed");
    1081               0 :         return OGRERR_FAILURE;
    1082                 :     }
    1083                 : 
    1084               0 :     char* pszLine = (char*) psResult->pabyData;
    1085               0 :     if (pszLine == NULL ||
    1086                 :         strncmp(pszLine, "OK", 2) != 0 ||
    1087                 :         psResult->pszErrBuf != NULL)
    1088                 :     {
    1089               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Feature deletion failed");
    1090               0 :         CPLHTTPDestroyResult(psResult);
    1091               0 :         return OGRERR_FAILURE;
    1092                 :     }
    1093                 : 
    1094               0 :     CPLHTTPDestroyResult(psResult);
    1095                 : 
    1096               0 :     return OGRERR_NONE;
    1097                 : }
    1098                 : 
    1099                 : /************************************************************************/
    1100                 : /*                         StartTransaction()                           */
    1101                 : /************************************************************************/
    1102                 : 
    1103               0 : OGRErr OGRGFTTableLayer::StartTransaction()
    1104                 : {
    1105               0 :     GetLayerDefn();
    1106                 : 
    1107               0 :     if (bInTransaction)
    1108                 :     {
    1109               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Already in transaction");
    1110               0 :         return OGRERR_FAILURE;
    1111                 :     }
    1112                 : 
    1113               0 :     if (!poDS->IsReadWrite())
    1114                 :     {
    1115                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1116               0 :                  "Operation not available in read-only mode");
    1117               0 :         return OGRERR_FAILURE;
    1118                 :     }
    1119                 : 
    1120               0 :     if (osTableId.size() == 0)
    1121                 :     {
    1122               0 :         CreateTableIfNecessary();
    1123               0 :         if (osTableId.size() == 0)
    1124                 :         {
    1125                 :             CPLError(CE_Failure, CPLE_NotSupported,
    1126               0 :                     "Cannot add feature to non-created table");
    1127               0 :             return OGRERR_FAILURE;
    1128                 :         }
    1129                 :     }
    1130                 : 
    1131               0 :     if (poDS->GetAuth().size() == 0)
    1132                 :     {
    1133                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1134               0 :                  "Operation not available in unauthenticated mode");
    1135               0 :         return OGRERR_FAILURE;
    1136                 :     }
    1137                 : 
    1138               0 :     bInTransaction = TRUE;
    1139               0 :     osTransaction.resize(0);
    1140               0 :     nFeaturesInTransaction = 0;
    1141                 : 
    1142               0 :     return OGRERR_NONE;
    1143                 : }
    1144                 : 
    1145                 : /************************************************************************/
    1146                 : /*                         CommitTransaction()                          */
    1147                 : /************************************************************************/
    1148                 : 
    1149               0 : OGRErr OGRGFTTableLayer::CommitTransaction()
    1150                 : {
    1151               0 :     GetLayerDefn();
    1152                 : 
    1153               0 :     if (!bInTransaction)
    1154                 :     {
    1155               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Should be in transaction");
    1156               0 :         return OGRERR_FAILURE;
    1157                 :     }
    1158                 : 
    1159               0 :     bInTransaction = FALSE;
    1160                 : 
    1161               0 :     if (nFeaturesInTransaction > 0)
    1162                 :     {
    1163               0 :         if (nFeaturesInTransaction > 1)
    1164               0 :             osTransaction += ";";
    1165                 : 
    1166               0 :         CPLHTTPResult * psResult = poDS->RunSQL(osTransaction);
    1167               0 :         osTransaction.resize(0);
    1168               0 :         nFeaturesInTransaction = 0;
    1169                 : 
    1170               0 :         if (psResult == NULL)
    1171                 :         {
    1172               0 :             CPLError(CE_Failure, CPLE_AppDefined, "CommitTransaction failed");
    1173               0 :             return OGRERR_FAILURE;
    1174                 :         }
    1175                 : 
    1176               0 :         char* pszLine = (char*) psResult->pabyData;
    1177               0 :         if (pszLine == NULL ||
    1178                 :             strncmp(pszLine, "rowid", 5) != 0 ||
    1179                 :             psResult->pszErrBuf != NULL)
    1180                 :         {
    1181                 :             CPLError(CE_Failure, CPLE_AppDefined, "CommitTransaction failed : %s",
    1182               0 :                      pszLine ? pszLine : psResult->pszErrBuf);
    1183               0 :             CPLHTTPDestroyResult(psResult);
    1184               0 :             return OGRERR_FAILURE;
    1185                 :         }
    1186                 : 
    1187               0 :         pszLine = OGRGFTGotoNextLine(pszLine);
    1188               0 :         while(pszLine && *pszLine != 0)
    1189                 :         {
    1190               0 :             char* pszNextLine = OGRGFTGotoNextLine(pszLine);
    1191               0 :             if (pszNextLine)
    1192               0 :                 pszNextLine[-1] = 0;
    1193                 :             //CPLDebug("GFT", "Feature id = %s",  pszLine);
    1194                 : 
    1195               0 :             pszLine = pszNextLine;
    1196                 :         }
    1197                 : 
    1198               0 :         CPLHTTPDestroyResult(psResult);
    1199                 :     }
    1200                 : 
    1201               0 :     return OGRERR_NONE;
    1202                 : }
    1203                 : 
    1204                 : /************************************************************************/
    1205                 : /*                        RollbackTransaction()                         */
    1206                 : /************************************************************************/
    1207                 : 
    1208               0 : OGRErr OGRGFTTableLayer::RollbackTransaction()
    1209                 : {
    1210               0 :     GetLayerDefn();
    1211                 : 
    1212               0 :     if (!bInTransaction)
    1213                 :     {
    1214               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Should be in transaction");
    1215               0 :         return OGRERR_FAILURE;
    1216                 :     }
    1217               0 :     bInTransaction = FALSE;
    1218               0 :     nFeaturesInTransaction = 0;
    1219               0 :     osTransaction.resize(0);
    1220               0 :     return OGRERR_NONE;
    1221                 : }
    1222                 : 
    1223                 : /************************************************************************/
    1224                 : /*                         SetAttributeFilter()                         */
    1225                 : /************************************************************************/
    1226                 : 
    1227               1 : OGRErr OGRGFTTableLayer::SetAttributeFilter( const char *pszQuery )
    1228                 : 
    1229                 : {
    1230               1 :     GetLayerDefn();
    1231                 : 
    1232               1 :     if( pszQuery == NULL )
    1233               0 :         osQuery = "";
    1234                 :     else
    1235                 :     {
    1236               1 :         osQuery = PatchSQL(pszQuery);
    1237                 :     }
    1238                 : 
    1239               1 :     BuildWhere();
    1240                 : 
    1241               1 :     ResetReading();
    1242                 : 
    1243               1 :     return OGRERR_NONE;
    1244                 : }
    1245                 : 
    1246                 : 
    1247                 : /************************************************************************/
    1248                 : /*                          SetSpatialFilter()                          */
    1249                 : /************************************************************************/
    1250                 : 
    1251               1 : void OGRGFTTableLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
    1252                 : 
    1253                 : {
    1254               1 :     GetLayerDefn();
    1255                 : 
    1256               1 :     if( InstallFilter( poGeomIn ) )
    1257                 :     {
    1258               1 :         BuildWhere();
    1259                 : 
    1260               1 :         ResetReading();
    1261                 :     }
    1262               1 : }
    1263                 : 
    1264                 : /************************************************************************/
    1265                 : /*                             BuildWhere()                             */
    1266                 : /*                                                                      */
    1267                 : /*      Build the WHERE statement appropriate to the current set of     */
    1268                 : /*      criteria (spatial and attribute queries).                       */
    1269                 : /************************************************************************/
    1270                 : 
    1271               2 : void OGRGFTTableLayer::BuildWhere()
    1272                 : 
    1273                 : {
    1274               2 :     osWHERE = "";
    1275                 : 
    1276               4 :     if( m_poFilterGeom != NULL && iGeometryField >= 0)
    1277                 :     {
    1278               2 :         OGREnvelope  sEnvelope;
    1279                 : 
    1280               2 :         m_poFilterGeom->getEnvelope( &sEnvelope );
    1281                 : 
    1282               2 :         CPLString osQuotedGeomColumn(EscapeAndQuote(GetGeometryColumn()));
    1283                 : 
    1284                 :         osWHERE.Printf("WHERE ST_INTERSECTS(%s, RECTANGLE(LATLNG(%.12f, %.12f), LATLNG(%.12f, %.12f)))",
    1285                 :                        osQuotedGeomColumn.c_str(),
    1286                 :                        MAX(-90.,sEnvelope.MinY - 1e-11), MAX(-180., sEnvelope.MinX - 1e-11),
    1287               2 :                        MIN(90.,sEnvelope.MaxY + 1e-11), MIN(180.,sEnvelope.MaxX + 1e-11));
    1288                 :     }
    1289                 : 
    1290               2 :     if( strlen(osQuery) > 0 )
    1291                 :     {
    1292               1 :         if( strlen(osWHERE) == 0 )
    1293               0 :             osWHERE = "WHERE ";
    1294                 :         else
    1295               1 :             osWHERE += " AND ";
    1296               1 :         osWHERE += osQuery;
    1297                 :     }
    1298               2 : }
    1299                 : 
    1300                 : /************************************************************************/
    1301                 : /*                          SetGeometryType()                           */
    1302                 : /************************************************************************/
    1303                 : 
    1304               0 : void OGRGFTTableLayer::SetGeometryType(OGRwkbGeometryType eGType)
    1305                 : {
    1306               0 :     eGTypeForCreation = eGType;
    1307               0 : }

Generated by: LCOV version 1.7