LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/sqlite - ogrsqlitevirtualogr.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 622 560 90.0 %
Date: 2013-03-30 Functions: 41 38 92.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrsqlitevirtualogr.cpp 25726 2013-03-10 13:26:42Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  SQLite Virtual Table module using OGR layers
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 :  
      30                 : #include "ogrsqlitevirtualogr.h"
      31                 : #include "ogr_api.h"
      32                 : #include "swq.h"
      33                 : #include <map>
      34                 : #include <vector>
      35                 : 
      36                 : #ifdef HAVE_SQLITE_VFS
      37                 : 
      38                 : #define VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
      39                 : //#define DEBUG_OGR2SQLITE
      40                 : 
      41                 : #if defined(SPATIALITE_AMALGAMATION)
      42                 : #include "ogrsqlite3ext.h"
      43                 : #else
      44                 : #include "sqlite3ext.h"
      45                 : #endif
      46                 : 
      47                 : /* Declaration of sqlite3_api structure */
      48                 : SQLITE_EXTENSION_INIT1
      49                 : 
      50                 : /* The layout of fields is :
      51                 :    0   : RegularField0
      52                 :    ...
      53                 :    n-1 : RegularField(n-1)
      54                 :    n   : OGR_STYLE (may be HIDDEN)
      55                 :    n+1 : GEOMETRY
      56                 : */
      57                 : 
      58                 : #define COMPILATION_ALLOWED
      59                 : #include "ogrsqlitesqlfunctions.cpp" /* yes the .cpp file, to make it work on Windows with load_extension('gdalXX.dll') */
      60                 : #undef COMPILATION_ALLOWED
      61                 : 
      62                 : /************************************************************************/
      63                 : /*                           OGR2SQLITEModule                           */
      64                 : /************************************************************************/
      65                 : 
      66                 : class OGR2SQLITEModule
      67                 : {
      68                 : #ifdef DEBUG
      69                 :     void* pDummy; /* to track memory leaks */
      70                 : #endif
      71                 :     sqlite3* hDB; /* *NOT* to be freed */
      72                 : 
      73                 :     OGRDataSource* poDS; /* *NOT* to be freed */
      74                 :     std::vector<OGRDataSource*> apoExtraDS; /* each datasource to be freed */
      75                 : 
      76                 :     OGRSQLiteDataSource* poSQLiteDS;  /* *NOT* to be freed, might be NULL */
      77                 : 
      78                 :     std::map< CPLString, OGRLayer* > oMapVTableToOGRLayer;
      79                 : 
      80                 :     void* hHandleSQLFunctions;
      81                 : 
      82                 :   public:
      83                 :                                  OGR2SQLITEModule();
      84                 :                                 ~OGR2SQLITEModule();
      85                 : 
      86                 :     int                          Setup(OGRDataSource* poDS,
      87                 :                                        OGRSQLiteDataSource* poSQLiteDS);
      88                 :     int                          Setup(sqlite3* hDB);
      89                 : 
      90             247 :     OGRDataSource*               GetDS() { return poDS; }
      91                 : 
      92                 :     int                          AddExtraDS(OGRDataSource* poDS);
      93                 :     OGRDataSource               *GetExtraDS(int nIndex);
      94                 : 
      95                 :     int                          FetchSRSId(OGRSpatialReference* poSRS);
      96                 : 
      97                 :     void                         RegisterVTable(const char* pszVTableName, OGRLayer* poLayer);
      98                 :     void                         UnregisterVTable(const char* pszVTableName);
      99                 :     OGRLayer*                    GetLayerForVTable(const char* pszVTableName);
     100                 : 
     101                 :     void                         SetHandleSQLFunctions(void* hHandleSQLFunctionsIn);
     102                 : };
     103                 : 
     104                 : /************************************************************************/
     105                 : /*                        OGR2SQLITEModule()                            */
     106                 : /************************************************************************/
     107                 : 
     108             751 : OGR2SQLITEModule::OGR2SQLITEModule() :
     109             751 :     hDB(NULL), poDS(NULL), poSQLiteDS(NULL), hHandleSQLFunctions(NULL)
     110                 : {
     111                 : #ifdef DEBUG
     112             751 :     pDummy = CPLMalloc(1);
     113                 : #endif
     114             751 : }
     115                 : 
     116                 : /************************************************************************/
     117                 : /*                          ~OGR2SQLITEModule                           */
     118                 : /************************************************************************/
     119                 : 
     120             751 : OGR2SQLITEModule::~OGR2SQLITEModule()
     121                 : {
     122                 : #ifdef DEBUG
     123             751 :     CPLFree(pDummy);
     124                 : #endif
     125                 : 
     126             755 :     for(int i=0;i<(int)apoExtraDS.size();i++)
     127               4 :         delete apoExtraDS[i];
     128                 : 
     129             751 :     OGRSQLiteUnregisterSQLFunctions(hHandleSQLFunctions);
     130             751 : }
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                        SetHandleSQLFunctions()                       */
     134                 : /************************************************************************/
     135                 : 
     136             751 : void OGR2SQLITEModule::SetHandleSQLFunctions(void* hHandleSQLFunctionsIn)
     137                 : {
     138             751 :     CPLAssert(hHandleSQLFunctions == NULL);
     139             751 :     hHandleSQLFunctions = hHandleSQLFunctionsIn;
     140             751 : }
     141                 : 
     142                 : /************************************************************************/
     143                 : /*                            AddExtraDS()                              */
     144                 : /************************************************************************/
     145                 : 
     146               4 : int OGR2SQLITEModule::AddExtraDS(OGRDataSource* poDS)
     147                 : {
     148               4 :     int nRet = (int)apoExtraDS.size();
     149               4 :     apoExtraDS.push_back(poDS);
     150               4 :     return nRet;
     151                 : }
     152                 : 
     153                 : /************************************************************************/
     154                 : /*                            GetExtraDS()                              */
     155                 : /************************************************************************/
     156                 : 
     157               4 : OGRDataSource* OGR2SQLITEModule::GetExtraDS(int nIndex)
     158                 : {
     159               4 :     if( nIndex < 0 || nIndex >= (int)apoExtraDS.size() )
     160               0 :         return NULL;
     161               4 :     return apoExtraDS[nIndex];
     162                 : }
     163                 : 
     164                 : /************************************************************************/
     165                 : /*                                Setup()                               */
     166                 : /************************************************************************/
     167                 : 
     168             487 : int OGR2SQLITEModule::Setup(OGRDataSource* poDSIn,
     169                 :                             OGRSQLiteDataSource* poSQLiteDSIn)
     170                 : {
     171             487 :     CPLAssert(poDS == NULL);
     172             487 :     CPLAssert(poSQLiteDS == NULL);
     173             487 :     poDS = poDSIn;
     174             487 :     poSQLiteDS = poSQLiteDSIn;
     175             487 :     return Setup(poSQLiteDS->GetDB());
     176                 : }
     177                 : 
     178                 : /************************************************************************/
     179                 : /*                            FetchSRSId()                              */
     180                 : /************************************************************************/
     181                 : 
     182              86 : int OGR2SQLITEModule::FetchSRSId(OGRSpatialReference* poSRS)
     183                 : {
     184                 :     int nSRSId;
     185                 : 
     186              86 :     if( poSQLiteDS != NULL )
     187                 :     {
     188              67 :         nSRSId = poSQLiteDS->GetUndefinedSRID();
     189              67 :         if( poSRS != NULL )
     190              65 :             nSRSId = poSQLiteDS->FetchSRSId(poSRS);
     191                 :     }
     192                 :     else
     193                 :     {
     194              19 :         nSRSId = -1;
     195              19 :         if( poSRS != NULL )
     196                 :         {
     197              19 :             const char* pszAuthorityName = poSRS->GetAuthorityName(NULL);
     198              19 :             if (pszAuthorityName != NULL && EQUAL(pszAuthorityName, "EPSG"))
     199                 :             {
     200               0 :                 const char* pszAuthorityCode = poSRS->GetAuthorityCode(NULL);
     201               0 :                 if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 )
     202                 :                 {
     203               0 :                     nSRSId = atoi(pszAuthorityCode);
     204                 :                 }
     205                 :             }
     206                 :         }
     207                 :     }
     208                 : 
     209              86 :     return nSRSId;
     210                 : }
     211                 : 
     212                 : /************************************************************************/
     213                 : /*                          RegisterVTable()                            */
     214                 : /************************************************************************/
     215                 : 
     216             238 : void OGR2SQLITEModule::RegisterVTable(const char* pszVTableName,
     217                 :                                       OGRLayer* poLayer)
     218                 : {
     219             238 :     oMapVTableToOGRLayer[pszVTableName] = poLayer;
     220             238 : }
     221                 : 
     222                 : /************************************************************************/
     223                 : /*                          UnregisterVTable()                          */
     224                 : /************************************************************************/
     225                 : 
     226             238 : void OGR2SQLITEModule::UnregisterVTable(const char* pszVTableName)
     227                 : {
     228             238 :     oMapVTableToOGRLayer[pszVTableName] = NULL;
     229             238 : }
     230                 : 
     231                 : /************************************************************************/
     232                 : /*                          GetLayerForVTable()                         */
     233                 : /************************************************************************/
     234                 : 
     235               9 : OGRLayer* OGR2SQLITEModule::GetLayerForVTable(const char* pszVTableName)
     236                 : {
     237                 :     std::map<CPLString, OGRLayer*>::iterator oIter =
     238               9 :         oMapVTableToOGRLayer.find(pszVTableName);
     239               9 :     if( oIter == oMapVTableToOGRLayer.end() )
     240               1 :         return NULL;
     241                 : 
     242               8 :     OGRLayer* poLayer = oIter->second;
     243               8 :     if( poLayer == NULL )
     244                 :     {
     245                 :         /* If the associate layer is null, then try to "ping" the virtual */
     246                 :         /* table since we know that we have managed to create it before */
     247               0 :         if( sqlite3_exec(hDB,
     248                 :                      CPLSPrintf("PRAGMA table_info(\"%s\")",
     249                 :                                 OGRSQLiteEscapeName(pszVTableName).c_str()),
     250                 :                      NULL, NULL, NULL) == SQLITE_OK )
     251                 :         {
     252               0 :             poLayer = oMapVTableToOGRLayer[pszVTableName];
     253                 :         }
     254                 :     }
     255                 : 
     256               8 :     return poLayer;
     257                 : }
     258                 : 
     259                 : /* See http://www.sqlite.org/vtab.html for the documentation on how to
     260                 :    implement a new module for the Virtual Table mechanism. */
     261                 : 
     262                 : /************************************************************************/
     263                 : /*                            OGR2SQLITE_vtab                           */
     264                 : /************************************************************************/
     265                 : 
     266                 : typedef struct
     267                 : {
     268                 :     /* Mandatory fields by sqlite3: don't change or reorder them ! */
     269                 :     const sqlite3_module *pModule;
     270                 :     int                   nRef;
     271                 :     char                 *zErrMsg;
     272                 : 
     273                 :     /* Extension fields */
     274                 :     char                 *pszVTableName;
     275                 :     OGR2SQLITEModule     *poModule;
     276                 :     OGRDataSource        *poDS;
     277                 :     int                   bCloseDS;
     278                 :     OGRLayer             *poLayer;
     279                 :     int                   nMyRef;
     280                 : } OGR2SQLITE_vtab;
     281                 : 
     282                 : /************************************************************************/
     283                 : /*                          OGR2SQLITE_vtab_cursor                      */
     284                 : /************************************************************************/
     285                 : 
     286                 : typedef struct
     287                 : {
     288                 :     /* Mandatory fields by sqlite3: don't change or reorder them ! */
     289                 :     OGR2SQLITE_vtab *pVTab;
     290                 : 
     291                 :     /* Extension fields */
     292                 :     OGRDataSource *poDupDataSource;
     293                 :     OGRLayer      *poLayer;
     294                 :     OGRFeature    *poFeature;
     295                 : 
     296                 :     /* nFeatureCount >= 0 if the layer has a feast feature count capability. */
     297                 :     /* In which case nNextWishedIndex and nCurFeatureIndex */
     298                 :     /* will be used to avoid useless GetNextFeature() */
     299                 :     /* Helps in SELECT COUNT(*) FROM xxxx scenarios */
     300                 :     int            nFeatureCount;
     301                 :     int            nNextWishedIndex;
     302                 :     int            nCurFeatureIndex;
     303                 : 
     304                 :     GByte         *pabyGeomBLOB;
     305                 :     int            nGeomBLOBLen;
     306                 : } OGR2SQLITE_vtab_cursor;
     307                 : 
     308                 : 
     309                 : /************************************************************************/
     310                 : /*                  OGR2SQLITE_GetNameForGeometryColumn()               */
     311                 : /************************************************************************/
     312                 : 
     313             261 : CPLString OGR2SQLITE_GetNameForGeometryColumn(OGRLayer* poLayer)
     314                 : {
     315             522 :     if( poLayer->GetGeometryColumn() != NULL &&
     316             261 :         !EQUAL(poLayer->GetGeometryColumn(), "") )
     317                 :     {
     318               0 :         return poLayer->GetGeometryColumn();
     319                 :     }
     320                 :     else
     321                 :     {
     322             261 :         CPLString osGeomCol("GEOMETRY");
     323             261 :         int bTry = 2;
     324             526 :         while( poLayer->GetLayerDefn()->GetFieldIndex(osGeomCol) >= 0 )
     325                 :         {
     326               4 :             osGeomCol.Printf("GEOMETRY%d", bTry++);
     327                 :         }
     328             261 :         return osGeomCol;
     329                 :     }
     330                 : }
     331                 : 
     332                 : #ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
     333                 : 
     334                 : /************************************************************************/
     335                 : /*                     OGR2SQLITEDetectSuspiciousUsage()                */
     336                 : /************************************************************************/
     337                 : 
     338              25 : static int OGR2SQLITEDetectSuspiciousUsage(sqlite3* hDB,
     339                 :                                            const char* pszVirtualTableName,
     340                 :                                            char**pzErr)
     341                 : {
     342              25 :     char **papszResult = NULL;
     343              25 :     int nRowCount = 0, nColCount = 0;
     344                 :     int i;
     345                 : 
     346              25 :     std::vector<CPLString> aosDatabaseNames;
     347                 : 
     348                 :     /* Collect database names */
     349                 :     sqlite3_get_table( hDB, "PRAGMA database_list",
     350              25 :                        &papszResult, &nRowCount, &nColCount, NULL );
     351                 : 
     352              50 :     for(i = 1; i <= nRowCount; i++)
     353                 :     {
     354              25 :         const char* pszUnescapedName = papszResult[i * nColCount + 1];
     355                 :         aosDatabaseNames.push_back(
     356                 :             CPLSPrintf("\"%s\".sqlite_master",
     357              25 :                        OGRSQLiteEscapeName(pszUnescapedName).c_str()));
     358                 :     }
     359                 : 
     360                 :     /* Add special database (just in case, not sure it is really needed) */
     361              25 :     aosDatabaseNames.push_back("sqlite_temp_master");
     362                 : 
     363              25 :     sqlite3_free_table(papszResult);
     364              25 :     papszResult = NULL;
     365                 : 
     366                 :     /* Check the triggers of each database */
     367              71 :     for(i = 0; i < (int)aosDatabaseNames.size(); i++ )
     368                 :     {
     369              48 :         nRowCount = 0; nColCount = 0;
     370                 : 
     371                 :         const char* pszSQL;
     372                 : 
     373                 :         pszSQL = CPLSPrintf("SELECT name, sql FROM %s "
     374                 :                             "WHERE (type = 'trigger' OR type = 'view') AND ("
     375                 :                             "sql LIKE '%%%s%%' OR "
     376                 :                             "sql LIKE '%%\"%s\"%%' OR "
     377                 :                             "sql LIKE '%%ogr_layer_%%' )",
     378                 :                             aosDatabaseNames[i].c_str(),
     379                 :                             pszVirtualTableName,
     380              48 :                             OGRSQLiteEscapeName(pszVirtualTableName).c_str());
     381                 : 
     382                 :         sqlite3_get_table( hDB, pszSQL, &papszResult, &nRowCount, &nColCount,
     383              48 :                            NULL );
     384                 : 
     385              48 :         sqlite3_free_table(papszResult);
     386              48 :         papszResult = NULL;
     387                 : 
     388              48 :         if( nRowCount > 0 )
     389                 :         {
     390               2 :             if( !CSLTestBoolean(CPLGetConfigOption("ALLOW_VIRTUAL_OGR_FROM_TRIGGER_AND_VIEW", "NO")) )
     391                 :             {
     392                 :                 *pzErr = sqlite3_mprintf(
     393                 :                     "A trigger and/or view might reference VirtualOGR table '%s'.\n"
     394                 :                     "This is suspicious practice that could be used to steal data without your consent.\n"
     395                 :                     "Disabling access to it unless you define the ALLOW_VIRTUAL_OGR_FROM_TRIGGER_AND_VIEW "
     396                 :                     "configuration option to YES.",
     397               2 :                     pszVirtualTableName);
     398               2 :                 return TRUE;
     399                 :             }
     400                 :         }
     401                 :     }
     402                 : 
     403              23 :     return FALSE;
     404                 : }
     405                 : 
     406                 : #endif // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
     407                 : 
     408                 : /************************************************************************/
     409                 : /*                      OGR2SQLITE_ConnectCreate()                      */
     410                 : /************************************************************************/
     411                 : 
     412                 : static
     413                 : int OGR2SQLITE_DisconnectDestroy(sqlite3_vtab *pVTab);
     414                 : 
     415                 : static
     416             247 : int OGR2SQLITE_ConnectCreate(sqlite3* hDB, void *pAux,
     417                 :                              int argc, const char *const*argv,
     418                 :                              sqlite3_vtab **ppVTab, char**pzErr)
     419                 : {
     420             247 :     OGR2SQLITEModule* poModule = (OGR2SQLITEModule*) pAux;
     421             247 :     OGRLayer* poLayer = NULL;
     422             247 :     OGRDataSource* poDS = NULL;
     423             247 :     int bExposeOGR_STYLE = FALSE;
     424             247 :     int bCloseDS = FALSE;
     425                 :     int i;
     426                 : 
     427                 : #ifdef DEBUG_OGR2SQLITE
     428                 :     CPLDebug("OGR2SQLITE", "ConnectCreate(%s)", argv[2]);
     429                 : #endif
     430                 : 
     431                 :     /*for(i=0;i<argc;i++)
     432                 :         printf("[%d] %s\n", i, argv[i]);*/
     433                 : 
     434                 : /* -------------------------------------------------------------------- */
     435                 : /*      If called from ogrexecutesql.cpp                                */
     436                 : /* -------------------------------------------------------------------- */
     437             247 :     poDS = poModule->GetDS();
     438             247 :     if( poDS != NULL && argc == 6 &&
     439                 :         CPLGetValueType(argv[3]) == CPL_VALUE_INTEGER )
     440                 :     {
     441             220 :         if( argc != 6 )
     442                 :         {
     443                 :             *pzErr = sqlite3_mprintf(
     444                 :                 "Expected syntax: CREATE VIRTUAL TABLE xxx USING "
     445               0 :                 "VirtualOGR(ds_idx, layer_name, expose_ogr_style)");
     446               0 :             return SQLITE_ERROR;
     447                 :         }
     448                 : 
     449             220 :         int nDSIndex = atoi(argv[3]);
     450             220 :         if( nDSIndex >= 0 )
     451                 :         {
     452               4 :             poDS = poModule->GetExtraDS(nDSIndex);
     453               4 :             if( poDS == NULL )
     454                 :             {
     455               0 :                 *pzErr = sqlite3_mprintf("Invalid dataset index : %d", nDSIndex);
     456               0 :                 return SQLITE_ERROR;
     457                 :             }
     458                 :         }
     459             220 :         CPLString osLayerName(OGRSQLiteParamsUnquote(argv[4]));
     460                 : 
     461             220 :         poLayer = poDS->GetLayerByName(osLayerName);
     462             220 :         if( poLayer == NULL )
     463                 :         {
     464                 :             *pzErr = sqlite3_mprintf( "Cannot find layer '%s' in '%s'",
     465               0 :                                       osLayerName.c_str(), poDS->GetName() );
     466               0 :             return SQLITE_ERROR;
     467                 :         }
     468                 : 
     469             220 :         bExposeOGR_STYLE = atoi(OGRSQLiteParamsUnquote(argv[5]));
     470                 :     }
     471                 : #ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
     472                 : /* -------------------------------------------------------------------- */
     473                 : /*      If called from outside (OGR loaded as a sqlite3 extension)      */
     474                 : /* -------------------------------------------------------------------- */
     475                 :     else
     476                 :     {
     477              27 :         if( argc < 4 || argc > 7 )
     478                 :         {
     479                 :             *pzErr = sqlite3_mprintf(
     480                 :                 "Expected syntax: CREATE VIRTUAL TABLE xxx USING "
     481               2 :                 "VirtualOGR(datasource_name[, update_mode, [layer_name[, expose_ogr_style]]])");
     482               2 :             return SQLITE_ERROR;
     483                 :         }
     484                 : 
     485              25 :         if( OGR2SQLITEDetectSuspiciousUsage(hDB, argv[2], pzErr) )
     486                 :         {
     487               2 :             return SQLITE_ERROR;
     488                 :         }
     489                 : 
     490              23 :         CPLString osDSName(OGRSQLiteParamsUnquote(argv[3]));
     491              23 :         CPLString osUpdate(OGRSQLiteParamsUnquote((argc >= 5) ? argv[4] : "0"));
     492                 : 
     493              23 :         if( !EQUAL(osUpdate, "1") && !EQUAL(osUpdate, "0") )
     494                 :         {
     495                 :             *pzErr = sqlite3_mprintf(
     496               1 :                 "update_mode parameter should be 0 or 1");
     497               1 :             return SQLITE_ERROR;
     498                 :         }
     499                 : 
     500              22 :         int bUpdate = atoi(osUpdate);
     501                 : 
     502              22 :         poDS = (OGRDataSource* )OGROpenShared(osDSName, bUpdate, NULL);
     503              22 :         if( poDS == NULL )
     504                 :         {
     505               1 :             *pzErr = sqlite3_mprintf( "Cannot open datasource '%s'", osDSName.c_str() );
     506               1 :             return SQLITE_ERROR;
     507                 :         }
     508                 : 
     509              21 :         CPLString osLayerName;
     510              21 :         if( argc >= 6 )
     511                 :         {
     512              10 :             osLayerName = OGRSQLiteParamsUnquote(argv[5]);
     513              10 :             poLayer = poDS->GetLayerByName(osLayerName);
     514                 :         }
     515                 :         else
     516                 :         {
     517              11 :             if( poDS->GetLayerCount() == 0 )
     518                 :             {
     519                 :                 *pzErr = sqlite3_mprintf( "Datasource '%s' has no layers",
     520               1 :                                           osDSName.c_str() );
     521               1 :                 poDS->Release();
     522               1 :                 return SQLITE_ERROR;
     523                 :             }
     524                 : 
     525              10 :             if( poDS->GetLayerCount() > 1 )
     526                 :             {
     527                 :                 *pzErr = sqlite3_mprintf( "Datasource '%s' has more than one layers, and none was explicitely selected.",
     528               1 :                                           osDSName.c_str() );
     529               1 :                 poDS->Release();
     530               1 :                 return SQLITE_ERROR;
     531                 :             }
     532                 : 
     533               9 :             poLayer = poDS->GetLayer(0);
     534                 :         }
     535                 : 
     536              19 :         if( poLayer == NULL )
     537                 :         {
     538               1 :             *pzErr = sqlite3_mprintf( "Cannot find layer '%s' in '%s'", osLayerName.c_str(), osDSName.c_str() );
     539               1 :             poDS->Release();
     540               1 :             return SQLITE_ERROR;
     541                 :         }
     542                 : 
     543              18 :         if( argc == 7 )
     544                 :         {
     545               4 :             bExposeOGR_STYLE = atoi(OGRSQLiteParamsUnquote(argv[6]));
     546                 :         }
     547                 :         
     548              18 :         bCloseDS = TRUE;
     549                 :     }
     550                 : #endif // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
     551                 :     OGR2SQLITE_vtab* vtab =
     552             238 :                 (OGR2SQLITE_vtab*) CPLCalloc(1, sizeof(OGR2SQLITE_vtab));
     553                 :     /* We dont need to fill the non-extended fields */
     554             238 :     vtab->pszVTableName = CPLStrdup(OGRSQLiteEscapeName(argv[2]));
     555             238 :     vtab->poModule = poModule;
     556             238 :     vtab->poDS = poDS;
     557             238 :     vtab->bCloseDS = bCloseDS;
     558             238 :     vtab->poLayer = poLayer;
     559             238 :     vtab->nMyRef = 0;
     560                 : 
     561             238 :     poModule->RegisterVTable(vtab->pszVTableName, poLayer);
     562                 : 
     563             238 :     *ppVTab = (sqlite3_vtab*) vtab;
     564                 : 
     565             238 :     CPLString osSQL;
     566             476 :     osSQL = "CREATE TABLE ";
     567             238 :     osSQL += "\"";
     568             238 :     osSQL += OGRSQLiteEscapeName(argv[2]);
     569             238 :     osSQL += "\"";
     570             238 :     osSQL += "(";
     571                 : 
     572             238 :     int bAddComma = FALSE;
     573                 : 
     574             238 :     OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn();
     575            2033 :     for(i=0;i<poFDefn->GetFieldCount();i++)
     576                 :     {
     577            1795 :         if( bAddComma )
     578            1563 :             osSQL += ",";
     579            1795 :         bAddComma = TRUE;
     580                 : 
     581            1795 :         OGRFieldDefn* poFieldDefn = poFDefn->GetFieldDefn(i);
     582                 : 
     583            1795 :         osSQL += "\"";
     584            1795 :         osSQL += OGRSQLiteEscapeName(poFieldDefn->GetNameRef());
     585            1795 :         osSQL += "\"";
     586            1795 :         osSQL += " ";
     587            1795 :         osSQL += OGRSQLiteFieldDefnToSQliteFieldDefn(poFieldDefn);
     588                 :     }
     589                 : 
     590             238 :     if( bAddComma )
     591             232 :         osSQL += ",";
     592             238 :     bAddComma = TRUE;
     593             238 :     osSQL += "OGR_STYLE VARCHAR";
     594             238 :     if( !bExposeOGR_STYLE )
     595             226 :      osSQL += " HIDDEN";
     596                 : 
     597             238 :     if( poFDefn->GetGeomType() != wkbNone )
     598                 :     {
     599             139 :         if( bAddComma )
     600             139 :             osSQL += ",";
     601             139 :         bAddComma = TRUE;
     602                 : 
     603             139 :         osSQL += OGRSQLiteEscapeName(OGR2SQLITE_GetNameForGeometryColumn(poLayer));
     604             139 :         osSQL += " BLOB";
     605                 :     }
     606                 : 
     607             238 :     osSQL += ")";
     608                 : 
     609             238 :     CPLDebug("OGR2SQLITE", "sqlite3_declare_vtab(%s)", osSQL.c_str());
     610             238 :     if (sqlite3_declare_vtab (hDB, osSQL.c_str()) != SQLITE_OK)
     611                 :     {
     612                 :         *pzErr = sqlite3_mprintf("CREATE VIRTUAL: invalid SQL statement : %s",
     613               1 :                                  osSQL.c_str());
     614               1 :         OGR2SQLITE_DisconnectDestroy((sqlite3_vtab*) vtab);
     615               1 :         return SQLITE_ERROR;
     616                 :     }
     617                 : 
     618             237 :     return SQLITE_OK;
     619                 : }
     620                 : 
     621                 : /************************************************************************/
     622                 : /*                        OGR2SQLITE_BestIndex()                        */
     623                 : /************************************************************************/
     624                 : 
     625                 : static
     626             257 : int OGR2SQLITE_BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info* pIndex)
     627                 : {
     628                 :     int i;
     629             257 :     OGR2SQLITE_vtab* pMyVTab = (OGR2SQLITE_vtab*) pVTab;
     630             257 :     OGRFeatureDefn* poFDefn = pMyVTab->poLayer->GetLayerDefn();
     631                 : 
     632                 : #ifdef DEBUG_OGR2SQLITE
     633                 :     CPLString osQueryPatternUsable, osQueryPatternNotUsable;
     634                 :     for (i = 0; i < pIndex->nConstraint; i++)
     635                 :     {
     636                 :         int iCol = pIndex->aConstraint[i].iColumn;
     637                 :         const char* pszFieldName;
     638                 :         if( iCol == -1 )
     639                 :             pszFieldName = "FID";
     640                 :         else if( iCol >= 0 && iCol < poFDefn->GetFieldCount() )
     641                 :             pszFieldName = poFDefn->GetFieldDefn(iCol)->GetNameRef();
     642                 :         else
     643                 :             pszFieldName = "unkown_field";
     644                 : 
     645                 :         const char* pszOp;
     646                 :         switch(pIndex->aConstraint[i].op)
     647                 :         {
     648                 :             case SQLITE_INDEX_CONSTRAINT_EQ: pszOp = " = "; break;
     649                 :             case SQLITE_INDEX_CONSTRAINT_GT: pszOp = " > "; break;
     650                 :             case SQLITE_INDEX_CONSTRAINT_LE: pszOp = " <= "; break;
     651                 :             case SQLITE_INDEX_CONSTRAINT_LT: pszOp = " < "; break;
     652                 :             case SQLITE_INDEX_CONSTRAINT_GE: pszOp = " >= "; break;
     653                 :             case SQLITE_INDEX_CONSTRAINT_MATCH: pszOp = " MATCH "; break;
     654                 :             default: pszOp = " (unknown op) "; break;
     655                 :         }
     656                 : 
     657                 :         if (pIndex->aConstraint[i].usable)
     658                 :         {
     659                 :             if (osQueryPatternUsable.size()) osQueryPatternUsable += " AND ";
     660                 :             osQueryPatternUsable += pszFieldName;
     661                 :             osQueryPatternUsable += pszOp;
     662                 :             osQueryPatternUsable += "?";
     663                 :         }
     664                 :         else
     665                 :         {
     666                 :             if (osQueryPatternNotUsable.size()) osQueryPatternNotUsable += " AND ";
     667                 :             osQueryPatternNotUsable += pszFieldName;
     668                 :             osQueryPatternNotUsable += pszOp;
     669                 :             osQueryPatternNotUsable += "?";
     670                 :         }
     671                 :     }
     672                 :     CPLDebug("OGR2SQLITE", "BestIndex, usable ( %s ), not usable ( %s )",
     673                 :              osQueryPatternUsable.c_str(), osQueryPatternNotUsable.c_str());
     674                 : #endif
     675                 : 
     676             257 :     int nConstraints = 0;
     677             469 :     for (i = 0; i < pIndex->nConstraint; i++)
     678                 :     {
     679             212 :         int iCol = pIndex->aConstraint[i].iColumn;
     680             411 :         if (pIndex->aConstraint[i].usable &&
     681             199 :             pIndex->aConstraint[i].op != SQLITE_INDEX_CONSTRAINT_MATCH &&
     682                 :             iCol < poFDefn->GetFieldCount() &&
     683                 :             (iCol < 0 || poFDefn->GetFieldDefn(iCol)->GetType() != OFTBinary))
     684                 :         {
     685             189 :             pIndex->aConstraintUsage[i].argvIndex = nConstraints + 1;
     686             189 :             pIndex->aConstraintUsage[i].omit = TRUE;
     687                 : 
     688             189 :             nConstraints ++;
     689                 :         }
     690                 :         else
     691                 :         {
     692              23 :             pIndex->aConstraintUsage[i].argvIndex = 0;
     693              23 :             pIndex->aConstraintUsage[i].omit = FALSE;
     694                 :         }
     695                 :     }
     696                 : 
     697             257 :     int* panConstraints = NULL;
     698                 : 
     699             257 :     if( nConstraints )
     700                 :     {
     701                 :         panConstraints = (int*)
     702             180 :                     sqlite3_malloc( sizeof(int) * (1 + 2 * nConstraints) );
     703             180 :         panConstraints[0] = nConstraints;
     704                 : 
     705             180 :         nConstraints = 0;
     706                 : 
     707             370 :         for (i = 0; i < pIndex->nConstraint; i++)
     708                 :         {
     709             190 :             if (pIndex->aConstraintUsage[i].omit)
     710                 :             {
     711             189 :                 panConstraints[2 * nConstraints + 1] =
     712             189 :                                             pIndex->aConstraint[i].iColumn;
     713             189 :                 panConstraints[2 * nConstraints + 2] =
     714             189 :                                             pIndex->aConstraint[i].op;
     715                 : 
     716             189 :                 nConstraints ++;
     717                 :             }
     718                 :         }
     719                 :     }
     720                 : 
     721             257 :     pIndex->orderByConsumed = FALSE;
     722             257 :     pIndex->idxNum = 0;
     723                 : 
     724             257 :     if (nConstraints != 0)
     725                 :     {
     726             180 :         pIndex->idxStr = (char *) panConstraints;
     727             180 :         pIndex->needToFreeIdxStr = TRUE;
     728                 :     }
     729                 :     else
     730                 :     {
     731              77 :         pIndex->idxStr = NULL;
     732              77 :         pIndex->needToFreeIdxStr = FALSE;
     733                 :     }
     734                 : 
     735             257 :     return SQLITE_OK;
     736                 : }
     737                 : 
     738                 : /************************************************************************/
     739                 : /*                      OGR2SQLITE_DisconnectDestroy()                  */
     740                 : /************************************************************************/
     741                 : 
     742                 : static
     743             238 : int OGR2SQLITE_DisconnectDestroy(sqlite3_vtab *pVTab)
     744                 : {
     745             238 :     OGR2SQLITE_vtab* pMyVTab = (OGR2SQLITE_vtab*) pVTab;
     746                 : 
     747                 : #ifdef DEBUG_OGR2SQLITE
     748                 :     CPLDebug("OGR2SQLITE", "DisconnectDestroy(%s)",pMyVTab->pszVTableName);
     749                 : #endif
     750                 : 
     751             238 :     sqlite3_free(pMyVTab->zErrMsg);
     752             238 :     if( pMyVTab->bCloseDS )
     753              18 :         pMyVTab->poDS->Release();
     754             238 :     pMyVTab->poModule->UnregisterVTable(pMyVTab->pszVTableName);
     755             238 :     CPLFree(pMyVTab->pszVTableName);
     756             238 :     CPLFree(pMyVTab);
     757                 : 
     758             238 :     return SQLITE_OK;
     759                 : }
     760                 : 
     761                 : /************************************************************************/
     762                 : /*                           OGR2SQLITE_Open()                          */
     763                 : /************************************************************************/
     764                 : 
     765                 : static
     766             237 : int OGR2SQLITE_Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
     767                 : {
     768             237 :     OGR2SQLITE_vtab* pMyVTab = (OGR2SQLITE_vtab*) pVTab;
     769                 : #ifdef DEBUG_OGR2SQLITE
     770                 :     CPLDebug("OGR2SQLITE", "Open(%s, %s)",
     771                 :              pMyVTab->poDS->GetName(), pMyVTab->poLayer->GetName());
     772                 : #endif
     773                 : 
     774             237 :     OGRDataSource* poDupDataSource = NULL;
     775             237 :     OGRLayer* poLayer = NULL;
     776                 : 
     777             237 :     if( pMyVTab->nMyRef == 0 )
     778                 :     {
     779             226 :         poLayer = pMyVTab->poLayer;
     780                 :     }
     781                 :     else
     782                 :     {
     783                 :         poDupDataSource =
     784              11 :             (OGRDataSource*) OGROpen(pMyVTab->poDS->GetName(), FALSE, NULL);
     785              11 :         if( poDupDataSource == NULL )
     786               1 :             return SQLITE_ERROR;
     787                 :         poLayer = poDupDataSource->GetLayerByName(
     788              10 :                                                 pMyVTab->poLayer->GetName());
     789              10 :         if( poLayer == NULL )
     790                 :         {
     791               0 :             delete poDupDataSource;
     792               0 :             return SQLITE_ERROR;
     793                 :         }
     794              20 :         if( !poLayer->GetLayerDefn()->
     795              10 :                 IsSame(pMyVTab->poLayer->GetLayerDefn()) )
     796                 :         {
     797               0 :             delete poDupDataSource;
     798               0 :             return SQLITE_ERROR;
     799                 :         }
     800                 :     }
     801             236 :     pMyVTab->nMyRef ++;
     802                 : 
     803                 :     OGR2SQLITE_vtab_cursor* pCursor = (OGR2SQLITE_vtab_cursor*)
     804             236 :                                 CPLCalloc(1, sizeof(OGR2SQLITE_vtab_cursor));
     805                 :     /* We dont need to fill the non-extended fields */
     806             236 :     *ppCursor = (sqlite3_vtab_cursor *)pCursor;
     807                 : 
     808             236 :     pCursor->poDupDataSource = poDupDataSource;
     809             236 :     pCursor->poLayer = poLayer;
     810             236 :     pCursor->poLayer->ResetReading();
     811             236 :     pCursor->poFeature = NULL;
     812             236 :     pCursor->nNextWishedIndex = 0;
     813             236 :     pCursor->nCurFeatureIndex = -1;
     814             236 :     pCursor->nFeatureCount = -1;
     815                 : 
     816             236 :     pCursor->pabyGeomBLOB = NULL;
     817             236 :     pCursor->nGeomBLOBLen = -1;
     818                 : 
     819             236 :     return SQLITE_OK;
     820                 : }
     821                 : 
     822                 : /************************************************************************/
     823                 : /*                           OGR2SQLITE_Close()                         */
     824                 : /************************************************************************/
     825                 : 
     826                 : static
     827             236 : int OGR2SQLITE_Close(sqlite3_vtab_cursor* pCursor)
     828                 : {
     829             236 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
     830             236 :     OGR2SQLITE_vtab* pMyVTab = pMyCursor->pVTab;
     831                 : #ifdef DEBUG_OGR2SQLITE
     832                 :     CPLDebug("OGR2SQLITE", "Close(%s, %s)",
     833                 :              pMyVTab->poDS->GetName(), pMyVTab->poLayer->GetName());
     834                 : #endif
     835             236 :     pMyVTab->nMyRef --;
     836                 : 
     837             236 :     delete pMyCursor->poFeature;
     838             236 :     delete pMyCursor->poDupDataSource;
     839                 : 
     840             236 :     CPLFree(pMyCursor->pabyGeomBLOB);
     841                 : 
     842             236 :     CPLFree(pCursor);
     843                 : 
     844             236 :     return SQLITE_OK;
     845                 : }
     846                 : 
     847                 : /************************************************************************/
     848                 : /*                          OGR2SQLITE_Filter()                         */
     849                 : /************************************************************************/
     850                 : 
     851                 : static
     852             286 : int OGR2SQLITE_Filter(sqlite3_vtab_cursor* pCursor,
     853                 :                       int idxNum, const char *idxStr,
     854                 :                       int argc, sqlite3_value **argv)
     855                 : {
     856             286 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
     857                 : #ifdef DEBUG_OGR2SQLITE
     858                 :     CPLDebug("OGR2SQLITE", "Filter");
     859                 : #endif
     860                 : 
     861             286 :     int* panConstraints = (int*) idxStr;
     862             286 :     int nConstraints = panConstraints ? panConstraints[0] : 0;
     863                 : 
     864             286 :     if( nConstraints != argc )
     865               0 :         return SQLITE_ERROR;
     866                 : 
     867             286 :     CPLString osAttributeFilter;
     868                 : 
     869             286 :     OGRFeatureDefn* poFDefn = pMyCursor->poLayer->GetLayerDefn();
     870                 : 
     871                 :     int i;
     872             509 :     for (i = 0; i < argc; i++)
     873                 :     {
     874             223 :         int nCol = panConstraints[2 * i + 1];
     875             223 :         OGRFieldDefn* poFieldDefn = NULL;
     876             223 :         if( nCol >= 0 )
     877                 :         {
     878             205 :             poFieldDefn = poFDefn->GetFieldDefn(nCol);
     879             205 :             if( poFieldDefn == NULL )
     880               0 :                 return SQLITE_ERROR;
     881                 :         }
     882                 : 
     883             223 :         if( i != 0 )
     884               8 :             osAttributeFilter += " AND ";
     885                 : 
     886             223 :         if( poFieldDefn != NULL )
     887                 :         {
     888             205 :             const char* pszFieldName = poFieldDefn->GetNameRef();
     889                 :             char ch;
     890             205 :             int bNeedsQuoting = swq_is_reserved_keyword(pszFieldName);
     891            1811 :             for(int j = 0; !bNeedsQuoting &&
     892                 :                            (ch = pszFieldName[j]) != '\0'; j++ )
     893                 :             {
     894            1606 :                 if (!(isalnum((int)ch) || ch == '_'))
     895               0 :                     bNeedsQuoting = FALSE;
     896                 :             }
     897                 : 
     898             205 :             if( bNeedsQuoting )
     899                 :             {
     900                 :                 /* FIXME: we would need some virtual method */
     901               8 :                 OGRSFDriver* poDriver = pMyCursor->pVTab->poDS->GetDriver();
     902                 :                 char chQuote;
     903                 : 
     904              32 :                 if (poDriver && (
     905               8 :                     EQUAL(poDriver->GetName(), "PostgreSQL") ||
     906               8 :                     EQUAL(poDriver->GetName(), "SQLite") ||
     907               8 :                     EQUAL(poDriver->GetName(), "FileGDB" )) )
     908               0 :                     chQuote = '"';
     909                 :                 else
     910               8 :                     chQuote = '\'';
     911                 : 
     912               8 :                 osAttributeFilter += chQuote;
     913               8 :                 if( chQuote == '"' )
     914               0 :                     osAttributeFilter += OGRSQLiteEscapeName(pszFieldName);
     915                 :                 else
     916               8 :                     osAttributeFilter += OGRSQLiteEscape(pszFieldName);
     917               8 :                 osAttributeFilter += chQuote;
     918                 :             }
     919                 :             else
     920                 :             {
     921             197 :                 osAttributeFilter += pszFieldName;
     922                 :             }
     923                 :         }
     924                 :         else
     925              18 :             osAttributeFilter += "FID";
     926                 : 
     927             223 :         switch(panConstraints[2 * i + 2])
     928                 :         {
     929             126 :             case SQLITE_INDEX_CONSTRAINT_EQ: osAttributeFilter += " = "; break;
     930              25 :             case SQLITE_INDEX_CONSTRAINT_GT: osAttributeFilter += " > "; break;
     931              24 :             case SQLITE_INDEX_CONSTRAINT_LE: osAttributeFilter += " <= "; break;
     932              24 :             case SQLITE_INDEX_CONSTRAINT_LT: osAttributeFilter += " < "; break;
     933              24 :             case SQLITE_INDEX_CONSTRAINT_GE: osAttributeFilter += " >= "; break;
     934                 :             default:
     935                 :             {
     936               0 :                 sqlite3_free(pMyCursor->pVTab->zErrMsg);
     937                 :                 pMyCursor->pVTab->zErrMsg = sqlite3_mprintf(
     938                 :                                         "Unhandled constraint operator : %d",
     939               0 :                                         panConstraints[2 * i + 2]);
     940               0 :                 return SQLITE_ERROR;
     941                 :             }
     942                 :         }
     943                 : 
     944             223 :         if (sqlite3_value_type (argv[i]) == SQLITE_INTEGER)
     945                 :         {
     946                 :             osAttributeFilter +=
     947              87 :                 CPLSPrintf(CPL_FRMT_GIB, sqlite3_value_int64 (argv[i]));
     948                 :         }
     949             136 :         else if (sqlite3_value_type (argv[i]) == SQLITE_FLOAT)
     950                 :         {
     951                 :             osAttributeFilter +=
     952              88 :                 CPLSPrintf("%.18g", sqlite3_value_double (argv[i]));
     953                 :         }
     954              48 :         else if (sqlite3_value_type (argv[i]) == SQLITE_TEXT)
     955                 :         {
     956              48 :             osAttributeFilter += "'";
     957              48 :             osAttributeFilter += OGRSQLiteEscape((const char*) sqlite3_value_text (argv[i]));
     958              48 :             osAttributeFilter += "'";
     959                 :         }
     960                 :         else
     961                 :         {
     962               0 :             sqlite3_free(pMyCursor->pVTab->zErrMsg);
     963                 :             pMyCursor->pVTab->zErrMsg = sqlite3_mprintf(
     964                 :                                     "Unhandled constraint data type : %d",
     965               0 :                                     sqlite3_value_type (argv[i]));
     966               0 :             return SQLITE_ERROR;
     967                 :         }
     968                 :     }
     969                 : 
     970                 : #ifdef DEBUG_OGR2SQLITE
     971                 :     CPLDebug("OGR2SQLITE", "Attribute filter : %s",
     972                 :              osAttributeFilter.c_str());
     973                 : #endif
     974                 : 
     975             572 :     if( pMyCursor->poLayer->SetAttributeFilter( osAttributeFilter.size() ?
     976             286 :                             osAttributeFilter.c_str() : NULL) != OGRERR_NONE )
     977                 :     {
     978               0 :         sqlite3_free(pMyCursor->pVTab->zErrMsg);
     979                 :         pMyCursor->pVTab->zErrMsg = sqlite3_mprintf(
     980                 :                 "Cannot apply attribute filter : %s",
     981               0 :                 osAttributeFilter.c_str());
     982               0 :         return SQLITE_ERROR;
     983                 :     }
     984                 : 
     985             286 :     if( pMyCursor->poLayer->TestCapability(OLCFastFeatureCount) )
     986                 :     {
     987              69 :         pMyCursor->nFeatureCount = pMyCursor->poLayer->GetFeatureCount();
     988              69 :         pMyCursor->poLayer->ResetReading();
     989                 :     }
     990                 :     else
     991             217 :         pMyCursor->nFeatureCount = -1;
     992                 : 
     993             286 :     if( pMyCursor->nFeatureCount < 0 )
     994                 :     {
     995             217 :         pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
     996                 : #ifdef DEBUG_OGR2SQLITE
     997                 :         CPLDebug("OGR2SQLITE", "GetNextFeature() --> %d",
     998                 :             pMyCursor->poFeature ? (int)pMyCursor->poFeature->GetFID() : -1);
     999                 : #endif
    1000                 :     }
    1001                 : 
    1002             286 :     pMyCursor->nNextWishedIndex = 0;
    1003             286 :     pMyCursor->nCurFeatureIndex = -1;
    1004                 : 
    1005             286 :     return SQLITE_OK;
    1006                 : }
    1007                 : 
    1008                 : /************************************************************************/
    1009                 : /*                          OGR2SQLITE_Next()                           */
    1010                 : /************************************************************************/
    1011                 : 
    1012                 : static
    1013             189 : int OGR2SQLITE_Next(sqlite3_vtab_cursor* pCursor)
    1014                 : {
    1015             189 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
    1016                 : #ifdef DEBUG_OGR2SQLITE
    1017                 :     CPLDebug("OGR2SQLITE", "Next");
    1018                 : #endif
    1019                 : 
    1020             189 :     pMyCursor->nNextWishedIndex ++;
    1021             189 :     if( pMyCursor->nFeatureCount < 0 )
    1022                 :     {
    1023              62 :         delete pMyCursor->poFeature;
    1024              62 :         pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
    1025                 : 
    1026              62 :         CPLFree(pMyCursor->pabyGeomBLOB);
    1027              62 :         pMyCursor->pabyGeomBLOB = NULL;
    1028              62 :         pMyCursor->nGeomBLOBLen = -1;
    1029                 : 
    1030                 : #ifdef DEBUG_OGR2SQLITE
    1031                 :         CPLDebug("OGR2SQLITE", "GetNextFeature() --> %d",
    1032                 :             pMyCursor->poFeature ? (int)pMyCursor->poFeature->GetFID() : -1);
    1033                 : #endif
    1034                 :     }
    1035             189 :     return SQLITE_OK;
    1036                 : }
    1037                 : 
    1038                 : /************************************************************************/
    1039                 : /*                          OGR2SQLITE_Eof()                            */
    1040                 : /************************************************************************/
    1041                 : 
    1042                 : static
    1043             475 : int OGR2SQLITE_Eof(sqlite3_vtab_cursor* pCursor)
    1044                 : {
    1045             475 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
    1046                 : #ifdef DEBUG_OGR2SQLITE
    1047                 :     CPLDebug("OGR2SQLITE", "Eof");
    1048                 : #endif
    1049                 : 
    1050             475 :     if( pMyCursor->nFeatureCount < 0 )
    1051                 :     {
    1052             279 :         return (pMyCursor->poFeature == NULL);
    1053                 :     }
    1054                 :     else
    1055                 :     {
    1056             196 :         return ( pMyCursor->nNextWishedIndex >= pMyCursor->nFeatureCount );
    1057                 :     }
    1058                 : }
    1059                 : 
    1060                 : /************************************************************************/
    1061                 : /*                      OGR2SQLITE_GoToWishedIndex()                    */
    1062                 : /************************************************************************/
    1063                 : 
    1064            1352 : static void OGR2SQLITE_GoToWishedIndex(OGR2SQLITE_vtab_cursor* pMyCursor)
    1065                 : {
    1066            1352 :     if( pMyCursor->nFeatureCount >= 0 )
    1067                 :     {
    1068             548 :         if( pMyCursor->nCurFeatureIndex < pMyCursor->nNextWishedIndex )
    1069                 :         {
    1070             135 :             do
    1071                 :             {
    1072             135 :                 pMyCursor->nCurFeatureIndex ++;
    1073                 : 
    1074             135 :                 delete pMyCursor->poFeature;
    1075             135 :                 pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
    1076                 : #ifdef DEBUG_OGR2SQLITE
    1077                 :                 CPLDebug("OGR2SQLITE", "GetNextFeature() --> %d",
    1078                 :                     pMyCursor->poFeature ? (int)pMyCursor->poFeature->GetFID() : -1);
    1079                 : #endif
    1080                 :             }
    1081                 :             while( pMyCursor->nCurFeatureIndex < pMyCursor->nNextWishedIndex );
    1082                 : 
    1083             135 :             CPLFree(pMyCursor->pabyGeomBLOB);
    1084             135 :             pMyCursor->pabyGeomBLOB = NULL;
    1085             135 :             pMyCursor->nGeomBLOBLen = -1;
    1086                 :         }
    1087                 :     }
    1088            1352 : }
    1089                 : 
    1090                 : /************************************************************************/
    1091                 : /*                         OGR2SQLITE_Column()                          */
    1092                 : /************************************************************************/
    1093                 : 
    1094                 : static
    1095            1314 : int OGR2SQLITE_Column(sqlite3_vtab_cursor* pCursor,
    1096                 :                       sqlite3_context* pContext, int nCol)
    1097                 : {
    1098            1314 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
    1099                 :     OGRFeature* poFeature;
    1100                 : #ifdef DEBUG_OGR2SQLITE
    1101                 :     CPLDebug("OGR2SQLITE", "Column %d", nCol);
    1102                 : #endif
    1103                 : 
    1104            1314 :     OGR2SQLITE_GoToWishedIndex(pMyCursor);
    1105                 : 
    1106            1314 :     poFeature = pMyCursor->poFeature;
    1107            1314 :     if( poFeature == NULL)
    1108               0 :         return SQLITE_ERROR;
    1109                 : 
    1110            1314 :     OGRFeatureDefn* poFDefn = pMyCursor->poLayer->GetLayerDefn();
    1111            1314 :     int nFieldCount = poFDefn->GetFieldCount();
    1112                 : 
    1113            1314 :     if( nCol == nFieldCount )
    1114                 :     {
    1115                 :         sqlite3_result_text(pContext,
    1116              22 :                             poFeature->GetStyleString(),
    1117              44 :                             -1, SQLITE_TRANSIENT);
    1118              22 :         return SQLITE_OK;
    1119                 :     }
    1120            1292 :     else if( nCol == (nFieldCount + 1) &&
    1121                 :              poFDefn->GetGeomType() != wkbNone )
    1122                 :     {
    1123             149 :         if( pMyCursor->nGeomBLOBLen < 0 )
    1124                 :         {
    1125             133 :             OGRGeometry* poGeom = poFeature->GetGeometryRef();
    1126             133 :             if( poGeom == NULL )
    1127                 :             {
    1128              50 :                 pMyCursor->nGeomBLOBLen = 0;
    1129                 :             }
    1130                 :             else
    1131                 :             {
    1132              83 :                 CPLAssert(pMyCursor->pabyGeomBLOB == NULL);
    1133                 : 
    1134              83 :                 OGRSpatialReference* poSRS = poGeom->getSpatialReference();
    1135              83 :                 int nSRSId = pMyCursor->pVTab->poModule->FetchSRSId(poSRS);
    1136                 : 
    1137              83 :                 if( OGRSQLiteLayer::ExportSpatiaLiteGeometry(
    1138                 :                         poGeom, nSRSId, wkbNDR, FALSE, FALSE, FALSE,
    1139                 :                         &pMyCursor->pabyGeomBLOB,
    1140                 :                         &pMyCursor->nGeomBLOBLen ) != CE_None )
    1141                 :                 {
    1142               0 :                     pMyCursor->nGeomBLOBLen = 0;
    1143                 :                 }
    1144                 :             }
    1145                 :         }
    1146                 : 
    1147             149 :         if( pMyCursor->nGeomBLOBLen == 0 )
    1148                 :         {
    1149              50 :             sqlite3_result_null(pContext);
    1150                 :         }
    1151                 :         else
    1152                 :         {
    1153                 :             GByte *pabyGeomBLOBDup = (GByte*)
    1154              99 :                                 CPLMalloc(pMyCursor->nGeomBLOBLen);
    1155                 :             memcpy(pabyGeomBLOBDup,
    1156              99 :                    pMyCursor->pabyGeomBLOB, pMyCursor->nGeomBLOBLen);
    1157                 :             sqlite3_result_blob(pContext, pabyGeomBLOBDup,
    1158              99 :                                 pMyCursor->nGeomBLOBLen, CPLFree);
    1159                 :         }
    1160                 : 
    1161             149 :         return SQLITE_OK;
    1162                 :     }
    1163            1143 :     else if( nCol < 0 || nCol >= nFieldCount )
    1164                 :     {
    1165               0 :         return SQLITE_ERROR;
    1166                 :     }
    1167            1143 :     else if( !poFeature->IsFieldSet(nCol) )
    1168                 :     {
    1169             116 :         sqlite3_result_null(pContext);
    1170             116 :         return SQLITE_OK;
    1171                 :     }
    1172                 : 
    1173            1027 :     switch( poFDefn->GetFieldDefn(nCol)->GetType() )
    1174                 :     {
    1175                 :         case OFTInteger:
    1176                 :             sqlite3_result_int(pContext,
    1177             119 :                                poFeature->GetFieldAsInteger(nCol));
    1178             119 :             break;
    1179                 : 
    1180                 :         case OFTReal:
    1181                 :             sqlite3_result_double(pContext,
    1182             266 :                                   poFeature->GetFieldAsDouble(nCol));
    1183             266 :             break;
    1184                 : 
    1185                 :         case OFTBinary:
    1186                 :         {
    1187                 :             int nSize;
    1188             100 :             GByte* pBlob = poFeature->GetFieldAsBinary(nCol, &nSize);
    1189             100 :             sqlite3_result_blob(pContext, pBlob, nSize, SQLITE_TRANSIENT);
    1190             100 :             break;
    1191                 :         }
    1192                 : 
    1193                 :         case OFTDateTime:
    1194                 :         {
    1195                 :             int nYear, nMonth, nDay, nHour, nMinute, nSecond, nTZ;
    1196                 :             poFeature->GetFieldAsDateTime(nCol, &nYear, &nMonth, &nDay,
    1197              96 :                                           &nHour, &nMinute, &nSecond, &nTZ);
    1198                 :             char szBuffer[64];
    1199                 :             sprintf(szBuffer, "%04d-%02d-%02dT%02d:%02d:%02d",
    1200              96 :                     nYear, nMonth, nDay, nHour, nMinute, nSecond);
    1201                 :             sqlite3_result_text(pContext,
    1202                 :                                 szBuffer,
    1203              96 :                                 -1, SQLITE_TRANSIENT);
    1204              96 :             break;
    1205                 :         }
    1206                 : 
    1207                 :         case OFTDate:
    1208                 :         {
    1209                 :             int nYear, nMonth, nDay, nHour, nMinute, nSecond, nTZ;
    1210                 :             poFeature->GetFieldAsDateTime(nCol, &nYear, &nMonth, &nDay,
    1211              96 :                                           &nHour, &nMinute, &nSecond, &nTZ);
    1212                 :             char szBuffer[64];
    1213              96 :             sprintf(szBuffer, "%04d-%02d-%02dT", nYear, nMonth, nDay);
    1214                 :             sqlite3_result_text(pContext,
    1215                 :                                 szBuffer,
    1216              96 :                                 -1, SQLITE_TRANSIENT);
    1217              96 :             break;
    1218                 :         }
    1219                 : 
    1220                 :         case OFTTime:
    1221                 :         {
    1222                 :             int nYear, nMonth, nDay, nHour, nMinute, nSecond, nTZ;
    1223                 :             poFeature->GetFieldAsDateTime(nCol, &nYear, &nMonth, &nDay,
    1224              92 :                                           &nHour, &nMinute, &nSecond, &nTZ);
    1225                 :             char szBuffer[64];
    1226              92 :             sprintf(szBuffer, "%02d:%02d:%02d", nHour, nMinute, nSecond);
    1227                 :             sqlite3_result_text(pContext,
    1228                 :                                 szBuffer,
    1229              92 :                                 -1, SQLITE_TRANSIENT);
    1230              92 :             break;
    1231                 :         }
    1232                 : 
    1233                 :         default:
    1234                 :             sqlite3_result_text(pContext,
    1235                 :                                 poFeature->GetFieldAsString(nCol),
    1236             258 :                                 -1, SQLITE_TRANSIENT);
    1237                 :             break;
    1238                 :     }
    1239                 : 
    1240            1027 :     return SQLITE_OK;
    1241                 : }
    1242                 : 
    1243                 : /************************************************************************/
    1244                 : /*                         OGR2SQLITE_Rowid()                           */
    1245                 : /************************************************************************/
    1246                 : 
    1247                 : static
    1248              38 : int OGR2SQLITE_Rowid(sqlite3_vtab_cursor* pCursor, sqlite3_int64 *pRowid)
    1249                 : {
    1250              38 :     OGR2SQLITE_vtab_cursor* pMyCursor = (OGR2SQLITE_vtab_cursor*) pCursor;
    1251                 : #ifdef DEBUG_OGR2SQLITE
    1252                 :     CPLDebug("OGR2SQLITE", "Rowid");
    1253                 : #endif
    1254                 : 
    1255              38 :     OGR2SQLITE_GoToWishedIndex(pMyCursor);
    1256                 : 
    1257              38 :     if( pMyCursor->poFeature == NULL)
    1258               0 :         return SQLITE_ERROR;
    1259                 : 
    1260              38 :     *pRowid = pMyCursor->poFeature->GetFID();
    1261                 : 
    1262              38 :     return SQLITE_OK;
    1263                 : }
    1264                 : 
    1265                 : /************************************************************************/
    1266                 : /*                         OGR2SQLITE_Rename()                          */
    1267                 : /************************************************************************/
    1268                 : 
    1269                 : static
    1270               0 : int OGR2SQLITE_Rename(sqlite3_vtab *pVtab, const char *zNew)
    1271                 : {
    1272                 :     //CPLDebug("OGR2SQLITE", "Rename");
    1273               0 :     return SQLITE_ERROR;
    1274                 : }
    1275                 : 
    1276                 : #if 0
    1277                 : /************************************************************************/
    1278                 : /*                        OGR2SQLITE_FindFunction()                     */
    1279                 : /************************************************************************/
    1280                 : 
    1281                 : static
    1282                 : int OGR2SQLITE_FindFunction(sqlite3_vtab *pVtab,
    1283                 :                             int nArg,
    1284                 :                             const char *zName,
    1285                 :                             void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
    1286                 :                             void **ppArg)
    1287                 : {
    1288                 :     CPLDebug("OGR2SQLITE", "FindFunction %s", zName);
    1289                 : 
    1290                 :     return 0;
    1291                 : }
    1292                 : #endif
    1293                 : 
    1294                 : /************************************************************************/
    1295                 : /*                     OGR2SQLITE_FeatureFromArgs()                     */
    1296                 : /************************************************************************/
    1297                 : 
    1298              14 : static OGRFeature* OGR2SQLITE_FeatureFromArgs(OGRLayer* poLayer,
    1299                 :                                               int argc,
    1300                 :                                               sqlite3_value **argv)
    1301                 : {
    1302              14 :     OGRFeatureDefn* poLayerDefn = poLayer->GetLayerDefn();
    1303              14 :     int nFieldCount = poLayerDefn->GetFieldCount();
    1304              14 :     int bHasGeomField = (poLayerDefn->GetGeomType() != wkbNone);
    1305              14 :     if( argc != 2 + nFieldCount + 1 + bHasGeomField)
    1306                 :     {
    1307                 :         CPLDebug("OGR2SQLITE", "Did not get expect argument count : %d, %d", argc,
    1308               0 :                     2 + nFieldCount + 1 + bHasGeomField);
    1309               0 :         return NULL;
    1310                 :     }
    1311                 : 
    1312              14 :     OGRFeature* poFeature = new OGRFeature(poLayerDefn);
    1313                 :     int i;
    1314             128 :     for(i = 0; i < nFieldCount; i++)
    1315                 :     {
    1316             114 :         switch( sqlite3_value_type(argv[2 + i]) )
    1317                 :         {
    1318                 :             case SQLITE_INTEGER:
    1319                 :                 //FIXME use int64 when OGR has 64bit integer support
    1320              14 :                 poFeature->SetField(i, sqlite3_value_int(argv[2 + i]));
    1321              14 :                 break;
    1322                 :             case SQLITE_FLOAT:
    1323              10 :                 poFeature->SetField(i, sqlite3_value_double(argv[2 + i]));
    1324              10 :                 break;
    1325                 :             case SQLITE_TEXT:
    1326                 :             {
    1327              42 :                 const char* pszValue = (const char*) sqlite3_value_text(argv[2 + i]);
    1328              42 :                 switch( poLayerDefn->GetFieldDefn(i)->GetType() )
    1329                 :                 {
    1330                 :                     case OFTDate:
    1331                 :                     case OFTTime:
    1332                 :                     case OFTDateTime:
    1333                 :                     {
    1334              24 :                         if( !OGRSQLITEStringToDateTimeField( poFeature, i, pszValue ) )
    1335               0 :                             poFeature->SetField(i, pszValue);
    1336              24 :                         break;
    1337                 :                     }
    1338                 : 
    1339                 :                     default:
    1340              18 :                         poFeature->SetField(i, pszValue);
    1341                 :                         break;
    1342                 :                 }
    1343              42 :                 break;
    1344                 :             }
    1345                 :             case SQLITE_BLOB:
    1346                 :             {
    1347               8 :                 GByte* paby = (GByte *) sqlite3_value_blob (argv[2 + i]);
    1348               8 :                 int nLen = sqlite3_value_bytes (argv[2 + i]);
    1349               8 :                 poFeature->SetField(i, nLen, paby);
    1350                 :                 break;
    1351                 :             }
    1352                 :             default:
    1353                 :                 break;
    1354                 :         }
    1355                 :     }
    1356                 : 
    1357              14 :     int nStyleIdx = 2 + nFieldCount;
    1358              14 :     if( sqlite3_value_type(argv[nStyleIdx]) == SQLITE_TEXT )
    1359                 :     {
    1360               2 :         poFeature->SetStyleString((const char*) sqlite3_value_text(argv[nStyleIdx]));
    1361                 :     }
    1362                 : 
    1363              14 :     if( bHasGeomField )
    1364                 :     {
    1365               8 :         int nGeomFieldIdx = 2 + nFieldCount + 1;
    1366               8 :         if( sqlite3_value_type(argv[nGeomFieldIdx]) == SQLITE_BLOB )
    1367                 :         {
    1368               2 :             GByte* pabyBlob = (GByte *) sqlite3_value_blob (argv[nGeomFieldIdx]);
    1369               2 :             int nLen = sqlite3_value_bytes (argv[nGeomFieldIdx]);
    1370               2 :             OGRGeometry* poGeom = NULL;
    1371               2 :             if( OGRSQLiteLayer::ImportSpatiaLiteGeometry(
    1372                 :                             pabyBlob, nLen, &poGeom ) == CE_None )
    1373                 :             {
    1374               2 :                 poFeature->SetGeometryDirectly(poGeom);
    1375                 :             }
    1376                 :         }
    1377                 :     }
    1378                 : 
    1379              14 :     if( sqlite3_value_type(argv[1]) == SQLITE_INTEGER )
    1380              10 :         poFeature->SetFID( sqlite3_value_int64(argv[1]) );
    1381                 : 
    1382              14 :     return poFeature;
    1383                 : }
    1384                 : 
    1385                 : /************************************************************************/
    1386                 : /*                            OGR2SQLITE_Update()                       */
    1387                 : /************************************************************************/
    1388                 : 
    1389                 : static
    1390              22 : int OGR2SQLITE_Update(sqlite3_vtab *pVTab,
    1391                 :                       int argc,
    1392                 :                       sqlite3_value **argv,
    1393                 :                       sqlite_int64 *pRowid)
    1394                 : {
    1395              22 :     CPLDebug("OGR2SQLITE", "OGR2SQLITE_Update");
    1396                 : 
    1397              22 :     OGR2SQLITE_vtab* pMyVTab = (OGR2SQLITE_vtab*) pVTab;
    1398              22 :     OGRLayer* poLayer = pMyVTab->poLayer;
    1399                 : 
    1400              22 :     if( argc == 1 )
    1401                 :     {
    1402                 :          /* DELETE */
    1403                 : 
    1404               8 :         OGRErr eErr = poLayer->DeleteFeature(sqlite3_value_int64(argv[0]));
    1405                 : 
    1406               8 :         return ( eErr == OGRERR_NONE ) ? SQLITE_OK : SQLITE_ERROR;
    1407                 :     }
    1408              14 :     else if( argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_NULL )
    1409                 :     {
    1410                 :          /* INSERT */
    1411                 : 
    1412               8 :         OGRFeature* poFeature = OGR2SQLITE_FeatureFromArgs(poLayer, argc, argv);
    1413               8 :         if( poFeature == NULL )
    1414               0 :             return SQLITE_ERROR;
    1415                 : 
    1416               8 :         OGRErr eErr = poLayer->CreateFeature(poFeature);
    1417               8 :         if( eErr == OGRERR_NONE )
    1418               8 :             *pRowid = poFeature->GetFID();
    1419                 : 
    1420               8 :         delete poFeature;
    1421                 : 
    1422               8 :         return ( eErr == OGRERR_NONE ) ? SQLITE_OK : SQLITE_ERROR;
    1423                 :     }
    1424               6 :     else if( argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_INTEGER &&
    1425                 :              sqlite3_value_type(argv[1]) == SQLITE_INTEGER &&
    1426                 :              sqlite3_value_int64(argv[0]) == sqlite3_value_int64(argv[1]) )
    1427                 :     {
    1428                 :         /* UPDATE */
    1429                 : 
    1430               6 :         OGRFeature* poFeature = OGR2SQLITE_FeatureFromArgs(poLayer, argc, argv);
    1431               6 :         if( poFeature == NULL )
    1432               0 :             return SQLITE_ERROR;
    1433                 : 
    1434               6 :         OGRErr eErr = poLayer->SetFeature(poFeature);
    1435                 : 
    1436               6 :         delete poFeature;
    1437                 : 
    1438               6 :         return ( eErr == OGRERR_NONE ) ? SQLITE_OK : SQLITE_ERROR;
    1439                 :     }
    1440                 : 
    1441                 :     // UPDATE table SET rowid=rowid+1 WHERE ... unsupported
    1442                 : 
    1443               0 :     return SQLITE_ERROR;
    1444                 : }
    1445                 : 
    1446                 : /************************************************************************/
    1447                 : /*                        sOGR2SQLITEModule                             */
    1448                 : /************************************************************************/
    1449                 : 
    1450                 : static const struct sqlite3_module sOGR2SQLITEModule =
    1451                 : {
    1452                 :     1, /* iVersion */
    1453                 :     OGR2SQLITE_ConnectCreate, /* xCreate */
    1454                 :     OGR2SQLITE_ConnectCreate, /* xConnect */
    1455                 :     OGR2SQLITE_BestIndex,
    1456                 :     OGR2SQLITE_DisconnectDestroy, /* xDisconnect */
    1457                 :     OGR2SQLITE_DisconnectDestroy, /* xDestroy */
    1458                 :     OGR2SQLITE_Open,
    1459                 :     OGR2SQLITE_Close,
    1460                 :     OGR2SQLITE_Filter,
    1461                 :     OGR2SQLITE_Next,
    1462                 :     OGR2SQLITE_Eof,
    1463                 :     OGR2SQLITE_Column,
    1464                 :     OGR2SQLITE_Rowid,
    1465                 :     OGR2SQLITE_Update,
    1466                 :     NULL, /* xBegin */
    1467                 :     NULL, /* xSync */
    1468                 :     NULL, /* xCommit */
    1469                 :     NULL, /* xFindFunctionRollback */
    1470                 :     NULL, /* xFindFunction */  // OGR2SQLITE_FindFunction;
    1471                 :     OGR2SQLITE_Rename
    1472                 : };
    1473                 : 
    1474                 : /************************************************************************/
    1475                 : /*                           OGR2SQLITE_GetLayer()                      */
    1476                 : /************************************************************************/
    1477                 : 
    1478                 : static
    1479              10 : OGRLayer* OGR2SQLITE_GetLayer(const char* pszFuncName,
    1480                 :                               sqlite3_context* pContext,
    1481                 :                               int argc, sqlite3_value** argv)
    1482                 : {
    1483              10 :     if( argc != 1 )
    1484                 :     {
    1485                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1486                 :                  "%s: %s(): %s",
    1487                 :                  "VirtualOGR",
    1488                 :                  pszFuncName,
    1489               0 :                  "Invalid number of arguments");
    1490               0 :         sqlite3_result_null (pContext);
    1491               0 :         return NULL;
    1492                 :     }
    1493                 : 
    1494              10 :     if( sqlite3_value_type (argv[0]) != SQLITE_TEXT )
    1495                 :     {
    1496                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1497                 :                  "%s: %s(): %s",
    1498                 :                  "VirtualOGR",
    1499                 :                  pszFuncName,
    1500               1 :                  "Invalid argument type");
    1501               1 :         sqlite3_result_null (pContext);
    1502               1 :         return NULL;
    1503                 :     }
    1504                 : 
    1505               9 :     const char* pszVTableName = (const char*)sqlite3_value_text(argv[0]);
    1506                 : 
    1507                 :     OGR2SQLITEModule* poModule =
    1508               9 :                     (OGR2SQLITEModule*) sqlite3_user_data(pContext);
    1509                 : 
    1510               9 :     OGRLayer* poLayer = poModule->GetLayerForVTable(OGRSQLiteParamsUnquote(pszVTableName));
    1511               9 :     if( poLayer == NULL )
    1512                 :     {
    1513                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1514                 :                  "%s: %s(): %s",
    1515                 :                  "VirtualOGR",
    1516                 :                  pszFuncName,
    1517               1 :                  "Unknown virtual table");
    1518               1 :         sqlite3_result_null (pContext);
    1519               1 :         return NULL;
    1520                 :     }
    1521                 : 
    1522               8 :     return poLayer;
    1523                 : }
    1524                 : 
    1525                 : /************************************************************************/
    1526                 : /*                       OGR2SQLITE_ogr_layer_Extent()                  */
    1527                 : /************************************************************************/
    1528                 : 
    1529                 : static
    1530               4 : void OGR2SQLITE_ogr_layer_Extent(sqlite3_context* pContext,
    1531                 :                                  int argc, sqlite3_value** argv)
    1532                 : {
    1533                 :     OGRLayer* poLayer = OGR2SQLITE_GetLayer("ogr_layer_Extent",
    1534               4 :                                             pContext, argc, argv);
    1535               4 :     if( poLayer == NULL )
    1536               2 :         return;
    1537                 : 
    1538                 :     OGR2SQLITEModule* poModule =
    1539               2 :                     (OGR2SQLITEModule*) sqlite3_user_data(pContext);
    1540                 : 
    1541               2 :     if( poLayer->GetGeomType() == wkbNone )
    1542                 :     {
    1543               1 :         sqlite3_result_null (pContext);
    1544               1 :         return;
    1545                 :     }
    1546                 : 
    1547               1 :     OGREnvelope sExtent;
    1548               1 :     if( poLayer->GetExtent(&sExtent) != OGRERR_NONE )
    1549                 :     {
    1550                 :         CPLError(CE_Failure, CPLE_AppDefined,
    1551                 :                  "%s: %s(): %s",
    1552                 :                  "VirtualOGR",
    1553                 :                  "ogr_layer_Extent",
    1554               0 :                  "Cannot fetch layer extent");
    1555               0 :         sqlite3_result_null (pContext);
    1556               0 :         return;
    1557                 :     }
    1558                 : 
    1559               1 :     OGRPolygon oPoly;
    1560               1 :     OGRLinearRing* poRing = new OGRLinearRing();
    1561               1 :     oPoly.addRingDirectly(poRing);
    1562               1 :     poRing->addPoint(sExtent.MinX, sExtent.MinY);
    1563               1 :     poRing->addPoint(sExtent.MaxX, sExtent.MinY);
    1564               1 :     poRing->addPoint(sExtent.MaxX, sExtent.MaxY);
    1565               1 :     poRing->addPoint(sExtent.MinX, sExtent.MaxY);
    1566               1 :     poRing->addPoint(sExtent.MinX, sExtent.MinY);
    1567                 : 
    1568               1 :     GByte* pabySLBLOB = NULL;
    1569               1 :     int nBLOBLen = 0;
    1570               1 :     int nSRID = poModule->FetchSRSId(poLayer->GetSpatialRef());
    1571               1 :     if( OGRSQLiteLayer::ExportSpatiaLiteGeometry(
    1572                 :                     &oPoly, nSRID, wkbNDR, FALSE,
    1573                 :                     FALSE, FALSE, &pabySLBLOB, &nBLOBLen ) == CE_None )
    1574                 :     {
    1575               1 :         sqlite3_result_blob(pContext, pabySLBLOB, nBLOBLen, CPLFree);
    1576                 :     }
    1577                 :     else
    1578                 :     {
    1579               0 :         sqlite3_result_null (pContext);
    1580               1 :     }
    1581                 : }
    1582                 : 
    1583                 : /************************************************************************/
    1584                 : /*                       OGR2SQLITE_ogr_layer_SRID()                    */
    1585                 : /************************************************************************/
    1586                 : 
    1587                 : static
    1588               3 : void OGR2SQLITE_ogr_layer_SRID(sqlite3_context* pContext,
    1589                 :                                  int argc, sqlite3_value** argv)
    1590                 : {
    1591                 :     OGRLayer* poLayer = OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_SRID",
    1592               3 :                                             pContext, argc, argv);
    1593               3 :     if( poLayer == NULL )
    1594               0 :         return;
    1595                 : 
    1596                 :     OGR2SQLITEModule* poModule =
    1597               3 :                     (OGR2SQLITEModule*) sqlite3_user_data(pContext);
    1598                 : 
    1599               3 :     if( poLayer->GetGeomType() == wkbNone )
    1600                 :     {
    1601               1 :         sqlite3_result_null (pContext);
    1602               1 :         return;
    1603                 :     }
    1604                 : 
    1605               2 :     int nSRID = poModule->FetchSRSId(poLayer->GetSpatialRef());
    1606               2 :     sqlite3_result_int(pContext, nSRID);
    1607                 : }
    1608                 : 
    1609                 : /************************************************************************/
    1610                 : /*                 OGR2SQLITE_ogr_layer_GeometryType()                  */
    1611                 : /************************************************************************/
    1612                 : 
    1613                 : static
    1614               2 : void OGR2SQLITE_ogr_layer_GeometryType(sqlite3_context* pContext,
    1615                 :                                  int argc, sqlite3_value** argv)
    1616                 : {
    1617                 :     OGRLayer* poLayer = OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_GeometryType",
    1618               2 :                                             pContext, argc, argv);
    1619               2 :     if( poLayer == NULL )
    1620               0 :         return;
    1621                 : 
    1622               2 :     OGRwkbGeometryType eType = poLayer->GetGeomType();
    1623                 : 
    1624               2 :     if( eType == wkbNone )
    1625                 :     {
    1626               1 :         sqlite3_result_null (pContext);
    1627               1 :         return;
    1628                 :     }
    1629                 : 
    1630               1 :     const char* psz2DName = OGRToOGCGeomType(eType);
    1631               1 :     if( eType & wkb25DBit )
    1632               0 :         sqlite3_result_text( pContext, CPLSPrintf("%s Z", psz2DName), -1, SQLITE_TRANSIENT );
    1633                 :     else
    1634               1 :         sqlite3_result_text( pContext, psz2DName, -1, SQLITE_TRANSIENT );
    1635                 : }
    1636                 : 
    1637                 : /************************************************************************/
    1638                 : /*                OGR2SQLITE_ogr_layer_FeatureCount()                   */
    1639                 : /************************************************************************/
    1640                 : 
    1641                 : static
    1642               1 : void OGR2SQLITE_ogr_layer_FeatureCount(sqlite3_context* pContext,
    1643                 :                                        int argc, sqlite3_value** argv)
    1644                 : {
    1645                 :     OGRLayer* poLayer = OGR2SQLITE_GetLayer("OGR2SQLITE_ogr_layer_FeatureCount",
    1646               1 :                                             pContext, argc, argv);
    1647               1 :     if( poLayer == NULL )
    1648               0 :         return;
    1649                 : 
    1650               1 :     sqlite3_result_int64( pContext, poLayer->GetFeatureCount() );
    1651                 : }
    1652                 : 
    1653                 : /************************************************************************/
    1654                 : /*                      OGR2SQLITEDestroyModule()                       */
    1655                 : /************************************************************************/
    1656                 : 
    1657             751 : static void OGR2SQLITEDestroyModule(void* pData)
    1658                 : {
    1659             751 :     CPLDebug("OGR", "Unloading VirtualOGR module");
    1660             751 :     delete (OGR2SQLITEModule*) pData;
    1661             751 : }
    1662                 : 
    1663                 : /* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */
    1664                 : #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
    1665                 : 
    1666                 : /************************************************************************/
    1667                 : /*                    OGR2SQLITESpatialIndex_vtab                       */
    1668                 : /************************************************************************/
    1669                 : 
    1670                 : typedef struct
    1671                 : {
    1672                 :     /* Mandatory fields by sqlite3: don't change or reorder them ! */
    1673                 :     const sqlite3_module *pModule;
    1674                 :     int                   nRef;
    1675                 :     char                 *zErrMsg;
    1676                 : 
    1677                 :     /* Extension fields */
    1678                 :     char                 *pszVTableName;
    1679                 :     OGR2SQLITEModule     *poModule;
    1680                 :     OGRDataSource        *poDS;
    1681                 :     int                   bCloseDS;
    1682                 :     OGRLayer             *poLayer;
    1683                 :     int                   nMyRef;
    1684                 : } OGR2SQLITESpatialIndex_vtab;
    1685                 : 
    1686                 : /************************************************************************/
    1687                 : /*                  OGR2SQLITESpatialIndex_vtab_cursor                  */
    1688                 : /************************************************************************/
    1689                 : 
    1690                 : typedef struct
    1691                 : {
    1692                 :     /* Mandatory fields by sqlite3: don't change or reorder them ! */
    1693                 :     OGR2SQLITESpatialIndex_vtab *pVTab;
    1694                 : 
    1695                 :     /* Extension fields */
    1696                 :     OGRDataSource *poDupDataSource;
    1697                 :     OGRLayer      *poLayer;
    1698                 :     OGRFeature    *poFeature;
    1699                 :     int            bHasSetBounds;
    1700                 :     double         dfMinX, dfMinY, dfMaxX, dfMaxY;
    1701                 : } OGR2SQLITESpatialIndex_vtab_cursor;
    1702                 : 
    1703                 : /************************************************************************/
    1704                 : /*                   OGR2SQLITESpatialIndex_ConnectCreate()             */
    1705                 : /************************************************************************/
    1706                 : 
    1707                 : static
    1708                 : int OGR2SQLITESpatialIndex_ConnectCreate(sqlite3* hDB, void *pAux,
    1709                 :                              int argc, const char *const*argv,
    1710                 :                              sqlite3_vtab **ppVTab, char**pzErr)
    1711                 : {
    1712                 :     OGR2SQLITEModule* poModule = (OGR2SQLITEModule*) pAux;
    1713                 :     OGRLayer* poLayer = NULL;
    1714                 :     OGRDataSource* poDS = NULL;
    1715                 :     int bCloseDS = FALSE;
    1716                 :     int i;
    1717                 : 
    1718                 : #ifdef DEBUG_OGR2SQLITE
    1719                 :     CPLDebug("OGR2SQLITE", "ConnectCreate(%s)", argv[2]);
    1720                 : #endif
    1721                 : 
    1722                 :     /*for(i=0;i<argc;i++)
    1723                 :         printf("[%d] %s\n", i, argv[i]);*/
    1724                 : 
    1725                 : /* -------------------------------------------------------------------- */
    1726                 : /*      If called from ogrexecutesql.cpp                                */
    1727                 : /* -------------------------------------------------------------------- */
    1728                 :     poDS = poModule->GetDS();
    1729                 :     if( poDS == NULL )
    1730                 :         return SQLITE_ERROR;
    1731                 : 
    1732                 :     if( argc != 10 )
    1733                 :     {
    1734                 :         *pzErr = sqlite3_mprintf(
    1735                 :             "Expected syntax: CREATE VIRTUAL TABLE xxx USING "
    1736                 :             "VirtualOGRSpatialIndex(ds_idx, layer_name, pkid, xmin, xmax, ymin, ymax)");
    1737                 :         return SQLITE_ERROR;
    1738                 :     }
    1739                 : 
    1740                 :     int nDSIndex = atoi(argv[3]);
    1741                 :     if( nDSIndex >= 0 )
    1742                 :     {
    1743                 :         poDS = poModule->GetExtraDS(nDSIndex);
    1744                 :         if( poDS == NULL )
    1745                 :         {
    1746                 :             *pzErr = sqlite3_mprintf("Invalid dataset index : %d", nDSIndex);
    1747                 :             return SQLITE_ERROR;
    1748                 :         }
    1749                 :     }
    1750                 : 
    1751                 :     poDS = (OGRDataSource*) OGROpen( poDS->GetName(), FALSE, NULL);
    1752                 :     if( poDS == NULL )
    1753                 :     {
    1754                 :         return SQLITE_ERROR;
    1755                 :     }
    1756                 :     bCloseDS = TRUE;
    1757                 : 
    1758                 :     CPLString osLayerName(OGRSQLiteParamsUnquote(argv[4]));
    1759                 : 
    1760                 :     poLayer = poDS->GetLayerByName(osLayerName);
    1761                 :     if( poLayer == NULL )
    1762                 :     {
    1763                 :         *pzErr = sqlite3_mprintf( "Cannot find layer '%s' in '%s'",
    1764                 :                                     osLayerName.c_str(), poDS->GetName() );
    1765                 :         return SQLITE_ERROR;
    1766                 :     }
    1767                 : 
    1768                 :     OGR2SQLITESpatialIndex_vtab* vtab =
    1769                 :                 (OGR2SQLITESpatialIndex_vtab*) CPLCalloc(1, sizeof(OGR2SQLITESpatialIndex_vtab));
    1770                 :     /* We dont need to fill the non-extended fields */
    1771                 :     vtab->pszVTableName = CPLStrdup(OGRSQLiteEscapeName(argv[2]));
    1772                 :     vtab->poModule = poModule;
    1773                 :     vtab->poDS = poDS;
    1774                 :     vtab->bCloseDS = bCloseDS;
    1775                 :     vtab->poLayer = poLayer;
    1776                 :     vtab->nMyRef = 0;
    1777                 : 
    1778                 :     *ppVTab = (sqlite3_vtab*) vtab;
    1779                 : 
    1780                 :     CPLString osSQL;
    1781                 :     osSQL = "CREATE TABLE ";
    1782                 :     osSQL += "\"";
    1783                 :     osSQL += OGRSQLiteEscapeName(argv[2]);
    1784                 :     osSQL += "\"";
    1785                 :     osSQL += "(";
    1786                 : 
    1787                 :     int bAddComma = FALSE;
    1788                 : 
    1789                 :     for(i=0;i<5;i++)
    1790                 :     {
    1791                 :         if( bAddComma )
    1792                 :             osSQL += ",";
    1793                 :         bAddComma = TRUE;
    1794                 : 
    1795                 :         osSQL += "\"";
    1796                 :         osSQL += OGRSQLiteEscapeName(OGRSQLiteParamsUnquote(argv[5+i]));
    1797                 :         osSQL += "\"";
    1798                 :         osSQL += " ";
    1799                 :         osSQL += (i == 0) ? "INTEGER" : "FLOAT";
    1800                 :     }
    1801                 : 
    1802                 :     osSQL += ")";
    1803                 : 
    1804                 :     CPLDebug("OGR2SQLITE", "sqlite3_declare_vtab(%s)", osSQL.c_str());
    1805                 :     if (sqlite3_declare_vtab (hDB, osSQL.c_str()) != SQLITE_OK)
    1806                 :     {
    1807                 :         *pzErr = sqlite3_mprintf("CREATE VIRTUAL: invalid SQL statement : %s",
    1808                 :                                  osSQL.c_str());
    1809                 :         return SQLITE_ERROR;
    1810                 :     }
    1811                 : 
    1812                 :     return SQLITE_OK;
    1813                 : }
    1814                 : 
    1815                 : /************************************************************************/
    1816                 : /*                      OGR2SQLITESpatialIndex_BestIndex()              */
    1817                 : /************************************************************************/
    1818                 : 
    1819                 : static
    1820                 : int OGR2SQLITESpatialIndex_BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info* pIndex)
    1821                 : {
    1822                 : #ifdef DEBUG_OGR2SQLITE
    1823                 :     CPLDebug("OGR2SQLITE", "BestIndex");
    1824                 : #endif
    1825                 : 
    1826                 :     int i;
    1827                 : 
    1828                 :     int bMinX = FALSE, bMinY = FALSE, bMaxX = FALSE, bMaxY = FALSE;
    1829                 : 
    1830                 :     for (i = 0; i < pIndex->nConstraint; i++)
    1831                 :     {
    1832                 :         int iCol = pIndex->aConstraint[i].iColumn;
    1833                 :         /* MinX */
    1834                 :         if( !bMinX && iCol == 1 && pIndex->aConstraint[i].usable &&
    1835                 :             (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LE ||
    1836                 :                 pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LT) )
    1837                 :             bMinX = TRUE;
    1838                 :         /* MaxX */
    1839                 :         else if( !bMaxX && iCol == 2 && pIndex->aConstraint[i].usable &&
    1840                 :             (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GE ||
    1841                 :                 pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GT) )
    1842                 :             bMaxX = TRUE;
    1843                 :         /* MinY */
    1844                 :         else if( !bMinY && iCol == 3 && pIndex->aConstraint[i].usable &&
    1845                 :             (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LE ||
    1846                 :                 pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_LT) )
    1847                 :             bMinY = TRUE;
    1848                 :         /* MaxY */
    1849                 :         else if( !bMaxY && iCol == 4 && pIndex->aConstraint[i].usable &&
    1850                 :             (pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GE ||
    1851                 :                 pIndex->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GT) )
    1852                 :             bMaxY = TRUE;
    1853                 :         else
    1854                 :             break;
    1855                 :     }
    1856                 : 
    1857                 :     if( bMinX && bMinY && bMaxX && bMaxY )
    1858                 :     {
    1859                 :         CPLAssert( pIndex->nConstraint == 4 );
    1860                 : 
    1861                 :         int nConstraints = 0;
    1862                 :         for (i = 0; i < pIndex->nConstraint; i++)
    1863                 :         {
    1864                 :             pIndex->aConstraintUsage[i].argvIndex = nConstraints + 1;
    1865                 :             pIndex->aConstraintUsage[i].omit = TRUE;
    1866                 : 
    1867                 :             nConstraints ++;
    1868                 :         }
    1869                 : 
    1870                 :         int* panConstraints = (int*)
    1871                 :                     sqlite3_malloc( sizeof(int) * (1 + 2 * nConstraints) );
    1872                 :         panConstraints[0] = nConstraints;
    1873                 : 
    1874                 :         nConstraints = 0;
    1875                 : 
    1876                 :         for (i = 0; i < pIndex->nConstraint; i++)
    1877                 :         {
    1878                 :             if (pIndex->aConstraintUsage[i].omit)
    1879                 :             {
    1880                 :                 panConstraints[2 * nConstraints + 1] =
    1881                 :                                             pIndex->aConstraint[i].iColumn;
    1882                 :                 panConstraints[2 * nConstraints + 2] =
    1883                 :                                             pIndex->aConstraint[i].op;
    1884                 : 
    1885                 :                 nConstraints ++;
    1886                 :             }
    1887                 :         }
    1888                 : 
    1889                 :         pIndex->idxStr = (char *) panConstraints;
    1890                 :         pIndex->needToFreeIdxStr = TRUE;
    1891                 : 
    1892                 :         pIndex->orderByConsumed = FALSE;
    1893                 :         pIndex->idxNum = 0;
    1894                 : 
    1895                 :         return SQLITE_OK;
    1896                 :     }
    1897                 :     else
    1898                 :     {
    1899                 :         CPLDebug("OGR2SQLITE", "OGR2SQLITESpatialIndex_BestIndex: unhandled request");
    1900                 :         return SQLITE_ERROR;
    1901                 : /*
    1902                 :         for (i = 0; i < pIndex->nConstraint; i++)
    1903                 :         {
    1904                 :             pIndex->aConstraintUsage[i].argvIndex = 0;
    1905                 :             pIndex->aConstraintUsage[i].omit = FALSE;
    1906                 :         }
    1907                 : 
    1908                 :         pIndex->idxStr = NULL;
    1909                 :         pIndex->needToFreeIdxStr = FALSE;
    1910                 : */
    1911                 :     }
    1912                 : }
    1913                 : 
    1914                 : /************************************************************************/
    1915                 : /*                  OGR2SQLITESpatialIndex_DisconnectDestroy()          */
    1916                 : /************************************************************************/
    1917                 : 
    1918                 : static
    1919                 : int OGR2SQLITESpatialIndex_DisconnectDestroy(sqlite3_vtab *pVTab)
    1920                 : {
    1921                 :     OGR2SQLITESpatialIndex_vtab* pMyVTab = (OGR2SQLITESpatialIndex_vtab*) pVTab;
    1922                 : 
    1923                 : #ifdef DEBUG_OGR2SQLITE
    1924                 :     CPLDebug("OGR2SQLITE", "DisconnectDestroy(%s)",pMyVTab->pszVTableName);
    1925                 : #endif
    1926                 : 
    1927                 :     sqlite3_free(pMyVTab->zErrMsg);
    1928                 :     if( pMyVTab->bCloseDS )
    1929                 :         delete pMyVTab->poDS;
    1930                 :     CPLFree(pMyVTab->pszVTableName);
    1931                 :     CPLFree(pMyVTab);
    1932                 : 
    1933                 :     return SQLITE_OK;
    1934                 : }
    1935                 : 
    1936                 : /************************************************************************/
    1937                 : /*                    OGR2SQLITESpatialIndex_Open()                     */
    1938                 : /************************************************************************/
    1939                 : 
    1940                 : static
    1941                 : int OGR2SQLITESpatialIndex_Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
    1942                 : {
    1943                 :     OGR2SQLITESpatialIndex_vtab* pMyVTab = (OGR2SQLITESpatialIndex_vtab*) pVTab;
    1944                 : #ifdef DEBUG_OGR2SQLITE
    1945                 :     CPLDebug("OGR2SQLITE", "Open(%s, %s)",
    1946                 :              pMyVTab->poDS->GetName(), pMyVTab->poLayer->GetName());
    1947                 : #endif
    1948                 : 
    1949                 :     OGRDataSource* poDupDataSource = NULL;
    1950                 :     OGRLayer* poLayer = NULL;
    1951                 : 
    1952                 :     if( pMyVTab->nMyRef == 0 )
    1953                 :     {
    1954                 :         poLayer = pMyVTab->poLayer;
    1955                 :     }
    1956                 :     else
    1957                 :     {
    1958                 :         poDupDataSource =
    1959                 :             (OGRDataSource*) OGROpen(pMyVTab->poDS->GetName(), FALSE, NULL);
    1960                 :         if( poDupDataSource == NULL )
    1961                 :             return SQLITE_ERROR;
    1962                 :         poLayer = poDupDataSource->GetLayerByName(
    1963                 :                                                 pMyVTab->poLayer->GetName());
    1964                 :         if( poLayer == NULL )
    1965                 :         {
    1966                 :             delete poDupDataSource;
    1967                 :             return SQLITE_ERROR;
    1968                 :         }
    1969                 :         if( !poLayer->GetLayerDefn()->
    1970                 :                 IsSame(pMyVTab->poLayer->GetLayerDefn()) )
    1971                 :         {
    1972                 :             delete poDupDataSource;
    1973                 :             return SQLITE_ERROR;
    1974                 :         }
    1975                 :     }
    1976                 :     pMyVTab->nMyRef ++;
    1977                 : 
    1978                 :     OGR2SQLITESpatialIndex_vtab_cursor* pCursor = (OGR2SQLITESpatialIndex_vtab_cursor*)
    1979                 :                                 CPLCalloc(1, sizeof(OGR2SQLITESpatialIndex_vtab_cursor));
    1980                 :     /* We dont need to fill the non-extended fields */
    1981                 :     *ppCursor = (sqlite3_vtab_cursor *)pCursor;
    1982                 : 
    1983                 :     pCursor->poDupDataSource = poDupDataSource;
    1984                 :     pCursor->poLayer = poLayer;
    1985                 :     pCursor->poLayer->ResetReading();
    1986                 :     pCursor->poFeature = NULL;
    1987                 : 
    1988                 :     return SQLITE_OK;
    1989                 : }
    1990                 : 
    1991                 : /************************************************************************/
    1992                 : /*                      OGR2SQLITESpatialIndex_Close()                  */
    1993                 : /************************************************************************/
    1994                 : 
    1995                 : static
    1996                 : int OGR2SQLITESpatialIndex_Close(sqlite3_vtab_cursor* pCursor)
    1997                 : {
    1998                 :     OGR2SQLITESpatialIndex_vtab_cursor* pMyCursor = (OGR2SQLITESpatialIndex_vtab_cursor*) pCursor;
    1999                 :     OGR2SQLITESpatialIndex_vtab* pMyVTab = pMyCursor->pVTab;
    2000                 : #ifdef DEBUG_OGR2SQLITE
    2001                 :     CPLDebug("OGR2SQLITE", "Close(%s, %s)",
    2002                 :              pMyVTab->poDS->GetName(), pMyVTab->poLayer->GetName());
    2003                 : #endif
    2004                 :     pMyVTab->nMyRef --;
    2005                 : 
    2006                 :     delete pMyCursor->poFeature;
    2007                 :     delete pMyCursor->poDupDataSource;
    2008                 : 
    2009                 :     CPLFree(pCursor);
    2010                 : 
    2011                 :     return SQLITE_OK;
    2012                 : }
    2013                 : 
    2014                 : /************************************************************************/
    2015                 : /*                     OGR2SQLITESpatialIndex_Filter()                  */
    2016                 : /************************************************************************/
    2017                 : 
    2018                 : static
    2019                 : int OGR2SQLITESpatialIndex_Filter(sqlite3_vtab_cursor* pCursor,
    2020                 :                       int idxNum, const char *idxStr,
    2021                 :                       int argc, sqlite3_value **argv)
    2022                 : {
    2023                 :     OGR2SQLITESpatialIndex_vtab_cursor* pMyCursor = (OGR2SQLITESpatialIndex_vtab_cursor*) pCursor;
    2024                 : #ifdef DEBUG_OGR2SQLITE
    2025                 :     CPLDebug("OGR2SQLITE", "Filter");
    2026                 : #endif
    2027                 : 
    2028                 :     int* panConstraints = (int*) idxStr;
    2029                 :     int nConstraints = panConstraints ? panConstraints[0] : 0;
    2030                 : 
    2031                 :     if( nConstraints != argc )
    2032                 :         return SQLITE_ERROR;
    2033                 : 
    2034                 :     int i;
    2035                 :     double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0;
    2036                 :     for (i = 0; i < argc; i++)
    2037                 :     {
    2038                 :         int nCol = panConstraints[2 * i + 1];
    2039                 :         if( nCol < 0 )
    2040                 :             return SQLITE_ERROR;
    2041                 : 
    2042                 :         double dfVal;
    2043                 :         if (sqlite3_value_type (argv[i]) == SQLITE_INTEGER)
    2044                 :             dfVal = sqlite3_value_int64 (argv[i]);
    2045                 :         else if (sqlite3_value_type (argv[i]) == SQLITE_FLOAT)
    2046                 :             dfVal = sqlite3_value_double (argv[i]);
    2047                 :         else
    2048                 :             return SQLITE_ERROR;
    2049                 : 
    2050                 :         if( nCol == 1 )
    2051                 :             dfMaxX = dfVal;
    2052                 :         else if( nCol == 2 )
    2053                 :             dfMinX = dfVal;
    2054                 :         else if( nCol == 3 )
    2055                 :             dfMaxY = dfVal;
    2056                 :         else if( nCol == 4 )
    2057                 :             dfMinY = dfVal;
    2058                 :         else
    2059                 :             return SQLITE_ERROR;
    2060                 :     }
    2061                 : 
    2062                 : #ifdef DEBUG_OGR2SQLITE
    2063                 :     CPLDebug("OGR2SQLITE", "Spatial filter : %.18g, %.18g, %.18g, %.18g",
    2064                 :               dfMinX, dfMinY, dfMaxX, dfMaxY);
    2065                 : #endif
    2066                 : 
    2067                 :     pMyCursor->poLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
    2068                 :     pMyCursor->poLayer->ResetReading();
    2069                 : 
    2070                 :     pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
    2071                 :     pMyCursor->bHasSetBounds = FALSE;
    2072                 : 
    2073                 :     return SQLITE_OK;
    2074                 : }
    2075                 : 
    2076                 : /************************************************************************/
    2077                 : /*                    OGR2SQLITESpatialIndex_Next()                     */
    2078                 : /************************************************************************/
    2079                 : 
    2080                 : static
    2081                 : int OGR2SQLITESpatialIndex_Next(sqlite3_vtab_cursor* pCursor)
    2082                 : {
    2083                 :     OGR2SQLITESpatialIndex_vtab_cursor* pMyCursor = (OGR2SQLITESpatialIndex_vtab_cursor*) pCursor;
    2084                 : #ifdef DEBUG_OGR2SQLITE
    2085                 :     CPLDebug("OGR2SQLITE", "Next");
    2086                 : #endif
    2087                 : 
    2088                 :     delete pMyCursor->poFeature;
    2089                 :     pMyCursor->poFeature = pMyCursor->poLayer->GetNextFeature();
    2090                 :     pMyCursor->bHasSetBounds = FALSE;
    2091                 : 
    2092                 :     return SQLITE_OK;
    2093                 : }
    2094                 : 
    2095                 : /************************************************************************/
    2096                 : /*                      OGR2SQLITESpatialIndex_Eof()                    */
    2097                 : /************************************************************************/
    2098                 : 
    2099                 : static
    2100                 : int OGR2SQLITESpatialIndex_Eof(sqlite3_vtab_cursor* pCursor)
    2101                 : {
    2102                 :     OGR2SQLITESpatialIndex_vtab_cursor* pMyCursor = (OGR2SQLITESpatialIndex_vtab_cursor*) pCursor;
    2103                 : #ifdef DEBUG_OGR2SQLITE
    2104                 :     CPLDebug("OGR2SQLITE", "Eof");
    2105                 : #endif
    2106                 : 
    2107                 :     return (pMyCursor->poFeature == NULL);
    2108                 : }
    2109                 : 
    2110                 : /************************************************************************/
    2111                 : /*                    OGR2SQLITESpatialIndex_Column()                   */
    2112                 : /************************************************************************/
    2113                 : 
    2114                 : static
    2115                 : int OGR2SQLITESpatialIndex_Column(sqlite3_vtab_cursor* pCursor,
    2116                 :                       sqlite3_context* pContext, int nCol)
    2117                 : {
    2118                 :     OGR2SQLITESpatialIndex_vtab_cursor* pMyCursor = (OGR2SQLITESpatialIndex_vtab_cursor*) pCursor;
    2119                 :     OGRFeature* poFeature;
    2120                 : #ifdef DEBUG_OGR2SQLITE
    2121                 :     CPLDebug("OGR2SQLITE", "Column %d", nCol);
    2122                 : #endif
    2123                 : 
    2124                 :     poFeature = pMyCursor->poFeature;
    2125                 :     if( poFeature == NULL)
    2126                 :         return SQLITE_ERROR;
    2127                 : 
    2128                 :     if( nCol == 0 )
    2129                 :     {
    2130                 :         CPLDebug("OGR2SQLITE", "--> FID = %ld", poFeature->GetFID());
    2131                 :         sqlite3_result_int64(pContext, poFeature->GetFID());
    2132                 :         return SQLITE_OK;
    2133                 :     }
    2134                 : 
    2135                 :     if( !pMyCursor->bHasSetBounds )
    2136                 :     {
    2137                 :         OGRGeometry* poGeom = poFeature->GetGeometryRef();
    2138                 :         if( poGeom != NULL && !poGeom->IsEmpty() )
    2139                 :         {
    2140                 :             OGREnvelope sEnvelope;
    2141                 :             poGeom->getEnvelope(&sEnvelope);
    2142                 :             pMyCursor->bHasSetBounds = TRUE;
    2143                 :             pMyCursor->dfMinX = sEnvelope.MinX;
    2144                 :             pMyCursor->dfMinY = sEnvelope.MinY;
    2145                 :             pMyCursor->dfMaxX = sEnvelope.MaxX;
    2146                 :             pMyCursor->dfMaxY = sEnvelope.MaxY;
    2147                 :         }
    2148                 :     }
    2149                 :     if( !pMyCursor->bHasSetBounds )
    2150                 :     {
    2151                 :         sqlite3_result_null(pContext);
    2152                 :         return SQLITE_OK;
    2153                 :     }
    2154                 : 
    2155                 :     if( nCol == 1 )
    2156                 :     {
    2157                 :         sqlite3_result_double(pContext, pMyCursor->dfMinX);
    2158                 :         return SQLITE_OK;
    2159                 :     }
    2160                 :     if( nCol == 2 )
    2161                 :     {
    2162                 :         sqlite3_result_double(pContext, pMyCursor->dfMaxX);
    2163                 :         return SQLITE_OK;
    2164                 :     }
    2165                 :     if( nCol == 3 )
    2166                 :     {
    2167                 :         sqlite3_result_double(pContext, pMyCursor->dfMinY);
    2168                 :         return SQLITE_OK;
    2169                 :     }
    2170                 :     if( nCol == 4 )
    2171                 :     {
    2172                 :         sqlite3_result_double(pContext, pMyCursor->dfMaxY);
    2173                 :         return SQLITE_OK;
    2174                 :     }
    2175                 : 
    2176                 :     return SQLITE_ERROR;
    2177                 : }
    2178                 : 
    2179                 : /************************************************************************/
    2180                 : /*                    OGR2SQLITESpatialIndex_Rowid()                    */
    2181                 : /************************************************************************/
    2182                 : 
    2183                 : static
    2184                 : int OGR2SQLITESpatialIndex_Rowid(sqlite3_vtab_cursor* pCursor, sqlite3_int64 *pRowid)
    2185                 : {
    2186                 : #ifdef DEBUG_OGR2SQLITE
    2187                 :     CPLDebug("OGR2SQLITE", "Rowid");
    2188                 : #endif
    2189                 : 
    2190                 :     return SQLITE_ERROR;
    2191                 : }
    2192                 : 
    2193                 : /************************************************************************/
    2194                 : /*                   OGR2SQLITESpatialIndex_Rename()                    */
    2195                 : /************************************************************************/
    2196                 : 
    2197                 : static
    2198                 : int OGR2SQLITESpatialIndex_Rename(sqlite3_vtab *pVtab, const char *zNew)
    2199                 : {
    2200                 :     //CPLDebug("OGR2SQLITE", "Rename");
    2201                 :     return SQLITE_ERROR;
    2202                 : }
    2203                 : 
    2204                 : /************************************************************************/
    2205                 : /*                       sOGR2SQLITESpatialIndex                        */
    2206                 : /************************************************************************/
    2207                 : 
    2208                 : static const struct sqlite3_module sOGR2SQLITESpatialIndex =
    2209                 : {
    2210                 :     1, /* iVersion */
    2211                 :     OGR2SQLITESpatialIndex_ConnectCreate, /* xCreate */
    2212                 :     OGR2SQLITESpatialIndex_ConnectCreate, /* xConnect */
    2213                 :     OGR2SQLITESpatialIndex_BestIndex,
    2214                 :     OGR2SQLITESpatialIndex_DisconnectDestroy, /* xDisconnect */
    2215                 :     OGR2SQLITESpatialIndex_DisconnectDestroy, /* xDestroy */
    2216                 :     OGR2SQLITESpatialIndex_Open,
    2217                 :     OGR2SQLITESpatialIndex_Close,
    2218                 :     OGR2SQLITESpatialIndex_Filter,
    2219                 :     OGR2SQLITESpatialIndex_Next,
    2220                 :     OGR2SQLITESpatialIndex_Eof,
    2221                 :     OGR2SQLITESpatialIndex_Column,
    2222                 :     OGR2SQLITESpatialIndex_Rowid,
    2223                 :     NULL, /* xUpdate */
    2224                 :     NULL, /* xBegin */
    2225                 :     NULL, /* xSync */
    2226                 :     NULL, /* xCommit */
    2227                 :     NULL, /* xFindFunctionRollback */
    2228                 :     NULL, /* xFindFunction */
    2229                 :     OGR2SQLITESpatialIndex_Rename
    2230                 : };
    2231                 : #endif // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
    2232                 : 
    2233                 : /************************************************************************/
    2234                 : /*                              Setup()                                 */
    2235                 : /************************************************************************/
    2236                 : 
    2237             751 : int OGR2SQLITEModule::Setup(sqlite3* hDB)
    2238                 : {
    2239                 :     int rc;
    2240                 : 
    2241             751 :     this->hDB = hDB;
    2242                 : 
    2243                 :     rc = sqlite3_create_module_v2(hDB, "VirtualOGR", &sOGR2SQLITEModule, this,
    2244             751 :                                   OGR2SQLITEDestroyModule);
    2245             751 :     if( rc != SQLITE_OK )
    2246               0 :         return FALSE;
    2247                 : 
    2248                 : #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
    2249                 :     rc = sqlite3_create_module(hDB, "VirtualOGRSpatialIndex",
    2250                 :                                 &sOGR2SQLITESpatialIndex, this);
    2251                 :     if( rc != SQLITE_OK )
    2252                 :         return FALSE;
    2253                 : #endif // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX
    2254                 : 
    2255                 :     rc= sqlite3_create_function(hDB, "ogr_layer_Extent", 1, SQLITE_ANY, this,
    2256             751 :                                 OGR2SQLITE_ogr_layer_Extent, NULL, NULL);
    2257             751 :     if( rc != SQLITE_OK )
    2258               0 :         return FALSE;
    2259                 : 
    2260                 :     rc= sqlite3_create_function(hDB, "ogr_layer_SRID", 1, SQLITE_ANY, this,
    2261             751 :                                 OGR2SQLITE_ogr_layer_SRID, NULL, NULL);
    2262             751 :     if( rc != SQLITE_OK )
    2263               0 :         return FALSE;
    2264                 : 
    2265                 :     rc= sqlite3_create_function(hDB, "ogr_layer_GeometryType", 1, SQLITE_ANY, this,
    2266             751 :                                 OGR2SQLITE_ogr_layer_GeometryType, NULL, NULL);
    2267             751 :     if( rc != SQLITE_OK )
    2268               0 :         return FALSE;
    2269                 : 
    2270                 :     rc= sqlite3_create_function(hDB, "ogr_layer_FeatureCount", 1, SQLITE_ANY, this,
    2271             751 :                                 OGR2SQLITE_ogr_layer_FeatureCount, NULL, NULL);
    2272             751 :     if( rc != SQLITE_OK )
    2273               0 :         return FALSE;
    2274                 : 
    2275             751 :     SetHandleSQLFunctions(OGRSQLiteRegisterSQLFunctions(hDB));
    2276                 : 
    2277             751 :     return TRUE;
    2278                 : }
    2279                 : 
    2280                 : /************************************************************************/
    2281                 : /*                        OGR2SQLITE_Setup()                            */
    2282                 : /************************************************************************/
    2283                 : 
    2284             487 : OGR2SQLITEModule* OGR2SQLITE_Setup(OGRDataSource* poDS,
    2285                 :                                    OGRSQLiteDataSource* poSQLiteDS)
    2286                 : {
    2287             487 :     OGR2SQLITEModule* poModule = new OGR2SQLITEModule();
    2288             487 :     poModule->Setup(poDS, poSQLiteDS);
    2289             487 :     return poModule;
    2290                 : }
    2291                 : 
    2292                 : /************************************************************************/
    2293                 : /*                       OGR2SQLITE_AddExtraDS()                        */
    2294                 : /************************************************************************/
    2295                 : 
    2296               4 : int OGR2SQLITE_AddExtraDS(OGR2SQLITEModule* poModule, OGRDataSource* poDS)
    2297                 : {
    2298               4 :     return poModule->AddExtraDS(poDS);
    2299                 : }
    2300                 : 
    2301                 : #ifdef VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
    2302                 : 
    2303                 : /************************************************************************/
    2304                 : /*                        sqlite3_extension_init()                      */
    2305                 : /************************************************************************/
    2306                 : 
    2307                 : CPL_C_START
    2308                 : int CPL_DLL sqlite3_extension_init (sqlite3 * hDB, char **pzErrMsg,
    2309                 :                                     const sqlite3_api_routines * pApi);
    2310                 : CPL_C_END
    2311                 : 
    2312                 : /* Entry point for dynamically loaded extension (typically called by load_extension()) */
    2313               1 : int sqlite3_extension_init (sqlite3 * hDB, char **pzErrMsg,
    2314                 :                             const sqlite3_api_routines * pApi)
    2315                 : {
    2316               1 :     CPLDebug("OGR", "OGR SQLite extension loading...");
    2317                 : 
    2318               1 :     SQLITE_EXTENSION_INIT2(pApi);
    2319                 : 
    2320               1 :     *pzErrMsg = NULL;
    2321                 : 
    2322               1 :     OGRRegisterAll();
    2323                 : 
    2324               1 :     OGR2SQLITEModule* poModule = new OGR2SQLITEModule();
    2325               1 :     if( poModule->Setup(hDB) )
    2326                 :     {
    2327               1 :         CPLDebug("OGR", "OGR SQLite extension loaded");
    2328               1 :         return SQLITE_OK;
    2329                 :     }
    2330                 :     else
    2331               0 :         return SQLITE_ERROR;
    2332                 : }
    2333                 : 
    2334                 : #endif // VIRTUAL_OGR_DYNAMIC_EXTENSION_ENABLED
    2335                 : 
    2336                 : /************************************************************************/
    2337                 : /*                        OGR2SQLITE_static_register()                  */
    2338                 : /************************************************************************/
    2339                 : 
    2340                 : CPL_C_START
    2341                 : int CPL_DLL OGR2SQLITE_static_register (sqlite3 * hDB, char **pzErrMsg,
    2342                 :                                         const sqlite3_api_routines * pApi);
    2343                 : CPL_C_END
    2344                 : 
    2345             750 : int OGR2SQLITE_static_register (sqlite3 * hDB, char **pzErrMsg,
    2346                 :                                 const sqlite3_api_routines * pApi)
    2347                 : {
    2348             750 :     SQLITE_EXTENSION_INIT2 (pApi);
    2349                 : 
    2350             750 :     *pzErrMsg = NULL;
    2351                 : 
    2352                 :     /* The config option is turned off by ogrsqliteexecutesql.cpp that needs */
    2353                 :     /* to create a custom module */
    2354             750 :     if( CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "YES")) )
    2355                 :     {
    2356                 :         /* Can happen if sqlite is compiled with SQLITE_OMIT_LOAD_EXTENSION (with sqlite 3.6.10 for example) */
    2357                 :         /* We return here OK since it is not vital for regular SQLite dababases */
    2358                 :         /* to load the OGR SQL functions */
    2359             263 :         if( pApi->create_module == NULL )
    2360               0 :             return SQLITE_OK;
    2361                 : 
    2362             263 :         OGR2SQLITEModule* poModule = new OGR2SQLITEModule();
    2363             263 :         return poModule->Setup(hDB) ? SQLITE_OK : SQLITE_ERROR;
    2364                 :     }
    2365                 :     else
    2366                 :     {
    2367                 :         /* Can happen if sqlite is compiled with SQLITE_OMIT_LOAD_EXTENSION (with sqlite 3.6.10 for example) */
    2368                 :         /* We return fail since Setup() will later be called, and crash */
    2369                 :         /* if create_module isn't available */
    2370             487 :         if( pApi->create_module == NULL )
    2371               0 :             return SQLITE_ERROR;
    2372                 :     }
    2373                 : 
    2374             487 :     return SQLITE_OK;
    2375                 : }
    2376                 : 
    2377                 : /************************************************************************/
    2378                 : /*                           OGR2SQLITE_Register()                      */
    2379                 : /************************************************************************/
    2380                 : 
    2381                 : /* We call this function so that each time a db is created, */
    2382                 : /* OGR2SQLITE_static_register is called, to initialize the sqlite3_api */
    2383                 : /* structure with the right pointers. */
    2384                 : 
    2385             753 : void OGR2SQLITE_Register()
    2386                 : {
    2387             753 :     sqlite3_auto_extension ((void (*)(void)) OGR2SQLITE_static_register);
    2388             753 : }
    2389                 : 
    2390                 : #endif // HAVE_SQLITE_VFS

Generated by: LCOV version 1.7