LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitetablelayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 688 531 77.2 %
Date: 2012-04-28 Functions: 32 28 87.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitetablelayer.cpp 24314 2012-04-24 21:01:34Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRSQLiteTableLayer class, access to an existing table.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2004, Frank Warmerdam
      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 "cpl_conv.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_sqlite.h"
      33                 : #include "ogr_p.h"
      34                 : #include <string>
      35                 : 
      36                 : #define UNSUPPORTED_OP_READ_ONLY "%s : unsupported operation on a read-only datasource."
      37                 : 
      38                 : CPL_CVSID("$Id: ogrsqlitetablelayer.cpp 24314 2012-04-24 21:01:34Z rouault $");
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                        OGRSQLiteTableLayer()                         */
      42                 : /************************************************************************/
      43                 : 
      44            2168 : OGRSQLiteTableLayer::OGRSQLiteTableLayer( OGRSQLiteDataSource *poDSIn )
      45                 : 
      46                 : {
      47            2168 :     poDS = poDSIn;
      48                 :   
      49            2168 :     bSpatialite2D = FALSE;
      50            2168 :     bLaunderColumnNames = TRUE;
      51                 : 
      52            2168 :     iNextShapeId = 0;
      53                 : 
      54            2168 :     nSRSId = -1;
      55                 : 
      56            2168 :     poFeatureDefn = NULL;
      57            2168 :     pszTableName = NULL;
      58            2168 :     pszEscapedTableName = NULL;
      59                 : 
      60            2168 :     bHasCheckedSpatialIndexTable = FALSE;
      61                 : 
      62            2168 :     hInsertStmt = NULL;
      63                 : 
      64            2168 :     eGeomType = wkbUnknown;
      65            2168 :     bLayerDefnError = FALSE;
      66                 : 
      67            2168 :     bCachedExtentIsValid = FALSE;
      68            2168 : }
      69                 : 
      70                 : /************************************************************************/
      71                 : /*                        ~OGRSQLiteTableLayer()                        */
      72                 : /************************************************************************/
      73                 : 
      74            2168 : OGRSQLiteTableLayer::~OGRSQLiteTableLayer()
      75                 : 
      76                 : {
      77            2168 :     ClearStatement();
      78            2168 :     ClearInsertStmt();
      79            2168 :     CPLFree(pszTableName);
      80            2168 :     CPLFree(pszEscapedTableName);
      81            2168 : }
      82                 : 
      83                 : /************************************************************************/
      84                 : /*                          ClearInsertStmt()                           */
      85                 : /************************************************************************/
      86                 : 
      87            2608 : void OGRSQLiteTableLayer::ClearInsertStmt()
      88                 : {
      89            2608 :     if( hInsertStmt != NULL )
      90                 :     {
      91             328 :         sqlite3_finalize( hInsertStmt );
      92             328 :         hInsertStmt = NULL;
      93                 :     }
      94            2608 :     osLastInsertStmt = "";
      95            2608 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                             Initialize()                             */
      99                 : /************************************************************************/
     100                 : 
     101            2168 : CPLErr OGRSQLiteTableLayer::Initialize( const char *pszTableName, 
     102                 :                                         const char *pszGeomCol,
     103                 :                                         OGRwkbGeometryType eGeomType,
     104                 :                                         const char *pszGeomFormat,
     105                 :                                         OGRSpatialReference *poSRS,
     106                 :                                         int nSRSId,
     107                 :                                         int bHasSpatialIndex,
     108                 :                                         int bHasM, 
     109                 :                                         int bSpatialiteReadOnly,
     110                 :                                         int bSpatialiteLoaded,
     111                 :                                         int iSpatialiteVersion,
     112                 :                                         int bIsVirtualShapeIn )
     113                 : 
     114                 : {
     115                 :     int rc;
     116            2168 :     sqlite3 *hDB = poDS->GetDB();
     117                 : 
     118            2168 :     if( pszGeomCol == NULL )
     119            1630 :         osGeomColumn = "";
     120                 :     else
     121             538 :         osGeomColumn = pszGeomCol;
     122                 : 
     123            2168 :     if( pszGeomFormat )
     124                 :     {
     125             538 :         if ( EQUAL(pszGeomFormat, "WKT") )
     126              14 :             eGeomFormat = OSGF_WKT;
     127             524 :         else if ( EQUAL(pszGeomFormat,"WKB") )
     128             102 :             eGeomFormat = OSGF_WKB;
     129             422 :         else if ( EQUAL(pszGeomFormat,"FGF") )
     130               2 :             eGeomFormat = OSGF_FGF;
     131             420 :         else if( EQUAL(pszGeomFormat,"SpatiaLite") )
     132             420 :             eGeomFormat = OSGF_SpatiaLite;
     133                 :     }
     134                 : 
     135            2168 :     CPLFree( pszFIDColumn );
     136            2168 :     pszFIDColumn = NULL;
     137                 : 
     138            2168 :     this->poSRS = poSRS;
     139            2168 :     this->nSRSId = nSRSId;
     140            2168 :     this->bHasSpatialIndex = bHasSpatialIndex;
     141            2168 :     this->bHasM = bHasM;
     142            2168 :     this->bSpatialiteReadOnly = bSpatialiteReadOnly;
     143            2168 :     this->bSpatialiteLoaded = bSpatialiteLoaded;
     144            2168 :     this->iSpatialiteVersion = iSpatialiteVersion;
     145            2168 :     this->bIsVirtualShape = bIsVirtualShapeIn;
     146            2168 :     this->pszTableName = CPLStrdup(pszTableName);
     147            2168 :     this->eGeomType = eGeomType;
     148                 : 
     149            2168 :     pszEscapedTableName = CPLStrdup(OGRSQLiteEscape(pszTableName));
     150                 : 
     151            2168 :     sqlite3_stmt *hColStmt = NULL;
     152                 :     const char *pszSQL;
     153                 : 
     154            2588 :     if ( eGeomFormat == OSGF_SpatiaLite &&
     155                 :          bSpatialiteLoaded == TRUE && 
     156                 :          iSpatialiteVersion < 24 && poDS->GetUpdate() )
     157                 :     {
     158                 :     // we need to test version required by Spatialite TRIGGERs 
     159               0 :         hColStmt = NULL;
     160                 :         pszSQL = CPLSPrintf( "SELECT sql FROM sqlite_master WHERE type = 'trigger' AND tbl_name = '%s' AND sql LIKE '%%RTreeAlign%%'",
     161               0 :             pszEscapedTableName );
     162                 : 
     163                 :         int nRowTriggerCount, nColTriggerCount;
     164                 :         char **papszTriggerResult, *pszErrMsg;
     165                 : 
     166                 :         rc = sqlite3_get_table( hDB, pszSQL, &papszTriggerResult,
     167               0 :             &nRowTriggerCount, &nColTriggerCount, &pszErrMsg );
     168               0 :         if( nRowTriggerCount >= 1 )
     169                 :         {
     170                 :         // obsolete library version not supporting new triggers
     171                 :         // enforcing ReadOnly mode
     172               0 :             CPLDebug("SQLITE", "Enforcing ReadOnly mode : obsolete library version not supporting new triggers");
     173               0 :             this->bSpatialiteReadOnly = TRUE;
     174                 :         }
     175                 : 
     176               0 :         sqlite3_free_table( papszTriggerResult );
     177                 :     }
     178                 :   
     179            2168 :     if( poSRS )
     180             450 :         poSRS->Reference();
     181                 : 
     182            2168 :     return CE_None;
     183                 : }
     184                 : 
     185                 : /************************************************************************/
     186                 : /*                         EstablishFeatureDefn()                       */
     187                 : /************************************************************************/
     188                 : 
     189            1192 : CPLErr OGRSQLiteTableLayer::EstablishFeatureDefn()
     190                 : {
     191            1192 :     sqlite3 *hDB = poDS->GetDB();
     192                 :     int rc;
     193                 :     const char *pszSQL;
     194            1192 :     sqlite3_stmt *hColStmt = NULL;
     195                 : 
     196                 : /* -------------------------------------------------------------------- */
     197                 : /*      Get the column definitions for this table.                      */
     198                 : /* -------------------------------------------------------------------- */
     199                 : 
     200                 :     pszSQL = CPLSPrintf( "SELECT _rowid_, * FROM '%s' LIMIT 1",
     201            1192 :                                      pszEscapedTableName );
     202                 : 
     203            1192 :     rc = sqlite3_prepare( hDB, pszSQL, strlen(pszSQL), &hColStmt, NULL ); 
     204            1192 :     if( rc != SQLITE_OK )
     205                 :     {
     206                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     207                 :                   "Unable to query table %s for column definitions : %s.",
     208               0 :                   pszTableName, sqlite3_errmsg(hDB) );
     209                 :         
     210               0 :         return CE_Failure;
     211                 :     }
     212                 : 
     213            1192 :     rc = sqlite3_step( hColStmt );
     214            1192 :     if ( rc != SQLITE_DONE && rc != SQLITE_ROW )
     215                 :     {
     216                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     217                 :                   "In Initialize(): sqlite3_step(%s):\n  %s", 
     218               0 :                   pszSQL, sqlite3_errmsg(hDB) );
     219               0 :         sqlite3_finalize( hColStmt );
     220               0 :         return CE_Failure;
     221                 :     }
     222                 : 
     223                 : /* -------------------------------------------------------------------- */
     224                 : /*      What should we use as FID?  If there is a primary key           */
     225                 : /*      integer field, then this will be used as the _rowid_, and we    */
     226                 : /*      will pick up the real column name here.  Otherwise, we will     */
     227                 : /*      just use fid.                                                   */
     228                 : /*                                                                      */
     229                 : /*      Note that the select _rowid_ will return the real column        */
     230                 : /*      name if the rowid corresponds to another primary key            */
     231                 : /*      column.                                                         */
     232                 : /* -------------------------------------------------------------------- */
     233            1192 :     pszFIDColumn = CPLStrdup(sqlite3_column_name( hColStmt, 0 ));
     234                 : 
     235                 : /* -------------------------------------------------------------------- */
     236                 : /*      Collect the rest of the fields.                                 */
     237                 : /* -------------------------------------------------------------------- */
     238            1192 :     BuildFeatureDefn( pszTableName, hColStmt );
     239            1192 :     sqlite3_finalize( hColStmt );
     240                 : 
     241                 : /* -------------------------------------------------------------------- */
     242                 : /*      Set the geometry type if we know it.                            */
     243                 : /* -------------------------------------------------------------------- */
     244            1192 :     if( eGeomType != wkbUnknown )
     245             368 :         poFeatureDefn->SetGeomType( eGeomType );
     246                 : 
     247            1192 :     return CE_None;
     248                 : }
     249                 : 
     250                 : /************************************************************************/
     251                 : /*                           GetLayerDefn()                             */
     252                 : /************************************************************************/
     253                 : 
     254            5820 : OGRFeatureDefn* OGRSQLiteTableLayer::GetLayerDefn()
     255                 : {
     256            5820 :     if (poFeatureDefn)
     257            4628 :         return poFeatureDefn;
     258                 : 
     259            1192 :     EstablishFeatureDefn();
     260                 : 
     261            1192 :     if (poFeatureDefn == NULL)
     262                 :     {
     263               0 :         bLayerDefnError = TRUE;
     264                 : 
     265               0 :         poFeatureDefn = new OGRFeatureDefn( pszTableName );
     266               0 :         poFeatureDefn->Reference();
     267                 :     }
     268                 : 
     269            1192 :     return poFeatureDefn;
     270                 : }
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                           ResetStatement()                           */
     274                 : /************************************************************************/
     275                 : 
     276             418 : OGRErr OGRSQLiteTableLayer::ResetStatement()
     277                 : 
     278                 : {
     279                 :     int rc;
     280             418 :     CPLString osSQL;
     281                 : 
     282             418 :     ClearStatement();
     283                 : 
     284             418 :     iNextShapeId = 0;
     285                 : 
     286                 :     osSQL.Printf( "SELECT _rowid_, * FROM '%s' %s",
     287                 :                     pszEscapedTableName, 
     288             418 :                     osWHERE.c_str() );
     289                 : 
     290                 : 
     291                 : //#ifdef HAVE_SQLITE3_PREPARE_V2
     292                 : //    rc = sqlite3_prepare_v2( poDS->GetDB(), osSQL, osSQL.size(),
     293                 : //                  &hStmt, NULL );
     294                 : //#else
     295                 :     rc = sqlite3_prepare( poDS->GetDB(), osSQL, osSQL.size(),
     296             418 :               &hStmt, NULL );
     297                 : //#endif
     298                 : 
     299             418 :     if( rc == SQLITE_OK )
     300                 :     {
     301             416 :   return OGRERR_NONE;
     302                 :     }
     303                 :     else
     304                 :     {
     305                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     306                 :                   "In ResetStatement(): sqlite3_prepare(%s):\n  %s", 
     307               2 :                   osSQL.c_str(), sqlite3_errmsg(poDS->GetDB()) );
     308               2 :         hStmt = NULL;
     309               2 :         return OGRERR_FAILURE;
     310               0 :     }
     311                 : }
     312                 : 
     313                 : /************************************************************************/
     314                 : /*                           GetNextFeature()                           */
     315                 : /************************************************************************/
     316                 : 
     317            1148 : OGRFeature *OGRSQLiteTableLayer::GetNextFeature()
     318                 : 
     319                 : {
     320            1148 :     if (HasLayerDefnError())
     321               0 :         return NULL;
     322                 : 
     323            1148 :     return OGRSQLiteLayer::GetNextFeature();
     324                 : }
     325                 : 
     326                 : /************************************************************************/
     327                 : /*                             GetFeature()                             */
     328                 : /************************************************************************/
     329                 : 
     330              16 : OGRFeature *OGRSQLiteTableLayer::GetFeature( long nFeatureId )
     331                 : 
     332                 : {
     333              16 :     if (HasLayerDefnError())
     334               0 :         return NULL;
     335                 : 
     336                 : /* -------------------------------------------------------------------- */
     337                 : /*      If we don't have an explicit FID column, just read through      */
     338                 : /*      the result set iteratively to find our target.                  */
     339                 : /* -------------------------------------------------------------------- */
     340              16 :     if( pszFIDColumn == NULL )
     341               0 :         return OGRSQLiteLayer::GetFeature( nFeatureId );
     342                 : 
     343                 : /* -------------------------------------------------------------------- */
     344                 : /*      Setup explicit query statement to fetch the record we want.     */
     345                 : /* -------------------------------------------------------------------- */
     346              16 :     CPLString osSQL;
     347                 :     int rc;
     348                 : 
     349              16 :     ClearStatement();
     350                 : 
     351              16 :     iNextShapeId = nFeatureId;
     352                 : 
     353                 :     osSQL.Printf( "SELECT _rowid_, * FROM '%s' WHERE \"%s\" = %ld",
     354                 :                   pszEscapedTableName, 
     355              16 :                   pszFIDColumn, nFeatureId );
     356                 : 
     357              16 :     CPLDebug( "OGR_SQLITE", "exec(%s)", osSQL.c_str() );
     358                 : 
     359                 :     rc = sqlite3_prepare( poDS->GetDB(), osSQL, osSQL.size(), 
     360              16 :                           &hStmt, NULL );
     361              16 :     if( rc != SQLITE_OK )
     362                 :     {
     363                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     364                 :                   "In GetFeature(): sqlite3_prepare(%s):\n  %s", 
     365               0 :                   osSQL.c_str(), sqlite3_errmsg(poDS->GetDB()) );
     366                 : 
     367               0 :         return NULL;
     368                 :     }
     369                 : /* -------------------------------------------------------------------- */
     370                 : /*      Get the feature if possible.                                    */
     371                 : /* -------------------------------------------------------------------- */
     372              16 :     OGRFeature *poFeature = NULL;
     373                 : 
     374              16 :     poFeature = GetNextRawFeature();
     375                 : 
     376              16 :     ResetReading();
     377                 : 
     378              16 :     return poFeature;
     379                 : }
     380                 : 
     381                 : /************************************************************************/
     382                 : /*                         SetAttributeFilter()                         */
     383                 : /************************************************************************/
     384                 : 
     385              80 : OGRErr OGRSQLiteTableLayer::SetAttributeFilter( const char *pszQuery )
     386                 : 
     387                 : {
     388              80 :     if( pszQuery == NULL )
     389              38 :         osQuery = "";
     390                 :     else
     391              42 :         osQuery = pszQuery;
     392                 : 
     393              80 :     BuildWhere();
     394                 : 
     395              80 :     ResetReading();
     396                 : 
     397              80 :     return OGRERR_NONE;
     398                 : }
     399                 : 
     400                 : 
     401                 : /************************************************************************/
     402                 : /*                          SetSpatialFilter()                          */
     403                 : /************************************************************************/
     404                 : 
     405              52 : void OGRSQLiteTableLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
     406                 : 
     407                 : {
     408              52 :     if( InstallFilter( poGeomIn ) )
     409                 :     {
     410              22 :         BuildWhere();
     411                 : 
     412              22 :         ResetReading();
     413                 :     }
     414              52 : }
     415                 : 
     416                 : /************************************************************************/
     417                 : /*                        CheckSpatialIndexTable()                      */
     418                 : /************************************************************************/
     419                 : 
     420             100 : int OGRSQLiteTableLayer::CheckSpatialIndexTable()
     421                 : {
     422             100 :     if (bHasSpatialIndex && !bHasCheckedSpatialIndexTable)
     423                 :     {
     424              56 :         bHasCheckedSpatialIndexTable = TRUE;
     425                 :         char **papszResult;
     426                 :         int nRowCount, nColCount;
     427              56 :         char *pszErrMsg = NULL;
     428                 : 
     429              56 :         CPLString osSQL;
     430                 : 
     431                 :         /* This will ensure that RTree support is available */
     432                 :         osSQL.Printf("SELECT pkid FROM 'idx_%s_%s' WHERE xmax > 0 AND xmin < 0 AND ymax > 0 AND ymin < 0",
     433              56 :                      pszEscapedTableName, osGeomColumn.c_str());
     434                 : 
     435                 :         int  rc = sqlite3_get_table( poDS->GetDB(), osSQL.c_str(),
     436                 :                                     &papszResult, &nRowCount,
     437              56 :                                     &nColCount, &pszErrMsg );
     438                 : 
     439              56 :         if( rc != SQLITE_OK )
     440                 :         {
     441                 :             CPLDebug("SQLITE", "Count not find or use idx_%s_%s layer (%s). Disabling spatial index",
     442               0 :                         pszEscapedTableName, osGeomColumn.c_str(), pszErrMsg);
     443               0 :             sqlite3_free( pszErrMsg );
     444               0 :             bHasSpatialIndex = FALSE;
     445                 :         }
     446                 :         else
     447                 :         {
     448              56 :             sqlite3_free_table(papszResult);
     449              56 :         }
     450                 :     }
     451                 : 
     452             100 :     return bHasSpatialIndex;
     453                 : }
     454                 : 
     455                 : /************************************************************************/
     456                 : /*                           GetSpatialWhere()                          */
     457                 : /************************************************************************/
     458                 : 
     459             118 : CPLString OGRSQLiteTableLayer::GetSpatialWhere(OGRGeometry* poFilterGeom)
     460                 : {
     461             118 :     CPLString osSpatialWHERE;
     462                 : 
     463             118 :     if( poFilterGeom != NULL && CheckSpatialIndexTable() )
     464                 :     {
     465              22 :         OGREnvelope  sEnvelope;
     466                 : 
     467              22 :         CPLLocaleC  oLocaleEnforcer;
     468                 : 
     469              22 :         poFilterGeom->getEnvelope( &sEnvelope );
     470                 : 
     471                 :         osSpatialWHERE.Printf("ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE "
     472                 :                         "xmax >= %.12f AND xmin <= %.12f AND ymax >= %.12f AND ymin <= %.12f)",
     473                 :                         pszEscapedTableName, osGeomColumn.c_str(),
     474                 :                         sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11,
     475              22 :                         sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11);
     476                 :     }
     477                 : 
     478             118 :     if( poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex)
     479                 :     {
     480               2 :         OGREnvelope  sEnvelope;
     481                 : 
     482               2 :         CPLLocaleC  oLocaleEnforcer;
     483                 : 
     484               2 :         poFilterGeom->getEnvelope( &sEnvelope );
     485                 : 
     486                 :         /* A bit inefficient but still faster than OGR filtering */
     487                 :         osSpatialWHERE.Printf("MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d))",
     488                 :                        osGeomColumn.c_str(),
     489                 :                        sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11,
     490                 :                        sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11,
     491               2 :                        nSRSId);
     492                 :     }
     493                 : 
     494               0 :     return osSpatialWHERE;
     495                 : }
     496                 : 
     497                 : /************************************************************************/
     498                 : /*                             BuildWhere()                             */
     499                 : /*                                                                      */
     500                 : /*      Build the WHERE statement appropriate to the current set of     */
     501                 : /*      criteria (spatial and attribute queries).                       */
     502                 : /************************************************************************/
     503                 : 
     504             102 : void OGRSQLiteTableLayer::BuildWhere()
     505                 : 
     506                 : {
     507             102 :     osWHERE = "";
     508                 : 
     509             102 :     CPLString osSpatialWHERE = GetSpatialWhere(m_poFilterGeom);
     510             204 :     if (osSpatialWHERE.size() != 0)
     511                 :     {
     512               8 :         osWHERE = "WHERE ";
     513               8 :         osWHERE += osSpatialWHERE;
     514                 :     }
     515                 : 
     516             102 :     if( osQuery.size() > 0 )
     517                 :     {
     518              38 :         if( osWHERE.size() == 0 )
     519                 :         {
     520              38 :             osWHERE = "WHERE ";
     521              38 :             osWHERE += osQuery;
     522                 :         }
     523                 :         else  
     524                 :         {
     525               0 :             osWHERE += " AND (";
     526               0 :             osWHERE += osQuery;
     527               0 :             osWHERE += ")";
     528                 :         }
     529             102 :     }
     530             102 : }
     531                 : 
     532                 : /************************************************************************/
     533                 : /*                           TestCapability()                           */
     534                 : /************************************************************************/
     535                 : 
     536             126 : int OGRSQLiteTableLayer::TestCapability( const char * pszCap )
     537                 : 
     538                 : {
     539             126 :     if (EQUAL(pszCap,OLCFastFeatureCount))
     540                 :         return m_poFilterGeom == NULL || osGeomColumn.size() == 0 ||
     541              78 :                bHasSpatialIndex;
     542                 : 
     543              48 :     else if (EQUAL(pszCap,OLCFastSpatialFilter))
     544               4 :         return bHasSpatialIndex;
     545                 : 
     546              44 :     else if( EQUAL(pszCap,OLCRandomRead) )
     547               8 :         return pszFIDColumn != NULL;
     548                 : 
     549              36 :     else if( EQUAL(pszCap,OLCSequentialWrite) 
     550                 :              || EQUAL(pszCap,OLCRandomWrite) )
     551                 :     {
     552               8 :         if ( bSpatialiteReadOnly == TRUE)
     553               0 :             return FALSE;
     554               8 :         return poDS->GetUpdate();
     555                 :     }
     556                 : 
     557              28 :     else if( EQUAL(pszCap,OLCDeleteFeature) )
     558                 :     {
     559               6 :         if ( bSpatialiteReadOnly == TRUE)
     560               0 :             return FALSE;
     561               6 :         return poDS->GetUpdate() && pszFIDColumn != NULL;
     562                 :     }
     563                 : 
     564              22 :     else if( EQUAL(pszCap,OLCCreateField) )
     565               0 :         return poDS->GetUpdate();
     566                 : 
     567              22 :     else if( EQUAL(pszCap,OLCDeleteField) )
     568               2 :         return poDS->GetUpdate();
     569                 : 
     570              20 :     else if( EQUAL(pszCap,OLCAlterFieldDefn) )
     571               2 :         return poDS->GetUpdate();
     572                 : 
     573              18 :     else if( EQUAL(pszCap,OLCReorderFields) )
     574               2 :         return poDS->GetUpdate();
     575                 : 
     576                 :     else 
     577              16 :         return OGRSQLiteLayer::TestCapability( pszCap );
     578                 : }
     579                 : 
     580                 : /************************************************************************/
     581                 : /*                          GetFeatureCount()                           */
     582                 : /*                                                                      */
     583                 : /*      If a spatial filter is in effect, we turn control over to       */
     584                 : /*      the generic counter.  Otherwise we return the total count.      */
     585                 : /*      Eventually we should consider implementing a more efficient     */
     586                 : /*      way of counting features matching a spatial query.              */
     587                 : /************************************************************************/
     588                 : 
     589              74 : int OGRSQLiteTableLayer::GetFeatureCount( int bForce )
     590                 : 
     591                 : {
     592              74 :     if (HasLayerDefnError())
     593               0 :         return 0;
     594                 : 
     595              74 :     if( !TestCapability(OLCFastFeatureCount) )
     596              10 :         return OGRSQLiteLayer::GetFeatureCount( bForce );
     597                 : 
     598                 : /* -------------------------------------------------------------------- */
     599                 : /*      Form count SQL.                                                 */
     600                 : /* -------------------------------------------------------------------- */
     601                 :     const char *pszSQL;
     602                 : 
     603              64 :     if (m_poFilterGeom != NULL && CheckSpatialIndexTable() &&
     604                 :         strlen(osQuery) == 0)
     605                 :     {
     606               6 :         OGREnvelope  sEnvelope;
     607                 : 
     608               6 :         m_poFilterGeom->getEnvelope( &sEnvelope );
     609                 :         pszSQL = CPLSPrintf("SELECT count(*) FROM 'idx_%s_%s' WHERE "
     610                 :                             "xmax >= %.12f AND xmin <= %.12f AND ymax >= %.12f AND ymin <= %.12f",
     611                 :                             pszEscapedTableName, osGeomColumn.c_str(),
     612                 :                             sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11,
     613               6 :                             sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11);
     614                 :     }
     615                 :     else
     616                 :     {
     617                 :         pszSQL = CPLSPrintf( "SELECT count(*) FROM '%s' %s",
     618              58 :                             pszEscapedTableName, osWHERE.c_str() );
     619                 :     }
     620                 : 
     621              64 :     CPLDebug("SQLITE", "Running %s", pszSQL);
     622                 : 
     623                 : /* -------------------------------------------------------------------- */
     624                 : /*      Execute.                                                        */
     625                 : /* -------------------------------------------------------------------- */
     626                 :     char **papszResult, *pszErrMsg;
     627                 :     int nRowCount, nColCount;
     628              64 :     int nResult = -1;
     629                 : 
     630              64 :     if( sqlite3_get_table( poDS->GetDB(), pszSQL, &papszResult, 
     631                 :                            &nRowCount, &nColCount, &pszErrMsg ) != SQLITE_OK )
     632               0 :         return -1;
     633                 : 
     634              64 :     if( nRowCount == 1 && nColCount == 1 )
     635              64 :         nResult = atoi(papszResult[1]);
     636                 : 
     637              64 :     sqlite3_free_table( papszResult );
     638                 : 
     639              64 :     return nResult;
     640                 : }
     641                 : 
     642                 : /************************************************************************/
     643                 : /*                             GetExtent()                              */
     644                 : /************************************************************************/
     645                 : 
     646              60 : OGRErr OGRSQLiteTableLayer::GetExtent(OGREnvelope *psExtent, int bForce)
     647                 : {
     648              60 :     if (HasLayerDefnError())
     649               0 :         return OGRERR_FAILURE;
     650                 : 
     651              60 :     if (GetGeomType() == wkbNone)
     652               0 :         return OGRERR_FAILURE;
     653                 : 
     654              60 :     if (bCachedExtentIsValid)
     655                 :     {
     656               2 :         memcpy(psExtent, &oCachedExtent, sizeof(oCachedExtent));
     657               2 :         return OGRERR_NONE;
     658                 :     }
     659                 : 
     660              58 :     if (CheckSpatialIndexTable() &&
     661                 :         !CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_EXACT_EXTENT", "NO")))
     662                 :     {
     663                 :         const char* pszSQL;
     664                 : 
     665                 :         pszSQL = CPLSPrintf("SELECT MIN(xmin), MIN(ymin), MAX(xmax), MAX(ymax) FROM 'idx_%s_%s'",
     666               4 :                             pszEscapedTableName, osGeomColumn.c_str());
     667                 : 
     668               4 :         CPLDebug("SQLITE", "Running %s", pszSQL);
     669                 : 
     670                 : /* -------------------------------------------------------------------- */
     671                 : /*      Execute.                                                        */
     672                 : /* -------------------------------------------------------------------- */
     673                 :         char **papszResult, *pszErrMsg;
     674                 :         int nRowCount, nColCount;
     675                 : 
     676               4 :         if( sqlite3_get_table( poDS->GetDB(), pszSQL, &papszResult,
     677                 :                                &nRowCount, &nColCount, &pszErrMsg ) != SQLITE_OK )
     678               0 :             return OGRSQLiteLayer::GetExtent(psExtent, bForce);
     679                 : 
     680               4 :         OGRErr eErr = OGRERR_FAILURE;
     681                 : 
     682              20 :         if( nRowCount == 1 && nColCount == 4 &&
     683               4 :             papszResult[4+0] != NULL &&
     684               4 :             papszResult[4+1] != NULL &&
     685               4 :             papszResult[4+2] != NULL &&
     686               4 :             papszResult[4+3] != NULL)
     687                 :         {
     688               4 :             psExtent->MinX = atof(papszResult[4+0]);
     689               4 :             psExtent->MinY = atof(papszResult[4+1]);
     690               4 :             psExtent->MaxX = atof(papszResult[4+2]);
     691               4 :             psExtent->MaxY = atof(papszResult[4+3]);
     692               4 :             eErr = OGRERR_NONE;
     693                 : 
     694               4 :             bCachedExtentIsValid = TRUE;
     695               4 :             memcpy(&oCachedExtent, psExtent, sizeof(oCachedExtent));
     696                 :         }
     697                 : 
     698               4 :         sqlite3_free_table( papszResult );
     699                 : 
     700               4 :         if (eErr == OGRERR_NONE)
     701               4 :             return eErr;
     702                 :     }
     703                 : 
     704              54 :     OGRErr eErr = OGRSQLiteLayer::GetExtent(psExtent, bForce);
     705              54 :     if (eErr == OGRERR_NONE)
     706                 :     {
     707              54 :         bCachedExtentIsValid = TRUE;
     708              54 :         memcpy(&oCachedExtent, psExtent, sizeof(oCachedExtent));
     709                 :     }
     710              54 :     return eErr;
     711                 : }
     712                 : 
     713                 : /************************************************************************/
     714                 : /*                      OGRFieldTypeToSQliteType()                      */
     715                 : /************************************************************************/
     716                 : 
     717             256 : static const char* OGRFieldTypeToSQliteType( OGRFieldType eType )
     718                 : {
     719             256 :     if( eType == OFTInteger )
     720              26 :         return "INTEGER";
     721             230 :     else if( eType == OFTReal )
     722              22 :         return "FLOAT";
     723             208 :     else if( eType == OFTBinary )
     724              10 :         return "BLOB";
     725                 :     else
     726             198 :         return "VARCHAR";
     727                 : }
     728                 : 
     729                 : /************************************************************************/
     730                 : /*                            CreateField()                             */
     731                 : /************************************************************************/
     732                 : 
     733              78 : OGRErr OGRSQLiteTableLayer::CreateField( OGRFieldDefn *poFieldIn, 
     734                 :                                          int bApproxOK )
     735                 : 
     736                 : {
     737              78 :     OGRFieldDefn        oField( poFieldIn );
     738                 : 
     739              78 :     if (HasLayerDefnError())
     740               0 :         return OGRERR_FAILURE;
     741                 : 
     742              78 :     ResetReading();
     743                 : 
     744              78 :     if (!poDS->GetUpdate())
     745                 :     {
     746                 :         CPLError( CE_Failure, CPLE_NotSupported,
     747                 :                   UNSUPPORTED_OP_READ_ONLY,
     748               0 :                   "CreateField");
     749               0 :         return OGRERR_FAILURE;
     750                 :     }
     751                 : 
     752              78 :     ClearInsertStmt();
     753                 : 
     754                 : /* -------------------------------------------------------------------- */
     755                 : /*      Do we want to "launder" the column names into SQLite            */
     756                 : /*      friendly format?                                                */
     757                 : /* -------------------------------------------------------------------- */
     758              78 :     if( bLaunderColumnNames )
     759                 :     {
     760              78 :         char    *pszSafeName = poDS->LaunderName( oField.GetNameRef() );
     761                 : 
     762              78 :         oField.SetName( pszSafeName );
     763              78 :         CPLFree( pszSafeName );
     764                 :     }
     765                 : 
     766                 :     /* ADD COLUMN only avaliable since sqlite 3.1.3 */
     767              78 :     if (CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_USE_ADD_COLUMN", "YES")) &&
     768                 :         sqlite3_libversion_number() > 3 * 1000000 + 1 * 1000 + 3)
     769                 :     {
     770                 :         int rc;
     771              78 :         char *pszErrMsg = NULL;
     772              78 :         sqlite3 *hDB = poDS->GetDB();
     773              78 :         CPLString osCommand;
     774                 : 
     775                 :         osCommand.Printf("ALTER TABLE '%s' ADD COLUMN '%s' %s",
     776                 :                         pszEscapedTableName,
     777                 :                         oField.GetNameRef(),
     778              78 :                         OGRFieldTypeToSQliteType(oField.GetType()));
     779                 : 
     780                 :     #ifdef DEBUG
     781              78 :         CPLDebug( "OGR_SQLITE", "exec(%s)", osCommand.c_str() );
     782                 :     #endif
     783                 : 
     784              78 :         rc = sqlite3_exec( hDB, osCommand, NULL, NULL, &pszErrMsg );
     785              78 :         if( rc != SQLITE_OK )
     786                 :         {
     787                 :             CPLError( CE_Failure, CPLE_AppDefined,
     788                 :                       "Failed to add field %s to table %s:\n %s",
     789                 :                       oField.GetNameRef(), poFeatureDefn->GetName(), 
     790               0 :                       pszErrMsg );
     791               0 :             sqlite3_free( pszErrMsg );
     792               0 :             return OGRERR_FAILURE;
     793               0 :         }
     794                 :     }
     795                 :     else
     796                 :     {
     797               0 :         OGRErr eErr = AddColumnAncientMethod(oField);
     798               0 :         if (eErr != OGRERR_NONE)
     799               0 :             return eErr;
     800                 :     }
     801                 : 
     802                 : /* -------------------------------------------------------------------- */
     803                 : /*      Add the field to the OGRFeatureDefn.                            */
     804                 : /* -------------------------------------------------------------------- */
     805                 :     int iNewField;
     806              78 :     int iNextOrdinal = 3; /* _rowid_ is 1, OGC_FID is 2 */
     807                 : 
     808              78 :     if( poFeatureDefn->GetGeomType() != wkbNone )
     809                 :     {
     810              78 :         iNextOrdinal++;
     811                 :     }
     812                 : 
     813             182 :     for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     814                 :     {
     815             104 :         OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField);
     816                 : 
     817                 :         // we already added OGC_FID so don't do it again
     818             104 :         if( EQUAL(poFldDefn->GetNameRef(),"OGC_FID") )
     819               0 :             continue;
     820                 : 
     821             104 :         iNextOrdinal++;
     822                 :     }
     823                 : 
     824              78 :     poFeatureDefn->AddFieldDefn( &oField );
     825                 : 
     826              78 :     iNewField = poFeatureDefn->GetFieldCount() - 1;
     827                 :     panFieldOrdinals = (int *)
     828              78 :         CPLRealloc(panFieldOrdinals, (iNewField+1) * sizeof(int) );
     829              78 :     panFieldOrdinals[iNewField] = iNextOrdinal;
     830                 : 
     831              78 :     return OGRERR_NONE;
     832                 : }
     833                 : 
     834                 : /************************************************************************/
     835                 : /*                     InitFieldListForRecrerate()                      */
     836                 : /************************************************************************/
     837                 : 
     838              46 : void OGRSQLiteTableLayer::InitFieldListForRecrerate(char* & pszNewFieldList,
     839                 :                                                     char* & pszFieldListForSelect,
     840                 :                                                     int nExtraSpace)
     841                 : {
     842              46 :     int iField, nFieldListLen = 100 + nExtraSpace;
     843                 : 
     844             236 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     845                 :     {
     846                 :         nFieldListLen +=
     847             190 :             strlen(poFeatureDefn->GetFieldDefn(iField)->GetNameRef()) + 50;
     848                 :     }
     849                 : 
     850              46 :     pszFieldListForSelect = (char *) CPLCalloc(1,nFieldListLen);
     851              46 :     pszNewFieldList = (char *) CPLCalloc(1,nFieldListLen);
     852                 : 
     853                 : /* -------------------------------------------------------------------- */
     854                 : /*      Build list of old fields, and the list of new fields.           */
     855                 : /* -------------------------------------------------------------------- */
     856              46 :     sprintf( pszFieldListForSelect, "%s", pszFIDColumn ? pszFIDColumn : "OGC_FID" );
     857              46 :     sprintf( pszNewFieldList, "%s INTEGER PRIMARY KEY",pszFIDColumn ? pszFIDColumn : "OGC_FID" );
     858                 : 
     859              46 :     if( poFeatureDefn->GetGeomType() != wkbNone )
     860                 :     {
     861              46 :         strcat( pszFieldListForSelect, "," );
     862              46 :         strcat( pszNewFieldList, "," );
     863                 : 
     864              46 :         strcat( pszFieldListForSelect, osGeomColumn );
     865              46 :         strcat( pszNewFieldList, osGeomColumn );
     866                 : 
     867              46 :         if ( eGeomFormat == OSGF_WKT )
     868               0 :             strcat( pszNewFieldList, " VARCHAR" );
     869                 :         else
     870              46 :             strcat( pszNewFieldList, " BLOB" );
     871                 :     }
     872              46 : }
     873                 : 
     874                 : /************************************************************************/
     875                 : /*                       AddColumnAncientMethod()                       */
     876                 : /************************************************************************/
     877                 : 
     878               0 : OGRErr OGRSQLiteTableLayer::AddColumnAncientMethod( OGRFieldDefn& oField)
     879                 : {
     880                 :     
     881                 : /* -------------------------------------------------------------------- */
     882                 : /*      How much space do we need for the list of fields.               */
     883                 : /* -------------------------------------------------------------------- */
     884                 :     int iField;
     885                 :     char *pszOldFieldList, *pszNewFieldList;
     886                 : 
     887                 :     InitFieldListForRecrerate(pszNewFieldList, pszOldFieldList,
     888               0 :                               strlen( oField.GetNameRef() ));
     889                 : 
     890                 : /* -------------------------------------------------------------------- */
     891                 : /*      Build list of old fields, and the list of new fields.           */
     892                 : /* -------------------------------------------------------------------- */
     893                 : 
     894               0 :     int iNextOrdinal = 3; /* _rowid_ is 1, OGC_FID is 2 */
     895                 : 
     896               0 :     if( poFeatureDefn->GetGeomType() != wkbNone )
     897                 :     {
     898               0 :         iNextOrdinal++;
     899                 :     }
     900                 : 
     901               0 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     902                 :     {
     903               0 :         OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField);
     904                 : 
     905                 :         // we already added OGC_FID so don't do it again
     906               0 :         if( EQUAL(poFldDefn->GetNameRef(),pszFIDColumn ? pszFIDColumn : "OGC_FID") )
     907               0 :             continue;
     908                 : 
     909                 :         sprintf( pszOldFieldList+strlen(pszOldFieldList), 
     910               0 :                  ", \"%s\"", poFldDefn->GetNameRef() );
     911                 : 
     912                 :         sprintf( pszNewFieldList+strlen(pszNewFieldList), 
     913                 :                  ", '%s' %s", poFldDefn->GetNameRef(),
     914               0 :                  OGRFieldTypeToSQliteType(poFldDefn->GetType()) );
     915                 : 
     916               0 :         iNextOrdinal++;
     917                 :     }
     918                 : 
     919                 : /* -------------------------------------------------------------------- */
     920                 : /*      Add the new field.                                              */
     921                 : /* -------------------------------------------------------------------- */
     922                 : 
     923                 :     sprintf( pszNewFieldList+strlen(pszNewFieldList), 
     924                 :              ", '%s' %s", oField.GetNameRef(),
     925               0 :              OGRFieldTypeToSQliteType(oField.GetType()) );
     926                 : 
     927                 : /* ==================================================================== */
     928                 : /*      Backup, destroy, recreate and repopulate the table.  SQLite     */
     929                 : /*      has no ALTER TABLE so we have to do all this to add a           */
     930                 : /*      column.                                                         */
     931                 : /* ==================================================================== */
     932                 : 
     933                 : /* -------------------------------------------------------------------- */
     934                 : /*      Do this all in a transaction.                                   */
     935                 : /* -------------------------------------------------------------------- */
     936               0 :     poDS->SoftStartTransaction();
     937                 : 
     938                 : /* -------------------------------------------------------------------- */
     939                 : /*      Save existing related triggers and index                        */
     940                 : /* -------------------------------------------------------------------- */
     941                 :     int rc;
     942               0 :     char *pszErrMsg = NULL;
     943               0 :     sqlite3 *hDB = poDS->GetDB();
     944               0 :     CPLString osSQL;
     945                 : 
     946                 :     osSQL.Printf( "SELECT sql FROM sqlite_master WHERE type IN ('trigger','index') AND tbl_name='%s'",
     947               0 :                    pszEscapedTableName );
     948                 : 
     949                 :     int nRowTriggerIndexCount, nColTriggerIndexCount;
     950               0 :     char **papszTriggerIndexResult = NULL;
     951                 :     rc = sqlite3_get_table( hDB, osSQL.c_str(), &papszTriggerIndexResult, 
     952               0 :                             &nRowTriggerIndexCount, &nColTriggerIndexCount, &pszErrMsg );
     953                 : 
     954                 : /* -------------------------------------------------------------------- */
     955                 : /*      Make a backup of the table.                                     */
     956                 : /* -------------------------------------------------------------------- */
     957                 : 
     958               0 :     if( rc == SQLITE_OK )
     959                 :         rc = sqlite3_exec( hDB, 
     960                 :                        CPLSPrintf( "CREATE TEMPORARY TABLE t1_back(%s)",
     961                 :                                    pszOldFieldList ),
     962               0 :                        NULL, NULL, &pszErrMsg );
     963                 : 
     964               0 :     if( rc == SQLITE_OK )
     965                 :         rc = sqlite3_exec( hDB, 
     966                 :                            CPLSPrintf( "INSERT INTO t1_back SELECT %s FROM '%s'",
     967                 :                                        pszOldFieldList, 
     968                 :                                        pszEscapedTableName ),
     969               0 :                            NULL, NULL, &pszErrMsg );
     970                 : 
     971                 : 
     972                 : /* -------------------------------------------------------------------- */
     973                 : /*      Drop the original table, and recreate with new field.           */
     974                 : /* -------------------------------------------------------------------- */
     975               0 :     if( rc == SQLITE_OK )
     976                 :         rc = sqlite3_exec( hDB, 
     977                 :                            CPLSPrintf( "DROP TABLE '%s'", 
     978                 :                                        pszEscapedTableName ),
     979               0 :                            NULL, NULL, &pszErrMsg );
     980                 : 
     981               0 :     if( rc == SQLITE_OK )
     982                 :     {
     983                 :         const char *pszCmd = 
     984                 :             CPLSPrintf( "CREATE TABLE '%s' (%s)", 
     985                 :                         pszEscapedTableName,
     986               0 :                         pszNewFieldList );
     987                 :         rc = sqlite3_exec( hDB, pszCmd, 
     988               0 :                            NULL, NULL, &pszErrMsg );
     989                 : 
     990               0 :         CPLDebug( "OGR_SQLITE", "exec(%s)", pszCmd );
     991                 :     }
     992                 : 
     993                 : /* -------------------------------------------------------------------- */
     994                 : /*      Copy backup field values into new table.                        */
     995                 : /* -------------------------------------------------------------------- */
     996                 :     
     997               0 :     if( rc == SQLITE_OK )
     998                 :         rc = sqlite3_exec( hDB, 
     999                 :                            CPLSPrintf( "INSERT INTO '%s' SELECT %s, NULL FROM t1_back",
    1000                 :                                        pszEscapedTableName,
    1001                 :                                        pszOldFieldList ),
    1002               0 :                            NULL, NULL, &pszErrMsg );
    1003                 : 
    1004               0 :     CPLFree( pszOldFieldList );
    1005               0 :     CPLFree( pszNewFieldList );
    1006                 : 
    1007                 : /* -------------------------------------------------------------------- */
    1008                 : /*      Cleanup backup table.                                           */
    1009                 : /* -------------------------------------------------------------------- */
    1010                 :     
    1011               0 :     if( rc == SQLITE_OK )
    1012                 :         rc = sqlite3_exec( hDB, 
    1013                 :                            CPLSPrintf( "DROP TABLE t1_back" ),
    1014               0 :                            NULL, NULL, &pszErrMsg );
    1015                 : 
    1016                 : /* -------------------------------------------------------------------- */
    1017                 : /*      Recreate existing related tables, triggers and index            */
    1018                 : /* -------------------------------------------------------------------- */
    1019                 : 
    1020               0 :     if( rc == SQLITE_OK )
    1021                 :     {
    1022                 :         int i;
    1023                 : 
    1024               0 :         for(i = 1; i <= nRowTriggerIndexCount && nColTriggerIndexCount == 1 && rc == SQLITE_OK; i++)
    1025                 :         {
    1026               0 :             if (papszTriggerIndexResult[i] != NULL && papszTriggerIndexResult[i][0] != '\0')
    1027                 :                 rc = sqlite3_exec( hDB, 
    1028               0 :                             papszTriggerIndexResult[i],
    1029               0 :                             NULL, NULL, &pszErrMsg );
    1030                 :         }
    1031                 :     }
    1032                 : 
    1033                 : /* -------------------------------------------------------------------- */
    1034                 : /*      COMMIT on success or ROLLBACK on failuire.                      */
    1035                 : /* -------------------------------------------------------------------- */
    1036                 : 
    1037               0 :     sqlite3_free_table( papszTriggerIndexResult );
    1038                 : 
    1039               0 :     if( rc == SQLITE_OK )
    1040                 :     {
    1041               0 :         poDS->SoftCommit();
    1042                 :     }
    1043                 :     else
    1044                 :     {
    1045                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1046                 :                   "Failed to add field %s to table %s:\n %s",
    1047                 :                   oField.GetNameRef(), poFeatureDefn->GetName(), 
    1048               0 :                   pszErrMsg );
    1049               0 :         sqlite3_free( pszErrMsg );
    1050                 : 
    1051               0 :         poDS->SoftRollback();
    1052                 : 
    1053               0 :         return OGRERR_FAILURE;
    1054                 :     }
    1055                 : 
    1056               0 :     return OGRERR_NONE;
    1057                 : }
    1058                 : 
    1059                 : /************************************************************************/
    1060                 : /*                           RecreateTable()                            */
    1061                 : /************************************************************************/
    1062                 : 
    1063              46 : OGRErr OGRSQLiteTableLayer::RecreateTable(const char* pszFieldListForSelect,
    1064                 :                                           const char* pszNewFieldList,
    1065                 :                                           const char* pszGenericErrorMessage)
    1066                 : {
    1067                 : /* -------------------------------------------------------------------- */
    1068                 : /*      Do this all in a transaction.                                   */
    1069                 : /* -------------------------------------------------------------------- */
    1070              46 :     poDS->SoftStartTransaction();
    1071                 : 
    1072                 : /* -------------------------------------------------------------------- */
    1073                 : /*      Save existing related triggers and index                        */
    1074                 : /* -------------------------------------------------------------------- */
    1075                 :     int rc;
    1076              46 :     char *pszErrMsg = NULL;
    1077              46 :     sqlite3 *hDB = poDS->GetDB();
    1078              46 :     CPLString osSQL;
    1079                 : 
    1080                 :     osSQL.Printf( "SELECT sql FROM sqlite_master WHERE type IN ('trigger','index') AND tbl_name='%s'",
    1081              46 :                    pszEscapedTableName );
    1082                 : 
    1083                 :     int nRowTriggerIndexCount, nColTriggerIndexCount;
    1084              46 :     char **papszTriggerIndexResult = NULL;
    1085                 :     rc = sqlite3_get_table( hDB, osSQL.c_str(), &papszTriggerIndexResult,
    1086              46 :                             &nRowTriggerIndexCount, &nColTriggerIndexCount, &pszErrMsg );
    1087                 : 
    1088                 : /* -------------------------------------------------------------------- */
    1089                 : /*      Make a backup of the table.                                     */
    1090                 : /* -------------------------------------------------------------------- */
    1091                 : 
    1092              46 :     if( rc == SQLITE_OK )
    1093                 :         rc = sqlite3_exec( hDB,
    1094                 :                        CPLSPrintf( "CREATE TABLE t1_back(%s)",
    1095                 :                                    pszNewFieldList ),
    1096              46 :                        NULL, NULL, &pszErrMsg );
    1097                 : 
    1098              46 :     if( rc == SQLITE_OK )
    1099                 :         rc = sqlite3_exec( hDB,
    1100                 :                            CPLSPrintf( "INSERT INTO t1_back SELECT %s FROM '%s'",
    1101                 :                                        pszFieldListForSelect,
    1102                 :                                        pszEscapedTableName ),
    1103              46 :                            NULL, NULL, &pszErrMsg );
    1104                 : 
    1105                 : 
    1106                 : /* -------------------------------------------------------------------- */
    1107                 : /*      Drop the original table                                         */
    1108                 : /* -------------------------------------------------------------------- */
    1109              46 :     if( rc == SQLITE_OK )
    1110                 :         rc = sqlite3_exec( hDB,
    1111                 :                            CPLSPrintf( "DROP TABLE '%s'",
    1112                 :                                        pszEscapedTableName ),
    1113              46 :                            NULL, NULL, &pszErrMsg );
    1114                 : 
    1115                 : /* -------------------------------------------------------------------- */
    1116                 : /*      Rename backup table as new table                                */
    1117                 : /* -------------------------------------------------------------------- */
    1118              46 :     if( rc == SQLITE_OK )
    1119                 :     {
    1120                 :         const char *pszCmd =
    1121                 :             CPLSPrintf( "ALTER TABLE t1_back RENAME TO '%s'",
    1122              46 :                         pszEscapedTableName);
    1123                 :         rc = sqlite3_exec( hDB, pszCmd,
    1124              46 :                            NULL, NULL, &pszErrMsg );
    1125                 :     }
    1126                 : 
    1127                 : /* -------------------------------------------------------------------- */
    1128                 : /*      Recreate existing related tables, triggers and index            */
    1129                 : /* -------------------------------------------------------------------- */
    1130                 : 
    1131              46 :     if( rc == SQLITE_OK )
    1132                 :     {
    1133                 :         int i;
    1134                 : 
    1135              46 :         for(i = 1; i <= nRowTriggerIndexCount && nColTriggerIndexCount == 1 && rc == SQLITE_OK; i++)
    1136                 :         {
    1137               0 :             if (papszTriggerIndexResult[i] != NULL && papszTriggerIndexResult[i][0] != '\0')
    1138                 :                 rc = sqlite3_exec( hDB,
    1139               0 :                             papszTriggerIndexResult[i],
    1140               0 :                             NULL, NULL, &pszErrMsg );
    1141                 :         }
    1142                 :     }
    1143                 : 
    1144                 : /* -------------------------------------------------------------------- */
    1145                 : /*      COMMIT on success or ROLLBACK on failuire.                      */
    1146                 : /* -------------------------------------------------------------------- */
    1147                 : 
    1148              46 :     sqlite3_free_table( papszTriggerIndexResult );
    1149                 : 
    1150              46 :     if( rc == SQLITE_OK )
    1151                 :     {
    1152              46 :         poDS->SoftCommit();
    1153                 : 
    1154              46 :         return OGRERR_NONE;
    1155                 :     }
    1156                 :     else
    1157                 :     {
    1158                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1159                 :                   "%s:\n %s",
    1160                 :                   pszGenericErrorMessage,
    1161               0 :                   pszErrMsg );
    1162               0 :         sqlite3_free( pszErrMsg );
    1163                 : 
    1164               0 :         poDS->SoftRollback();
    1165                 : 
    1166               0 :         return OGRERR_FAILURE;
    1167               0 :     }
    1168                 : }
    1169                 : 
    1170                 : /************************************************************************/
    1171                 : /*                             DeleteField()                            */
    1172                 : /************************************************************************/
    1173                 : 
    1174              16 : OGRErr OGRSQLiteTableLayer::DeleteField( int iFieldToDelete )
    1175                 : {
    1176              16 :     if (HasLayerDefnError())
    1177               0 :         return OGRERR_FAILURE;
    1178                 : 
    1179              16 :     if (!poDS->GetUpdate())
    1180                 :     {
    1181                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1182                 :                   UNSUPPORTED_OP_READ_ONLY,
    1183               0 :                   "DeleteField");
    1184               0 :         return OGRERR_FAILURE;
    1185                 :     }
    1186                 : 
    1187              16 :     if (iFieldToDelete < 0 || iFieldToDelete >= poFeatureDefn->GetFieldCount())
    1188                 :     {
    1189                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1190               4 :                   "Invalid field index");
    1191               4 :         return OGRERR_FAILURE;
    1192                 :     }
    1193                 : 
    1194              12 :     ResetReading();
    1195                 : 
    1196                 : /* -------------------------------------------------------------------- */
    1197                 : /*      Build list of old fields, and the list of new fields.           */
    1198                 : /* -------------------------------------------------------------------- */
    1199                 :     int iField;
    1200                 :     char *pszNewFieldList, *pszFieldListForSelect;
    1201              12 :     InitFieldListForRecrerate(pszNewFieldList, pszFieldListForSelect);
    1202                 : 
    1203              52 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    1204                 :     {
    1205              40 :         OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField);
    1206                 : 
    1207              40 :         if (iField == iFieldToDelete)
    1208              12 :             continue;
    1209                 : 
    1210                 :         sprintf( pszFieldListForSelect+strlen(pszFieldListForSelect),
    1211              28 :                  ", \"%s\"", poFldDefn->GetNameRef() );
    1212                 : 
    1213                 :         sprintf( pszNewFieldList+strlen(pszNewFieldList),
    1214                 :                  ", '%s' %s", poFldDefn->GetNameRef(),
    1215              28 :                  OGRFieldTypeToSQliteType(poFldDefn->GetType()) );
    1216                 :     }
    1217                 : 
    1218                 : /* -------------------------------------------------------------------- */
    1219                 : /*      Recreate table.                                                 */
    1220                 : /* -------------------------------------------------------------------- */
    1221              12 :     CPLString osErrorMsg;
    1222                 :     osErrorMsg.Printf("Failed to remove field %s from table %s",
    1223                 :                   poFeatureDefn->GetFieldDefn(iFieldToDelete)->GetNameRef(),
    1224              12 :                   poFeatureDefn->GetName());
    1225                 : 
    1226                 :     OGRErr eErr = RecreateTable(pszFieldListForSelect,
    1227                 :                                 pszNewFieldList,
    1228              12 :                                 osErrorMsg.c_str());
    1229                 : 
    1230              12 :     CPLFree( pszFieldListForSelect );
    1231              12 :     CPLFree( pszNewFieldList );
    1232                 : 
    1233              12 :     if (eErr != OGRERR_NONE)
    1234               0 :         return eErr;
    1235                 : 
    1236                 : /* -------------------------------------------------------------------- */
    1237                 : /*      Finish                                                          */
    1238                 : /* -------------------------------------------------------------------- */
    1239              12 :     int iNextOrdinal = 3; /* _rowid_ is 1, OGC_FID is 2 */
    1240                 : 
    1241              12 :     if( poFeatureDefn->GetGeomType() != wkbNone )
    1242                 :     {
    1243              12 :         iNextOrdinal++;
    1244                 :     }
    1245                 : 
    1246              12 :     int iNewField = 0;
    1247              52 :     for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    1248                 :     {
    1249              40 :         if (iField == iFieldToDelete)
    1250              12 :             continue;
    1251                 : 
    1252              28 :         panFieldOrdinals[iNewField ++] = iNextOrdinal++;
    1253                 :     }
    1254                 : 
    1255              12 :     return poFeatureDefn->DeleteFieldDefn( iFieldToDelete );
    1256                 : }
    1257                 : 
    1258                 : /************************************************************************/
    1259                 : /*                           AlterFieldDefn()                           */
    1260                 : /************************************************************************/
    1261                 : 
    1262              18 : OGRErr OGRSQLiteTableLayer::AlterFieldDefn( int iFieldToAlter, OGRFieldDefn* poNewFieldDefn, int nFlags )
    1263                 : {
    1264              18 :     if (HasLayerDefnError())
    1265               0 :         return OGRERR_FAILURE;
    1266                 : 
    1267              18 :     if (!poDS->GetUpdate())
    1268                 :     {
    1269                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1270                 :                   UNSUPPORTED_OP_READ_ONLY,
    1271               0 :                   "AlterFieldDefn");
    1272               0 :         return OGRERR_FAILURE;
    1273                 :     }
    1274                 : 
    1275              18 :     if (iFieldToAlter < 0 || iFieldToAlter >= poFeatureDefn->GetFieldCount())
    1276                 :     {
    1277                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1278               4 :                   "Invalid field index");
    1279               4 :         return OGRERR_FAILURE;
    1280                 :     }
    1281                 : 
    1282              14 :     ClearInsertStmt();
    1283              14 :     ResetReading();
    1284                 : 
    1285                 : /* -------------------------------------------------------------------- */
    1286                 : /*      Build list of old fields, and the list of new fields.           */
    1287                 : /* -------------------------------------------------------------------- */
    1288                 :     int iField;
    1289                 :     char *pszNewFieldList, *pszFieldListForSelect;
    1290                 :     InitFieldListForRecrerate(pszNewFieldList, pszFieldListForSelect,
    1291              14 :                               strlen(poNewFieldDefn->GetNameRef()));
    1292                 : 
    1293              80 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    1294                 :     {
    1295              66 :         OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(iField);
    1296                 : 
    1297                 :         sprintf( pszFieldListForSelect+strlen(pszFieldListForSelect),
    1298              66 :                  ", \"%s\"", poFldDefn->GetNameRef() );
    1299                 : 
    1300              66 :         if (iField == iFieldToAlter)
    1301                 :         {
    1302                 :             sprintf( pszNewFieldList+strlen(pszNewFieldList),
    1303                 :                     ", '%s' %s",
    1304                 :                     (nFlags & ALTER_NAME_FLAG) ? poNewFieldDefn->GetNameRef() :
    1305                 :                                                  poFldDefn->GetNameRef(),
    1306                 :                     OGRFieldTypeToSQliteType((nFlags & ALTER_TYPE_FLAG) ?
    1307              14 :                             poNewFieldDefn->GetType() : poFldDefn->GetType()) );
    1308                 :         }
    1309                 :         else
    1310                 :         {
    1311                 :             sprintf( pszNewFieldList+strlen(pszNewFieldList),
    1312                 :                     ", '%s' %s", poFldDefn->GetNameRef(),
    1313              52 :                     OGRFieldTypeToSQliteType(poFldDefn->GetType()) );
    1314                 :         }
    1315                 :     }
    1316                 : 
    1317                 : /* -------------------------------------------------------------------- */
    1318                 : /*      Recreate table.                                                 */
    1319                 : /* -------------------------------------------------------------------- */
    1320              14 :     CPLString osErrorMsg;
    1321                 :     osErrorMsg.Printf("Failed to alter field %s from table %s",
    1322                 :                   poFeatureDefn->GetFieldDefn(iFieldToAlter)->GetNameRef(),
    1323              14 :                   poFeatureDefn->GetName());
    1324                 : 
    1325                 :     OGRErr eErr = RecreateTable(pszFieldListForSelect,
    1326                 :                                 pszNewFieldList,
    1327              14 :                                 osErrorMsg.c_str());
    1328                 : 
    1329              14 :     CPLFree( pszFieldListForSelect );
    1330              14 :     CPLFree( pszNewFieldList );
    1331                 : 
    1332              14 :     if (eErr != OGRERR_NONE)
    1333               0 :         return eErr;
    1334                 : 
    1335                 : /* -------------------------------------------------------------------- */
    1336                 : /*      Finish                                                          */
    1337                 : /* -------------------------------------------------------------------- */
    1338                 : 
    1339              14 :     OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iFieldToAlter);
    1340                 : 
    1341              14 :     if (nFlags & ALTER_TYPE_FLAG)
    1342              14 :         poFieldDefn->SetType(poNewFieldDefn->GetType());
    1343              14 :     if (nFlags & ALTER_NAME_FLAG)
    1344              14 :         poFieldDefn->SetName(poNewFieldDefn->GetNameRef());
    1345              14 :     if (nFlags & ALTER_WIDTH_PRECISION_FLAG)
    1346                 :     {
    1347              14 :         poFieldDefn->SetWidth(poNewFieldDefn->GetWidth());
    1348              14 :         poFieldDefn->SetPrecision(poNewFieldDefn->GetPrecision());
    1349                 :     }
    1350              14 :     return OGRERR_NONE;
    1351                 : }
    1352                 : 
    1353                 : /************************************************************************/
    1354                 : /*                           ReorderFields()                            */
    1355                 : /************************************************************************/
    1356                 : 
    1357              24 : OGRErr OGRSQLiteTableLayer::ReorderFields( int* panMap )
    1358                 : {
    1359              24 :     if (HasLayerDefnError())
    1360               0 :         return OGRERR_FAILURE;
    1361                 : 
    1362              24 :     if (!poDS->GetUpdate())
    1363                 :     {
    1364                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1365                 :                   UNSUPPORTED_OP_READ_ONLY,
    1366               0 :                   "ReorderFields");
    1367               0 :         return OGRERR_FAILURE;
    1368                 :     }
    1369                 : 
    1370              24 :     if (poFeatureDefn->GetFieldCount() == 0)
    1371               2 :         return OGRERR_NONE;
    1372                 : 
    1373              22 :     OGRErr eErr = OGRCheckPermutation(panMap, poFeatureDefn->GetFieldCount());
    1374              22 :     if (eErr != OGRERR_NONE)
    1375               2 :         return eErr;
    1376                 : 
    1377              20 :     ClearInsertStmt();
    1378              20 :     ResetReading();
    1379                 : 
    1380                 : /* -------------------------------------------------------------------- */
    1381                 : /*      Build list of old fields, and the list of new fields.           */
    1382                 : /* -------------------------------------------------------------------- */
    1383                 :     int iField;
    1384                 :     char *pszNewFieldList, *pszFieldListForSelect;
    1385              20 :     InitFieldListForRecrerate(pszNewFieldList, pszFieldListForSelect);
    1386                 : 
    1387             104 :     for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
    1388                 :     {
    1389              84 :         OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(panMap[iField]);
    1390                 : 
    1391                 :         sprintf( pszFieldListForSelect+strlen(pszFieldListForSelect),
    1392              84 :                  ", \"%s\"", poFldDefn->GetNameRef() );
    1393                 : 
    1394                 :         sprintf( pszNewFieldList+strlen(pszNewFieldList),
    1395                 :                 ", '%s' %s", poFldDefn->GetNameRef(),
    1396              84 :                 OGRFieldTypeToSQliteType(poFldDefn->GetType()) );
    1397                 :     }
    1398                 : 
    1399                 : /* -------------------------------------------------------------------- */
    1400                 : /*      Recreate table.                                                 */
    1401                 : /* -------------------------------------------------------------------- */
    1402              20 :     CPLString osErrorMsg;
    1403                 :     osErrorMsg.Printf("Failed to reorder fields from table %s",
    1404              20 :                   poFeatureDefn->GetName());
    1405                 : 
    1406                 :     eErr = RecreateTable(pszFieldListForSelect,
    1407                 :                                 pszNewFieldList,
    1408              20 :                                 osErrorMsg.c_str());
    1409                 : 
    1410              20 :     CPLFree( pszFieldListForSelect );
    1411              20 :     CPLFree( pszNewFieldList );
    1412                 : 
    1413              20 :     if (eErr != OGRERR_NONE)
    1414               0 :         return eErr;
    1415                 : 
    1416                 : /* -------------------------------------------------------------------- */
    1417                 : /*      Finish                                                          */
    1418                 : /* -------------------------------------------------------------------- */
    1419                 : 
    1420              20 :     return poFeatureDefn->ReorderFieldDefns( panMap );
    1421                 : }
    1422                 : 
    1423                 : /************************************************************************/
    1424                 : /*                             BindValues()                             */
    1425                 : /************************************************************************/
    1426                 : 
    1427                 : /* the bBindNullValues is set to TRUE by SetFeature() for UPDATE statements, */
    1428                 : /* and to FALSE by CreateFeature() for INSERT statements; */
    1429                 : 
    1430             670 : OGRErr OGRSQLiteTableLayer::BindValues( OGRFeature *poFeature,
    1431                 :                                         sqlite3_stmt* hStmt,
    1432                 :                                         int bBindNullValues )
    1433                 : {
    1434                 :     int rc;
    1435             670 :     sqlite3 *hDB = poDS->GetDB();
    1436                 : 
    1437                 : /* -------------------------------------------------------------------- */
    1438                 : /*      Bind the geometry                                               */
    1439                 : /* -------------------------------------------------------------------- */
    1440             670 :     int nBindField = 1;
    1441                 : 
    1442             670 :     if( osGeomColumn.size() != 0 &&
    1443                 :         eGeomFormat != OSGF_FGF )
    1444                 :     {
    1445             630 :         OGRGeometry* poGeom = poFeature->GetGeometryRef();
    1446             630 :         if ( poGeom != NULL )
    1447                 :         {
    1448             604 :             if ( eGeomFormat == OSGF_WKT )
    1449                 :             {
    1450               2 :                 char *pszWKT = NULL;
    1451               2 :                 poGeom->exportToWkt( &pszWKT );
    1452               2 :                 rc = sqlite3_bind_text( hStmt, nBindField++, pszWKT, -1, CPLFree );
    1453                 :             }
    1454             602 :             else if( eGeomFormat == OSGF_WKB )
    1455                 :             {
    1456             190 :                 int nWKBLen = poGeom->WkbSize();
    1457             190 :                 GByte *pabyWKB = (GByte *) CPLMalloc(nWKBLen + 1);
    1458                 : 
    1459             190 :                 poGeom->exportToWkb( wkbNDR, pabyWKB );
    1460             190 :                 rc = sqlite3_bind_blob( hStmt, nBindField++, pabyWKB, nWKBLen, CPLFree );
    1461                 :             }
    1462             412 :             else if ( eGeomFormat == OSGF_SpatiaLite )
    1463                 :             {
    1464                 :                 int     nBLOBLen;
    1465                 :                 GByte   *pabySLBLOB;
    1466                 : 
    1467                 :                 ExportSpatiaLiteGeometry( poGeom, nSRSId, wkbNDR, bHasM,
    1468             412 :                                         bSpatialite2D, bUseComprGeom, &pabySLBLOB, &nBLOBLen );
    1469                 :                 rc = sqlite3_bind_blob( hStmt, nBindField++, pabySLBLOB,
    1470             412 :                                         nBLOBLen, CPLFree );
    1471                 :             }
    1472                 :             else
    1473                 :             {
    1474               0 :                 rc = SQLITE_OK;
    1475               0 :                 CPLAssert(0);
    1476                 :             }
    1477                 :         }
    1478                 :         else
    1479                 :         {
    1480              26 :             if (bBindNullValues)
    1481               4 :                 rc = sqlite3_bind_null( hStmt, nBindField++ );
    1482                 :             else
    1483              22 :                 rc = SQLITE_OK;
    1484                 :         }
    1485                 : 
    1486             630 :         if( rc != SQLITE_OK )
    1487                 :         {
    1488                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1489                 :                       "sqlite3_bind_blob/text() failed:\n  %s",
    1490               0 :                       sqlite3_errmsg(hDB) );
    1491               0 :             return OGRERR_FAILURE;
    1492                 :         }
    1493                 :     }
    1494                 : 
    1495                 : /* -------------------------------------------------------------------- */
    1496                 : /*      Bind field values.                                              */
    1497                 : /* -------------------------------------------------------------------- */
    1498                 :     int iField;
    1499             670 :     int nFieldCount = poFeatureDefn->GetFieldCount();
    1500            1904 :     for( iField = 0; iField < nFieldCount; iField++ )
    1501                 :     {
    1502                 :         const char *pszRawValue;
    1503                 : 
    1504            1234 :         if( !poFeature->IsFieldSet( iField ) )
    1505                 :         {
    1506             442 :             if (bBindNullValues)
    1507              14 :                 rc = sqlite3_bind_null( hStmt, nBindField++ );
    1508                 :             else
    1509             428 :                 rc = SQLITE_OK;
    1510                 :         }
    1511                 :         else
    1512                 :         {
    1513             792 :             switch( poFeatureDefn->GetFieldDefn(iField)->GetType() )
    1514                 :             {
    1515                 :                 case OFTInteger:
    1516                 :                 {
    1517             198 :                     int nFieldVal = poFeature->GetFieldAsInteger( iField );
    1518             198 :                     rc = sqlite3_bind_int(hStmt, nBindField++, nFieldVal);
    1519             198 :                     break;
    1520                 :                 }
    1521                 : 
    1522                 :                 case OFTReal:
    1523                 :                 {
    1524             226 :                     double dfFieldVal = poFeature->GetFieldAsDouble( iField );
    1525             226 :                     rc = sqlite3_bind_double(hStmt, nBindField++, dfFieldVal);
    1526             226 :                     break;
    1527                 :                 }
    1528                 : 
    1529                 :                 case OFTBinary:
    1530                 :                 {
    1531              42 :                     int nDataLength = 0;
    1532                 :                     GByte* pabyData =
    1533              42 :                         poFeature->GetFieldAsBinary( iField, &nDataLength );
    1534                 :                     rc = sqlite3_bind_blob(hStmt, nBindField++,
    1535              42 :                                         pabyData, nDataLength, SQLITE_TRANSIENT);
    1536              42 :                     break;
    1537                 :                 }
    1538                 : 
    1539                 :                 default:
    1540                 :                 {
    1541             326 :                     pszRawValue = poFeature->GetFieldAsString( iField );
    1542                 :                     rc = sqlite3_bind_text(hStmt, nBindField++,
    1543             326 :                                         pszRawValue, -1, SQLITE_TRANSIENT);
    1544                 :                     break;
    1545                 :                 }
    1546                 :             }
    1547                 :         }
    1548                 : 
    1549            1234 :         if( rc != SQLITE_OK )
    1550                 :         {
    1551                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1552                 :                       "sqlite3_bind_() for column %s failed:\n  %s",
    1553                 :                       poFeatureDefn->GetFieldDefn(iField)->GetNameRef(),
    1554               0 :                       sqlite3_errmsg(hDB) );
    1555               0 :             return OGRERR_FAILURE;
    1556                 :         }
    1557                 :     }
    1558                 : 
    1559             670 :     return OGRERR_NONE;
    1560                 : }
    1561                 : 
    1562                 : /************************************************************************/
    1563                 : /*                             SetFeature()                             */
    1564                 : /************************************************************************/
    1565                 : 
    1566              16 : OGRErr OGRSQLiteTableLayer::SetFeature( OGRFeature *poFeature )
    1567                 : 
    1568                 : {
    1569              16 :     if (HasLayerDefnError())
    1570               0 :         return OGRERR_FAILURE;
    1571                 : 
    1572              16 :     if( pszFIDColumn == NULL )
    1573                 :     {
    1574                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1575               0 :                   "SetFeature() without any FID column." );
    1576               0 :         return OGRERR_FAILURE;
    1577                 :     }
    1578                 :     
    1579              16 :     if( poFeature->GetFID() == OGRNullFID )
    1580                 :     {
    1581                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1582               0 :                   "SetFeature() with unset FID fails." );
    1583               0 :         return OGRERR_FAILURE;
    1584                 :     }
    1585                 : 
    1586              16 :     if (bSpatialiteReadOnly || !poDS->GetUpdate())
    1587                 :     {
    1588                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1589                 :                   UNSUPPORTED_OP_READ_ONLY,
    1590               0 :                   "SetFeature");
    1591               0 :         return OGRERR_FAILURE;
    1592                 :     }
    1593                 : 
    1594              16 :     sqlite3 *hDB = poDS->GetDB();
    1595              16 :     CPLString      osCommand;
    1596              16 :     int            bNeedComma = FALSE;
    1597                 : 
    1598              16 :     bCachedExtentIsValid = FALSE;
    1599                 : 
    1600              16 :     ResetReading();
    1601                 : 
    1602                 : /* -------------------------------------------------------------------- */
    1603                 : /*      Form the UPDATE command.                                        */
    1604                 : /* -------------------------------------------------------------------- */
    1605              16 :     osCommand += CPLSPrintf( "UPDATE '%s' SET ", pszEscapedTableName );
    1606                 : 
    1607                 : /* -------------------------------------------------------------------- */
    1608                 : /*      Add geometry field name.                                        */
    1609                 : /* -------------------------------------------------------------------- */
    1610              16 :     if( osGeomColumn.size() != 0 &&
    1611                 :         eGeomFormat != OSGF_FGF )
    1612                 :     {
    1613              16 :         osCommand += "\"";
    1614              16 :         osCommand += osGeomColumn;
    1615              16 :         osCommand += "\" = ?";
    1616                 : 
    1617              16 :         bNeedComma = TRUE;
    1618                 :     }
    1619                 : 
    1620                 : /* -------------------------------------------------------------------- */
    1621                 : /*      Add field names.                                                */
    1622                 : /* -------------------------------------------------------------------- */
    1623                 :     int iField;
    1624              16 :     int nFieldCount = poFeatureDefn->GetFieldCount();
    1625                 : 
    1626              72 :     for( iField = 0; iField < nFieldCount; iField++ )
    1627                 :     {
    1628              56 :         if( bNeedComma )
    1629              56 :             osCommand += ",";
    1630                 : 
    1631              56 :         osCommand += "\"";
    1632              56 :         osCommand +=poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
    1633              56 :         osCommand += "\" = ?";
    1634                 : 
    1635              56 :         bNeedComma = TRUE;
    1636                 :     }
    1637                 : 
    1638              16 :     if (!bNeedComma)
    1639               0 :         return OGRERR_NONE;
    1640                 : 
    1641                 : /* -------------------------------------------------------------------- */
    1642                 : /*      Merge final command.                                            */
    1643                 : /* -------------------------------------------------------------------- */
    1644              16 :     osCommand += " WHERE \"";
    1645              16 :     osCommand += pszFIDColumn;
    1646              16 :     osCommand += CPLSPrintf("\" = %ld", poFeature->GetFID());
    1647                 : 
    1648                 : /* -------------------------------------------------------------------- */
    1649                 : /*      Prepare the statement.                                          */
    1650                 : /* -------------------------------------------------------------------- */
    1651                 :     int rc;
    1652                 :     sqlite3_stmt *hUpdateStmt;
    1653                 : 
    1654                 : #ifdef DEBUG
    1655              16 :     CPLDebug( "OGR_SQLITE", "prepare(%s)", osCommand.c_str() );
    1656                 : #endif
    1657                 : 
    1658              16 :     rc = sqlite3_prepare( hDB, osCommand, -1, &hUpdateStmt, NULL );
    1659              16 :     if( rc != SQLITE_OK )
    1660                 :     {
    1661                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1662                 :                   "In SetFeature(): sqlite3_prepare(%s):\n  %s",
    1663               0 :                   osCommand.c_str(), sqlite3_errmsg(hDB) );
    1664                 : 
    1665               0 :         return OGRERR_FAILURE;
    1666                 :     }
    1667                 : 
    1668                 : /* -------------------------------------------------------------------- */
    1669                 : /*      Bind values.                                                   */
    1670                 : /* -------------------------------------------------------------------- */
    1671              16 :     OGRErr eErr = BindValues( poFeature, hUpdateStmt, TRUE );
    1672              16 :     if (eErr != OGRERR_NONE)
    1673                 :     {
    1674               0 :         sqlite3_finalize( hUpdateStmt );
    1675               0 :         return eErr;
    1676                 :     }
    1677                 : 
    1678                 : /* -------------------------------------------------------------------- */
    1679                 : /*      Execute the update.                                             */
    1680                 : /* -------------------------------------------------------------------- */
    1681              16 :     rc = sqlite3_step( hUpdateStmt );
    1682                 : 
    1683              16 :     if( rc != SQLITE_OK && rc != SQLITE_DONE )
    1684                 :     {
    1685                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1686                 :                   "sqlite3_step() failed:\n  %s",
    1687               0 :                   sqlite3_errmsg(hDB) );
    1688                 : 
    1689               0 :         sqlite3_finalize( hUpdateStmt );
    1690               0 :         return OGRERR_FAILURE;
    1691                 :     }
    1692                 : 
    1693              16 :     sqlite3_finalize( hUpdateStmt );
    1694                 : 
    1695              16 :     return OGRERR_NONE;
    1696                 : }
    1697                 : 
    1698                 : /************************************************************************/
    1699                 : /*                           CreateFeature()                            */
    1700                 : /************************************************************************/
    1701                 : 
    1702             654 : OGRErr OGRSQLiteTableLayer::CreateFeature( OGRFeature *poFeature )
    1703                 : 
    1704                 : {
    1705             654 :     sqlite3 *hDB = poDS->GetDB();
    1706             654 :     CPLString      osCommand;
    1707             654 :     CPLString      osValues;
    1708             654 :     int            bNeedComma = FALSE;
    1709                 : 
    1710             654 :     if (HasLayerDefnError())
    1711               0 :         return OGRERR_FAILURE;
    1712                 : 
    1713             654 :     if (bSpatialiteReadOnly || !poDS->GetUpdate())
    1714                 :     {
    1715                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1716                 :                   UNSUPPORTED_OP_READ_ONLY,
    1717               0 :                   "CreateFeature");
    1718               0 :         return OGRERR_FAILURE;
    1719                 :     }
    1720                 : 
    1721             654 :     bCachedExtentIsValid = FALSE;
    1722                 : 
    1723             654 :     ResetReading();
    1724                 : 
    1725                 : /* -------------------------------------------------------------------- */
    1726                 : /*      Form the INSERT command.                                        */
    1727                 : /* -------------------------------------------------------------------- */
    1728             654 :     osCommand += CPLSPrintf( "INSERT INTO '%s' (", pszEscapedTableName );
    1729                 : 
    1730                 : /* -------------------------------------------------------------------- */
    1731                 : /*      Add FID if we have a cleartext FID column.                      */
    1732                 : /* -------------------------------------------------------------------- */
    1733             654 :     if( pszFIDColumn != NULL // && !EQUAL(pszFIDColumn,"OGC_FID") 
    1734                 :         && poFeature->GetFID() != OGRNullFID )
    1735                 :     {
    1736             116 :         osCommand += "\"";
    1737             116 :         osCommand += pszFIDColumn;
    1738             116 :         osCommand += "\"";
    1739                 : 
    1740             116 :         osValues += CPLSPrintf( "%ld", poFeature->GetFID() );
    1741             116 :         bNeedComma = TRUE;
    1742                 :     }
    1743                 : 
    1744                 : /* -------------------------------------------------------------------- */
    1745                 : /*      Add geometry.                                                   */
    1746                 : /* -------------------------------------------------------------------- */
    1747             654 :     OGRGeometry *poGeom = poFeature->GetGeometryRef();
    1748                 : 
    1749             654 :     if( osGeomColumn.size() != 0 &&
    1750                 :         poGeom != NULL &&
    1751                 :         eGeomFormat != OSGF_FGF )
    1752                 :     {
    1753                 : 
    1754             592 :         if( bNeedComma )
    1755                 :         {
    1756             116 :             osCommand += ",";
    1757             116 :             osValues += ",";
    1758                 :         }
    1759                 : 
    1760             592 :         osCommand += "\"";
    1761             592 :         osCommand += osGeomColumn;
    1762             592 :         osCommand += "\"";
    1763                 : 
    1764             592 :         osValues += "?";
    1765                 : 
    1766             592 :         bNeedComma = TRUE;
    1767                 :     }
    1768                 : 
    1769                 : /* -------------------------------------------------------------------- */
    1770                 : /*      Add field values.                                               */
    1771                 : /* -------------------------------------------------------------------- */
    1772                 :     int iField;
    1773             654 :     int nFieldCount = poFeatureDefn->GetFieldCount();
    1774                 : 
    1775            1832 :     for( iField = 0; iField < nFieldCount; iField++ )
    1776                 :     {
    1777            1178 :         if( !poFeature->IsFieldSet( iField ) )
    1778             428 :             continue;
    1779                 : 
    1780             750 :         if( bNeedComma )
    1781                 :         {
    1782             690 :             osCommand += ",";
    1783             690 :             osValues += ",";
    1784                 :         }
    1785                 : 
    1786             750 :         osCommand += "\"";
    1787             750 :         osCommand +=poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
    1788             750 :         osCommand += "\"";
    1789                 : 
    1790             750 :         osValues += "?";
    1791                 : 
    1792             750 :         bNeedComma = TRUE;
    1793                 :     }
    1794                 : 
    1795                 : /* -------------------------------------------------------------------- */
    1796                 : /*      Merge final command.                                            */
    1797                 : /* -------------------------------------------------------------------- */
    1798             654 :     osCommand += ") VALUES (";
    1799             654 :     osCommand += osValues;
    1800             654 :     osCommand += ")";
    1801                 : 
    1802             654 :     if (bNeedComma == FALSE)
    1803               2 :         osCommand = CPLSPrintf( "INSERT INTO '%s' DEFAULT VALUES", pszEscapedTableName );
    1804                 : 
    1805                 : /* -------------------------------------------------------------------- */
    1806                 : /*      Prepare the statement.                                          */
    1807                 : /* -------------------------------------------------------------------- */
    1808                 :     int rc;
    1809                 : 
    1810             654 :     if (hInsertStmt == NULL ||
    1811                 :         osCommand != osLastInsertStmt)
    1812                 :     {
    1813                 :     #ifdef DEBUG
    1814             328 :         CPLDebug( "OGR_SQLITE", "prepare(%s)", osCommand.c_str() );
    1815                 :     #endif
    1816                 : 
    1817             328 :         ClearInsertStmt();
    1818             328 :         osLastInsertStmt = osCommand;
    1819                 : 
    1820                 : #ifdef HAVE_SQLITE3_PREPARE_V2
    1821             328 :         rc = sqlite3_prepare_v2( hDB, osCommand, -1, &hInsertStmt, NULL );
    1822                 : #else
    1823                 :         rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
    1824                 : #endif
    1825             328 :         if( rc != SQLITE_OK )
    1826                 :         {
    1827                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1828                 :                     "In CreateFeature(): sqlite3_prepare(%s):\n  %s",
    1829               0 :                     osCommand.c_str(), sqlite3_errmsg(hDB) );
    1830                 : 
    1831               0 :             ClearInsertStmt();
    1832               0 :             return OGRERR_FAILURE;
    1833                 :         }
    1834                 :     }
    1835                 : 
    1836                 : /* -------------------------------------------------------------------- */
    1837                 : /*      Bind values.                                                   */
    1838                 : /* -------------------------------------------------------------------- */
    1839             654 :     OGRErr eErr = BindValues( poFeature, hInsertStmt, FALSE );
    1840             654 :     if (eErr != OGRERR_NONE)
    1841                 :     {
    1842               0 :         sqlite3_reset( hInsertStmt );
    1843               0 :         return eErr;
    1844                 :     }
    1845                 : 
    1846                 : /* -------------------------------------------------------------------- */
    1847                 : /*      Execute the insert.                                             */
    1848                 : /* -------------------------------------------------------------------- */
    1849             654 :     rc = sqlite3_step( hInsertStmt );
    1850                 : 
    1851             654 :     if( rc != SQLITE_OK && rc != SQLITE_DONE )
    1852                 :     {
    1853                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1854                 :                   "sqlite3_step() failed:\n  %s (%d)", 
    1855               0 :                   sqlite3_errmsg(hDB), rc );
    1856               0 :         sqlite3_reset( hInsertStmt );
    1857               0 :         return OGRERR_FAILURE;
    1858                 :     }
    1859                 : 
    1860                 : /* -------------------------------------------------------------------- */
    1861                 : /*      Capture the FID/rowid.                                          */
    1862                 : /* -------------------------------------------------------------------- */
    1863             654 :     const sqlite_int64 nFID = sqlite3_last_insert_rowid( hDB );
    1864             654 :     if(nFID > 0)
    1865                 :     {
    1866             652 :         poFeature->SetFID( (long)nFID ); /* Possible truncation if nFID is 64bit */
    1867                 :     }
    1868                 : 
    1869             654 :     sqlite3_reset( hInsertStmt );
    1870                 : 
    1871             654 :     return OGRERR_NONE;
    1872                 : }
    1873                 : 
    1874                 : /************************************************************************/
    1875                 : /*                           DeleteFeature()                            */
    1876                 : /************************************************************************/
    1877                 : 
    1878               4 : OGRErr OGRSQLiteTableLayer::DeleteFeature( long nFID )
    1879                 : 
    1880                 : {
    1881               4 :     CPLString      osSQL;
    1882                 :     int            rc;
    1883               4 :     char          *pszErrMsg = NULL;
    1884                 : 
    1885               4 :     if (HasLayerDefnError())
    1886               0 :         return OGRERR_FAILURE;
    1887                 : 
    1888               4 :     if( pszFIDColumn == NULL )
    1889                 :     {
    1890                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1891               0 :                   "Can't delete feature on a layer without FID column.");
    1892               0 :         return OGRERR_FAILURE;
    1893                 :     }
    1894                 : 
    1895               4 :     if (bSpatialiteReadOnly || !poDS->GetUpdate())
    1896                 :     {
    1897                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1898                 :                   UNSUPPORTED_OP_READ_ONLY,
    1899               0 :                   "DeleteFeature");
    1900               0 :         return OGRERR_FAILURE;
    1901                 :     }
    1902                 : 
    1903               4 :     bCachedExtentIsValid = FALSE;
    1904                 : 
    1905               4 :     ResetReading();
    1906                 : 
    1907                 :     osSQL.Printf( "DELETE FROM '%s' WHERE \"%s\" = %ld",
    1908                 :                   pszEscapedTableName,
    1909               4 :                   pszFIDColumn, nFID );
    1910                 : 
    1911               4 :     CPLDebug( "OGR_SQLITE", "exec(%s)", osSQL.c_str() );
    1912                 : 
    1913               4 :     rc = sqlite3_exec( poDS->GetDB(), osSQL, NULL, NULL, &pszErrMsg );
    1914               4 :     if( rc != SQLITE_OK )
    1915                 :     {
    1916                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1917                 :                     "In DeleteFeature(): sqlite3_exec(%s):\n  %s",
    1918               0 :                     osSQL.c_str(), pszErrMsg );
    1919               0 :         sqlite3_free( pszErrMsg );
    1920               0 :         return OGRERR_FAILURE;
    1921                 :     }
    1922                 : 
    1923               4 :     return OGRERR_NONE;
    1924                 : }

Generated by: LCOV version 1.7