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