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
|