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